Esempio n. 1
0
        /// <summary>
        /// Find the block-level element associated with the start or end of the range
        /// </summary>
        static IDomNode findBlock(IDomNode container, int offset, bool findStart)
        {
            IDomNode foundBlock;

            if (!isBlock(container))
            {
                //range starts or ends in/on an inline element so find the block-level ancestor
                for (foundBlock = container.parentNode; !isBlock(foundBlock); foundBlock = foundBlock.parentNode)
                {
                    if (foundBlock.nodeName == "body")
                    {
                        //
                        return(null);
                    }
                }
            }
            else
            {
                //range starts or ends in/on a block-level element so find any block-level descendent
                for (
                    foundBlock = container;
                    //if the child of this block is a block ...
                    (offset < foundBlock.childNodes.count) && isBlock(foundBlock.childNodes.itemAt(offset));
                    //... then descend to either the first or the last the child block
                    foundBlock = foundBlock.childNodes.itemAt(offset), offset = (findStart) ? 0 : Math.Max(0, foundBlock.childNodes.count - 1)
                    )
                {
                    ;
                }
            }
            return(foundBlock);
        }
Esempio n. 2
0
        bool IsKeyboardElement(IDomNode node)
        {
            if (node == null)
            {
                return(false);
            }

            if (node.TagName.ToLower() == "input")
            {
                if (!node.HasAttribute("type") || node.HasAttribute("type") && (node["type"] != "checkbox" && node["type"] != "radio"))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else if (node.TagName.ToLower() == "textarea")
            {
                return(true);
            }
            else if (node.HasAttribute("contenteditable"))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 3
0
 internal void insert(IDomNode newChild)
 {
     if (m_previousNode != null)
     {
         //insert after previous node
         int      offset   = m_parent.childNodes.indexOf(m_previousNode);
         IDomNode refChild = (offset < (m_parent.childNodes.count - 1)) ? m_parent.childNodes.itemAt(offset + 1) : null;
         m_parent.insertBefore(newChild, refChild);
         //next time insert after the just-inserted node
         m_previousNode = newChild;
     }
     else
     {
         m_parent.insertBefore(newChild, null);
     }
 }
Esempio n. 4
0
        static IEnumerable <IDomNode> getChildNodes(IDomNode ancestor)
        {
            foreach (IDomNode child in ancestor.childNodes.elements)
            {
                yield return(child);

                //recurse
                if (child.childNodes != null)
                {
                    foreach (IDomNode descendent in getChildNodes(child))
                    {
                        yield return(descendent);
                    }
                }
            }
        }
Esempio n. 5
0
 void onClick(ModelText.ModelDom.Events.IDomEvent domEvent)
 {
     //see whether the clicked node is an anchor element
     //(or an ancestor of the clicked node, because the clicked node
     //is actually the text node which is a child of the anchor node)
     for (IDomNode target = domEvent.target; target != null; target = target.parentNode)
     {
         if ((target.nodeType == DomNodeType.Element) && (target.nodeName == "a"))
         {
             //invoke the method which would be invoked if the user
             //pressed the "Hyperlink" button on the toolbar
             onInsertHyperlink();
             return;
         }
     }
 }
Esempio n. 6
0
        string GetNodeValue(IDomNode node)
        {
            if (node == null)
            {
                return(null);
            }

            if (node.TagName.ToLower() == "input")
            {
                return(node.HasAttribute("value") ? node["value"] : "");
            }
            else if (node.TagName.ToLower() == "textarea")
            {
                return("");
            }

            return(null);
        }
Esempio n. 7
0
        /// <summary>
        /// Return true if this is a block-level element, or false if it's an inline-level element or a text node.
        /// </summary>
        static bool isBlock(IDomNode domNode)
        {
            //A more sophisticated implementation of this method would use the
            //the ModelText.ModelCssInterfaces.View.ICssViewCss.getComputedStyle method
            //to determine the CSS styling for each element at run-time.
            //Instead, this element assumes that there isn't user-defined CSS which
            //for example renders <p> elements as inline instead of as block.
            switch (domNode.nodeType)
            {
            case DomNodeType.Text:
                //it's a text node
                return(false);

            //it's an element node
            case DomNodeType.Element:
                break;

            default:
                throw new ApplicationException("unexpected");
            }

            IDomElement domElement = (IDomElement)domNode;

            switch (domElement.tagName)
            {
            case "h1":
            case "h2":
            case "h3":
            case "h4":
            case "h5":
            case "h6":
            case "div":
            case "p":
            case "li":
            case "ol":
            case "ul":

                return(true);

            default:

                return(false);
            }
        }
Esempio n. 8
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);
                }
            }
        }
