Exemplo n.º 1
0
        public static IHTMLElement GetSelectedChildEditField(IHTMLElement parent, MarkupRange selection)
        {
            if (selection == null || !selection.Positioned)
            {
                Trace.Fail("Selection is invalid!");
                return(null);
            }

            IHTMLElement element = selection.ParentElement();

            if (element == null || !HTMLElementHelper.IsChildOrSameElement(parent, element))
            {
                return(null);
            }

            do
            {
                if (InlineEditField.IsEditField(element))
                {
                    return(element);
                }

                element = element.parentElement;
            } while (element != null && element.sourceIndex != parent.sourceIndex);

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Returns a rectangle based on the given IDisplayPointer
        /// </summary>
        /// <param name="element">The element that contains the display pointer</param>
        /// <param name="displayPointer"></param>
        /// <returns></returns>
        protected Rectangle GetLineRect(IHTMLElement element, IDisplayPointerRaw displayPointer)
        {
            ILineInfo lineInfo;

            displayPointer.GetLineInfo(out lineInfo);

            Rectangle elementRect = HTMLElementHelper.GetClientRectangle(element);

            //determine the rectangle based on the baseline and text height.
            //Note: baseline is relative to the parent element, and the text
            //height includes the textDescent, which is below the baseline
            int lineBottom = elementRect.Y + lineInfo.baseLine + lineInfo.textDescent;
            int lineTop    = lineBottom - lineInfo.textHeight;
            int lineLeft   = elementRect.X;
            int lineWidth  = elementRect.Width;

            //Calculate the height of line.  Since the bottom pixel line is shared by the next line,
            //we subtract 1 from the height. This height exactly matches height of the caret.
            //Note: this height adjustment fixes a bug that can occur with some text styles where a
            //caret placed on the next line is detected as being within this rectangle.
            int lineHeight = lineInfo.textHeight - 1;

            //create a rectangle that exactly fits the caret for this line
            //Note: this can be verified by painting a rectangle over the line using this rectangle
            return(new Rectangle(lineLeft, lineTop, lineWidth, lineHeight));
        }
Exemplo n.º 3
0
        protected override int HandlePreHandleEvent(int inEvtDispId, IHTMLEventObj pIEventObj)
        {
            if (ShouldProcessEvents(inEvtDispId, pIEventObj))
            {
                if (inEvtDispId == DISPID_HTMLELEMENTEVENTS2.ONMOUSEDOWN)
                {
                    leftMouseDown = (Control.MouseButtons & MouseButtons.Left) == MouseButtons.Left;

                    if (!Selected && HTMLElementHelper.IsChildOrSameElement(HTMLElement, pIEventObj.srcElement))
                    {
                        return(HandlePreHandleEventLeftMouseButtonDown(inEvtDispId, pIEventObj));
                    }

                    rightMouseDown = (Control.MouseButtons & MouseButtons.Right) == MouseButtons.Right;
                    if (rightMouseDown)
                    {
                        //cancel the event so that the editor doesn't try to do a right drag drop
                        //we'll handle showing the context menu on our own.
                        return(HRESULT.S_OK);
                    }
                }

                int controlResult = base.HandlePreHandleEvent(inEvtDispId, pIEventObj);


                UpdateCursor(Selected, inEvtDispId, pIEventObj);

                if (_resizerControl.Mode == SizerMode.Resizing)
                {
                    //if the control is resizing, kill all events so that the editor doesn't
                    //try to do a drag and drop.
                    return(HRESULT.S_OK);
                }
                else
                {
                    if (_dragDropController.PreHandleEvent(inEvtDispId, pIEventObj) == HRESULT.S_OK)
                    {
                        return(HRESULT.S_OK);
                    }

                    //eat the mouse events so that the editor doesn't try to
                    //do anything funny (like opening a browser URL).
                    //Note: Allow non-left clicks through for right-click context menus
                    switch (inEvtDispId)
                    {
                    case DISPID_HTMLELEMENTEVENTS2.ONMOUSEUP:
                        if (rightMouseDown & (Control.MouseButtons & MouseButtons.Right) != MouseButtons.Right)
                        {
                            rightMouseDown = false;
                            Point p = EditorContext.PointToScreen(new Point(pIEventObj.clientX, pIEventObj.clientY));
                            EditorContext.ShowContextMenu(p);
                            return(HRESULT.S_OK);
                        }
                        return(leftMouseDown ? HRESULT.S_OK : HRESULT.S_FALSE);
                    }
                }
                return(controlResult);
            }
            return(HRESULT.S_FALSE);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns an array of the parent elements that match the specified filter.
        /// </summary>
        /// <param name="filter"></param>
        /// <returns>an array of matching parents (closest parent at index zero)</returns>
        public IHTMLElement[] GetParentElements(IHTMLElementFilter filter)
        {
            ArrayList    list   = null;
            IHTMLElement parent = CurrentScope;

            while (parent != null)
            {
                if (filter(parent))
                {
                    if (list == null)
                    {
                        list = new ArrayList();
                    }
                    list.Add(parent);
                }
                parent = parent.parentElement;
            }
            if (list != null)
            {
                return(HTMLElementHelper.ToElementArray(list));
            }
            else
            {
                return(new IHTMLElement[0]);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Fixes up all the headers in the entire markupRange.
        /// </summary>
        /// <param name="turnBold">Whether or not the text should be turning bold.</param>
        private void FixupHeaders(bool turnBold)
        {
            IHTMLElement elementStartHeader = markupRange.Start.GetParentElement(ElementFilters.HEADER_ELEMENTS);
            IHTMLElement elementEndHeader   = markupRange.End.GetParentElement(ElementFilters.HEADER_ELEMENTS);
            MarkupRange  currentRange       = markupRange.Clone();

            if (elementStartHeader != null)
            {
                // Takes care of the following cases:
                //  <h1>...|blah|...</h1>
                //  <h1>...|blah...</h1>...|...
                MarkupRange startRange = markupServices.CreateMarkupRange(elementStartHeader, false);
                startRange.Start.MoveToPointer(markupRange.Start);

                if (startRange.End.IsRightOf(markupRange.End))
                {
                    startRange.End.MoveToPointer(markupRange.End);
                }

                FixupHeaderRange(startRange, turnBold);

                currentRange.Start.MoveAdjacentToElement(elementStartHeader, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                if (currentRange.End.IsLeftOf(currentRange.Start))
                {
                    currentRange.End.MoveToPointer(currentRange.Start);
                }
            }

            if (elementEndHeader != null && !HTMLElementHelper.ElementsAreEqual(elementStartHeader, elementEndHeader))
            {
                // Takes care of the following case:
                //  ...|...<h1>...blah|...</h1>
                MarkupRange endRange = markupServices.CreateMarkupRange(elementEndHeader, false);
                endRange.End.MoveToPointer(markupRange.End);

                FixupHeaderRange(endRange, turnBold);

                currentRange.End.MoveAdjacentToElement(elementEndHeader, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);
                if (currentRange.Start.IsRightOf(currentRange.End))
                {
                    currentRange.Start.MoveToPointer(currentRange.End);
                }
            }

            if (!markupRange.InRange(currentRange))
            {
                return;
            }

            IHTMLElement[] headerElements = currentRange.GetElements(ElementFilters.HEADER_ELEMENTS, true);
            if (headerElements != null && headerElements.Length > 0)
            {
                foreach (IHTMLElement element in headerElements)
                {
                    MarkupRange headerRange = markupServices.CreateMarkupRange(element, false);
                    FixupHeaderRange(headerRange, turnBold);
                }
            }
        }
Exemplo n.º 6
0
        public void RemoveElementsByTagId(_ELEMENT_TAG_ID tagId, bool onlyIfNoAttributes)
        {
            if (tagId == _ELEMENT_TAG_ID.TAGID_NULL)
            {
                return;
            }

            // Remove the tagId up the parent chain
            IHTMLElement currentElement = ParentElement();

            while (currentElement != null)
            {
                if (MarkupServices.GetElementTagId(currentElement) == tagId &&
                    (!onlyIfNoAttributes || !HTMLElementHelper.HasMeaningfulAttributes(currentElement)))
                {
                    try
                    {
                        MarkupServices.RemoveElement(currentElement);
                    }
                    catch (COMException e)
                    {
                        Trace.Fail(String.Format("Failed to remove element ({0}) with error: {1}",
                                                 currentElement.outerHTML, // {0}
                                                 e                         // {1}
                                                 ));
                    }
                }
                currentElement = currentElement.parentElement;
            }

            // Remove any other instances
            IHTMLElement[] elements =
                GetElements(ElementFilters.CreateTagIdFilter(MarkupServices.GetNameForTagId(tagId)), false);
            foreach (IHTMLElement e in elements)
            {
                if (MarkupServices.GetElementTagId(e) == tagId &&
                    (!onlyIfNoAttributes || !HTMLElementHelper.HasMeaningfulAttributes(e)))
                {
                    try
                    {
                        MarkupServices.RemoveElement(e);
                    }
                    catch (COMException ex)
                    {
                        Trace.Fail(String.Format("Failed to remove element ({0}) with error: {1}",
                                                 e.outerHTML, // {0}
                                                 ex           // {1}
                                                 ));
                    }
                }
            }
        }
Exemplo n.º 7
0
        public TableCellEditingElementBehavior GetCellBehavior(IHTMLElement cellElement)
        {
            foreach (TableCellEditingElementBehavior cellBehavior in _cellElementBehaviors)
            {
                if (cellBehavior.Attached && HTMLElementHelper.ElementsAreEqual(cellElement, cellBehavior.HTMLElement))
                {
                    return(cellBehavior);
                }
            }

            // didn't find the behavior
            return(null);
        }
        public static void InsertEditorHtmlIntoElement(IContentSourceSidebarContext contentSourceContext, SmartContentSource source, ISmartContent sContent, IHTMLElement element)
        {
            string content = source.GenerateEditorHtml(sContent, contentSourceContext);

            // If the plugin returned null has the HTML it would like to insert, remove the element from the editor
            if (content == null)
            {
                HTMLElementHelper.RemoveElement(element);
            }
            else
            {
                InsertContentIntoElement(content, sContent, contentSourceContext, element);
            }
        }
Exemplo n.º 9
0
        /// <summary>
        /// Wraps the range from startPointer to endPointer with the given element (as long as the range is non-empty)
        /// and then moves the pointers past the inserted element.
        /// </summary>
        /// <param name="element">The element to wrap the range in.</param>
        /// <param name="markupServices">The MarkupServices for the start and end pointers.</param>
        /// <param name="startPointer">Pointer to place the beginning of the element.</param>
        /// <param name="endPointer">Pointer to place the end of the element.</param>
        private void InsertElement(IHTMLElement element, MshtmlMarkupServices markupServices,
                                   MarkupPointer startPointer, MarkupPointer endPointer)
        {
            Debug.Assert(startPointer.IsLeftOfOrEqualTo(endPointer), "Expected start to be left of or equal to end!");
            Debug.Assert(HTMLElementHelper.ElementsAreEqual(startPointer.CurrentScope, endPointer.CurrentScope),
                         "Expected start and end to be in the same scope, otherwise resulting HTML will be invalid!");

            if (startPointer.IsLeftOf(endPointer))
            {
                markupServices.InsertElement(element, startPointer, endPointer);
            }

            endPointer.Right(true);
            startPointer.MoveToPointer(endPointer);
        }
        /// <summary>
        /// Delayed processing for showing tooltips (only show them if the user hovers
        /// over a link for more than a specified period of time)
        /// </summary>
        /// <param name="sender">sender</param>
        /// <param name="e">event args</param>
        private void toolTipDelayTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                // get the delay element from the timer
                ToolTipDelayTimer toolTipDelayTimer = sender as ToolTipDelayTimer;
                IHTMLElement      delayElement      = toolTipDelayTimer.DelayElement;

                // stop and dispose timer
                toolTipDelayTimer.Stop();
                toolTipDelayTimer.Dispose();

                // determine the link element the mouse is currently over and check to  see
                // if the delay element is the same as the current element -- if so, show the tooltip
                IHTMLElement mouseOverElement = _htmlEditorControl.ElementAtPoint(Control.MousePosition);
                if (mouseOverElement != null && (GetLinkElement(mouseOverElement) == delayElement) && !navigatedToCurrentLinkElement && currentLinkElement != null)
                {
                    // calculate the screen coordinate of the top of the current link element
                    int   elementClientY  = HTMLElementHelper.GetTopRelativeToClient(mouseOverElement);
                    Point elementScreenPt = _htmlEditorControl.ClientPointToScreenPoint(new Point(0, elementClientY));

                    // set location - x-based on mouse, y-based on top of element (minus height of tooltip)
                    toolTip.Location = new Point(Control.MousePosition.X, elementScreenPt.Y - 20);

                    // set tooltip text
                    string href = (string)currentLinkElement.getAttribute("href", 2);                        // 2 means don't auto-escape
                    href = StringHelper.Ellipsis(href, 35);
                    toolTip.SetToolTip(String.Format(CultureInfo.CurrentCulture, Res.Get(StringId.LinkToolTip), href));

                    // start timer which monitors whether the main frame is still active and
                    // hides the tooltip if it does not
                    _frameActiveTimer          = new Timer();
                    _frameActiveTimer.Interval = 100;
                    _frameActiveTimer.Tick    += new EventHandler(frameActiveTimer_Tick);
                    _frameActiveTimer.Start();
                }
            }
            catch (Exception ex)
            {
                // eat exceptions that occur in here (bizzare timing bugs can occur w/ drag and
                // drop of images -- this is harmless and the user shouldn't be burdened with
                // an error message
                Debug.Fail("Unexpected error during tool tip delay timer: " + ex.ToString());
            }
        }
Exemplo n.º 11
0
        private IHTMLElement GetTargetCell(Point clientPoint)
        {
            // maximum amount of scanning buffer is based on cell spacing
            int maxScanningRange = Math.Max(TableHelper.GetAttributeAsInteger(_table.cellSpacing), 2);

            // copy client point so we can modify the x-coordinate while scanning
            Point targetPoint = new Point(clientPoint.X, clientPoint.Y);

            // if we go past the end of the table allow the cell closest to the cursor
            // to become the target cell (necessary for sizing the table larger)
            Point          xTargetPoint = new Point(targetPoint.X, targetPoint.Y);
            IHTMLTableCell targetCell   = null;

            while (targetCell == null && xTargetPoint.X >= (targetPoint.X - maxScanningRange))   // 0 )
            {
                // determine the cell we are over
                targetCell = _editorContext.ElementFromClientPoint(xTargetPoint) as IHTMLTableCell;

                // screen cells that don't belong to us
                if (!HTMLElementHelper.ElementsAreEqual(_table as IHTMLElement, TableHelper.GetContainingTableElement(targetCell as IHTMLElement) as IHTMLElement))
                {
                    targetCell = null;
                }

                xTargetPoint.X--;
            }


            // if we got a target cell then ensure that the point is over the document area
            if (targetCell != null)
            {
                if (_editorContext.PointIsOverDocumentArea(clientPoint))
                {
                    return(targetCell as IHTMLElement);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 12
0
        public TableSelection(MarkupRange markupRange)
        {
            // calculate the begin and end cells
            IHTMLTableCell beginCell;
            IHTMLTableCell endCell;
            ArrayList      selectedCells;

            FindCellRange(markupRange, out selectedCells, out beginCell, out endCell);

            // see if the two cells have a single containing table
            IHTMLTable table = GetSelectedTable(beginCell, endCell, markupRange) as IHTMLTable;

            // if we have a table then calculate the rest of our states
            if (table != null)
            {
                // validate the table selection
                if (ValidateTableSelection(table, markupRange, out _entireTableSelected))
                {
                    _table = table;

                    _beginCell = beginCell;
                    _endCell   = endCell;

                    // filter selected cells to only include direct descendents of this table (no
                    // cells from nested tables)
                    _selectedCells = new ArrayList();
                    foreach (IHTMLElement cell in selectedCells)
                    {
                        if (HTMLElementHelper.ElementsAreEqual(TableHelper.GetContainingTableElement(cell) as IHTMLElement, _table as IHTMLElement))
                        {
                            _selectedCells.Add(cell);
                        }
                    }

                    _hasContiguousSelection = !HTMLElementHelper.ElementsAreEqual(_beginCell as IHTMLElement, _endCell as IHTMLElement);

                    _beginRow = GetContainingRowForCell(beginCell);
                    _endRow   = GetContainingRowForCell(endCell);

                    _beginColumn = new HTMLTableColumn(_table, beginCell);
                    _endColumn   = new HTMLTableColumn(_table, endCell);
                }
            }
        }
Exemplo n.º 13
0
        //this is similar to the GetTopLevelElements except will also return table cells if correct filter
        // is set and recurse is equal to true
        public IHTMLElement[] GetTopLevelBlocksAndCells(IHTMLElementFilter filter, bool recurse)
        {
            ArrayList list         = new ArrayList();
            Hashtable usedElements = new Hashtable();

            MarkupPointer p       = MarkupServices.CreateMarkupPointer(Start);
            MarkupContext context = p.Right(false);

            //move p through the range to locate each of the top level elements
            while (p.IsLeftOf(End))
            {
                if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope || context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_NoScope)
                {
                    p.MoveAdjacentToElement(context.Element, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);
                    if (usedElements[context.Element] == null)
                    {
                        if (p.IsLeftOfOrEqualTo(End) && (filter == null || filter(context.Element)))
                        {
                            list.Add(context.Element);
                        }
                        //special case--inside of a table element, want to get out the cells inside
                        else if (recurse && ElementFilters.TABLE_ELEMENTS(context.Element))
                        {
                            MarkupRange newRange = MarkupServices.CreateMarkupRange(context.Element);
                            newRange.Start.MoveAdjacentToElement(context.Element, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterBegin);
                            if (newRange.Start.IsLeftOf(Start))
                            {
                                newRange.Start.MoveToPointer(Start);
                            }
                            if (newRange.End.IsRightOf(End))
                            {
                                newRange.End.MoveToPointer(End);
                            }
                            //recursively check inside table element for table cells
                            list.AddRange(newRange.GetTopLevelBlocksAndCells(filter, true));
                        }
                        //cache the fact that we've already tested this element.
                        usedElements[context.Element] = context.Element;
                    }
                }
                p.Right(true, context);
            }
            return(HTMLElementHelper.ToElementArray(list));
        }
Exemplo n.º 14
0
        /// <summary>
        /// <font><span>aaa[splitPoint]bbb</span></font> --> <font><span>aaa</span></font><font>[splitPoint]<span>bbb</span></font>
        /// </summary>
        private void SplitInlineTags(MarkupPointer splitPoint)
        {
            Debug.Assert(splitPoint.Positioned);

            IHTMLElement currentElement = splitPoint.GetParentElement(ElementFilters.CreateElementPassFilter());

            while (currentElement != null)
            {
                if (!ElementFilters.IsInlineElement(currentElement))
                {
                    return;
                }

                IHTMLElement parentElement = currentElement.parentElement;

                MarkupRange currentElementRange = _markupServices.CreateMarkupRange(currentElement, false);

                MarkupRange  leftRange   = _markupServices.CreateMarkupRange();
                IHTMLElement leftElement = _markupServices.CreateElement(_markupServices.GetElementTagId(currentElement), null);
                HTMLElementHelper.CopyAttributes(currentElement, leftElement);
                leftRange.MoveToPointers(currentElementRange.Start, splitPoint);
                _markupServices.InsertElement(leftElement, leftRange.Start, leftRange.End);

                splitPoint.MoveAdjacentToElement(leftElement, _ELEMENT_ADJACENCY.ELEM_ADJ_AfterEnd);

                MarkupRange  rightRange   = _markupServices.CreateMarkupRange();
                IHTMLElement rightElement = _markupServices.CreateElement(_markupServices.GetElementTagId(currentElement), null);
                HTMLElementHelper.CopyAttributes(currentElement, rightElement);
                rightRange.MoveToPointers(splitPoint, currentElementRange.End);

#if DEBUG
                // Verify that the right range does not overlap the left *element*
                MarkupRange leftElementRange = _markupServices.CreateMarkupRange(leftElement, true);
                Debug.Assert(leftElementRange.End.IsLeftOfOrEqualTo(rightRange.Start), "Your right range overlaps the left element that you just created!");
#endif
                _markupServices.InsertElement(rightElement, rightRange.Start, rightRange.End);
                splitPoint.MoveAdjacentToElement(rightElement, _ELEMENT_ADJACENCY.ELEM_ADJ_BeforeBegin);

                _markupServices.RemoveElement(currentElement);

                currentElement = parentElement;
            }
        }
Exemplo n.º 15
0
 protected override bool QueryElementSelected()
 {
     if (_tableIsEditable)
     {
         TableSelection tableSelection = new TableSelection(EditorContext.Selection.SelectedMarkupRange);
         if ((tableSelection.Table != null) && HTMLElementHelper.ElementsAreEqual(HTMLElement, tableSelection.Table as IHTMLElement))
         {
             _currentTableSelection = tableSelection;
             return(true);
         }
         else
         {
             _currentTableSelection = null;
             return(false);
         }
     }
     else
     {
         return(false);
     }
 }
Exemplo n.º 16
0
        private IHTMLElement GetSelectedTable(IHTMLTableCell beginCell, IHTMLTableCell endCell, MarkupRange selectionMarkupRange)
        {
            // screen null cases
            if (beginCell == null || endCell == null)
            {
                return(null);
            }

            // get containing tables
            IHTMLTable beginTable = TableHelper.GetContainingTableElement(beginCell as IHTMLElement);
            IHTMLTable endTable   = TableHelper.GetContainingTableElement(endCell as IHTMLElement);

            // see if they are from the same table
            if (HTMLElementHelper.ElementsAreEqual(beginTable as IHTMLElement, endTable as IHTMLElement))
            {
                return(beginTable as IHTMLElement);
            }
            else
            {
                return(null);
            }
        }
Exemplo n.º 17
0
        private void CopyBodyAttributes(string sourceHtml, IHTMLElement destinationBody)
        {
            Debug.Assert(destinationBody != null, "destinationBody should not be null!");
            if (destinationBody == null)
            {
                return;
            }

            var finder = new BodyTagFinder(sourceHtml);

            finder.Parse();
            if (finder.BodyBeginTag != null)
            {
                StringBuilder bodyAttributes = new StringBuilder();
                foreach (Attr attr in finder.BodyBeginTag.Attributes)
                {
                    bodyAttributes.AppendFormat(CultureInfo.InvariantCulture, "{0} ", attr);
                }
                IHTMLElement sourceBodyElement = EditorContext.MarkupServices.CreateElement(_ELEMENT_TAG_ID.TAGID_BODY, bodyAttributes.ToString());
                HTMLElementHelper.CopyAttributes(sourceBodyElement, destinationBody);
            }
        }
Exemplo n.º 18
0
        public static IHTMLElement[] FindText(string text, IHTMLElement fromElement)
        {
            try
            {
                string normalizedText = NormalizeText(text);

                ArrayList elementList = new ArrayList();
                AddElementsContainingText(normalizedText, fromElement, elementList);
                IHTMLElement[] elements = HTMLElementHelper.ToElementArray(elementList);
                return(elements);
            }
            catch (ArgumentException e)
            {
                Trace.WriteLine(e.Message);
                return(new IHTMLElement[0]);
            }
            catch (Exception e)
            {
                Trace.Fail("exception during findText", e.ToString());
                return(new IHTMLElement[0]);
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Gets the elements in the range that match the filter.
        /// </summary>
        /// <param name="filter">the delegate testing each element to determine if it should be added to the list of elements to return</param>
        /// <param name="inScopeElementsOnly">if true, the only</param>
        /// <returns></returns>
        public IHTMLElement[] GetElements(IHTMLElementFilter filter, bool inScopeElementsOnly)
        {
            ArrayList list = new ArrayList();

            if (!IsEmpty())
            {
                Hashtable     usedElements = new Hashtable();
                MarkupPointer p            = MarkupServices.CreateMarkupPointer(Start);
                MarkupPointer end          = MarkupServices.CreateMarkupPointer(End);
                MarkupContext context      = p.Right(false);

                //move p through the range to locate each the elements adding elements that pass the filter
                while (p.IsLeftOfOrEqualTo(end))
                {
                    if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope ||
                        context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_ExitScope ||
                        context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_NoScope)
                    {
                        if (usedElements[context.Element] == null)
                        {
                            if ((inScopeElementsOnly && isInScope(context.Element)) || !inScopeElementsOnly)
                            {
                                if (filter(context.Element))
                                {
                                    list.Add(context.Element);
                                }
                            }

                            //cache the fact that we've already tested this element.
                            usedElements[context.Element] = context.Element;
                        }
                    }
                    p.Right(true, context);
                }
            }
            return(HTMLElementHelper.ToElementArray(list));
        }
Exemplo n.º 20
0
 public bool Filter(IHTMLElement e)
 {
     return(HTMLElementHelper.ElementsAreEqual(e, _element));
 }
Exemplo n.º 21
0
 void IHtmlEditorCommandSource.ApplyFontSize(float fontSize)
 {
     ApplyFormattingTag("font", "size=\"" + HTMLElementHelper.PointFontSizeToHtmlFontSize(fontSize) + "\"");
 }
Exemplo n.º 22
0
        protected Rectangle GetClientRectangle(ELEMENT_REGION outerBoundary)
        {
            Rectangle elementBounds = GetClientRectangle();

            try
            {
                if (outerBoundary == ELEMENT_REGION.BORDER)
                {
                    return(new Rectangle(elementBounds.Location, elementBounds.Size));
                }

                int marginTop    = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringMarginTop, HTMLElement, null, true);
                int marginBottom = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringMarginBottom, HTMLElement, null, true);
                int marginLeft   = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringMarginLeft, HTMLElement, null, false);
                int marginRight  = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringMarginRight, HTMLElement, null, false);

                int paddingTop    = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringPaddingTop, HTMLElement, null, true);
                int paddingBottom = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringPaddingBottom, HTMLElement, null, true);
                int paddingLeft   = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringPaddingLeft, HTMLElement, null, false);
                int paddingRight  = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringPaddingRight, HTMLElement, null, false);

                int borderTop    = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringBorderTop, HTMLElement, null, true);
                int borderBottom = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringBorderBottom, HTMLElement, null, true);
                int borderLeft   = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringBorderLeft, HTMLElement, null, false);
                int borderRight  = (int)HTMLElementHelper.CSSUnitStringToPointSize(HTMLElementHelper.CSSUnitStringBorderRight, HTMLElement, null, false);

                int offsetX;
                int offsetY;
                int offsetRight;
                int offsetBottom;
                if (outerBoundary == ELEMENT_REGION.PADDING)
                {
                    offsetX      = borderLeft;
                    offsetY      = borderTop;
                    offsetRight  = -borderRight;
                    offsetBottom = -borderBottom;
                }
                else if (outerBoundary == ELEMENT_REGION.CONTENT)
                {
                    offsetX      = paddingLeft + borderLeft;
                    offsetY      = paddingTop + borderTop;
                    offsetRight  = -paddingRight - borderRight;
                    offsetBottom = -paddingBottom - borderBottom;
                }
                else if (outerBoundary == ELEMENT_REGION.MARGIN)
                {
                    offsetX      = -marginLeft;
                    offsetY      = -marginTop;
                    offsetRight  = marginRight;
                    offsetBottom = marginBottom;
                }
                else
                {
                    throw new ArgumentException("Unnsupported ELEMENT_REGION: " + outerBoundary.ToString());
                }

                Rectangle rect = new Rectangle(elementBounds.Location, elementBounds.Size);
                rect.X      += offsetX;
                rect.Y      += offsetY;
                rect.Width  += offsetRight - offsetX;
                rect.Height += offsetBottom - offsetY;
                return(rect);
            }
            catch (Exception e)
            {
                Trace.WriteLine("Error calculating element paint boundary: " + e.ToString());
                return(new Rectangle(elementBounds.Location, elementBounds.Size));
            }
        }
