Changeset 214844 in webkit


Ignore:
Timestamp:
Apr 3, 2017 3:09:23 PM (7 years ago)
Author:
Matt Baker
Message:

Web Inspector: Elements tab: show indicators for hidden DOM breakpoints
https://bugs.webkit.org/show_bug.cgi?id=168761

Reviewed by Timothy Hatcher.

  • Localizations/en.lproj/localizedStrings.js:

New DOM breakpoint content menu item.

  • UserInterface/Views/DOMTreeContentView.css:

(.content-view.dom-tree .tree-outline.dom li .status-image.breakpoint.subtree):
(.content-view.dom-tree .tree-outline.dom li.expanded .status-image.breakpoint.subtree):
New styles for collapsed breakpoint marker.

  • UserInterface/Views/DOMTreeElement.js:

(WebInspector.DOMTreeElement):
(WebInspector.DOMTreeElement.prototype.set breakpointStatus):
If the status change indicates the only breakpoint was added or removed,
update subtree breakpoint counts on the element's parent chain.

(WebInspector.DOMTreeElement.prototype.revealAndHighlight):
Reveal the tree element, and add a highlighted line animation
identical to the one used used by TextEditor.

(WebInspector.DOMTreeElement.prototype.subtreeBreakpointCountDidChange):
(WebInspector.DOMTreeElement.prototype.updateSelectionArea):
Selection area should be updated when animating the element highlight.
(WebInspector.DOMTreeElement.prototype.onreveal):
Animate highlight if needed.
(WebInspector.DOMTreeElement.prototype._updateBreakpointStatus):
(WebInspector.DOMTreeElement.prototype._statusImageClicked):
Do nothing when clicking the collapsed breakpoint marker.
(WebInspector.DOMTreeElement.prototype._statusImageContextmenu):
Add "Reveal Breakpoint" menu item. Reveals the first descendant
with at least one breakpoint.

(WebInspector.DOMTreeElement.prototype._highlightAnimationEnd):

  • UserInterface/Views/DOMTreeOutline.css:

(@keyframes dom-tree-outline-highlight-fadeout):
(.highlight .selection-area):
Styles for highlight fade animation.

  • UserInterface/Views/TreeElement.js:

(WebInspector.TreeElement.prototype.selfOrDescendant):

  • UserInterface/Views/TreeOutline.js:

(WebInspector.TreeOutline.prototype.selfOrDescendant):
Find a node matching a predicate.

