Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
   *
   * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
   * Other names may be trademarks of their respective owners.
   *
   * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common
  * Development and Distribution License("CDDL") (collectively, the
  * "License"). You may not use this file except in compliance with the
  * License. You can obtain a copy of the License at
  * http://www.netbeans.org/cddl-gplv2.html
  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  * specific language governing permissions and limitations under the
  * License.  When distributing the software, include this License Header
  * Notice in each file and include the License file at
  * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Oracle in the GPL Version 2 section of the License file that
  * accompanied this code. If applicable, add the following below the
  * License Header, with the fields enclosed by brackets [] replaced by
  * your own identifying information:
  * "Portions Copyrighted [year] [name of copyright owner]"
  *
  * If you wish your version of this file to be governed by only the CDDL
  * or only the GPL Version 2, indicate your decision by adding
  * "[Contributor] elects to include this software in this distribution
  * under the [CDDL or GPL Version 2] license." If you do not indicate a
  * single choice of license, a recipient has the option to distribute
  * your version of this file under either the CDDL, the GPL Version 2 or
  * to extend the choice of license to its licensees as provided above.
  * However, if you add GPL Version 2 code and therefore, elected the GPL
  * Version 2 license, then the option applies only if the new code is
  * made subject to such option by the copyright holder.
  *
  * Contributor(s):
  *
  * Portions Copyrighted 2012 Sun Microsystems, Inc.
  */
 package org.netbeans.modules.web.inspect.webkit;
 
 import java.util.List;
 import java.util.Map;
WebKit-based implementation of PageModel.

