| <!-- |
| Copyright (C) 2012 Google 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. |
| 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. |
| --> |
| <!DOCTYPE html> |
| <html> |
| <head> |
| <style> |
| body { |
| margin: 0; |
| padding: 0; |
| } |
| |
| body.touch { |
| cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAQAAAADHm0dAAABH0lEQVR4XpWTO2rDQBCG18S6gAWCoD6VFHKCCBZsN7qACgenFZn/OAZDrConMahJzmGM+oBJMfmziIUs8UMOXzHD7seyzMMwJOEDZ7r4ftEFZy5PwtvfNKIliE/Z4hVbFwmHZfRXTfWZWOEOI5iekctXINx5GqopZSdTmCOm2AmFt15lpMu9TGBOMsFe9InjXmVBzGHOMgfBR6cyJtYwF1mDYGyYEdmAmoNgZmgPcjOgjvEltEarFmaQd2hltN5cob5B6ytf/YBW//krMyIfUO99BWKiGVCbvq6+W+UFsfTd8jPQSXJGTND1MxBMViflyRe7YLK8rEuiQQ5fDRfz/o/uPD3egoIgDtJig9ZFwlGEWxASM6PVSmutaF0eh7c/zBRVQt5j3yoAAAAASUVORK5CYII=) 10 10, auto !important; |
| } |
| |
| body.platform-mac { |
| font-size: 11px; |
| font-family: Menlo, Monaco; |
| } |
| |
| body.platform-windows { |
| font-size: 12px; |
| font-family: Consolas, Lucida Console; |
| } |
| |
| body.platform-linux { |
| font-size: 11px; |
| font-family: dejavu sans mono; |
| } |
| |
| .fill { |
| position: absolute; |
| top: 0; |
| right: 0; |
| bottom: 0; |
| left: 0; |
| } |
| |
| .dimmed { |
| background-color: rgba(0, 0, 0, 0.31); |
| } |
| |
| #canvas { |
| pointer-events: none; |
| } |
| |
| .controls-line { |
| display: -webkit-flex; |
| -webkit-justify-content: center; |
| margin: 10px 0; |
| } |
| |
| .message-box { |
| padding: 2px 4px; |
| display: -webkit-flex; |
| -webkit-align-items: center; |
| cursor: default; |
| } |
| |
| .controls-line > * { |
| background-color: rgb(255, 255, 194); |
| border: 1px solid rgb(202, 202, 202); |
| height: 22px; |
| box-sizing: border-box; |
| } |
| |
| .controls-line button { |
| width: 26px; |
| margin-left: -1px; |
| margin-right: 0; |
| padding: 0; |
| } |
| |
| .controls-line button:hover { |
| cursor: pointer; |
| } |
| |
| .controls-line button .glyph { |
| width: 100%; |
| height: 100%; |
| background-color: rgba(0, 0, 0, 0.75); |
| opacity: 0.8; |
| -webkit-mask-repeat: no-repeat; |
| -webkit-mask-position: center; |
| } |
| |
| .controls-line button:active { |
| border: 1px solid rgb(120, 120, 120); |
| z-index: 1; |
| } |
| |
| #resume-button .glyph { |
| -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAKCAYAAABv7tTEAAAAAXNSR0IArs4c6QAAAFJJREFUKM+10bEJgGAMBeEPbR3BLRzEVdzEVRzELRzBVohVwEJ+iODBlQfhBeJhsmHU4C0KnFjQV6J0x1SNAhdWDJUoPTB3PvLLeaUhypM3n3sD/qc7lDrdpIEAAAAASUVORK5CYII=); |
| -webkit-mask-size: 13px 10px; |
| background-color: rgb(66, 129, 235); |
| } |
| |
| #step-over-button .glyph { |
| -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAKCAYAAAC5Sw6hAAAAAXNSR0IArs4c6QAAAOFJREFUKM+N0j8rhXEUB/DPcxW35CqhvIBrtqibkklhV8qkTHe4ZbdblcXgPVhuMdqUTUl5A2KRRCF5LGc4PT1P7qnfcr5/zu/8KdTHLFaxjHnc4RZXKI0QYxjgLQTVd42l/0wmg5iFX3iq5H6w22RS4DyRH7CB8cAXcBTGJT6xUmd0mEwuMdFQcA3fwXvGTAan8BrgPabTL9fRRyfx91PRMwyjGwcJ2EyCfsrfpPw2Pipz24NT/MZciiQYVshzOKnZ5Hturxt3k2MnCpS4SPkeHpPR8Sh3tYgttBoW9II2/AHiaEqvD2Fc0wAAAABJRU5ErkJggg==); |
| -webkit-mask-size: 18px 10px; |
| } |
| |
| .px { |
| color: rgb(128, 128, 128); |
| } |
| |
| #element-title { |
| position: absolute; |
| z-index: 10; |
| } |
| |
| #tag-name { |
| /* Keep this in sync with view-source.css (.webkit-html-tag) */ |
| color: rgb(136, 18, 128); |
| } |
| |
| #node-id { |
| /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */ |
| color: rgb(26, 26, 166); |
| } |
| |
| #class-name { |
| /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */ |
| color: rgb(153, 69, 0); |
| } |
| |
| #right-gutter { |
| display: none; |
| right: 0; |
| top: 0; |
| bottom: 0; |
| position: absolute; |
| background-color: darkgray; |
| } |
| |
| #bottom-gutter { |
| display: none; |
| left: 0; |
| right: 0; |
| bottom: 0; |
| position: absolute; |
| background-color: darkgray; |
| } |
| |
| #overrides-container { |
| display: inline-block; |
| padding: 0 0 10px 10px; |
| position: absolute; |
| top: 0; |
| right: 0; |
| } |
| |
| #overrides-message > div:not(:first-child) { |
| text-indent: 8px; |
| } |
| |
| #overrides-message { |
| display: inline-block; |
| font-size: 14px; |
| padding: 4px 6px; |
| color: red; |
| background-color: rgba(17, 17, 17, 0.843); /* Same as DebugColors::HUDBackgroundColor() */ |
| } |
| |
| #overrides-container:hover #overrides-message, |
| #overrides-container.hidden #overrides-message { |
| visibility: hidden; |
| } |
| </style> |
| <script> |
| const lightGridColor = "rgba(0,0,0,0.2)"; |
| const darkGridColor = "rgba(0,0,0,0.7)"; |
| const transparentColor = "rgba(0, 0, 0, 0)"; |
| const gridBackgroundColor = "rgba(255, 255, 255, 0.8)"; |
| |
| // The order must correspond to that in InspectorOverlay::OverrideType. |
| const overrideEntries = ["User-Agent", "Device Metrics", "Geolocation", "Device Orientation", "Touch", "Media"]; |
| const overrideTouchBit = 1 << 4; |
| |
| var overridesContainer; |
| var overridesMessageElement; |
| |
| function drawPausedInDebuggerMessage(message) |
| { |
| document.querySelector(".controls-line").style.visibility = "visible"; |
| document.getElementById("paused-in-debugger").textContent = message; |
| document.body.classList.add("dimmed"); |
| } |
| |
| function _drawGrid(rulerAtRight, rulerAtBottom) |
| { |
| if (window._gridPainted) |
| return; |
| window._gridPainted = true; |
| |
| context.save(); |
| |
| var pageFactor = pageZoomFactor * pageScaleFactor; |
| function zoom(x) |
| { |
| return Math.round(x * pageFactor); |
| } |
| function unzoom(x) |
| { |
| return Math.round(x / pageFactor); |
| } |
| |
| var width = canvasWidth / pageFactor; |
| var height = canvasHeight / pageFactor; |
| |
| const gridSubStep = 5; |
| const gridStep = 50; |
| |
| { |
| // Draw X grid background |
| context.save(); |
| context.fillStyle = gridBackgroundColor; |
| if (rulerAtBottom) |
| context.fillRect(0, zoom(height) - 15, zoom(width), zoom(height)); |
| else |
| context.fillRect(0, 0, zoom(width), 15); |
| |
| // Clip out backgrounds intersection |
| context.globalCompositeOperation = "destination-out"; |
| context.fillStyle = "red"; |
| if (rulerAtRight) |
| context.fillRect(zoom(width) - 15, 0, zoom(width), zoom(height)); |
| else |
| context.fillRect(0, 0, 15, zoom(height)); |
| context.restore(); |
| |
| // Draw Y grid background |
| context.fillStyle = gridBackgroundColor; |
| if (rulerAtRight) |
| context.fillRect(zoom(width) - 15, 0, zoom(width), zoom(height)); |
| else |
| context.fillRect(0, 0, 15, zoom(height)); |
| } |
| |
| context.lineWidth = 1; |
| context.strokeStyle = darkGridColor; |
| context.fillStyle = darkGridColor; |
| { |
| // Draw labels. |
| context.save(); |
| context.translate(-scrollX, 0.5 - scrollY); |
| var maxY = height + unzoom(scrollY); |
| for (var y = 2 * gridStep; y < maxY; y += 2 * gridStep) { |
| context.save(); |
| context.translate(scrollX, zoom(y)); |
| context.rotate(-Math.PI / 2); |
| context.fillText(y, 2, rulerAtRight ? zoom(width) - 7 : 13); |
| context.restore(); |
| } |
| context.translate(0.5, -0.5); |
| var maxX = width + unzoom(scrollX); |
| for (var x = 2 * gridStep; x < maxX; x += 2 * gridStep) { |
| context.save(); |
| context.fillText(x, zoom(x) + 2, rulerAtBottom ? scrollY + zoom(height) - 7 : scrollY + 13); |
| context.restore(); |
| } |
| context.restore(); |
| } |
| |
| { |
| // Draw vertical grid |
| context.save(); |
| if (rulerAtRight) { |
| context.translate(zoom(width), 0); |
| context.scale(-1, 1); |
| } |
| context.translate(-scrollX, 0.5 - scrollY); |
| var maxY = height + unzoom(scrollY); |
| for (var y = gridStep; y < maxY; y += gridStep) { |
| context.beginPath(); |
| context.moveTo(scrollX, zoom(y)); |
| var markLength = (y % (gridStep * 2)) ? 5 : 8; |
| context.lineTo(scrollX + markLength, zoom(y)); |
| context.stroke(); |
| } |
| context.strokeStyle = lightGridColor; |
| for (var y = gridSubStep; y < maxY; y += gridSubStep) { |
| if (!(y % gridStep)) |
| continue; |
| context.beginPath(); |
| context.moveTo(scrollX, zoom(y)); |
| context.lineTo(scrollX + gridSubStep, zoom(y)); |
| context.stroke(); |
| } |
| context.restore(); |
| } |
| |
| { |
| // Draw horizontal grid |
| context.save(); |
| if (rulerAtBottom) { |
| context.translate(0, zoom(height)); |
| context.scale(1, -1); |
| } |
| context.translate(0.5 - scrollX, -scrollY); |
| var maxX = width + unzoom(scrollX); |
| for (var x = gridStep; x < maxX; x += gridStep) { |
| context.beginPath(); |
| context.moveTo(zoom(x), scrollY); |
| var markLength = (x % (gridStep * 2)) ? 5 : 8; |
| context.lineTo(zoom(x), scrollY + markLength); |
| context.stroke(); |
| } |
| context.strokeStyle = lightGridColor; |
| for (var x = gridSubStep; x < maxX; x += gridSubStep) { |
| if (!(x % gridStep)) |
| continue; |
| context.beginPath(); |
| context.moveTo(zoom(x), scrollY); |
| context.lineTo(zoom(x), scrollY + gridSubStep); |
| context.stroke(); |
| } |
| context.restore(); |
| } |
| |
| context.restore(); |
| } |
| |
| function quadToPath(quad) |
| { |
| context.beginPath(); |
| context.moveTo(quad[0].x, quad[0].y); |
| context.lineTo(quad[1].x, quad[1].y); |
| context.lineTo(quad[2].x, quad[2].y); |
| context.lineTo(quad[3].x, quad[3].y); |
| context.closePath(); |
| return context; |
| } |
| |
| function drawOutlinedQuad(quad, fillColor, outlineColor) |
| { |
| context.save(); |
| context.lineWidth = 2; |
| quadToPath(quad).clip(); |
| context.fillStyle = fillColor; |
| context.fill(); |
| if (outlineColor) { |
| context.strokeStyle = outlineColor; |
| context.stroke(); |
| } |
| context.restore(); |
| } |
| |
| function drawOutlinedQuadWithClip(quad, clipQuad, fillColor) |
| { |
| var canvas = document.getElementById("canvas"); |
| context.fillStyle = fillColor; |
| context.save(); |
| context.lineWidth = 0; |
| quadToPath(quad).fill(); |
| context.globalCompositeOperation = "destination-out"; |
| context.fillStyle = "red"; |
| quadToPath(clipQuad).fill(); |
| context.restore(); |
| } |
| |
| function drawUnderlyingQuad(quad, fillColor) |
| { |
| context.save(); |
| context.lineWidth = 2; |
| context.globalCompositeOperation = "destination-over"; |
| context.fillStyle = fillColor; |
| quadToPath(quad).fill(); |
| context.restore(); |
| } |
| |
| function quadEquals(quad1, quad2) |
| { |
| return quad1[0].x === quad2[0].x && quad1[0].y === quad2[0].y && |
| quad1[1].x === quad2[1].x && quad1[1].y === quad2[1].y && |
| quad1[2].x === quad2[2].x && quad1[2].y === quad2[2].y && |
| quad1[3].x === quad2[3].x && quad1[3].y === quad2[3].y; |
| } |
| |
| function drawGutter() |
| { |
| var frameWidth = frameViewFullSize.width; |
| var frameHeight = frameViewFullSize.height; |
| |
| if (!frameWidth || document.body.offsetWidth <= frameWidth) |
| rightGutter.style.removeProperty("display"); |
| else { |
| rightGutter.style.display = "block"; |
| rightGutter.style.left = frameWidth + "px"; |
| } |
| |
| if (!frameHeight || document.body.offsetHeight <= frameHeight) |
| bottomGutter.style.removeProperty("display"); |
| else { |
| bottomGutter.style.display = "block"; |
| bottomGutter.style.top = frameHeight + "px"; |
| } |
| } |
| |
| function drawViewSize(drawViewSizeWithGrid) |
| { |
| var drawGridBoolean = drawViewSizeWithGrid === "true"; |
| var text = viewportSize.width + "px \u00D7 " + viewportSize.height + "px"; |
| context.save(); |
| context.font = "20px "; |
| switch (platform) { |
| case "windows": context.font = "14px Consolas"; break; |
| case "mac": context.font = "14px Menlo"; break; |
| case "linux": context.font = "14px dejavu sans mono"; break; |
| } |
| |
| var frameWidth = frameViewFullSize.width || canvasWidth; |
| var textWidth = context.measureText(text).width; |
| context.fillStyle = gridBackgroundColor; |
| context.fillRect(frameWidth - textWidth - 12, drawGridBoolean ? 15 : 0, frameWidth, 25); |
| context.fillStyle = darkGridColor; |
| context.fillText(text, frameWidth - textWidth - 6, drawGridBoolean ? 33 : 18); |
| context.restore(); |
| if (drawGridBoolean) |
| _drawGrid(); |
| } |
| |
| function drawOverridesMessage(data) |
| { |
| overridesContainer.style.top = data.topOffset + "px"; |
| var overrides = data.overrides; |
| overridesMessageElement.textContent = ""; |
| if (!overrides) { |
| overridesContainer.classList.add("hidden"); |
| document.body.classList.remove("touch"); |
| return; |
| } |
| |
| var header = document.createElement("div"); |
| header.id = "overrides-header"; |
| header.textContent = "Overrides:"; |
| overridesMessageElement.appendChild(header); |
| |
| var maskBit = 1; |
| for (var i = 0; i < overrideEntries.length; ++i, maskBit <<= 1) { |
| if (!(overrides & maskBit)) |
| continue; |
| var item = document.createElement("div"); |
| item.textContent = overrideEntries[i]; |
| overridesMessageElement.appendChild(item); |
| } |
| |
| overridesContainer.classList.remove("hidden"); |
| var hasTouch = overrides & overrideTouchBit; |
| if (hasTouch) |
| document.body.classList.add("touch"); |
| else |
| document.body.classList.remove("touch"); |
| } |
| |
| function reset(resetData) |
| { |
| window.viewportSize = resetData.viewportSize; |
| window.frameViewFullSize = resetData.frameViewFullSize; |
| window.deviceScaleFactor = resetData.deviceScaleFactor; |
| window.pageZoomFactor = resetData.pageZoomFactor; |
| window.pageScaleFactor = resetData.pageScaleFactor; |
| window.scrollX = Math.round(resetData.scrollX * pageScaleFactor); |
| window.scrollY = Math.round(resetData.scrollY * pageScaleFactor); |
| |
| window.canvas = document.getElementById("canvas"); |
| window.context = canvas.getContext("2d"); |
| window.rightGutter = document.getElementById("right-gutter"); |
| window.bottomGutter = document.getElementById("bottom-gutter"); |
| |
| canvas.width = deviceScaleFactor * viewportSize.width; |
| canvas.height = deviceScaleFactor * viewportSize.height; |
| canvas.style.width = viewportSize.width + "px"; |
| canvas.style.height = viewportSize.height + "px"; |
| context.scale(deviceScaleFactor, deviceScaleFactor); |
| window.canvasWidth = viewportSize.width; |
| window.canvasHeight = viewportSize.height; |
| |
| document.querySelector(".controls-line").style.visibility = "hidden"; |
| document.getElementById("element-title").style.visibility = "hidden"; |
| document.body.classList.remove("dimmed"); |
| window._gridPainted = false; |
| } |
| |
| function _drawElementTitle(highlight) |
| { |
| var elementInfo = highlight.elementInfo; |
| if (!highlight.elementInfo) |
| return; |
| |
| document.getElementById("tag-name").textContent = elementInfo.tagName; |
| document.getElementById("node-id").textContent = elementInfo.idValue ? "#" + elementInfo.idValue : ""; |
| var className = elementInfo.className; |
| if (className && className.length > 50) |
| className = className.substring(0, 50) + "\u2026"; |
| document.getElementById("class-name").textContent = className || ""; |
| document.getElementById("node-width").textContent = elementInfo.nodeWidth; |
| document.getElementById("node-height").textContent = elementInfo.nodeHeight; |
| var elementTitle = document.getElementById("element-title"); |
| |
| var marginQuad = highlight.quads[0]; |
| |
| var titleWidth = elementTitle.offsetWidth + 6; |
| var titleHeight = elementTitle.offsetHeight + 4; |
| |
| var anchorTop = marginQuad[0].y; |
| var anchorBottom = marginQuad[3].y |
| |
| const arrowHeight = 7; |
| var renderArrowUp = false; |
| var renderArrowDown = false; |
| |
| var boxX = Math.max(2, marginQuad[0].x); |
| if (boxX + titleWidth > canvasWidth) |
| boxX = canvasWidth - titleWidth - 2; |
| |
| var boxY; |
| if (anchorTop > canvasHeight) { |
| boxY = canvasHeight - titleHeight - arrowHeight; |
| renderArrowDown = true; |
| } else if (anchorBottom < 0) { |
| boxY = arrowHeight; |
| renderArrowUp = true; |
| } else if (anchorBottom + titleHeight + arrowHeight < canvasHeight) { |
| boxY = anchorBottom + arrowHeight - 4; |
| renderArrowUp = true; |
| } else if (anchorTop - titleHeight - arrowHeight > 0) { |
| boxY = anchorTop - titleHeight - arrowHeight + 3; |
| renderArrowDown = true; |
| } else |
| boxY = arrowHeight; |
| |
| context.save(); |
| context.translate(0.5, 0.5); |
| context.beginPath(); |
| context.moveTo(boxX, boxY); |
| if (renderArrowUp) { |
| context.lineTo(boxX + 2 * arrowHeight, boxY); |
| context.lineTo(boxX + 3 * arrowHeight, boxY - arrowHeight); |
| context.lineTo(boxX + 4 * arrowHeight, boxY); |
| } |
| context.lineTo(boxX + titleWidth, boxY); |
| context.lineTo(boxX + titleWidth, boxY + titleHeight); |
| if (renderArrowDown) { |
| context.lineTo(boxX + 4 * arrowHeight, boxY + titleHeight); |
| context.lineTo(boxX + 3 * arrowHeight, boxY + titleHeight + arrowHeight); |
| context.lineTo(boxX + 2 * arrowHeight, boxY + titleHeight); |
| } |
| context.lineTo(boxX, boxY + titleHeight); |
| context.closePath(); |
| context.fillStyle = "rgb(255, 255, 194)"; |
| context.fill(); |
| context.strokeStyle = "rgb(128, 128, 128)"; |
| context.stroke(); |
| |
| context.restore(); |
| |
| elementTitle.style.visibility = "visible"; |
| elementTitle.style.top = (boxY + 3) + "px"; |
| elementTitle.style.left = (boxX + 3) + "px"; |
| } |
| |
| function _drawRulers(highlight, rulerAtRight, rulerAtBottom) |
| { |
| context.save(); |
| var width = canvasWidth; |
| var height = canvasHeight; |
| context.strokeStyle = "rgba(128, 128, 128, 0.3)"; |
| context.lineWidth = 1; |
| context.translate(0.5, 0.5); |
| var leftmostXForY = {}; |
| var rightmostXForY = {}; |
| var topmostYForX = {}; |
| var bottommostYForX = {}; |
| |
| for (var i = 0; i < highlight.quads.length; ++i) { |
| var quad = highlight.quads[i]; |
| for (var j = 0; j < quad.length; ++j) { |
| var x = quad[j].x; |
| var y = quad[j].y; |
| leftmostXForY[Math.round(y)] = Math.min(leftmostXForY[y] || Number.MAX_VALUE, Math.round(quad[j].x)); |
| rightmostXForY[Math.round(y)] = Math.max(rightmostXForY[y] || Number.MIN_VALUE, Math.round(quad[j].x)); |
| topmostYForX[Math.round(x)] = Math.min(topmostYForX[x] || Number.MAX_VALUE, Math.round(quad[j].y)); |
| bottommostYForX[Math.round(x)] = Math.max(bottommostYForX[x] || Number.MIN_VALUE, Math.round(quad[j].y)); |
| } |
| } |
| |
| if (rulerAtRight) { |
| for (var y in rightmostXForY) { |
| context.beginPath(); |
| context.moveTo(width, y); |
| context.lineTo(rightmostXForY[y], y); |
| context.stroke(); |
| } |
| } else { |
| for (var y in leftmostXForY) { |
| context.beginPath(); |
| context.moveTo(0, y); |
| context.lineTo(leftmostXForY[y], y); |
| context.stroke(); |
| } |
| } |
| |
| if (rulerAtBottom) { |
| for (var x in bottommostYForX) { |
| context.beginPath(); |
| context.moveTo(x, height); |
| context.lineTo(x, topmostYForX[x]); |
| context.stroke(); |
| } |
| } else { |
| for (var x in topmostYForX) { |
| context.beginPath(); |
| context.moveTo(x, 0); |
| context.lineTo(x, topmostYForX[x]); |
| context.stroke(); |
| } |
| } |
| |
| context.restore(); |
| } |
| |
| function drawNodeHighlight(highlight) |
| { |
| { |
| for (var i = 0; i < highlight.quads.length; ++i) { |
| var quad = highlight.quads[i]; |
| for (var j = 0; j < quad.length; ++j) { |
| quad[j].x = Math.round(quad[j].x * pageScaleFactor - scrollX); |
| quad[j].y = Math.round(quad[j].y * pageScaleFactor - scrollY); |
| } |
| } |
| } |
| |
| if (!highlight.quads.length) { |
| if (highlight.showRulers) |
| _drawGrid(false, false); |
| return; |
| } |
| |
| context.save(); |
| |
| var quads = highlight.quads.slice(); |
| var eventTargetQuad = quads.length >= 5 ? quads.pop() : null; |
| var contentQuad = quads.pop(); |
| var paddingQuad = quads.pop(); |
| var borderQuad = quads.pop(); |
| var marginQuad = quads.pop(); |
| |
| var hasContent = contentQuad && highlight.contentColor !== transparentColor || highlight.contentOutlineColor !== transparentColor; |
| var hasPadding = paddingQuad && highlight.paddingColor !== transparentColor; |
| var hasBorder = borderQuad && highlight.borderColor !== transparentColor; |
| var hasMargin = marginQuad && highlight.marginColor !== transparentColor; |
| var hasEventTarget = eventTargetQuad && highlight.eventTargetColor !== transparentColor; |
| |
| var clipQuad; |
| if (hasMargin && (!hasBorder || !quadEquals(marginQuad, borderQuad))) { |
| drawOutlinedQuadWithClip(marginQuad, borderQuad, highlight.marginColor); |
| clipQuad = borderQuad; |
| } |
| if (hasBorder && (!hasPadding || !quadEquals(borderQuad, paddingQuad))) { |
| drawOutlinedQuadWithClip(borderQuad, paddingQuad, highlight.borderColor); |
| clipQuad = paddingQuad; |
| } |
| if (hasPadding && (!hasContent || !quadEquals(paddingQuad, contentQuad))) { |
| drawOutlinedQuadWithClip(paddingQuad, contentQuad, highlight.paddingColor); |
| clipQuad = contentQuad; |
| } |
| if (hasContent) |
| drawOutlinedQuad(contentQuad, highlight.contentColor, highlight.contentOutlineColor); |
| if (hasEventTarget) |
| drawUnderlyingQuad(eventTargetQuad, highlight.eventTargetColor); |
| |
| var width = canvasWidth; |
| var height = canvasHeight; |
| var minX = Number.MAX_VALUE, minY = Number.MAX_VALUE, maxX = Number.MIN_VALUE; maxY = Number.MIN_VALUE; |
| for (var i = 0; i < highlight.quads.length; ++i) { |
| var quad = highlight.quads[i]; |
| for (var j = 0; j < quad.length; ++j) { |
| minX = Math.min(minX, quad[j].x); |
| maxX = Math.max(maxX, quad[j].x); |
| minY = Math.min(minY, quad[j].y); |
| maxY = Math.max(maxY, quad[j].y); |
| } |
| } |
| |
| var rulerAtRight = minX < 20 && maxX + 20 < width; |
| var rulerAtBottom = minY < 20 && maxY + 20 < height; |
| |
| if (highlight.showRulers) { |
| _drawGrid(rulerAtRight, rulerAtBottom); |
| _drawRulers(highlight, rulerAtRight, rulerAtBottom); |
| } |
| _drawElementTitle(highlight); |
| |
| context.restore(); |
| } |
| |
| function drawQuadHighlight(highlight) |
| { |
| context.save(); |
| drawOutlinedQuad(highlight.quads[0], highlight.contentColor, highlight.contentOutlineColor); |
| context.restore(); |
| } |
| |
| function setPlatform(platform) |
| { |
| window.platform = platform; |
| document.body.classList.add("platform-" + platform); |
| } |
| |
| function dispatch(message) |
| { |
| var functionName = message.shift(); |
| window[functionName].apply(null, message); |
| } |
| |
| function log(text) |
| { |
| var logEntry = document.createElement("div"); |
| logEntry.textContent = text; |
| document.getElementById("log").appendChild(logEntry); |
| } |
| |
| function onResumeClick() |
| { |
| InspectorOverlayHost.resume(); |
| } |
| |
| function onStepOverClick() |
| { |
| InspectorOverlayHost.stepOver(); |
| } |
| |
| function onMouseMotion(isOverElement) |
| { |
| if (!overridesMessageElement.textContent.length) |
| return; |
| if (isOverElement) |
| overridesContainer.classList.add("hidden"); |
| else |
| overridesContainer.classList.remove("hidden"); |
| } |
| |
| function onFocus() |
| { |
| if (overridesMessageElement.textContent.length) |
| overridesContainer.classList.remove("hidden"); |
| } |
| |
| function onLoaded() |
| { |
| overridesContainer = document.getElementById("overrides-container"); |
| overridesMessageElement = document.getElementById("overrides-message"); |
| document.getElementById("resume-button").addEventListener("click", onResumeClick); |
| document.getElementById("step-over-button").addEventListener("click", onStepOverClick); |
| overridesContainer.addEventListener("mousemove", onMouseMotion.bind(this, true)); |
| overridesContainer.addEventListener("mouseout", onMouseMotion.bind(this, false)); |
| window.addEventListener("focus", onFocus); |
| } |
| |
| window.addEventListener("DOMContentLoaded", onLoaded); |
| |
| </script> |
| </head> |
| <body class="fill"> |
| <div class="controls-line"> |
| <div class="message-box"><div id="paused-in-debugger"></div></div> |
| <button id="resume-button" title="Resume script execution"><div class="glyph"></div></button> |
| <button id="step-over-button" title="Step over next function call"><div class="glyph"></div></button> |
| </div> |
| </body> |
| <canvas id="canvas" class="fill"></canvas> |
| <div id="element-title"> |
| <span id="tag-name"></span><span id="node-id"></span><span id="class-name"></span> |
| <span id="node-width"></span><span class="px">px</span><span class="px"> × </span><span id="node-height"></span><span class="px">px</span> |
| </div> |
| <div id="right-gutter"></div> |
| <div id="bottom-gutter"></div> |
| <div id="overrides-container"> |
| <div id="overrides-message"></div> |
| </div> |
| <div id="log"></div> |
| </html> |