summaryrefslogtreecommitdiff
path: root/Source/WebInspectorUI/UserInterface/Views/HoverMenu.js
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebInspectorUI/UserInterface/Views/HoverMenu.js
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebInspectorUI/UserInterface/Views/HoverMenu.js')
-rw-r--r--Source/WebInspectorUI/UserInterface/Views/HoverMenu.js275
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";