Esempio n. 9
0
        internal OffsetInElement(IDomNode ancestor, IDomNode parent, int offset)
        {
            m_ancestor = ancestor;
            m_offset   = 0;

            When     when;
            IDomNode lastNode;

            switch (parent.nodeType)
            {
            case DomNodeType.Text:
                //remember whether we're at the very end of this text node
                m_endOfNode = (offset == parent.nodeValue.Length);

                //add offset within the parent text node
                m_offset = offset;
                //now stop when (before) we've processed parent
                lastNode = parent;
                when     = When.BeforeNode;
                break;

            case DomNodeType.Element:
                //remember whether we're at the very end of this element
                m_endOfNode = (offset == parent.childNodes.count);

                //want to stop before we've processed child of parent
                if (offset == 0)
                {
                    //want to stop before we've processed parent
                    when     = When.BeforeNode;
                    lastNode = parent;
                }
                else if (offset == parent.childNodes.count)
                {
                    //want to stop after we've processed last descendent of parent
                    when = When.AfterNode;
                    //so find the last descendent
                    lastNode = parent;
                    while ((lastNode.nodeType == DomNodeType.Element) && (lastNode.childNodes.count > 0))
                    {
                        lastNode = lastNode.childNodes.itemAt(lastNode.childNodes.count - 1);
                    }
                }
                else
                {
                    //want to stop before we've processed child
                    when     = When.BeforeNode;
                    lastNode = parent.childNodes.itemAt(offset);
                }
                break;

            default:
                throw new ApplicationException("unexpected");
            }
            foreach (IDomNode descendent in getChildNodes(ancestor))
            {
                if ((when == When.BeforeNode) && ReferenceEquals(lastNode, descendent))
                {
                    return;
                }

                if (descendent.nodeType == DomNodeType.Text)
                {
                    m_offset += descendent.nodeValue.Length;
                }

                if ((when == When.AfterNode) && ReferenceEquals(lastNode, descendent))
                {
                    return;
                }
            }
            //didn't find the lastNode that we were looking for
            throw new ApplicationException("unexpected");
        }
 public void OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
 {
 }
 public void OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
 {
     //const string script = "document.addEventListener('DOMContentLoaded', function(){ alert('DomLoaded'); });";
     //frame.ExecuteJavaScriptAsync(script);
 }
        void IRenderProcessMessageHandler.OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
        {
            var message = node == null ? "lost focus" : node.ToString();

            Console.WriteLine("OnFocusedNodeChanged() - " + message);
        }
 public void OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
 {
 }
        void IRenderProcessMessageHandler.OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
        {
            var message = node == null ? "lost focus" : node.ToString();

            Console.WriteLine("OnFocusedNodeChanged() - " + message);
        }
Esempio n. 15
0
        static ParagraphsToMerge create(IDomRange domRange)
        {
            //find the block-level element associated with the start of the range
            IDomNode startBlock = findBlock(domRange.startContainer, domRange.startOffset, true);
            //find the block-level element associated with the end of the range
            IDomNode endBlock = findBlock(domRange.endContainer, domRange.endOffset, false);

            //block may be null if it's positioned directly under a <td>
            //which (removing things from a table) isn't a scenario supported by this class
            if ((startBlock == null) || (endBlock == null))
            {
                return(null);
            }

            //iterate the inline-level elements to be moved
            List <List <IDomNode> > selected = new List <List <IDomNode> >();

            IDomNode currentBlock = startBlock;

            for (; ;)
            {
                //get the inline elements inside this block
                List <IDomNode> children     = null;
                bool            childIsBlock = false;
                foreach (IDomNode child in currentBlock.childNodes.elements)
                {
                    if (!isBlock(child))
                    {
                        //found an inline child
                        if (children == null)
                        {
                            children = new List <IDomNode>();
                        }
                        children.Add(child);
                    }
                    else
                    {
                        //child of this block is itself a block
                        currentBlock = child;
                        childIsBlock = true;
                        break;
                    }
                }
                if (children != null)
                {
                    //found some inline children
                    selected.Add(children);
                }
                if (childIsBlock)
                {
                    //descend: iterate this child block
                    continue;
                }
                //else finished iterating children of currentBlock

                if (ReferenceEquals(currentBlock, endBlock))
                {
                    //currentBlock is the last block we wanted to iterate
                    break;
                }

                //find the next block to iterate
                for (; ;)
                {
                    IDomNode currentParent = currentBlock.parentNode;
                    int      currentIndex  = currentParent.childNodes.indexOf(currentBlock);
                    if (currentIndex < (currentParent.childNodes.count - 1))
                    {
                        //next we'll iterate the next sibling after currentBlock
                        currentBlock = currentParent.childNodes.itemAt(currentIndex + 1);
                        break;
                    }
                    else
                    {
                        //no next sibling after currentBlock
                        //so iterate next sibling after parent block
                        currentBlock = currentParent;
                        continue;
                    }
                }

                if (!isBlock(currentBlock))
                {
                    //this can happen if an 'anonymous block' is not the first block of a parent block
                    //which isn't supported by the current version of the renderer
                    throw new ApplicationException("unexpected");
                }
            }

            //find the block before the selected block
            //into which we'll merge the inline elements
            currentBlock = startBlock;
            Location previous;

            for (; ;)
            {
                //find the block before the first block
                IDomNode parent = currentBlock.parentNode;
                int      index  = parent.childNodes.indexOf(currentBlock);
                if (index > 0)
                {
                    //found a previous element
                    IDomNode previousNode = parent.childNodes.itemAt(index - 1);
                    if (isBlock(previousNode))
                    {
                        //previous element is a block
                        //but it might have block-level descendents
                        while ((previousNode.childNodes.count > 0) && isBlock(previousNode.childNodes.itemAt(previousNode.childNodes.count - 1)))
                        {
                            previousNode = previousNode.childNodes.itemAt(previousNode.childNodes.count - 1);
                        }
                        //want to insert at the end (after the last child) of the previousNode
                        previous = new Location(previousNode, null);
                        break;
                    }
                    else
                    {
                        //previous is not a block,
                        //so it's an anonymous block
                        //near the start of a list item or table cell
                        previous = new Location(parent, previousNode);
                        break;
                    }
                }
                if (parent.nodeName == "body")
                {
                    //startBlock is the first block in the body
                    //there is no previous block
                    //so don't merge
                    return(null);
                }
                currentBlock = parent;
                continue;
            }

            //search up to find the <body> element
            IDomNode body = startBlock;

            while (body.nodeName != "body")
            {
                body = body.parentNode;
            }

            //remember whether the selection range starts and ends
            //in order to restore it after we edit the DOM
            OffsetInElement start = new OffsetInElement(body, domRange.startContainer, domRange.startOffset);
            OffsetInElement end   = new OffsetInElement(body, domRange.endContainer, domRange.endOffset);

            return(new ParagraphsToMerge(previous, selected, start, end));
        }