Exemplo n.º 23
0
        private static void ProcessInitializedImages(List <NewImageInfo> newImages, IBlogPostHtmlEditor currentEditor, ContentEditor editor, Control owner, bool selectLastImage)
        {
            // Remove all invalid images first
            List <NewImageInfo> newImagesToUpdate = new List <NewImageInfo>();

            for (int i = 0; i < newImages.Count; i++)
            {
                NewImageInfo info = newImages[i];

                if (info.Remove)
                {
                    using (ContentEditor.EditorUndoUnit undo = new ContentEditor.EditorUndoUnit(currentEditor, true))
                    {
                        info.DisabledImageBehavior.DetachFromElement();
                        HTMLElementHelper.RemoveElement(info.Element);
                        undo.Commit();
                    }
                }
                else
                {
                    newImagesToUpdate.Add(info);
                }
            }

            // Queue up processing for any remaining valid images
            MultiTaskHelper tasks = new MultiTaskHelper(30);

            for (int i = 0; i < newImagesToUpdate.Count; i++)
            {
                bool         lastElement = i == (newImagesToUpdate.Count - 1);
                NewImageInfo info        = newImagesToUpdate[i];

                tasks.AddWork(delegate
                {
                    // WinLive 214012: If the original insertion operation is undone before we get to this point make
                    // sure we don't attempt to update the HTML. Elements that are removed via an undo, but that we
                    // still hold a reference to, are put into another document whose readyState is "uninitialized".
                    // It's also possible that the picture has already been updated if a user undoes and redoes the
                    // initial insertion multiple times.
                    IHTMLDocument2 doc = (IHTMLDocument2)info.Element.document;
                    if (doc == null || doc.readyState.Equals("uninitialized", StringComparison.OrdinalIgnoreCase) ||
                        BlogPostImageDataList.LookupImageDataByInlineUri(editor.ImageList, info.ImageData.InlineImageFile.Uri) != null)
                    {
                        info.DisabledImageBehavior.DetachFromElement();
                        return;
                    }

                    using (new QuickTimer("ProcessInitializedImage"))
                        using (ContentEditor.EditorUndoUnit undo = new ContentEditor.EditorUndoUnit(currentEditor, true))
                        {
                            editor.ImageList.AddImage(info.ImageData);

                            info.Element.setAttribute("src", UrlHelper.SafeToAbsoluteUri(info.ImageData.InlineImageFile.Uri), 0);
                            info.Element.removeAttribute("srcDelay", 0);
                            // Create the decorators
                            ImageEditingPropertyHandler.UpdateImageSource(info.ImageInfo, info.Element, editor, new ImageInsertHandler(), ImageDecoratorInvocationSource.InitialInsert);

                            // Manually detach the behavior so that the image can be selected and resized.
                            info.DisabledImageBehavior.DetachFromElement();

                            if (lastElement)
                            {
                                ApplicationPerformance.EndEvent("InsertImage");
                                HandleNewImage((BlogPostHtmlEditorControl)currentEditor, owner, info.Element, selectLastImage);
                            }

                            undo.Commit();

                            if (editor.ETWProvider != null)
                            {
                                editor.ETWProvider.WriteEvent("InlinePhotoEnd");
                            }
                        }
                });
            }

            // If there were no images to update, stop the perf timer
            if (newImagesToUpdate.Count == 0)
            {
                ApplicationPerformance.EndEvent("InsertImage");
            }

            // When the editor is closing, or changing to a new blog post we need to get rid of this object
            // which will then stop all the unfinished images from continuing to load.
            editor.DisposeOnEditorChange(tasks);
            tasks.Start();
        }
        private void timer_Tick(object sender, EventArgs e)
        {
            if (reentrant)
            {
                return;
            }
            reentrant = true;

            Timer timer = null;

            try
            {
                timer = sender as Timer;
                IHTMLDocument2 document = _browserControl.Document as IHTMLDocument2;

                // make sure the document is ready
                if (!DocumentReady(document))
                {
                    if (TimedOut)
                    {
                        CleanupAndExit(timer);
                    }

                    return;
                }

                if (Ids != null)
                {
                    IHTMLDocument3 doc3 = document as IHTMLDocument3;

                    foreach (string elementId in Ids)
                    {
                        IHTMLStyle3 style3 = (IHTMLStyle3)(doc3.getElementById(elementId)).style;
                        style3.wordWrap = "normal";
                    }

                    int originalWidth  = _browserControl.Width;
                    int originalHeight = _browserControl.Height;
                    foreach (string elementId in Ids)
                    {
                        try
                        {
                            IHTMLElement element = doc3.getElementById(elementId);

                            _browserControl.Height = element.offsetHeight + 2 + 2;

                            element.scrollIntoView(true);

                            Padding padding = HTMLElementHelper.PaddingInPixels(element);

                            Color backgroundColor = HTMLColorHelper.GetBackgroundColor(element, true, null, Color.White);

                            using (Bitmap elementBitmap = GetElementPreviewImage(doc3, element, _browserControl.Width, _browserControl.Height))
                            {
                                _htmlScreenCaptureCore.SetElementCaptureProperties(elementId, elementBitmap, backgroundColor, padding);
                            }
                        }
                        catch (Exception ex)
                        {
                            Trace.Fail("Failed to capture element " + elementId + ": " + ex);
                        }
                    }

                    // Restore the browser control size
                    _browserControl.Width  = originalWidth;
                    _browserControl.Height = originalHeight;
                }



                // fire event to see if the Bitmap is ready
                using (Bitmap bitmap = HtmlScreenCaptureCore.TakeSnapshot((IViewObject)_browserControl.Document, _browserControl.Width, _browserControl.Height))
                {
                    HtmlScreenCaptureAvailableEventArgsCore ea = new HtmlScreenCaptureAvailableEventArgsCore(bitmap);
                    _htmlScreenCaptureCore.FireHtmlScreenCaptureAvailable(ea);

                    if (ea.CaptureCompleted)
                    {
                        // provide the bitmap to our parent object
                        _htmlScreenCaptureCore.SetCapturedBitmap(bitmap);
                        //bitmap.Save(@"c:\temp\captured.bmp");

                        // exit
                        CleanupAndExit(timer);
                    }
                    else if (TimedOut) // if we have timed out then exit
                    {
                        CleanupAndExit(timer);
                    }

                    // otherwise just let the Timer call us again
                    // at the next interval...
                }
            }
            catch (Exception ex)
            {
                _htmlScreenCaptureCore.SetException(ex);
                CleanupAndExit(timer);
            }
            finally
            {
                reentrant = false;
            }
        }
