diff options
Diffstat (limited to 'WebCore/inspector/front-end/ElementsTreeOutline.js')
| -rw-r--r-- | WebCore/inspector/front-end/ElementsTreeOutline.js | 626 |
1 files changed, 0 insertions, 626 deletions
diff --git a/WebCore/inspector/front-end/ElementsTreeOutline.js b/WebCore/inspector/front-end/ElementsTreeOutline.js deleted file mode 100644 index 16e31b8..0000000 --- a/WebCore/inspector/front-end/ElementsTreeOutline.js +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -WebInspector.ElementsTreeOutline = function() { - this.element = document.createElement("ol"); - this.element.addEventListener("mousedown", this._onmousedown.bind(this), false); - this.element.addEventListener("dblclick", this._ondblclick.bind(this), false); - this.element.addEventListener("mousemove", this._onmousemove.bind(this), false); - this.element.addEventListener("mouseout", this._onmouseout.bind(this), false); - - TreeOutline.call(this, this.element); - - this.includeRootDOMNode = true; - this.selectEnabled = false; - this.rootDOMNode = null; - this.focusedDOMNode = null; -} - -WebInspector.ElementsTreeOutline.prototype = { - get rootDOMNode() - { - return this._rootDOMNode; - }, - - set rootDOMNode(x) - { - if (objectsAreSame(this._rootDOMNode, x)) - return; - - this._rootDOMNode = x; - - this.update(); - }, - - get focusedDOMNode() - { - return this._focusedDOMNode; - }, - - set focusedDOMNode(x) - { - if (objectsAreSame(this._focusedDOMNode, x)) { - this.revealAndSelectNode(x); - return; - } - - this._focusedDOMNode = x; - - this.revealAndSelectNode(x); - - // The revealAndSelectNode() method might find a different element if there is inlined text, - // and the select() call would change the focusedDOMNode and reenter this setter. So to - // avoid calling focusedNodeChanged() twice, first check if _focusedDOMNode is the same - // node as the one passed in. - if (objectsAreSame(this._focusedDOMNode, x)) { - this.focusedNodeChanged(); - - if (x && !this.suppressSelectHighlight) { - InspectorController.highlightDOMNode(x); - - if ("_restorePreviousHighlightNodeTimeout" in this) - clearTimeout(this._restorePreviousHighlightNodeTimeout); - - function restoreHighlightToHoveredNode() - { - var hoveredNode = WebInspector.hoveredDOMNode; - if (hoveredNode) - InspectorController.highlightDOMNode(hoveredNode); - else - InspectorController.hideDOMNodeHighlight(); - } - - this._restorePreviousHighlightNodeTimeout = setTimeout(restoreHighlightToHoveredNode, 2000); - } - } - }, - - update: function() - { - this.removeChildren(); - - if (!this.rootDOMNode) - return; - - var treeElement; - if (this.includeRootDOMNode) { - treeElement = new WebInspector.ElementsTreeElement(this.rootDOMNode); - treeElement.selectable = this.selectEnabled; - this.appendChild(treeElement); - } else { - // FIXME: this could use findTreeElement to reuse a tree element if it already exists - var node = (Preferences.ignoreWhitespace ? firstChildSkippingWhitespace.call(this.rootDOMNode) : this.rootDOMNode.firstChild); - while (node) { - treeElement = new WebInspector.ElementsTreeElement(node); - treeElement.selectable = this.selectEnabled; - this.appendChild(treeElement); - node = Preferences.ignoreWhitespace ? nextSiblingSkippingWhitespace.call(node) : node.nextSibling; - } - } - - this.updateSelection(); - }, - - updateSelection: function() - { - if (!this.selectedTreeElement) - return; - var element = this.treeOutline.selectedTreeElement; - element.updateSelection(); - }, - - focusedNodeChanged: function(forceUpdate) {}, - - findTreeElement: function(node, isAncestor, getParent, equal) - { - if (typeof isAncestor === "undefined") - isAncestor = isAncestorIncludingParentFrames; - if (typeof getParent === "undefined") - getParent = parentNodeOrFrameElement; - if (typeof equal === "undefined") - equal = objectsAreSame; - - var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, isAncestor, getParent, equal); - if (!treeElement && node.nodeType === Node.TEXT_NODE) { - // The text node might have been inlined if it was short, so try to find the parent element. - treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, isAncestor, getParent, equal); - } - - return treeElement; - }, - - revealAndSelectNode: function(node) - { - if (!node) - return; - - var treeElement = this.findTreeElement(node); - if (!treeElement) - return; - - treeElement.reveal(); - treeElement.select(); - }, - - _treeElementFromEvent: function(event) - { - var root = this.element; - - // We choose this X coordinate based on the knowledge that our list - // items extend nearly to the right edge of the outer <ol>. - var x = root.totalOffsetLeft + root.offsetWidth - 20; - - var y = event.pageY; - - // Our list items have 1-pixel cracks between them vertically. We avoid - // the cracks by checking slightly above and slightly below the mouse - // and seeing if we hit the same element each time. - var elementUnderMouse = this.treeElementFromPoint(x, y); - var elementAboveMouse = this.treeElementFromPoint(x, y - 2); - var element; - if (elementUnderMouse === elementAboveMouse) - element = elementUnderMouse; - else - element = this.treeElementFromPoint(x, y + 2); - - return element; - }, - - _ondblclick: function(event) - { - var element = this._treeElementFromEvent(event); - - if (!element || !element.ondblclick) - return; - - element.ondblclick(element, event); - }, - - _onmousedown: function(event) - { - var element = this._treeElementFromEvent(event); - - if (!element || element.isEventWithinDisclosureTriangle(event)) - return; - - element.select(); - }, - - _onmousemove: function(event) - { - if (this._previousHoveredElement) { - this._previousHoveredElement.hovered = false; - delete this._previousHoveredElement; - } - - var element = this._treeElementFromEvent(event); - if (element && !element.elementCloseTag) { - element.hovered = true; - this._previousHoveredElement = element; - } - - WebInspector.hoveredDOMNode = (element && !element.elementCloseTag ? element.representedObject : null); - }, - - _onmouseout: function(event) - { - var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY); - if (nodeUnderMouse.isDescendant(this.element)) - return; - - if (this._previousHoveredElement) { - this._previousHoveredElement.hovered = false; - delete this._previousHoveredElement; - } - - WebInspector.hoveredDOMNode = null; - } -} - -WebInspector.ElementsTreeOutline.prototype.__proto__ = TreeOutline.prototype; - -WebInspector.ElementsTreeElement = function(node) -{ - var hasChildren = node.contentDocument || (Preferences.ignoreWhitespace ? (firstChildSkippingWhitespace.call(node) ? true : false) : node.hasChildNodes()); - var titleInfo = nodeTitleInfo.call(node, hasChildren, WebInspector.linkifyURL); - - if (titleInfo.hasChildren) - this.whitespaceIgnored = Preferences.ignoreWhitespace; - - // The title will be updated in onattach. - TreeElement.call(this, "", node, titleInfo.hasChildren); -} - -WebInspector.ElementsTreeElement.prototype = { - get highlighted() - { - return this._highlighted; - }, - - set highlighted(x) - { - if (this._highlighted === x) - return; - - this._highlighted = x; - - if (this.listItemElement) { - if (x) - this.listItemElement.addStyleClass("highlighted"); - else - this.listItemElement.removeStyleClass("highlighted"); - } - }, - - get hovered() - { - return this._hovered; - }, - - set hovered(x) - { - if (this._hovered === x) - return; - - this._hovered = x; - - if (this.listItemElement) { - if (x) { - this.updateSelection(); - this.listItemElement.addStyleClass("hovered"); - } else - this.listItemElement.removeStyleClass("hovered"); - } - }, - - updateSelection: function() - { - var listItemElement = this.listItemElement; - if (!listItemElement) - return; - - if (document.body.offsetWidth <= 0) { - // The stylesheet hasn't loaded yet or the window is closed, - // so we can't calculate what is need. Return early. - return; - } - - if (!this.selectionElement) { - this.selectionElement = document.createElement("div"); - this.selectionElement.className = "selection selected"; - listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild); - } - - this.selectionElement.style.height = listItemElement.offsetHeight + "px"; - }, - - onattach: function() - { - this.listItemElement.addEventListener("mousedown", this.onmousedown.bind(this), false); - - if (this._highlighted) - this.listItemElement.addStyleClass("highlighted"); - - if (this._hovered) { - this.updateSelection(); - this.listItemElement.addStyleClass("hovered"); - } - - this._updateTitle(); - - this._preventFollowingLinksOnDoubleClick(); - }, - - _preventFollowingLinksOnDoubleClick: function() - { - var links = this.listItemElement.querySelectorAll("li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link"); - if (!links) - return; - - for (var i = 0; i < links.length; ++i) - links[i].preventFollowOnDoubleClick = true; - }, - - onpopulate: function() - { - if (this.children.length || this.whitespaceIgnored !== Preferences.ignoreWhitespace) - return; - - this.whitespaceIgnored = Preferences.ignoreWhitespace; - - this.updateChildren(); - }, - - updateChildren: function(fullRefresh) - { - if (fullRefresh) { - var selectedTreeElement = this.treeOutline.selectedTreeElement; - if (selectedTreeElement && selectedTreeElement.hasAncestor(this)) - this.select(); - this.removeChildren(); - } - - var treeElement = this; - var treeChildIndex = 0; - - function updateChildrenOfNode(node) - { - var treeOutline = treeElement.treeOutline; - var child = (Preferences.ignoreWhitespace ? firstChildSkippingWhitespace.call(node) : node.firstChild); - while (child) { - var currentTreeElement = treeElement.children[treeChildIndex]; - if (!currentTreeElement || !objectsAreSame(currentTreeElement.representedObject, child)) { - // Find any existing element that is later in the children list. - var existingTreeElement = null; - for (var i = (treeChildIndex + 1); i < treeElement.children.length; ++i) { - if (objectsAreSame(treeElement.children[i].representedObject, child)) { - existingTreeElement = treeElement.children[i]; - break; - } - } - - if (existingTreeElement && existingTreeElement.parent === treeElement) { - // If an existing element was found and it has the same parent, just move it. - var wasSelected = existingTreeElement.selected; - treeElement.removeChild(existingTreeElement); - treeElement.insertChild(existingTreeElement, treeChildIndex); - if (wasSelected) - existingTreeElement.select(); - } else { - // No existing element found, insert a new element. - var newElement = new WebInspector.ElementsTreeElement(child); - newElement.selectable = treeOutline.selectEnabled; - treeElement.insertChild(newElement, treeChildIndex); - } - } - - child = Preferences.ignoreWhitespace ? nextSiblingSkippingWhitespace.call(child) : child.nextSibling; - ++treeChildIndex; - } - } - - // Remove any tree elements that no longer have this node (or this node's contentDocument) as their parent. - for (var i = (this.children.length - 1); i >= 0; --i) { - if ("elementCloseTag" in this.children[i]) - continue; - - var currentChild = this.children[i]; - var currentNode = currentChild.representedObject; - var currentParentNode = currentNode.parentNode; - - if (objectsAreSame(currentParentNode, this.representedObject)) - continue; - if (this.representedObject.contentDocument && objectsAreSame(currentParentNode, this.representedObject.contentDocument)) - continue; - - var selectedTreeElement = this.treeOutline.selectedTreeElement; - if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild))) - this.select(); - - this.removeChildAtIndex(i); - - if (this.treeOutline.panel && currentNode.contentDocument) - this.treeOutline.panel.unregisterMutationEventListeners(currentNode.contentDocument.defaultView); - } - - if (this.representedObject.contentDocument) - updateChildrenOfNode(this.representedObject.contentDocument); - updateChildrenOfNode(this.representedObject); - - var lastChild = this.children[this.children.length - 1]; - if (this.representedObject.nodeType == Node.ELEMENT_NODE && (!lastChild || !lastChild.elementCloseTag)) { - var title = "<span class=\"webkit-html-tag close\"></" + this.representedObject.nodeName.toLowerCase().escapeHTML() + "></span>"; - var item = new TreeElement(title, null, false); - item.selectable = false; - item.elementCloseTag = true; - this.appendChild(item); - } - }, - - onexpand: function() - { - this.treeOutline.updateSelection(); - - if (this.treeOutline.panel && this.representedObject.contentDocument) - this.treeOutline.panel.registerMutationEventListeners(this.representedObject.contentDocument.defaultView); - }, - - oncollapse: function() - { - this.treeOutline.updateSelection(); - }, - - onreveal: function() - { - if (this.listItemElement) - this.listItemElement.scrollIntoViewIfNeeded(false); - }, - - onselect: function() - { - this.treeOutline.focusedDOMNode = this.representedObject; - this.updateSelection(); - }, - - onmousedown: function(event) - { - if (this._editing) - return; - - // Prevent selecting the nearest word on double click. - if (event.detail >= 2) - event.preventDefault(); - }, - - ondblclick: function(treeElement, event) - { - if (this._editing) - return; - - if (this._startEditing(event)) - return; - - if (this.treeOutline.panel) { - this.treeOutline.rootDOMNode = this.parent.representedObject; - this.treeOutline.focusedDOMNode = this.representedObject; - } - - if (this.hasChildren && !this.expanded) - this.expand(); - }, - - _startEditing: function(event) - { - if (this.treeOutline.focusedDOMNode != this.representedObject) - return; - - if (this.representedObject.nodeType != Node.ELEMENT_NODE && this.representedObject.nodeType != Node.TEXT_NODE) - return false; - - var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node"); - if (textNode) - return this._startEditingTextNode(textNode); - - var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute"); - if (attribute) - return this._startEditingAttribute(attribute, event); - - return false; - }, - - _startEditingAttribute: function(attribute, event) - { - if (WebInspector.isBeingEdited(attribute)) - return true; - - var attributeNameElement = attribute.getElementsByClassName("webkit-html-attribute-name")[0]; - if (!attributeNameElement) - return false; - - var attributeName = attributeNameElement.innerText; - - function removeZeroWidthSpaceRecursive(node) - { - if (node.nodeType === Node.TEXT_NODE) { - node.nodeValue = node.nodeValue.replace(/\u200B/g, ""); - return; - } - - if (node.nodeType !== Node.ELEMENT_NODE) - return; - - for (var child = node.firstChild; child; child = child.nextSibling) - removeZeroWidthSpaceRecursive(child); - } - - // Remove zero-width spaces that were added by nodeTitleInfo. - removeZeroWidthSpaceRecursive(attribute); - - this._editing = true; - - WebInspector.startEditing(attribute, this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName); - window.getSelection().setBaseAndExtent(event.target, 0, event.target, 1); - - return true; - }, - - _startEditingTextNode: function(textNode) - { - if (WebInspector.isBeingEdited(textNode)) - return true; - - this._editing = true; - - WebInspector.startEditing(textNode, this._textNodeEditingCommitted.bind(this), this._editingCancelled.bind(this)); - window.getSelection().setBaseAndExtent(textNode, 0, textNode, 1); - - return true; - }, - - _attributeEditingCommitted: function(element, newText, oldText, attributeName) - { - delete this._editing; - - var parseContainerElement = document.createElement("span"); - parseContainerElement.innerHTML = "<span " + newText + "></span>"; - var parseElement = parseContainerElement.firstChild; - if (!parseElement || !parseElement.hasAttributes()) { - editingCancelled(element, context); - return; - } - - var foundOriginalAttribute = false; - for (var i = 0; i < parseElement.attributes.length; ++i) { - var attr = parseElement.attributes[i]; - foundOriginalAttribute = foundOriginalAttribute || attr.name === attributeName; - InspectorController.inspectedWindow().Element.prototype.setAttribute.call(this.representedObject, attr.name, attr.value); - } - - if (!foundOriginalAttribute) - InspectorController.inspectedWindow().Element.prototype.removeAttribute.call(this.representedObject, attributeName); - - this._updateTitle(); - - this.treeOutline.focusedNodeChanged(true); - }, - - _textNodeEditingCommitted: function(element, newText) - { - delete this._editing; - - var textNode; - if (this.representedObject.nodeType == Node.ELEMENT_NODE) { - // We only show text nodes inline in elements if the element only - // has a single child, and that child is a text node. - textNode = this.representedObject.firstChild; - } else if (this.representedObject.nodeType == Node.TEXT_NODE) - textNode = this.representedObject; - - textNode.nodeValue = newText; - this._updateTitle(); - }, - - _editingCancelled: function(element, context) - { - delete this._editing; - - this._updateTitle(); - }, - - _updateTitle: function() - { - var title = nodeTitleInfo.call(this.representedObject, this.hasChildren, WebInspector.linkifyURL).title; - this.title = "<span class=\"highlight\">" + title + "</span>"; - delete this.selectionElement; - this.updateSelection(); - this._preventFollowingLinksOnDoubleClick(); - }, -} - -WebInspector.ElementsTreeElement.prototype.__proto__ = TreeElement.prototype; |