Esempio n. 16
0
        private void WebKitOverlay_FocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
        {
            if (IsKeyboardElement(node) && EnableKeyboard)
            {
                if (SteamVR_WebKit.ActiveKeyboardOverlay == this)
                {
                    return;
                }

                SteamVR_WebKit.OverlayManager.HideKeyboard();
                SteamVR_WebKit.ActiveKeyboardOverlay = null;

                if (CanDoUpdates())
                {
                    ShowKeyboard(GetNodeValue(node));
                }
            }
            else
            {
                if (SteamVR_WebKit.ActiveKeyboardOverlay == this)
                {
                    SteamVR_WebKit.OverlayManager.HideKeyboard();
                    SteamVR_WebKit.ActiveKeyboardOverlay = null;
                }
            }
        }
Esempio n. 17
0
            void IRenderProcessMessageHandler.OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
            {
                if (DebugMode)
                {
                    SteamVR_WebKit.Log("Node Focus Change: " + (node != null ? node.ToString() : " none"));
                }

                _parent.FocusedNodeChanged?.Invoke(browserControl, browser, frame, node);
            }
Esempio n. 18
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);
                    }
                }
            }
        }
 void IRenderProcessMessageHandler.OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode iDomNode)
 {
 }
Esempio n. 20
0
 public void OnFocusedNodeChanged(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IDomNode node)
 {
 }
Esempio n. 21
0
 /// <summary>
 /// Determines whether the specified tag is allowed.
 /// </summary>
 /// <param name="tag">The tag.</param>
 /// <returns><c>true</c> if the tag is allowed; otherwise, <c>false</c>.</returns>
 private bool IsAllowedTag(IDomNode tag)
 {
     return(AllowedTags.Contains(tag.NodeName));
 }
 public void OnFocusedNodeChanged(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IDomNode node)
 {
     throw new NotImplementedException();
 }
Esempio n. 23
0
 void IRenderProcessMessageHandler.OnFocusedNodeChanged(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IDomNode node)
 {
 }
Esempio n. 24
0
 internal Location(IDomNode parent, IDomNode previousNode)
 {
     m_parent       = parent;
     m_previousNode = previousNode;
 }
Esempio n. 25
0
 /// <summary>
 /// Determines whether the specified tag is allowed.
 /// </summary>
 /// <param name="tag">The tag.</param>
 /// <returns><c>true</c> if the tag is allowed; otherwise, <c>false</c>.</returns>
 private bool IsAllowedTag(IDomNode tag)
 {
     return AllowedTags.Contains(tag.NodeName);
 }
Esempio n. 26
0
 public void OnFocusedNodeChanged(IWebBrowser browserControl, IBrowser browser, IFrame frame, IDomNode node)
 {
     Logger.Debug("OnFocusedNodeChanged");
 }