Exemplo n.º 25
0
        /// <summary>
        /// Fixes up a range that is contained in a single header element.
        /// </summary>
        /// <param name="range">A range that is contained in a single header element.</param>
        /// <param name="turnBold">Whether or not the text should be turning bold.</param>
        private void FixupHeaderRange(MarkupRange range, bool turnBold)
        {
            IHTMLElement parentHeaderElement = range.ParentBlockElement();

            if (parentHeaderElement == null || !ElementFilters.IsHeaderElement(parentHeaderElement))
            {
                Debug.Fail("Expected entire range to be inside a single header element.");
                return;
            }

            MarkupRange expandedRange = range.Clone();

            // Make sure we expand the selection to include any <font> tags that may be wrapping us.
            MarkupPointerMoveHelper.MoveUnitBounded(expandedRange.Start, MarkupPointerMoveHelper.MoveDirection.LEFT,
                                                    MarkupPointerAdjacency.BeforeVisible, parentHeaderElement);
            MarkupPointerMoveHelper.MoveUnitBounded(expandedRange.End, MarkupPointerMoveHelper.MoveDirection.RIGHT,
                                                    MarkupPointerAdjacency.BeforeVisible, parentHeaderElement);

            // Walks in-scope elements and clears out any elements or styles that might affect the bold formatting.
            var elementsToRemove = new List <IHTMLElement>();

            expandedRange.WalkRange(
                delegate(MarkupRange currentexpandedRange, MarkupContext context, string text)
            {
                IHTMLElement currentElement = context.Element;
                if (currentElement != null && context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_EnterScope)
                {
                    if (IsStrongOrBold(currentElement))
                    {
                        elementsToRemove.Add(currentElement);
                    }
                    else if (IsFontableElement(currentElement) && HTMLElementHelper.IsBold((IHTMLElement2)currentElement) != turnBold)
                    {
                        currentElement.style.fontWeight = String.Empty;
                    }
                }

                return(true);
            }, true);

            elementsToRemove.ForEach(e => markupServices.RemoveElement(e));

            // Walks the range to find any segments of text that need to be fixed up.
            var rangesToWrap = new List <MarkupRange>();

            range.WalkRange(
                delegate(MarkupRange currentRange, MarkupContext context, string text)
            {
                if (context.Context == _MARKUP_CONTEXT_TYPE.CONTEXT_TYPE_Text)
                {
                    TextStyles currentTextStyles = new TextStyles(currentRange.Start);
                    if (currentTextStyles.Bold != turnBold)
                    {
                        rangesToWrap.Add(currentRange.Clone());
                    }
                }

                return(true);
            }, true);

            rangesToWrap.ForEach(r => WrapRangeInFontIfNecessary(r, turnBold));
        }
 public override IHTMLElement TitleElement(IHTMLDocument2 doc)
 {
     return(HTMLElementHelper.GetFragmentElement((IHTMLDocument3)doc, TITLE_FRAGMENT_ID));
 }