Author(s):
Jan Stola
 
 public class WebKitPageModel extends PageModel {
    
Request processor used by this class.
 
     private RequestProcessor RP = new RequestProcessor(WebKitPageModel.class);
    
Entry point to WebKit debugging API.
 
     WebKitDebugging webKit;
    
Document node.
 
     private DOMNode documentNode;
    
Nodes of the document (maps ID of the node to the node itself)
 
     private Map<Integer,DOMNodenodes = Collections.synchronizedMap(new HashMap<Integer,DOMNode>());
    
Selected nodes.
 
     private List<? extends org.openide.nodes.NodeselectedNodes = .;
    
Highlighted nodes.
 
     private List<? extends org.openide.nodes.NodehighlightedNodes = .;
    
Nodes matching the selected rule.
 
     private List<? extends org.openide.nodes.NodenodesMatchingSelectedRule = .;
    
Selector of the selected rule.
 
     private String selectedSelector;
    
Selector of the highlighted rule.
 
     private String highlightedSelector;
    
WebKit DOM domain listener.
 
     private DOM.Listener domListener;
    
WebKit CSS domain listener.
 
     private CSS.Listener cssListener;
    
Determines whether the selection mode is switched on.
 
     private boolean selectionMode;
    
Determines whether the selection between the IDE and the browser pane is synchronized.
 
     private boolean synchronizeSelection;
    
Owner project of the inspected page.
 
    private Project project;
    
Page context.
    private Lookup pageContext;
    
Updater of the stylesheets in the browser according to changes of the corresponding source files.
    private CSSUpdater cSSUpdater = CSSUpdater.getDefault();
    
Map with content documents in the inspected page. Maps node ID of the document node to the corresponding RemoteObject.
    private Map<Integer,RemoteObjectcontentDocumentMap = new HashMap<Integer,RemoteObject>();
    
Logger used by this class
    static final Logger LOG = Logger.getLogger(WebKitPageModel.class.getName());

    
Creates a new WebKitPageModel.

Parameters:
pageContext page context.
    public WebKitPageModel(Lookup pageContext) {
        this. = pageContext;
        this. = pageContext.lookup(WebKitDebugging.class);
        this. = pageContext.lookup(Project.class);
        this. = (pageContext.lookup(JToolBar.class) == null); // Ugly heuristics
        // Register DOM domain listener
         = createDOMListener();
        DOM dom = .getDOM();
        dom.addListener();
        
        // Register CSS domain listener
         = createCSSListener();
        CSS css = .getCSS();
        css.addListener();
        try {
            initializePage();
        } catch (TransportStateException tsex) {
            // The underlying transport became invalid
            // before the page was initialized.
        }
    }

    
Prepares the page for inspection.
    private void initializePage() {
        // documentUpdated event is not delivered when no node information
        // was sent to the client => requesting document node to make sure
        // that we obtain next documentUpdated event (that we need to be able
        // to reinitialize the page)
        org.openide.nodes.Node node = getDocumentNode();
        if (node == null) {
            .info("getDocumentNode() returned null!"); // NOI18N
        } else {
            // Do not initialize the temporary page unnecessarily
            Node webKitNode = node.getLookup().lookup(Node.class);
            webKitNode = convertNode(webKitNode);
            Node.Attribute attr = webKitNode.getAttribute(":netbeans_temporary"); // NOI18N
            if (attr == null) {
                // init
                String initScript = Files.getScript("initialization"); // NOI18N
                .getRuntime().evaluate(initScript);
                .start();
            }
        }
    }

    
Returns the underlaying WebKitDebugging object.

Returns:
the underlaying WebKitDebugging object.
    public WebKitDebugging getWebKit() {
        return ;
    }

    
Returns the owner project of the inspected page.

Returns:
the owner project of the inspected page.
    public Project getProject() {
        return ;
    }

    
Returns the page context.

Returns:
page context.
    public Lookup getPageContext() {
        return ;
    }
    @Override
    protected void dispose() {
        DOM dom = .getDOM();
        dom.removeListener();
        CSS css = .getCSS();
        css.removeListener();
        .stop();
    }
    @Override
    public org.openide.nodes.Node getDocumentNode() {
        synchronized (this) {
            if ( == null) {
                DOM dom = .getDOM();
                Node node = dom.getDocument();
                if (node != null) {
                     = updateNodes(node);
                }
            }
            return ;
        }
    }
    @Override
    public void removeNode(org.openide.nodes.Node node) {
        try {
            Node webKitNode = node.getLookup().lookup(Node.class);
            if (webKitNode != null) {
                .getDOM().removeNode(webKitNode);
            }
        } catch (TransportStateException tsex) {}
    }
    @Override
    public String getDocumentURL() {
        String documentURL = null;
        org.openide.nodes.Node node = getDocumentNode();
        if (node != null) {
            Node webKitNode = node.getLookup().lookup(Node.class);
            if (webKitNode != null) {
                documentURL = webKitNode.getDocumentURL();
            }
        }
        return documentURL;
    }

    
Creates DOM domain listener.

Returns:
DOM domain listener.
    private DOM.Listener createDOMListener() {
        return new DOM.Listener() {
            @Override
            public void childNodesSet(Node parent) {
                synchronized(WebKitPageModel.this) {
                    int nodeId = parent.getNodeId();
                    DOMNode domNode = .get(nodeId);
                    if (domNode != null) {
                        updateNodes(parent);
                        domNode.updateChildren(parent);
                    }
                }
            }
            @Override
            public void childNodeRemoved(Node parentNode child) {
                synchronized(WebKitPageModel.this) {
                    int nodeId = parent.getNodeId();
                    DOMNode domNode = .get(nodeId);
                    if (domNode != null) {
                        domNode.updateChildren(parent);
                    }
                    // Nodes with a content document are removed and added
                    // again when a content document changes (and sometimes
                    // even when it doesn't change) => we are not removing
                    // them from 'nodes' collection to be able to reuse
                    // them once they are back.
                    Node contentDocument = child.getContentDocument();
                    if (contentDocument == null) {
                        .remove(child.getNodeId());
                    } else {
                        .remove(contentDocument.getNodeId());
                    }
                }
            }
            @Override
            public void childNodeInserted(Node parentNode child) {
                synchronized(WebKitPageModel.this) {
                    int nodeId = parent.getNodeId();
                    updateNodes(child);
                    DOMNode domNode = .get(nodeId);
                    if (domNode != null) {
                        domNode.updateChildren(parent);
                    }
                }
            }
            @Override
            public void documentUpdated() {
                synchronized(WebKitPageModel.this) {
                    .clear();
                    .clear();
                     = null;
                     = .;
                     = .;
                    .post(new Runnable() {
                        @Override
                        public void run() {
                            firePropertyChange(nullnull);
                        }
                    });
                }
            }
            @Override
            public void attributeModified(Node nodeString attrName) {
                synchronized(WebKitPageModel.this) {
                    // Attribute modifications that represent selection/highlight
                    final boolean selected = ":netbeans_selected".equals(attrName); // NOI18N
                    final boolean highlighted = ":netbeans_highlighted".equals(attrName); // NOI18N
                    if (selected || highlighted) {
                        if (!isSelectionMode()) {
                            // Some delayed selection/highlight modifications
                            // can appear after deactivation of the selection mode
                            // => ignore these delayed events
                            return;
                        }
                        Node.Attribute attr = node.getAttribute(attrName);
                        DOMNode n = getNode(node.getNodeId());
                        final List<? extends org.openide.nodes.Nodeselection;
                        if (n == null) {
                            selection = .;
                        } else {
                            String attrValue = attr.getValue();
                            if ("set".equals(attrValue)) { // NOI18N
                                selection = Collections.singletonList(n);
                            } else if ("clear".equals(attrValue)) { // NOI18N
                                selection = .;
                            } else {
                                List<org.openide.nodes.NodenewSelection = new ArrayList<org.openide.nodes.Node>();
                                newSelection.addAll();
                                if ("add".equals(attrValue)) { // NOI18N
                                    newSelection.add(n);
                                } else if ("remove".equals(attrValue)) { // NOI18N
                                    newSelection.remove(n);
                                }
                                selection = newSelection;
                            }
                        }
                        .post(new Runnable() {
                            @Override
                            public void run() {
                                if (selected) {
                                    setSelectedNodes(selection);
                                    firePropertyChange(.nullnull);
                                    activateStylesView();
                                } else {
                                    setHighlightedNodesImpl(selection);
                                }
                            }
                        });
                        return;
                    }
                    // Update DOMNode
                    int nodeId = node.getNodeId();
                    DOMNode domNode = .get(nodeId);
                    if (domNode != null) {
                        domNode.updateAttributes();
                    }
                }
            }
            @Override
            public void attributeRemoved(Node nodeString attrName) {
                synchronized(WebKitPageModel.this) {
                    int nodeId = node.getNodeId();
                    DOMNode domNode = .get(nodeId);
                    if (domNode != null) {
                        domNode.updateAttributes();
                    }
                }
            }
            @Override
            public void characterDataModified(Node node) {
                synchronized(WebKitPageModel.this) {
                    int nodeId = node.getNodeId();
                    DOMNode domNode = .get(nodeId);
                    if (domNode != null) {
                        domNode.updateCharacterData();
                    }
                }
            }
        };
    }

    
Creates CSS domain listener.

Returns:
CSS domain listener.
    private CSS.Listener createCSSListener() {
        return new CSS.Listener() {
            @Override
            public void mediaQueryResultChanged() {
            }
            @Override
            public void styleSheetChanged(String styleSheetId) {
                .post(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            // Issue 217896
                            String script = "NetBeans.repaintGlassPane();"// NOI18N
                            invokeInAllDocuments(script);
                        } catch (TransportStateException tsex) {}
                    }
                });
            }
        };
    }

    
