/// <summary>
        /// Inserts foster parented characters.
        /// </summary>
        ///
        /// <param name="text">
        /// The text.
        /// </param>
        /// <param name="table">
        /// The table.
        /// </param>
        /// <param name="stackParent">
        /// The stack parent.
        /// </param>

        override protected void InsertFosterParentedCharacters(string text, DomObject table, DomObject stackParent)
        {
            IDomObject parent = table.ParentNode;

            if (parent != null)
            {
                // always an element if not null
                IDomObject previousSibling = table.PreviousSibling;
                if (previousSibling != null &&
                    previousSibling.NodeType == NodeType.TEXT_NODE)
                {
                    IDomText lastAsText = (IDomText)previousSibling;
                    lastAsText.NodeValue += text;
                    return;
                }
                parent.InsertBefore(Document.CreateTextNode(text), table);
                return;
            }
            // fall through

            IDomText lastChild = stackParent.LastChild as IDomText;

            if (lastChild != null)
            {
                lastChild.NodeValue += text;
                return;
            }
            else
            {
                stackParent.AppendChildUnsafe(Document.CreateTextNode(text));
            }
        }
        /// <summary>
        /// Appends text a node.
        /// </summary>
        ///
        /// <param name="parent">
        /// The parent.
        /// </param>
        /// <param name="text">
        /// The text.
        /// </param>

        override protected void AppendCharacters(DomObject parent, string text)
        {
            IDomText lastChild = parent.LastChild as IDomText;

            if (lastChild != null)
            {
                lastChild.NodeValue += text;
            }
            else
            {
                lastChild = Document.CreateTextNode(text);
                parent.AppendChildUnsafe(lastChild);
            }
        }
示例#3
0
        /// <summary>
        /// Sets a child text for this element, using the text node type appropriate for this element's type
        /// </summary>
        ///
        /// <param name="el">
        /// The element to add text to
        /// </param>
        /// <param name="text">
        /// The text.
        /// </param>

        private void SetChildText(IDomElement el, string text)
        {
            if (el.ChildrenAllowed)
            {
                el.ChildNodes.Clear();

                // Element types that cannot have HTML contents should not have the value encoded.
                // use DomInnerText node for those node types to preserve the raw text value

                IDomText textEl = el.InnerHtmlAllowed ?
                                  new DomText(text) :
                                  new DomInnerText(text);

                el.ChildNodes.Add(textEl);
            }
        }
示例#4
0
        void editDom(IDomDocument domDocument)
        {
            //increment the serialized range location start only once
            //to account for extra whitespace we add before the first block
            m_start.increment();

            foreach (List <IDomNode> elements in m_selected)
            {
                //insert a whitespace, instead of the 'carriage return' which used to separate the blocks
                IDomText whitespace = domDocument.createTextNode(" ");
                m_previous.insert(whitespace);

                //increment the serialized range location end multiple times
                //to account for extra whitespace we just added
                m_end.increment();

                IDomNode parent = elements[0].parentNode;

                //insert each element
                foreach (IDomNode element in elements)
                {
                    //remove from current parent before inerting into new parent
                    parent.removeChild(element);
                    //insert into new parent
                    m_previous.insert(element);
                }

                if (parent.childNodes.count == 0)
                {
                    //this block is now empty (all its children removed)
                    //so remove it from the document
                    IDomNode grandparent = parent.parentNode;
                    while (grandparent.childNodes.count == 1)
                    {
                        parent      = grandparent;
                        grandparent = grandparent.parentNode;
                    }
                    grandparent.removeChild(parent);
                }
            }
        }
