Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / inspector / InspectorOverlayPage.html
1 <!--
2  Copyright (C) 2012 Google Inc. All rights reserved.
3
4  Redistribution and use in source and binary forms, with or without
5  modification, are permitted provided that the following conditions
6  are met:
7
8  1.  Redistributions of source code must retain the above copyright
9      notice, this list of conditions and the following disclaimer.
10  2.  Redistributions in binary form must reproduce the above copyright
11      notice, this list of conditions and the following disclaimer in the
12      documentation and/or other materials provided with the distribution.
13  3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14      its contributors may be used to endorse or promote products derived
15      from this software without specific prior written permission.
16
17  THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 -->
28 <!DOCTYPE html>
29 <html>
30 <head>
31 <style>
32 body {
33     margin: 0;
34     padding: 0;
35 }
36
37 body.touch {
38     cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAQAAAADHm0dAAABH0lEQVR4XpWTO2rDQBCG18S6gAWCoD6VFHKCCBZsN7qACgenFZn/OAZDrConMahJzmGM+oBJMfmziIUs8UMOXzHD7seyzMMwJOEDZ7r4ftEFZy5PwtvfNKIliE/Z4hVbFwmHZfRXTfWZWOEOI5iekctXINx5GqopZSdTmCOm2AmFt15lpMu9TGBOMsFe9InjXmVBzGHOMgfBR6cyJtYwF1mDYGyYEdmAmoNgZmgPcjOgjvEltEarFmaQd2hltN5cob5B6ytf/YBW//krMyIfUO99BWKiGVCbvq6+W+UFsfTd8jPQSXJGTND1MxBMViflyRe7YLK8rEuiQQ5fDRfz/o/uPD3egoIgDtJig9ZFwlGEWxASM6PVSmutaF0eh7c/zBRVQt5j3yoAAAAASUVORK5CYII=) 10 10, auto !important;
39 }
40
41 body.platform-mac {
42     font-size: 11px;
43     font-family: Menlo, Monaco;
44 }
45
46 body.platform-windows {
47     font-size: 12px;
48     font-family: Consolas, Lucida Console;
49 }
50
51 body.platform-linux {
52     font-size: 11px;
53     font-family: dejavu sans mono;
54 }
55
56 .fill {
57     position: absolute;
58     top: 0;
59     right: 0;
60     bottom: 0;
61     left: 0;
62 }
63
64 .dimmed {
65     background-color: rgba(0, 0, 0, 0.31);
66 }
67
68 #canvas {
69     pointer-events: none;
70 }
71
72 .controls-line {
73     display: flex;
74     justify-content: center;
75     margin: 10px 0;
76 }
77
78 .message-box {
79     padding: 2px 4px;
80     display: flex;
81     align-items: center;
82     cursor: default;
83 }
84
85 .controls-line > * {
86     background-color: rgb(255, 255, 194);
87     border: 1px solid rgb(202, 202, 202);
88     height: 22px;
89     box-sizing: border-box;
90 }
91
92 .controls-line .button {
93     width: 26px;
94     margin-left: -1px;
95     margin-right: 0;
96     padding: 0;
97 }
98
99 .controls-line .button:hover {
100     cursor: pointer;
101 }
102
103 .controls-line .button .glyph {
104     width: 100%;
105     height: 100%;
106     background-color: rgba(0, 0, 0, 0.75);
107     opacity: 0.8;
108     -webkit-mask-repeat: no-repeat;
109     -webkit-mask-position: center;
110     position: relative;
111 }
112
113 .controls-line .button:active .glyph {
114     top: 1px;
115     left: 1px;
116 }
117
118 #resume-button .glyph {
119     -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAKCAYAAABv7tTEAAAAAXNSR0IArs4c6QAAAFJJREFUKM+10bEJgGAMBeEPbR3BLRzEVdzEVRzELRzBVohVwEJ+iODBlQfhBeJhsmHU4C0KnFjQV6J0x1SNAhdWDJUoPTB3PvLLeaUhypM3n3sD/qc7lDrdpIEAAAAASUVORK5CYII=);
120     -webkit-mask-size: 13px 10px;
121     background-color: rgb(66, 129, 235);
122 }
123
124 #step-over-button .glyph {
125     -webkit-mask-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAKCAYAAAC5Sw6hAAAAAXNSR0IArs4c6QAAAOFJREFUKM+N0j8rhXEUB/DPcxW35CqhvIBrtqibkklhV8qkTHe4ZbdblcXgPVhuMdqUTUl5A2KRRCF5LGc4PT1P7qnfcr5/zu/8KdTHLFaxjHnc4RZXKI0QYxjgLQTVd42l/0wmg5iFX3iq5H6w22RS4DyRH7CB8cAXcBTGJT6xUmd0mEwuMdFQcA3fwXvGTAan8BrgPabTL9fRRyfx91PRMwyjGwcJ2EyCfsrfpPw2Pipz24NT/MZciiQYVshzOKnZ5Hturxt3k2MnCpS4SPkeHpPR8Sh3tYgttBoW9II2/AHiaEqvD2Fc0wAAAABJRU5ErkJggg==);
126     -webkit-mask-size: 18px 10px;
127 }
128
129 .px {
130     color: rgb(128, 128, 128);
131 }
132
133 #element-title {
134     position: absolute;
135     z-index: 10;
136 }
137
138 #tag-name {
139     /* Keep this in sync with view-source.css (.webkit-html-tag) */
140     color: rgb(136, 18, 128);
141 }
142
143 #node-id {
144     /* Keep this in sync with view-source.css (.webkit-html-attribute-value) */
145     color: rgb(26, 26, 166);
146 }
147
148 #class-name {
149     /* Keep this in sync with view-source.css (.webkit-html-attribute-name) */
150     color: rgb(153, 69, 0);
151 }
152
153 </style>
154 <script>
155 const lightGridColor = "rgba(0,0,0,0.2)";
156 const darkGridColor = "rgba(0,0,0,0.7)";
157 const transparentColor = "rgba(0, 0, 0, 0)";
158 const gridBackgroundColor = "rgba(255, 255, 255, 0.8)";
159 // CSS shapes
160 const shapeHighlightColor = "rgba(96, 82, 127, 0.8)";
161 const shapeMarginHighlightColor = "rgba(96, 82, 127, 0.6)";
162
163 function drawPausedInDebuggerMessage(message)
164 {
165     window._controlsVisible = true;
166     document.querySelector(".controls-line").style.visibility = "visible";
167     document.getElementById("paused-in-debugger").textContent = message;
168     document.body.classList.add("dimmed");
169 }
170
171 function _drawGrid(rulerAtRight, rulerAtBottom)
172 {
173     if (window._gridPainted)
174         return;
175     window._gridPainted = true;
176
177     context.save();
178
179     var pageFactor = pageZoomFactor * pageScaleFactor;
180     function zoom(x)
181     {
182         return Math.round(x * pageFactor);
183     }
184     function unzoom(x)
185     {
186         return Math.round(x / pageFactor);
187     }
188
189     var width = canvasWidth / pageFactor;
190     var height = canvasHeight / pageFactor;
191
192     const gridSubStep = 5;
193     const gridStep = 50;
194
195     {
196         // Draw X grid background
197         context.save();
198         context.fillStyle = gridBackgroundColor;
199         if (rulerAtBottom)
200             context.fillRect(0, zoom(height) - 15, zoom(width), zoom(height));
201         else
202             context.fillRect(0, 0, zoom(width), 15);
203
204         // Clip out backgrounds intersection
205         context.globalCompositeOperation = "destination-out";
206         context.fillStyle = "red";
207         if (rulerAtRight)
208             context.fillRect(zoom(width) - 15, 0, zoom(width), zoom(height));
209         else
210             context.fillRect(0, 0, 15, zoom(height));
211         context.restore();
212
213         // Draw Y grid background
214         context.fillStyle = gridBackgroundColor;
215         if (rulerAtRight)
216             context.fillRect(zoom(width) - 15, 0, zoom(width), zoom(height));
217         else
218             context.fillRect(0, 0, 15, zoom(height));
219     }
220
221     context.lineWidth = 1;
222     context.strokeStyle = darkGridColor;
223     context.fillStyle = darkGridColor;
224     {
225         // Draw labels.
226         context.save();
227         context.translate(-scrollX, 0.5 - scrollY);
228         var maxY = height + unzoom(scrollY);
229         for (var y = 2 * gridStep; y < maxY; y += 2 * gridStep) {
230             context.save();
231             context.translate(scrollX, zoom(y));
232             context.rotate(-Math.PI / 2);
233             context.fillText(y, 2, rulerAtRight ? zoom(width) - 7 : 13);
234             context.restore();
235         }
236         context.translate(0.5, -0.5);
237         var maxX = width + unzoom(scrollX);
238         for (var x = 2 * gridStep; x < maxX; x += 2 * gridStep) {
239             context.save();
240             context.fillText(x, zoom(x) + 2, rulerAtBottom ? scrollY + zoom(height) - 7 : scrollY + 13);
241             context.restore();
242         }
243         context.restore();
244     }
245
246     {
247         // Draw vertical grid
248         context.save();
249         if (rulerAtRight) {
250             context.translate(zoom(width), 0);
251             context.scale(-1, 1);
252         }
253         context.translate(-scrollX, 0.5 - scrollY);
254         var maxY = height + unzoom(scrollY);
255         for (var y = gridStep; y < maxY; y += gridStep) {
256             context.beginPath();
257             context.moveTo(scrollX, zoom(y));
258             var markLength = (y % (gridStep * 2)) ? 5 : 8;
259             context.lineTo(scrollX + markLength, zoom(y));
260             context.stroke();
261         }
262         context.strokeStyle = lightGridColor;
263         for (var y = gridSubStep; y < maxY; y += gridSubStep) {
264             if (!(y % gridStep))
265                 continue;
266             context.beginPath();
267             context.moveTo(scrollX, zoom(y));
268             context.lineTo(scrollX + gridSubStep, zoom(y));
269             context.stroke();
270         }
271         context.restore();
272     }
273
274     {
275         // Draw horizontal grid
276         context.save();
277         if (rulerAtBottom) {
278             context.translate(0, zoom(height));
279             context.scale(1, -1);
280         }
281         context.translate(0.5 - scrollX, -scrollY);
282         var maxX = width + unzoom(scrollX);
283         for (var x = gridStep; x < maxX; x += gridStep) {
284             context.beginPath();
285             context.moveTo(zoom(x), scrollY);
286             var markLength = (x % (gridStep * 2)) ? 5 : 8;
287             context.lineTo(zoom(x), scrollY + markLength);
288             context.stroke();
289         }
290         context.strokeStyle = lightGridColor;
291         for (var x = gridSubStep; x < maxX; x += gridSubStep) {
292             if (!(x % gridStep))
293                 continue;
294             context.beginPath();
295             context.moveTo(zoom(x), scrollY);
296             context.lineTo(zoom(x), scrollY + gridSubStep);
297             context.stroke();
298         }
299         context.restore();
300     }
301
302     context.restore();
303 }
304
305 function quadToPath(quad)
306 {
307     context.beginPath();
308     context.moveTo(quad[0].x, quad[0].y);
309     context.lineTo(quad[1].x, quad[1].y);
310     context.lineTo(quad[2].x, quad[2].y);
311     context.lineTo(quad[3].x, quad[3].y);
312     context.closePath();
313     return context;
314 }
315
316 function drawOutlinedQuad(quad, fillColor, outlineColor)
317 {
318     context.save();
319     context.lineWidth = 2;
320     quadToPath(quad).clip();
321     context.fillStyle = fillColor;
322     context.fill();
323     if (outlineColor) {
324         context.strokeStyle = outlineColor;
325         context.stroke();
326     }
327     context.restore();
328 }
329
330 function drawOutlinedQuadWithClip(quad, clipQuad, fillColor)
331 {
332     context.fillStyle = fillColor;
333     context.save();
334     context.lineWidth = 0;
335     quadToPath(quad).fill();
336     context.globalCompositeOperation = "destination-out";
337     context.fillStyle = "red";
338     quadToPath(clipQuad).fill();
339     context.restore();
340 }
341
342 function drawUnderlyingQuad(quad, fillColor)
343 {
344     context.save();
345     context.lineWidth = 2;
346     context.globalCompositeOperation = "destination-over";
347     context.fillStyle = fillColor;
348     quadToPath(quad).fill();
349     context.restore();
350 }
351
352 function quadEquals(quad1, quad2)
353 {
354     return quad1[0].x === quad2[0].x && quad1[0].y === quad2[0].y &&
355         quad1[1].x === quad2[1].x && quad1[1].y === quad2[1].y &&
356         quad1[2].x === quad2[2].x && quad1[2].y === quad2[2].y &&
357         quad1[3].x === quad2[3].x && quad1[3].y === quad2[3].y;
358 }
359
360 function drawViewSize(drawViewSizeWithGrid)
361 {
362     var drawGridBoolean = drawViewSizeWithGrid === "true";
363     var text = viewportSize.width + "px \u00D7 " + viewportSize.height + "px";
364     context.save();
365     context.font = "20px ";
366     switch (platform) {
367     case "windows": context.font = "14px Consolas"; break;
368     case "mac": context.font = "14px Menlo"; break;
369     case "linux": context.font = "14px dejavu sans mono"; break;
370     }
371
372     var frameWidth = frameViewFullSize.width || canvasWidth;
373     var textWidth = context.measureText(text).width;
374     context.fillStyle = gridBackgroundColor;
375     context.fillRect(frameWidth - textWidth - 12, drawGridBoolean ? 15 : 0, frameWidth, 25);
376     context.fillStyle = darkGridColor;
377     context.fillText(text, frameWidth - textWidth - 6, drawGridBoolean ? 33 : 18);
378     context.restore();
379     if (drawGridBoolean)
380         _drawGrid();
381 }
382
383 function reset(resetData)
384 {
385     window.viewportSize = resetData.viewportSize;
386     window.frameViewFullSize = resetData.frameViewFullSize;
387     window.deviceScaleFactor = resetData.deviceScaleFactor;
388     window.pageZoomFactor = resetData.pageZoomFactor;
389     window.pageScaleFactor = resetData.pageScaleFactor;
390     window.scrollX = Math.round(resetData.scrollX * pageScaleFactor);
391     window.scrollY = Math.round(resetData.scrollY * pageScaleFactor);
392
393     window.canvas = document.getElementById("canvas");
394     window.context = canvas.getContext("2d");
395
396     canvas.width = deviceScaleFactor * viewportSize.width;
397     canvas.height = deviceScaleFactor * viewportSize.height;
398     canvas.style.width = viewportSize.width + "px";
399     canvas.style.height = viewportSize.height + "px";
400     context.scale(deviceScaleFactor, deviceScaleFactor);
401     window.canvasWidth = viewportSize.width;
402     window.canvasHeight = viewportSize.height;
403
404     window._controlsVisible = false;
405     document.querySelector(".controls-line").style.visibility = "hidden";
406     document.getElementById("element-title").style.visibility = "hidden";
407     document.body.classList.remove("dimmed");
408     window._gridPainted = false;
409 }
410
411 function _drawElementTitle(highlight)
412 {
413     var elementInfo = highlight.elementInfo;
414     if (!highlight.elementInfo)
415         return;
416
417     document.getElementById("tag-name").textContent = elementInfo.tagName;
418     document.getElementById("node-id").textContent = elementInfo.idValue ? "#" + elementInfo.idValue : "";
419     var className = elementInfo.className;
420     if (className && className.length > 50)
421        className = className.substring(0, 50) + "\u2026";
422     document.getElementById("class-name").textContent = className || "";
423     document.getElementById("node-width").textContent = elementInfo.nodeWidth;
424     document.getElementById("node-height").textContent = elementInfo.nodeHeight;
425     var elementTitle = document.getElementById("element-title");
426
427     var marginQuad = highlight.quads[0];
428
429     var titleWidth = elementTitle.offsetWidth + 6;
430     var titleHeight = elementTitle.offsetHeight + 4;
431
432     var anchorTop = Math.min(marginQuad[0].y, marginQuad[1].y, marginQuad[2].y, marginQuad[3].y);
433     var anchorBottom = Math.max(marginQuad[0].y, marginQuad[1].y, marginQuad[2].y, marginQuad[3].y);
434     var anchorLeft = Math.min(marginQuad[0].x, marginQuad[1].x, marginQuad[2].x, marginQuad[3].x);
435
436     const arrowHeight = 7;
437     var renderArrowUp = false;
438     var renderArrowDown = false;
439
440     var boxX = Math.max(2, anchorLeft);
441     if (boxX + titleWidth > canvasWidth)
442         boxX = canvasWidth - titleWidth - 2;
443
444     var boxY;
445     if (anchorTop > canvasHeight) {
446         boxY = canvasHeight - titleHeight - arrowHeight;
447         renderArrowDown = true;
448     } else if (anchorBottom < 0) {
449         boxY = arrowHeight;
450         renderArrowUp = true;
451     } else if (anchorBottom + titleHeight + arrowHeight < canvasHeight) {
452         boxY = anchorBottom + arrowHeight - 4;
453         renderArrowUp = true;
454     } else if (anchorTop - titleHeight - arrowHeight > 0) {
455         boxY = anchorTop - titleHeight - arrowHeight + 3;
456         renderArrowDown = true;
457     } else
458         boxY = arrowHeight;
459
460     context.save();
461     context.translate(0.5, 0.5);
462     context.beginPath();
463     context.moveTo(boxX, boxY);
464     if (renderArrowUp) {
465         context.lineTo(boxX + 2 * arrowHeight, boxY);
466         context.lineTo(boxX + 3 * arrowHeight, boxY - arrowHeight);
467         context.lineTo(boxX + 4 * arrowHeight, boxY);
468     }
469     context.lineTo(boxX + titleWidth, boxY);
470     context.lineTo(boxX + titleWidth, boxY + titleHeight);
471     if (renderArrowDown) {
472         context.lineTo(boxX + 4 * arrowHeight, boxY + titleHeight);
473         context.lineTo(boxX + 3 * arrowHeight, boxY + titleHeight + arrowHeight);
474         context.lineTo(boxX + 2 * arrowHeight, boxY + titleHeight);
475     }
476     context.lineTo(boxX, boxY + titleHeight);
477     context.closePath();
478     context.fillStyle = "rgb(255, 255, 194)";
479     context.fill();
480     context.strokeStyle = "rgb(128, 128, 128)";
481     context.stroke();
482
483     context.restore();
484
485     elementTitle.style.visibility = "visible";
486     elementTitle.style.top = (boxY + 3) + "px";
487     elementTitle.style.left = (boxX + 3) + "px";
488 }
489
490 function _drawRulers(highlight, rulerAtRight, rulerAtBottom)
491 {
492     context.save();
493     var width = canvasWidth;
494     var height = canvasHeight;
495     context.strokeStyle = "rgba(128, 128, 128, 0.3)";
496     context.lineWidth = 1;
497     context.translate(0.5, 0.5);
498     var leftmostXForY = {};
499     var rightmostXForY = {};
500     var topmostYForX = {};
501     var bottommostYForX = {};
502
503     for (var i = 0; i < highlight.quads.length; ++i) {
504         var quad = highlight.quads[i];
505         for (var j = 0; j < quad.length; ++j) {
506             var x = quad[j].x;
507             var y = quad[j].y;
508             leftmostXForY[Math.round(y)] = Math.min(leftmostXForY[y] || Number.MAX_VALUE, Math.round(quad[j].x));
509             rightmostXForY[Math.round(y)] = Math.max(rightmostXForY[y] || Number.MIN_VALUE, Math.round(quad[j].x));
510             topmostYForX[Math.round(x)] = Math.min(topmostYForX[x] || Number.MAX_VALUE, Math.round(quad[j].y));
511             bottommostYForX[Math.round(x)] = Math.max(bottommostYForX[x] || Number.MIN_VALUE, Math.round(quad[j].y));
512         }
513     }
514
515     if (rulerAtRight) {
516         for (var y in rightmostXForY) {
517             context.beginPath();
518             context.moveTo(width, y);
519             context.lineTo(rightmostXForY[y], y);
520             context.stroke();
521         }
522     } else {
523         for (var y in leftmostXForY) {
524             context.beginPath();
525             context.moveTo(0, y);
526             context.lineTo(leftmostXForY[y], y);
527             context.stroke();
528         }
529     }
530
531     if (rulerAtBottom) {
532         for (var x in bottommostYForX) {
533             context.beginPath();
534             context.moveTo(x, height);
535             context.lineTo(x, topmostYForX[x]);
536             context.stroke();
537         }
538     } else {
539         for (var x in topmostYForX) {
540             context.beginPath();
541             context.moveTo(x, 0);
542             context.lineTo(x, topmostYForX[x]);
543             context.stroke();
544         }
545     }
546
547     context.restore();
548 }
549 // CSS shapes 
550 function drawPath(commands, fillColor)
551 {
552     context.save();
553     context.beginPath();
554
555     var commandsIndex = 0;
556     var commandsLength = commands.length;
557     while (commandsIndex < commandsLength) {
558         switch (commands[commandsIndex++]) {
559         case "M":
560             context.moveTo(commands[commandsIndex++], commands[commandsIndex++]);
561             break;
562         case "L":
563             context.lineTo(commands[commandsIndex++], commands[commandsIndex++]);
564             break;
565         case "C":
566             context.bezierCurveTo(commands[commandsIndex++], commands[commandsIndex++], commands[commandsIndex++],
567                                   commands[commandsIndex++], commands[commandsIndex++], commands[commandsIndex++]);
568             break;
569         case "Q":
570             context.quadraticCurveTo(commands[commandsIndex++], commands[commandsIndex++], commands[commandsIndex++],
571                                      commands[commandsIndex++]);
572             break;
573         case "Z":
574             context.closePath();
575             break;
576         }
577     }
578     context.closePath();
579     context.fillStyle = fillColor;
580     context.fill();
581
582     context.restore();
583 }
584
585 function drawShapeHighlight(shapeInfo)
586 {
587     if (shapeInfo.marginShape)
588         drawPath(shapeInfo.marginShape, shapeMarginHighlightColor);
589     else
590         drawOutlinedQuad(shapeInfo.bounds, shapeHighlightColor, shapeHighlightColor);
591
592     if (shapeInfo.shape)
593         drawPath(shapeInfo.shape, shapeHighlightColor);
594    else
595         drawOutlinedQuad(shapeInfo.bounds, shapeHighlightColor, shapeHighlightColor);
596 }
597
598 function drawNodeHighlight(highlight)
599 {
600     {
601         for (var i = 0; i < highlight.quads.length; ++i) {
602             var quad = highlight.quads[i];
603             for (var j = 0; j < quad.length; ++j) {
604                 quad[j].x = Math.round(quad[j].x * pageScaleFactor - scrollX);
605                 quad[j].y = Math.round(quad[j].y * pageScaleFactor - scrollY);
606             }
607         }
608     }
609
610     if (!highlight.quads.length) {
611         if (highlight.showRulers)
612             _drawGrid(false, false);
613         return;
614     }
615
616     context.save();
617
618     var quads = highlight.quads.slice();
619     var eventTargetQuad = quads.length >= 5 ? quads.pop() : null;
620     var contentQuad = quads.pop();
621     var paddingQuad = quads.pop();
622     var borderQuad = quads.pop();
623     var marginQuad = quads.pop();
624
625     var hasContent = contentQuad && highlight.contentColor !== transparentColor || highlight.contentOutlineColor !== transparentColor;
626     var hasPadding = paddingQuad && highlight.paddingColor !== transparentColor;
627     var hasBorder = borderQuad && highlight.borderColor !== transparentColor;
628     var hasMargin = marginQuad && highlight.marginColor !== transparentColor;
629     var hasEventTarget = eventTargetQuad && highlight.eventTargetColor !== transparentColor;
630
631     var clipQuad;
632     if (hasMargin && (!hasBorder || !quadEquals(marginQuad, borderQuad))) {
633         drawOutlinedQuadWithClip(marginQuad, borderQuad, highlight.marginColor);
634         clipQuad = borderQuad;
635     }
636     if (hasBorder && (!hasPadding || !quadEquals(borderQuad, paddingQuad))) {
637         drawOutlinedQuadWithClip(borderQuad, paddingQuad, highlight.borderColor);
638         clipQuad = paddingQuad;
639     }
640     if (hasPadding && (!hasContent || !quadEquals(paddingQuad, contentQuad))) {
641         drawOutlinedQuadWithClip(paddingQuad, contentQuad, highlight.paddingColor);
642         clipQuad = contentQuad;
643     }
644     if (hasContent)
645         drawOutlinedQuad(contentQuad, highlight.contentColor, highlight.contentOutlineColor);
646     if (hasEventTarget)
647         drawUnderlyingQuad(eventTargetQuad, highlight.eventTargetColor);
648
649     var width = canvasWidth;
650     var height = canvasHeight;
651     var minX = Number.MAX_VALUE, minY = Number.MAX_VALUE, maxX = Number.MIN_VALUE; maxY = Number.MIN_VALUE;
652     for (var i = 0; i < highlight.quads.length; ++i) {
653         var quad = highlight.quads[i];
654         for (var j = 0; j < quad.length; ++j) {
655             minX = Math.min(minX, quad[j].x);
656             maxX = Math.max(maxX, quad[j].x);
657             minY = Math.min(minY, quad[j].y);
658             maxY = Math.max(maxY, quad[j].y);
659         }
660     }
661
662     var rulerAtRight = minX < 20 && maxX + 20 < width;
663     var rulerAtBottom = minY < 20 && maxY + 20 < height;
664
665     if (highlight.showRulers) {
666         _drawGrid(rulerAtRight, rulerAtBottom);
667         _drawRulers(highlight, rulerAtRight, rulerAtBottom);
668     }
669     if (highlight.elementInfo && highlight.elementInfo.shapeOutsideInfo)
670         drawShapeHighlight(highlight.elementInfo.shapeOutsideInfo);
671     _drawElementTitle(highlight);
672
673     context.restore();
674 }
675
676 function drawQuadHighlight(highlight)
677 {
678     context.save();
679     drawOutlinedQuad(highlight.quads[0], highlight.contentColor, highlight.contentOutlineColor);
680     context.restore();
681 }
682
683 function setPlatform(platform)
684 {
685     window.platform = platform;
686     document.body.classList.add("platform-" + platform);
687 }
688
689 function dispatch(message)
690 {
691     var functionName = message.shift();
692     window[functionName].apply(null, message);
693 }
694
695 function log(text)
696 {
697     var logEntry = document.createElement("div");
698     logEntry.textContent = text;
699     document.getElementById("log").appendChild(logEntry);
700 }
701
702 function onResumeClick()
703 {
704     InspectorOverlayHost.resume();
705 }
706
707 function onStepOverClick()
708 {
709     InspectorOverlayHost.stepOver();
710 }
711
712 function onLoaded()
713 {
714     document.getElementById("resume-button").addEventListener("click", onResumeClick);
715     document.getElementById("step-over-button").addEventListener("click", onStepOverClick);
716 }
717
718 function eventHasCtrlOrMeta(event)
719 {
720     return window.platform == "mac" ? (event.metaKey && !event.ctrlKey) : (event.ctrlKey && !event.metaKey);
721 }
722
723 function onDocumentKeyDown(event)
724 {
725     if (!window._controlsVisible)
726         return;
727     if (event.keyIdentifier == "F8" || eventHasCtrlOrMeta(event) && event.keyCode == 220 /* backslash */)
728         InspectorOverlayHost.resume();
729     else if (event.keyIdentifier == "F10" || eventHasCtrlOrMeta(event) && event.keyCode == 222 /* single quote */)
730         InspectorOverlayHost.stepOver();
731 }
732
733 window.addEventListener("DOMContentLoaded", onLoaded);
734 document.addEventListener("keydown", onDocumentKeyDown);
735
736 </script>
737 </head>
738 <body class="fill">
739 <div class="controls-line">
740     <div class="message-box"><div id="paused-in-debugger"></div></div>
741     <div class="button" id="resume-button" title="Resume script execution (F8)."><div class="glyph"></div></div>
742     <div class="button" id="step-over-button" title="Step over next function call (F10)."><div class="glyph"></div></div>
743 </div>
744 </body>
745 <canvas id="canvas" class="fill"></canvas>
746 <div id="element-title">
747   <span id="tag-name"></span><span id="node-id"></span><span id="class-name"></span>
748   <span id="node-width"></span><span class="px">px</span><span class="px"> &#xD7; </span><span id="node-height"></span><span class="px">px</span>
749 </div>
750 <div id="log"></div>
751 </html>