Updates the map of known nodes with the information about the specified node and its sub-nodes.

Parameters:
node node to start the update at.
Returns:
DOMNode that corresponds to the specified node.
    private DOMNode updateNodes(Node node) {
        int nodeId = node.getNodeId();
        DOMNode domNode = .get(nodeId);
        if (domNode == null) {
            domNode = new DOMNode(thisnode);
            .put(nodeIddomNode);
        }
        boolean updateChildren = false;
        List<NodesubNodes = null;
        synchronized (node) {
            List<NodeorigSubNodes = node.getChildren();
            if (origSubNodes != null) {
                subNodes = new ArrayList<Node>(origSubNodes);
            }
        }
        if (subNodes == null) {
            int nodeType = node.getNodeType();
            if (nodeType == .... || nodeType == ....) {
                .getDOM().requestChildNodes(nodeId);
            }
        } else {
            for (Node subNode : subNodes) {
                updateNodes(subNode);
            }
            updateChildren = true;
        }
        final Node contentDocument = node.getContentDocument();
        if (contentDocument != null) {
            updateNodes(contentDocument);
            updateChildren = true;
            .post(new Runnable() {
                @Override
                public void run() {
                    String initScript = Files.getScript("initialization"// NOI18N
                        + "\nNetBeans.setSelectionMode("++");"// NOI18N
                    RemoteObject remote = .getDOM().resolveNode(contentDocumentnull);
                    if (remote == null) {
                        .log(."Node with ID {0} resolved to null RemoteObject!"contentDocument.getNodeId()); // NOI18N
                    } else {
                        .getRuntime().callFunctionOn(remote"function() {\n"+initScript+"\n}");
                        synchronized (WebKitPageModel.this) {
                            .put(contentDocument.getNodeId(), remote);
                        }
                    }
                }
            });
        }
        if (updateChildren) {
            domNode.updateChildren(node);
        }
        return domNode;
    }

    
Returns DOMNode with the specified ID.

Parameters:
nodeId ID of the requested DOMNode.
Returns:
DOMNode with the speicified ID.
    DOMNode getNode(int nodeId) {
        return .get(nodeId);
    }
    @Override
    public void setSelectedNodes(List<? extends org.openide.nodes.Nodenodes) {
        synchronized (this) {
            if (.equals(nodes)) {
                return;
            }
             = nodes;
        }
        firePropertyChange(nullnull);
    }
    @Override
    public List<org.openide.nodes.NodegetSelectedNodes() {
        synchronized (this) {
            return Collections.unmodifiableList();
        }
    }
    @Override
    public void setHighlightedNodes(List<? extends org.openide.nodes.Nodenodes) {
        if (isSynchronizeSelection()) {
            setHighlightedNodesImpl(nodes);
        }
    }
    void setHighlightedNodesImpl(List<? extends org.openide.nodes.Nodenodes) {
        synchronized (this) {
            if (.equals(nodes)) {
                return;
            }
             = nodes;
        }
        firePropertyChange(nullnull);
    }
    @Override
    public List<? extends org.openide.nodes.NodegetHighlightedNodes() {
        synchronized (this) {
            return Collections.unmodifiableList();
        }
    }
    @Override
    public void setSelectedSelector(String selector) {
        synchronized (this) {
             = selector;
        }
        firePropertyChange(nullnull);
    }
    @Override
    public String getSelectedSelector() {
        synchronized (this) {
            return ;
        }
    }
    private void setNodesMatchingSelectedRule(List<? extends org.openide.nodes.Nodenodes) {
        synchronized (this) {
             = nodes;
        }
    }
    @Override
    public List<? extends org.openide.nodes.NodegetNodesMatchingSelectedRule() {
        synchronized (this) {
            return ;
        }
    }
    @Override
    public void setHighlightedSelector(String selector) {
        synchronized (this) {
             = selector;
        }
        setHighlightedNodes(matchingNodes(selector));
        firePropertyChange(nullnull);
    }
    @Override
    public String getHighlightedSelector() {
        synchronized (this) {
            return ;
        }
    }

    
Returns the nodes matching the specified selector.

Parameters:
selector selector that should match the nodes.
Returns:
nodes matching the specified selector.
    List<DOMNodematchingNodes(String selector) {
        List<DOMNodedomNodes;
        if (selector == null) {
            domNodes = .;
        } else {
            DOM dom = .getDOM();
            List<NodematchingNodes = dom.querySelectorAll(dom.getDocument(), selector);
            domNodes = new ArrayList<DOMNode>(matchingNodes.size());
            for (Node node : matchingNodes) {
                int nodeId = node.getNodeId();
                DOMNode domNode = getNode(nodeId);
                if (domNode != null) {
                    domNodes.add(domNode);
                }
            }
        }
        return domNodes;
    }
    @Override
    public void setSelectionMode(boolean selectionMode) {
        synchronized (this) {
            if (this. == selectionMode) {
                return;
            }
            this. = selectionMode;
        }
        firePropertyChange(, !selectionModeselectionMode);
        // Reset highlighted nodes
        if (!selectionMode) {
        }
        activateStylesView();
    }
    @Override
    public boolean isSelectionMode() {
        synchronized (this) {
            return ;
        }
    }
    @Override
    public void setSynchronizeSelection(boolean synchronizeSelection) {
        synchronized (this) {
            if (this. == synchronizeSelection) {
                return;
            }
            this. = synchronizeSelection;
        }
        firePropertyChange(, !synchronizeSelectionsynchronizeSelection);
    }
    @Override
    public boolean isSynchronizeSelection() {
        synchronized (this) {
            return ;
        }
    }

    
Invoke the specified script in all content documents.

Parameters:
script script to invoke.
    void invokeInAllDocuments(String script) {
        // Main document
        .getRuntime().evaluate(script);
        // Content documents
        script = "function() {\n" + script + "\n}"// NOI18N
        List<RemoteObjectdocuments;
        synchronized (this) {
            documents = new ArrayList<RemoteObject>(.size());
            documents.addAll(.values());
        }
        for (RemoteObject contentDocument : documents) {
            .getRuntime().callFunctionOn(contentDocumentscript);
        }
    }

    
Converts the WebKit node into a node that should be highlighted/selected. Usually this method returns the passed node, but there are some exceptions like document nodes.

Parameters:
node node to convert.
Returns:
node that should be highlighted/selected instead of the given node.
    Node convertNode(Node node) {
        Node result = node;
        int type = node.getNodeType();
        if (type == ....) {
            // Highlight/select document element
            synchronized (node) {
                List<NodesubNodes = node.getChildren();
                if (subNodes != null) {
                    for (Node subNode : subNodes) {
                        // There should be just one element
                        if (subNode.getNodeType() == ....) {
                            result = subNode;
                            break;
                        }
                    }
                }
            }
        }
        return result;
    }
    @Override
    public CSSStylesView getCSSStylesView() {
        CSSStylesPanel view = CSSStylesPanel.getDefault();
        view.updatePageModel();
        return view;
    }

    
Determines whether this page model corresponds to a page in an external browser.
    private boolean external;
    
    
Determines whether this page model corresponds to a page in an external browser.

Returns:
true when this page model corresponds to a page in an external browser, returns false otherwise.
    boolean isExternal() {
        return ;
    }

    
Activates CSS Styles view (to fill the content of Navigator).
    void activateStylesView() {
//        if (!isExternal()) {
//            return;
//        }
//        if (EventQueue.isDispatchThread()) {
//            WindowManager manager = WindowManager.getDefault();
//            TopComponent stylesTC = manager.findTopComponent(MatchedRules.ID);
//            if (stylesTC != null) {
//                stylesTC.requestActive();
//            }
//        } else {
//            EventQueue.invokeLater(new Runnable() {
//                @Override
//                public void run() {
//                    activateStylesView();
//                }
//            });
//        }
    }
    class WebPaneSynchronizer implements PropertyChangeListener {
        private final Object LOCK_HIGHLIGHT = new Object();
        private final Object LOCK_SELECTION = new Object();
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            try {
                String propName = evt.getPropertyName();
                if (propName.equals(.)) {
                    if (shouldSynchronizeHighlight()) {
                        updateHighlight();
                    }
                } else if (propName.equals(.)) {
                    if (shouldSynchronizeSelection()) {
                        updateSelection();
                    }
                } else if (propName.equals(.)) {
                    if (shouldSynchronizeSelection()) {
                        updateSelectedRule(getNodesMatchingSelectedRule());
                    }
                } else if (propName.equals(.)) {
                    updateSelectionMode();
                    updateSynchronization();
                } else if (propName.equals(.)) {
                    updateSelectionMode();
                    updateSynchronization();
                } else if (propName.equals(.)) {
                    initializePage();
                    updateSelectionMode();
                }
            } catch (TransportStateException tse) {
                // The underlying transport became invalid. No need to worry
                // about failed synchronization as this means that the debugging
                // session has been finished.
            }
        }
        private boolean shouldSynchronizeSelection() {
            return isSelectionMode();
        }
        private boolean shouldSynchronizeHighlight() {
            return true;
        }
        private void updateSynchronization() {
            if (shouldSynchronizeSelection()) {
                updateSelection();
                updateSelectedRule(getNodesMatchingSelectedRule());
            } else {
                updateSelection(.);
                updateSelectedRule(.);
            }
            if (shouldSynchronizeHighlight()) {
                updateHighlight();
            } else {
                updateHighlight(.);
            }
        }
        private void updateHighlight() {
            List<? extends org.openide.nodes.Nodenodes = getHighlightedNodes();
            updateHighlight(nodes);
        }
        private void updateHighlight(List<? extends org.openide.nodes.Nodenodes) {
            synchronized () {
                // Initialize the next highlight in all content documents
                invokeInAllDocuments("NetBeans.initNextHighlight();"); // NOI18N
                // Add highlighted nodes into the next highlight (in their document)
                for (org.openide.nodes.Node node : nodes) {
                    Node webKitNode = node.getLookup().lookup(Node.class);
                    webKitNode = convertNode(webKitNode);
                    RemoteObject remote = .getDOM().resolveNode(webKitNodenull);
                    if (remote != null) {
                        .getRuntime().callFunctionOn(remote"function() {NetBeans.addElementToNextHighlight(this);}"); // NOI18N
                    }
                }
                // Finalize the next highlight in all content documents
                invokeInAllDocuments("NetBeans.finishNextHighlight();"); // NOI18N
            }
        }
        private void updateSelection() {
            List<? extends org.openide.nodes.Nodenodes = getSelectedNodes();
            updateSelection(nodes);
        }
        private void updateSelection(List<? extends org.openide.nodes.Nodenodes) {
            updateSelection(nodes""); // NOI18N
        }
        
        private void updateSelection(List<? extends org.openide.nodes.NodenodesString type) {
            synchronized () {
                // Initialize the next selection in all content documents
                invokeInAllDocuments("NetBeans.initNext" + type + "Selection();"); // NOI18N
                // Add selected nodes into the next selection (in their document)
                for (org.openide.nodes.Node node : nodes) {
                    Node webKitNode = node.getLookup().lookup(Node.class);
                    webKitNode = convertNode(webKitNode);
                    RemoteObject remote = .getDOM().resolveNode(webKitNodenull);
                    if (remote != null) {
                        .getRuntime().callFunctionOn(remote"function() {NetBeans.addElementToNext" + type + "Selection(this);}"); // NOI18N
                    }
                }
                // Finalize the next selection in all content documents
                invokeInAllDocuments("NetBeans.finishNext" + type + "Selection();"); // NOI18N
            }
        }
        private void updateSelectedRule(List<? extends org.openide.nodes.Nodenodes) {
            updateSelection(nodes"Rule"); // NOI18N
        }
        private synchronized void updateSelectionMode() {
            boolean selectionMode = isSelectionMode();
            
            // PENDING notify Chrome extension that the selection mode has changed
            // Activate/deactivate (observation of mouse events over) canvas
            invokeInAllDocuments("NetBeans.setSelectionMode("+selectionMode+")"); // NOI18N
        }
    }
New to GrepCode? Check out our FAQ X