示例#5
0
        /// <summary>
        /// Adds the contents to 'node' to the StringBuilder.
        /// </summary>
        ///
        /// <param name="sb">
        /// The StringBuilder.
        /// </param>
        /// <param name="node">
        /// The node.
        /// </param>
        /// <param name="skipWhitespace">
        /// true to skip any leading whitespace for this node.
        /// </param>

        protected void AddContents(StringBuilder sb, IDomObject node, bool skipWhitespace)
        {
            // always skip the opening whitespace of a new child block

            if (node.HasChildren)
            {
                foreach (IDomObject el in node.ChildNodes)
                {
                    if (el.NodeType == NodeType.TEXT_NODE)
                    {
                        IDomText txtNode = (IDomText)el;
                        stringInfo.Target = el.NodeValue;

                        if (stringInfo.Whitespace)
                        {
                            if (!skipWhitespace)
                            {
                                sb.Append(" ");
                                skipWhitespace = true;
                            }
                        }
                        else
                        {
                            string val = CleanFragment(el.Render());
                            if (skipWhitespace)
                            {
                                val            = val.TrimStart();
                                skipWhitespace = false;
                            }

                            sb.Append(val);
                        }
                    }
                    else if (el.NodeType == NodeType.ELEMENT_NODE)
                    {
                        IDomElement elNode = (IDomElement)el;
                        // first add any inner contents

                        if (el.NodeName != "HEAD" && el.NodeName != "STYLE" && el.NodeName != "SCRIPT")
                        {
                            switch (elNode.NodeName)
                            {
                            case "BR":
                                sb.Append(System.Environment.NewLine);
                                break;

                            case "PRE":
                                RemoveTrailingWhitespace(sb);
                                sb.Append(System.Environment.NewLine);
                                sb.Append(ToStandardLineEndings(el.TextContent));
                                RemoveTrailingWhitespace(sb);
                                sb.Append(System.Environment.NewLine);
                                skipWhitespace = true;
                                break;

                            case "A":
                                sb.Append(el.TextContent + " (" + el["href"] + ")");
                                break;

                            default:

                                if (elNode.IsBlock && sb.Length > 0)
                                {
                                    RemoveTrailingWhitespace(sb);
                                    sb.Append(System.Environment.NewLine);
                                }

                                AddContents(sb, el, elNode.IsBlock);
                                RemoveTrailingWhitespace(sb);

                                if (elNode.IsBlock)
                                {
                                    sb.Append(System.Environment.NewLine);
                                    skipWhitespace = true;
                                }

                                break;
                            }
                        }
                    }
                }
            }
        }