Exemplo n.º 27
0
        private void PasteCellsIntoTable(IHTMLTable sourceTable, TableSelection tableSelection)
        {
            // collect up the top level cells we are pasting
            ArrayList cellsToPaste = new ArrayList();

            foreach (IHTMLTableRow row in sourceTable.rows)
            {
                foreach (IHTMLElement cell in row.cells)
                {
                    cellsToPaste.Add(cell);
                }
            }

            // get the list of cells we are pasting into
            int       appendRows  = 0;
            int       cellsPerRow = 0;
            ArrayList targetCells;

            if (tableSelection.SelectedCells.Count > 1)
            {
                targetCells = tableSelection.SelectedCells;
            }
            else
            {
                targetCells = new ArrayList();
                bool accumulatingCells = false;
                foreach (IHTMLTableRow row in tableSelection.Table.rows)
                {
                    cellsPerRow = row.cells.length;
                    foreach (IHTMLElement cell in row.cells)
                    {
                        if (!accumulatingCells && HTMLElementHelper.ElementsAreEqual(cell, tableSelection.BeginCell as IHTMLElement))
                        {
                            accumulatingCells = true;
                        }

                        if (accumulatingCells)
                        {
                            targetCells.Add(cell);
                        }
                    }
                }

                // if the target cells aren't enough to paste all of the cells, then
                // calculate the number of rows we need to append to fit all of the
                // cells being pasted
                int cellGap = cellsToPaste.Count - targetCells.Count;
                if (cellGap > 0 && cellsPerRow > 0)
                {
                    appendRows = cellGap / cellsPerRow + (cellGap % cellsPerRow == 0 ? 0 : 1);
                }
            }

            // perform the paste
            using (IUndoUnit undoUnit = EditorContext.CreateUndoUnit())
            {
                // append rows if needed
                if (appendRows > 0)
                {
                    // see if we can cast our editor context to the one required
                    // by the table editor
                    IHtmlEditorComponentContext editorContext = EditorContext as IHtmlEditorComponentContext;
                    if (editorContext != null)
                    {
                        // markup range based on last target cell
                        IHTMLElement lastCell      = targetCells[targetCells.Count - 1] as IHTMLElement;
                        MarkupRange  lastCellRange = EditorContext.MarkupServices.CreateMarkupRange(lastCell);
                        for (int i = 0; i < appendRows; i++)
                        {
                            IHTMLTableRow row = TableEditor.InsertRowBelow(editorContext, lastCellRange);
                            foreach (IHTMLElement cell in row.cells)
                            {
                                targetCells.Add(cell);
                            }
                            lastCellRange = EditorContext.MarkupServices.CreateMarkupRange(row as IHTMLElement);
                        }
                    }
                    else
                    {
                        Debug.Fail("Couldn't cast EditorContext!");
                    }
                }

                // do the paste
                for (int i = 0; i < cellsToPaste.Count && i < targetCells.Count; i++)
                {
                    (targetCells[i] as IHTMLElement).innerHTML = (cellsToPaste[i] as IHTMLElement).innerHTML;
                }
                undoUnit.Commit();
            }
        }