Location:
trunk/Source/WebInspectorUI
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r214843 r214844  
     12017-04-03  Matt Baker  <mattbaker@apple.com>
     2
     3        Web Inspector: Elements tab: show indicators for hidden DOM breakpoints
     4        https://bugs.webkit.org/show_bug.cgi?id=168761
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        * Localizations/en.lproj/localizedStrings.js:
     9        New DOM breakpoint content menu item.
     10
     11        * UserInterface/Views/DOMTreeContentView.css:
     12        (.content-view.dom-tree .tree-outline.dom li .status-image.breakpoint.subtree):
     13        (.content-view.dom-tree .tree-outline.dom li.expanded .status-image.breakpoint.subtree):
     14        New styles for collapsed breakpoint marker.
     15
     16        * UserInterface/Views/DOMTreeElement.js:
     17        (WebInspector.DOMTreeElement):
     18        (WebInspector.DOMTreeElement.prototype.set breakpointStatus):
     19        If the status change indicates the only breakpoint was added or removed,
     20        update subtree breakpoint counts on the element's parent chain.
     21
     22        (WebInspector.DOMTreeElement.prototype.revealAndHighlight):
     23        Reveal the tree element, and add a highlighted line animation
     24        identical to the one used used by TextEditor.
     25
     26        (WebInspector.DOMTreeElement.prototype.subtreeBreakpointCountDidChange):
     27        (WebInspector.DOMTreeElement.prototype.updateSelectionArea):
     28        Selection area should be updated when animating the element highlight.
     29        (WebInspector.DOMTreeElement.prototype.onreveal):
     30        Animate highlight if needed.
     31        (WebInspector.DOMTreeElement.prototype._updateBreakpointStatus):
     32        (WebInspector.DOMTreeElement.prototype._statusImageClicked):
     33        Do nothing when clicking the collapsed breakpoint marker.
     34        (WebInspector.DOMTreeElement.prototype._statusImageContextmenu):
     35        Add "Reveal Breakpoint" menu item. Reveals the first descendant
     36        with at least one breakpoint.
     37
     38        (WebInspector.DOMTreeElement.prototype._highlightAnimationEnd):
     39
     40        * UserInterface/Views/DOMTreeOutline.css:
     41        (@keyframes dom-tree-outline-highlight-fadeout):
     42        (.highlight .selection-area):
     43        Styles for highlight fade animation.
     44
     45        * UserInterface/Views/TreeElement.js:
     46        (WebInspector.TreeElement.prototype.selfOrDescendant):
     47        * UserInterface/Views/TreeOutline.js:
     48        (WebInspector.TreeOutline.prototype.selfOrDescendant):
     49        Find a node matching a predicate.
     50
    1512017-04-03  Matt Baker  <mattbaker@apple.com>
    252
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r214841 r214844  
    683683localizedStrings["Return type for anonymous function"] = "Return type for anonymous function";
    684684localizedStrings["Return type for function: %s"] = "Return type for function: %s";
     685localizedStrings["Reveal Breakpoint"] = "Reveal Breakpoint";
    685686localizedStrings["Reveal in DOM Tree"] = "Reveal in DOM Tree";
    686687localizedStrings["Reveal in Debugger Tab"] = "Reveal in Debugger Tab";
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeContentView.css

    r214196 r214844  
    8585    stroke: var(--breakpoint-unresolved-disabled-stroke-color);
    8686}
     87
     88.content-view.dom-tree .tree-outline.dom li .status-image.breakpoint.subtree {
     89    fill: none;
     90    opacity: 0.6;
     91}
     92
     93.content-view.dom-tree .tree-outline.dom li.expanded .status-image.breakpoint.subtree {
     94    display: none;
     95}
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeElement.js

    r214256 r214844  
    4343        this._expandedChildrenLimit = WebInspector.DOMTreeElement.InitialChildrenLimit;
    4444        this._breakpointStatus = WebInspector.DOMTreeElement.BreakpointStatus.None;
     45        this._animatingHighlight = false;
     46        this._shouldHighlightAfterReveal = false;
     47        this._boundHighlightAnimationEnd = this._highlightAnimationEnd.bind(this);
     48        this._subtreeBreakpointCount = 0;
    4549
    4650        this._recentlyModifiedAttributes = [];
     
    7680            return;
    7781
     82        let increment;
     83        if (this._breakpointStatus === WebInspector.DOMTreeElement.BreakpointStatus.None)
     84            increment = 1;
     85        else if (status === WebInspector.DOMTreeElement.BreakpointStatus.None)
     86            increment = -1;
     87
    7888        this._breakpointStatus = status;
     89        this._updateBreakpointStatus();
     90
     91        if (!increment)
     92            return;
     93
     94        let parentElement = this.parent;
     95        while (parentElement && !parentElement.root) {
     96            parentElement.subtreeBreakpointCountDidChange(increment);
     97            parentElement = parentElement.parent;
     98        }
     99    }
     100
     101    revealAndHighlight()
     102    {
     103        if (this._animatingHighlight)
     104            return;
     105
     106        this._shouldHighlightAfterReveal = true;
     107        this.reveal();
     108    }
     109
     110    subtreeBreakpointCountDidChange(increment)
     111    {
     112        this._subtreeBreakpointCount += increment;
    79113        this._updateBreakpointStatus();
    80114    }
     
    299333
    300334        // If there's no reason to have a selection area, remove the DOM element.
    301         let indicatesTreeOutlineState = this.treeOutline && (this.treeOutline.dragOverTreeElement === this || this.treeOutline.selectedTreeElement === this);
     335        let indicatesTreeOutlineState = this.treeOutline && (this.treeOutline.dragOverTreeElement === this || this.treeOutline.selectedTreeElement === this || this._animatingHighlight);
    302336        if (!this.hovered && !this.pseudoClassesEnabled && !indicatesTreeOutlineState) {
    303337            if (this._selectionElement) {
     
    535569    onreveal()
    536570    {
    537         if (this.listItemElement) {
    538             var tagSpans = this.listItemElement.getElementsByClassName("html-tag-name");
    539             if (tagSpans.length)
    540                 tagSpans[0].scrollIntoViewIfNeeded(false);
    541             else
    542                 this.listItemElement.scrollIntoViewIfNeeded(false);
    543         }
     571        let listItemElement = this.listItemElement;
     572        if (!listItemElement)
     573            return;
     574
     575        let tagSpans = listItemElement.getElementsByClassName("html-tag-name");
     576        if (tagSpans.length)
     577            tagSpans[0].scrollIntoViewIfNeeded(false);
     578        else
     579            listItemElement.scrollIntoViewIfNeeded(false);
     580
     581        if (!this._shouldHighlightAfterReveal)
     582            return;
     583
     584        this._shouldHighlightAfterReveal = false;
     585        this._animatingHighlight = true;
     586
     587        this.updateSelectionArea();
     588
     589        listItemElement.addEventListener("animationend", this._boundHighlightAnimationEnd);
     590        listItemElement.classList.add(WebInspector.DOMTreeElement.HighlightStyleClassName);
    544591    }
    545592
     
    16761723            return;
    16771724
    1678         if (this._breakpointStatus === WebInspector.DOMTreeElement.BreakpointStatus.None) {
     1725        let hasBreakpoint = this._breakpointStatus !== WebInspector.DOMTreeElement.BreakpointStatus.None;
     1726        let hasSubtreeBreakpoints = !!this._subtreeBreakpointCount;
     1727
     1728        if (!hasBreakpoint && !hasSubtreeBreakpoints) {
    16791729            if (this._statusImageElement)
    16801730                this._statusImageElement.remove();
     
    16901740        }
    16911741
     1742        this._statusImageElement.classList.toggle("subtree", !hasBreakpoint && hasSubtreeBreakpoints);
     1743
    16921744        this.listItemElement.insertBefore(this._statusImageElement, this.listItemElement.firstChild);
    16931745
     
    16981750    _statusImageClicked(event)
    16991751    {
     1752        if (this._breakpointStatus === WebInspector.DOMTreeElement.BreakpointStatus.None)
     1753            return;
     1754
    17001755        if (event.button !== 0 || event.ctrlKey)
    17011756            return;
     
    17111766    _statusImageContextmenu(event)
    17121767    {
    1713         const allowEditing = true;
     1768        let hasBreakpoint = this._breakpointStatus !== WebInspector.DOMTreeElement.BreakpointStatus.None;
     1769        let hasSubtreeBreakpoints = !!this._subtreeBreakpointCount;
     1770        if (!hasBreakpoint && !hasSubtreeBreakpoints)
     1771            return;
    17141772
    17151773        let contextMenu = WebInspector.ContextMenu.createFromEvent(event);
    1716         WebInspector.DOMBreakpointTreeController.appendBreakpointContextMenuItems(contextMenu, this.representedObject, allowEditing);
     1774        if (hasBreakpoint) {
     1775            const allowEditing = true;
     1776            WebInspector.DOMBreakpointTreeController.appendBreakpointContextMenuItems(contextMenu, this.representedObject, allowEditing);
     1777            return;
     1778        }
     1779
     1780        contextMenu.appendItem(WebInspector.UIString("Reveal Breakpoint"), () => {
     1781            let breakpointTreeElement = this.selfOrDescendant((treeElement) => treeElement.breakpointStatus && treeElement.breakpointStatus !== WebInspector.DOMTreeElement.BreakpointStatus.None);
     1782            console.assert(breakpointTreeElement, "Missing breakpoint descendant.", this)
     1783            if (!breakpointTreeElement)
     1784                return;
     1785
     1786            breakpointTreeElement.revealAndHighlight();
     1787        });
     1788    }
     1789
     1790    _highlightAnimationEnd()
     1791    {
     1792        let listItemElement = this.listItemElement;
     1793        if (!listItemElement)
     1794            return;
     1795
     1796        listItemElement.removeEventListener("animationend", this._boundHighlightAnimationEnd);
     1797        listItemElement.classList.remove(WebInspector.DOMTreeElement.HighlightStyleClassName);
     1798
     1799        this._animatingHighlight = false;
    17171800    }
    17181801};
     
    17441827};
    17451828
     1829WebInspector.DOMTreeElement.HighlightStyleClassName = "highlight";
    17461830WebInspector.DOMTreeElement.SearchHighlightStyleClassName = "search-highlight";
    17471831WebInspector.DOMTreeElement.BouncyHighlightStyleClassName = "bouncy-highlight";
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.css

    r214196 r214844  
    296296    animation: node-state-changed 1s cubic-bezier(0.25, 0, 0.25, 1);
    297297}
     298
     299@keyframes dom-tree-outline-highlight-fadeout {
     300    from { background-color: highlight; }
     301}
     302
     303.highlight .selection-area {
     304    animation: "dom-tree-outline-highlight-fadeout" 2s;
     305}
  • trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js

    r212913 r214844  
    6464    removeChildren() { return WebInspector.TreeOutline.prototype.removeChildren.apply(this, arguments); }
    6565    removeChildrenRecursive() { return WebInspector.TreeOutline.prototype.removeChildrenRecursive.apply(this, arguments); }
     66    selfOrDescendant() { return WebInspector.TreeOutline.prototype.selfOrDescendant.apply(this, arguments); }
    6667
    6768    get arrowToggleWidth()
  • trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js

    r214514 r214844  
    396396        }
    397397        return null;
     398    }
     399
     400    selfOrDescendant(predicate)
     401    {
     402        let treeElements = [this];
     403        while (treeElements.length) {
     404            let treeElement = treeElements.shift();
     405            if (predicate(treeElement))
     406                return treeElement;
     407
     408            treeElements = treeElements.concat(treeElement.children);
     409        }
     410
     411        return false;
    398412    }
    399413
Note: See TracChangeset for help on using the changeset viewer.