示例#6
0
        protected void AddContents(StringBuilder sb, IDomObject startEl)
        {
            if (startEl.HasChildren)
            {
                foreach (IDomObject el in startEl.ChildNodes)
                {
                    if (el.NodeType == NodeType.TEXT_NODE)
                    {
                        IDomText txtNode = (IDomText)el;
                        stringInfo.Target = el.NodeValue;
                        if (!stringInfo.Whitespace)
                        {
                            string val = txtNode.NodeValue;
                            if (skipWhitespace)
                            {
                                val = CleanFragment(val);
                            }
                            // always add if there's actually content
                            endingBlock    = false;
                            skipWhitespace = false;
                            sb.Append(val);
                        }
                        else
                        {
                            // just whitespace
                            if (!skipWhitespace)
                            {
                                // if not an ending block convert all whitespace to a single space, and
                                // act like it was an ending block (preventing further whitespace from being added)
                                sb.Append(" ");
                                skipWhitespace = true;
                            }
                        }
                    }
                    else if (el.NodeType == NodeType.ELEMENT_NODE)
                    {
                        IDomElement elNode = (IDomElement)el;
                        // first add any inner contents
                        if (el.NodeName != "HEAD" && el.NodeName != "STYLE" && el.NodeName != "SCRIPT")
                        {
                            AddContents(sb, el);

                            switch (elNode.NodeName)
                            {
                            case "BR":
                                sb.Append(System.Environment.NewLine);
                                skipWhitespace = true;
                                break;

                            case "PRE":
                                sb.Append(el.Render());
                                break;

                            case "A":
                                sb.Append(el.Cq().Children().RenderSelection() + " (" + el["href"] + ")");
                                break;

                            default:
                                if (elNode.IsBlock)
                                {
                                    if (!endingBlock)
                                    {
                                        // erase ending whitespace -- scan backwards until non-whitespace
                                        int i     = sb.Length - 1;
                                        int count = 0;
                                        while (i >= 0 && CharacterData.IsType(sb[i], CharacterType.Whitespace))
                                        {
                                            i--;
                                            count++;
                                        }
                                        if (i < sb.Length - 1)
                                        {
                                            sb.Remove(i + 1, count);
                                        }

                                        endingBlock    = true;
                                        skipWhitespace = true;
                                        sb.Append(System.Environment.NewLine + System.Environment.NewLine);
                                    }
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
示例#7
0
        void onInsertHyperlink()
        {
            //get the document fragment which the user has currently selected using mouse and/or cursor
            IWindowSelection windowSelection = modelEdit.windowSelection;

            //verify that there's only one selection
            if (windowSelection.rangeCount != 1)
            {
                //this can happen when the user has selected several cell in a table,
                //in which case each cell is a separate selection/range
                MessageBox.Show("Can't insert a hyperlink when more than one range in the document is selected");
                return;
            }
            using (IDomRange domRange = windowSelection.getRangeAt(0))
            {
                //verify that only one node is selected
                if (!domRange.startContainer.isSameNode(domRange.endContainer))
                {
                    //this can happen for example when the selection spans multiple paragraphs
                    MessageBox.Show("Can't insert a hyperlink when more than one node in the document is selected");
                    return;
                }
                IDomNode container = domRange.startContainer; //already just checked that this is the same as domRange.endContainer
                //read existing values from the current selection
                string      url;
                string      visibleText;
                IDomElement existingHyperlink;
                switch (container.nodeType)
                {
                case DomNodeType.Text:
                    //selection is a text fragment
                    visibleText = container.nodeValue.Substring(domRange.startOffset, domRange.endOffset - domRange.startOffset);
                    IDomNode parentNode = container.parentNode;
                    if ((parentNode.nodeType == DomNodeType.Element) && (parentNode.nodeName == "a"))
                    {
                        //parent of this text node is a <a> element
                        existingHyperlink = parentNode as IDomElement;
                        url         = existingHyperlink.getAttribute("href");
                        visibleText = container.nodeValue;
                        if ((existingHyperlink.childNodes.count != 1) || (existingHyperlink.childNodes.itemAt(0).nodeType != DomNodeType.Text))
                        {
                            //this can happen when an anchor tag wraps more than just a single, simple text node
                            //for example when it contains inline elements like <strong>
                            MessageBox.Show("Can't edit a complex hyperlink");
                            return;
                        }
                    }
                    else
                    {
                        existingHyperlink = null;
                        url = null;
                    }
                    break;

                default:
                    //unexpected
                    MessageBox.Show("Can't insert a hyperlink when more than one node in the document is selected");
                    return;
                }
                //display the modal dialog box
                using (FormInsertHyperlink formInsertHyperlink = new FormInsertHyperlink())
                {
                    formInsertHyperlink.url         = url;
                    formInsertHyperlink.visibleText = visibleText;
                    DialogResult dialogResult = formInsertHyperlink.ShowDialog();
                    if (dialogResult != DialogResult.OK)
                    {
                        //user cancelled
                        return;
                    }
                    //get new values from the dialog box
                    //the FormInsertHyperlink.onEditTextChanged method assures that both strings are non-empty
                    url         = formInsertHyperlink.url;
                    visibleText = formInsertHyperlink.visibleText;
                }
                //need to change href, change text, and possibly delete existing text;
                //do this within the scope of a single IEditorTransaction instance so
                //that if the user does 'undo' then it will undo all these operations at once, instead of one at a time
                using (IEditorTransaction editorTransaction = modelEdit.createEditorTransaction())
                {
                    if (existingHyperlink != null)
                    {
                        //changing an existing hyperlink ...
                        //... change the href attribute value
                        existingHyperlink.setAttribute("href", url);
                        //... change the text, by removing the old text node and inserting a new text node
                        IDomText newDomText = modelEdit.domDocument.createTextNode(visibleText);
                        IDomNode oldDomText = existingHyperlink.childNodes.itemAt(0);
                        existingHyperlink.removeChild(oldDomText);
                        existingHyperlink.insertBefore(newDomText, null);
                    }
                    else
                    {
                        //creating a new hyperlink
                        IDomElement newHyperlink = modelEdit.domDocument.createElement("a");
                        IDomText    newDomText   = modelEdit.domDocument.createTextNode(visibleText);
                        newHyperlink.insertBefore(newDomText, null);
                        newHyperlink.setAttribute("href", url);
                        //remove whatever was previously selected, if anything
                        if (!domRange.collapsed)
                        {
                            domRange.deleteContents();
                        }
                        //insert the new hyperlink
                        domRange.insertNode(newHyperlink);
                    }
                }
            }
        }