diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebInspectorUI/UserInterface/Views/HoverMenu.js | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/Views/HoverMenu.js')
-rw-r--r-- | Source/WebInspectorUI/UserInterface/Views/HoverMenu.js | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/Source/WebInspectorUI/UserInterface/Views/HoverMenu.js b/Source/WebInspectorUI/UserInterface/Views/HoverMenu.js new file mode 100644 index 000000000..09a6c9b0c --- /dev/null +++ b/Source/WebInspectorUI/UserInterface/Views/HoverMenu.js @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2013, 2015 Apple Inc. All rights reserved. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.HoverMenu = class HoverMenu extends WebInspector.Object +{ + constructor(delegate) + { + super(); + + this.delegate = delegate; + + this._element = document.createElement("div"); + this._element.className = "hover-menu"; + this._element.addEventListener("transitionend", this, true); + + this._outlineElement = this._element.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg")); + + this._button = this._element.appendChild(document.createElement("img")); + this._button.addEventListener("click", this); + } + + // Public + + get element() + { + return this._element; + } + + present(rects) + { + this._outlineElement.textContent = ""; + + document.body.appendChild(this._element); + this._drawOutline(rects); + this._element.classList.add(WebInspector.HoverMenu.VisibleClassName); + + window.addEventListener("scroll", this, true); + } + + dismiss(discrete) + { + if (this._element.parentNode !== document.body) + return; + + if (discrete) + this._element.remove(); + + this._element.classList.remove(WebInspector.HoverMenu.VisibleClassName); + + window.removeEventListener("scroll", this, true); + } + + // Protected + + handleEvent(event) + { + switch (event.type) { + case "scroll": + if (!this._element.contains(event.target)) + this.dismiss(true); + break; + case "click": + this._handleClickEvent(event); + break; + case "transitionend": + if (!this._element.classList.contains(WebInspector.HoverMenu.VisibleClassName)) + this._element.remove(); + break; + } + } + + // Private + + _handleClickEvent(event) + { + if (this.delegate && typeof this.delegate.hoverMenuButtonWasPressed === "function") + this.delegate.hoverMenuButtonWasPressed(this); + } + + _drawOutline(rects) + { + var buttonWidth = this._button.width; + var buttonHeight = this._button.height; + + // Add room for the button on the last line. + var lastRect = rects.pop(); + lastRect.size.width += buttonWidth; + rects.push(lastRect); + + if (rects.length === 1) + this._drawSingleLine(rects[0]); + else if (rects.length === 2 && rects[0].minX() >= rects[1].maxX()) + this._drawTwoNonOverlappingLines(rects); + else + this._drawOverlappingLines(rects); + + var bounds = WebInspector.Rect.unionOfRects(rects).pad(3); // padding + 1/2 stroke-width + + var style = this._element.style; + style.left = bounds.minX() + "px"; + style.top = bounds.minY() + "px"; + style.width = bounds.size.width + "px"; + style.height = bounds.size.height + "px"; + + this._outlineElement.style.width = bounds.size.width + "px"; + this._outlineElement.style.height = bounds.size.height + "px"; + + this._button.style.left = (lastRect.maxX() - bounds.minX() - buttonWidth) + "px"; + this._button.style.top = (lastRect.maxY() - bounds.minY() - buttonHeight) + "px"; + } + + _addRect(rect) + { + var r = 4; + + var svgRect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + svgRect.setAttribute("x", 1); + svgRect.setAttribute("y", 1); + svgRect.setAttribute("width", rect.size.width); + svgRect.setAttribute("height", rect.size.height); + svgRect.setAttribute("rx", r); + svgRect.setAttribute("ry", r); + return this._outlineElement.appendChild(svgRect); + } + + _addPath(commands, tx, ty) + { + var path = document.createElementNS("http://www.w3.org/2000/svg", "path"); + path.setAttribute("d", commands.join(" ")); + path.setAttribute("transform", "translate(" + (tx + 1) + "," + (ty + 1) + ")"); + return this._outlineElement.appendChild(path); + } + + _drawSingleLine(rect) + { + this._addRect(rect.pad(2)); + } + + _drawTwoNonOverlappingLines(rects) + { + var r = 4; + + var firstRect = rects[0].pad(2); + var secondRect = rects[1].pad(2); + + var tx = -secondRect.minX(); + var ty = -firstRect.minY(); + + var rect = firstRect; + this._addPath([ + "M", rect.maxX(), rect.minY(), + "H", rect.minX() + r, + "q", -r, 0, -r, r, + "V", rect.maxY() - r, + "q", 0, r, r, r, + "H", rect.maxX() + ], tx, ty); + + rect = secondRect; + this._addPath([ + "M", rect.minX(), rect.minY(), + "H", rect.maxX() - r, + "q", r, 0, r, r, + "V", rect.maxY() - r, + "q", 0, r, -r, r, + "H", rect.minX() + ], tx, ty); + } + + _drawOverlappingLines(rects) + { + var PADDING = 2; + var r = 4; + + var minX = Number.MAX_VALUE; + var maxX = -Number.MAX_VALUE; + for (var rect of rects) { + var minX = Math.min(rect.minX(), minX); + var maxX = Math.max(rect.maxX(), maxX); + } + + minX -= PADDING; + maxX += PADDING; + + var minY = rects[0].minY() - PADDING; + var maxY = rects.lastValue.maxY() + PADDING; + var firstLineMinX = rects[0].minX() - PADDING; + var lastLineMaxX = rects.lastValue.maxX() + PADDING; + + if (firstLineMinX === minX && lastLineMaxX === maxX) + return this._addRect(new WebInspector.Rect(minX, minY, maxX - minX, maxY - minY)); + + var lastLineMinY = rects.lastValue.minY() + PADDING; + if (rects[0].minX() === minX + PADDING) { + return this._addPath([ + "M", minX + r, minY, + "H", maxX - r, + "q", r, 0, r, r, + "V", lastLineMinY - r, + "q", 0, r, -r, r, + "H", lastLineMaxX + r, + "q", -r, 0, -r, r, + "V", maxY - r, + "q", 0, r, -r, r, + "H", minX + r, + "q", -r, 0, -r, -r, + "V", minY + r, + "q", 0, -r, r, -r + ], -minX, -minY); + } + + var firstLineMaxY = rects[0].maxY() - PADDING; + if (rects.lastValue.maxX() === maxX - PADDING) { + return this._addPath([ + "M", firstLineMinX + r, minY, + "H", maxX - r, + "q", r, 0, r, r, + "V", maxY - r, + "q", 0, r, -r, r, + "H", minX + r, + "q", -r, 0, -r, -r, + "V", firstLineMaxY + r, + "q", 0, -r, r, -r, + "H", firstLineMinX - r, + "q", r, 0, r, -r, + "V", minY + r, + "q", 0, -r, r, -r + ], -minX, -minY); + } + + return this._addPath([ + "M", firstLineMinX + r, minY, + "H", maxX - r, + "q", r, 0, r, r, + "V", lastLineMinY - r, + "q", 0, r, -r, r, + "H", lastLineMaxX + r, + "q", -r, 0, -r, r, + "V", maxY - r, + "q", 0, r, -r, r, + "H", minX + r, + "q", -r, 0, -r, -r, + "V", firstLineMaxY + r, + "q", 0, -r, r, -r, + "H", firstLineMinX - r, + "q", r, 0, r, -r, + "V", minY + r, + "q", 0, -r, r, -r + ], -minX, -minY); + } +}; + +WebInspector.HoverMenu.VisibleClassName = "visible"; |