Exemplo n.º 28
0
 /// <summary>
 /// Returns the bounds of the element in client-based coordinatates.
 /// Note: These bounds seem to map to the outer edge of the element's border region.
 /// </summary>
 /// <returns></returns>
 protected Rectangle GetClientRectangle()
 {
     return(HTMLElementHelper.GetClientRectangle(HTMLElement));
 }
Exemplo n.º 29
0
        /// <summary>
        /// Returns the .NET color that matches an element's background color.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="detectImage">
        /// Takes background-image into account when looking for background color.
        /// This is positionally sensitive so if you're not sure if your elements
        /// are in the "correct" positions relative to each other (such as in
        /// Web Layout view) you may want to set this to false.
        /// </param>
        /// <param name="pageUrl">The URL that should be used to escape relative background image paths. Can be null.</param>
        /// <param name="defaultColor"></param>
        /// <returns></returns>
        public static Color GetBackgroundColor(IHTMLElement element, bool detectImage, string pageUrl, Color defaultColor)
        {
            Rectangle childBounds = new Rectangle(HTMLElementHelper.CalculateOffset(element), new Size(element.offsetWidth, element.offsetHeight));

            while (element != null)
            {
                IHTMLCurrentStyle style    = ((IHTMLElement2)element).currentStyle;
                string            colorStr = style.backgroundColor as string;
                if (!string.IsNullOrEmpty(colorStr) && colorStr != "transparent")
                {
                    if (colorStr == "inherit")
                    {
                        detectImage = false;
                    }
                    else
                    {
                        return(GetColorFromHexColor(ParseColorToHex(colorStr), defaultColor));
                    }
                }

                string imageUrl = style.backgroundImage;
                if (detectImage &&
                    !string.IsNullOrEmpty(imageUrl) &&
                    imageUrl != "none" &&
                    (style.backgroundRepeat == "repeat" || style.backgroundRepeat == "repeat-y"))
                {
                    StyleUrl styleUrl = new CssParser(imageUrl.Trim()).Next() as StyleUrl;
                    Trace.Assert(styleUrl != null, "Style URL could not be parsed");
                    if (styleUrl != null)
                    {
                        // If there's a background image URL...
                        string url = styleUrl.LiteralText;
                        using (Stream imageStream = GetStreamForUrl(url, pageUrl, element))
                        {
                            if (imageStream != null)
                            {
                                // ...and we were able to open/download it...
                                using (Image image = Image.FromStream(imageStream))
                                {
                                    if (image is Bitmap)
                                    {
                                        // ...and it's a Bitmap, then use it to get the color.
                                        Rectangle containerBounds = new Rectangle(HTMLElementHelper.CalculateOffset(element), new Size(element.offsetWidth, element.offsetHeight));
                                        Color     color           = GetColorFromBackgroundImage((Bitmap)image,
                                                                                                childBounds,
                                                                                                containerBounds,
                                                                                                style);
                                        // We can't use semi-transparent backgrounds, keep looking
                                        if (color.A == 255)
                                        {
                                            return(color);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                element = element.parentElement;
            }

            return(defaultColor);
        }
 public override IHTMLElement PostBodyElement(IHTMLDocument2 doc)
 {
     return(HTMLElementHelper.GetFragmentElement((IHTMLDocument3)doc, BODY_FRAGMENT_ID));
 }