Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: Source/core/inspector/InspectorOverlayPage.html

Issue 430463002: DevTools: highlight page regions as paths, not quads (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 <!-- 1 <!--
2 Copyright (C) 2012 Google Inc. All rights reserved. 2 Copyright (C) 2012 Google Inc. All rights reserved.
3 3
4 Redistribution and use in source and binary forms, with or without 4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions 5 modification, are permitted provided that the following conditions
6 are met: 6 are met:
7 7
8 1. Redistributions of source code must retain the above copyright 8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer. 9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright 10 2. Redistributions in binary form must reproduce the above copyright
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 /* Keep this in sync with view-source.css (.html-attribute-name) */ 149 /* Keep this in sync with view-source.css (.html-attribute-name) */
150 color: rgb(153, 69, 0); 150 color: rgb(153, 69, 0);
151 } 151 }
152 152
153 </style> 153 </style>
154 <script> 154 <script>
155 const lightGridColor = "rgba(0,0,0,0.2)"; 155 const lightGridColor = "rgba(0,0,0,0.2)";
156 const darkGridColor = "rgba(0,0,0,0.7)"; 156 const darkGridColor = "rgba(0,0,0,0.7)";
157 const transparentColor = "rgba(0, 0, 0, 0)"; 157 const transparentColor = "rgba(0, 0, 0, 0)";
158 const gridBackgroundColor = "rgba(255, 255, 255, 0.8)"; 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 159
163 function drawPausedInDebuggerMessage(message) 160 function drawPausedInDebuggerMessage(message)
164 { 161 {
165 window._controlsVisible = true; 162 window._controlsVisible = true;
166 document.querySelector(".controls-line").style.visibility = "visible"; 163 document.querySelector(".controls-line").style.visibility = "visible";
167 document.getElementById("paused-in-debugger").textContent = message; 164 document.getElementById("paused-in-debugger").textContent = message;
168 document.body.classList.add("dimmed"); 165 document.body.classList.add("dimmed");
169 } 166 }
170 167
171 function _drawGrid(rulerAtRight, rulerAtBottom) 168 function _drawGrid(rulerAtRight, rulerAtBottom)
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 context.moveTo(zoom(x), scrollY); 292 context.moveTo(zoom(x), scrollY);
296 context.lineTo(zoom(x), scrollY + gridSubStep); 293 context.lineTo(zoom(x), scrollY + gridSubStep);
297 context.stroke(); 294 context.stroke();
298 } 295 }
299 context.restore(); 296 context.restore();
300 } 297 }
301 298
302 context.restore(); 299 context.restore();
303 } 300 }
304 301
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) 302 function drawViewSize(drawViewSizeWithGrid)
361 { 303 {
362 var drawGridBoolean = drawViewSizeWithGrid === "true"; 304 var drawGridBoolean = drawViewSizeWithGrid === "true";
363 var text = viewportSize.width + "px \u00D7 " + viewportSize.height + "px"; 305 var text = viewportSize.width + "px \u00D7 " + viewportSize.height + "px";
364 context.save(); 306 context.save();
365 context.font = "20px "; 307 context.font = "20px ";
366 switch (platform) { 308 switch (platform) {
367 case "windows": context.font = "14px Consolas"; break; 309 case "windows": context.font = "14px Consolas"; break;
368 case "mac": context.font = "14px Menlo"; break; 310 case "mac": context.font = "14px Menlo"; break;
369 case "linux": context.font = "14px dejavu sans mono"; break; 311 case "linux": context.font = "14px dejavu sans mono"; break;
(...skipping 30 matching lines...) Expand all
400 window.canvasWidth = viewportSize.width; 342 window.canvasWidth = viewportSize.width;
401 window.canvasHeight = viewportSize.height; 343 window.canvasHeight = viewportSize.height;
402 344
403 window._controlsVisible = false; 345 window._controlsVisible = false;
404 document.querySelector(".controls-line").style.visibility = "hidden"; 346 document.querySelector(".controls-line").style.visibility = "hidden";
405 document.getElementById("element-title").style.visibility = "hidden"; 347 document.getElementById("element-title").style.visibility = "hidden";
406 document.body.classList.remove("dimmed"); 348 document.body.classList.remove("dimmed");
407 window._gridPainted = false; 349 window._gridPainted = false;
408 } 350 }
409 351
410 function _drawElementTitle(highlight) 352 function _drawElementTitle(elementInfo, bounds)
411 { 353 {
412 var elementInfo = highlight.elementInfo;
413 if (!highlight.elementInfo)
414 return;
415
416 document.getElementById("tag-name").textContent = elementInfo.tagName; 354 document.getElementById("tag-name").textContent = elementInfo.tagName;
417 document.getElementById("node-id").textContent = elementInfo.idValue ? "#" + elementInfo.idValue : ""; 355 document.getElementById("node-id").textContent = elementInfo.idValue ? "#" + elementInfo.idValue : "";
418 var className = elementInfo.className; 356 var className = elementInfo.className;
419 if (className && className.length > 50) 357 if (className && className.length > 50)
420 className = className.substring(0, 50) + "\u2026"; 358 className = className.substring(0, 50) + "\u2026";
421 document.getElementById("class-name").textContent = className || ""; 359 document.getElementById("class-name").textContent = className || "";
422 document.getElementById("node-width").textContent = elementInfo.nodeWidth; 360 document.getElementById("node-width").textContent = elementInfo.nodeWidth;
423 document.getElementById("node-height").textContent = elementInfo.nodeHeight; 361 document.getElementById("node-height").textContent = elementInfo.nodeHeight;
424 var elementTitle = document.getElementById("element-title"); 362 var elementTitle = document.getElementById("element-title");
425 363
426 var marginQuad = highlight.quads[0];
427
428 var titleWidth = elementTitle.offsetWidth + 6; 364 var titleWidth = elementTitle.offsetWidth + 6;
429 var titleHeight = elementTitle.offsetHeight + 4; 365 var titleHeight = elementTitle.offsetHeight + 4;
430 366
431 var anchorTop = Math.min(marginQuad[0].y, marginQuad[1].y, marginQuad[2].y, marginQuad[3].y); 367 var anchorTop = bounds.minY;
432 var anchorBottom = Math.max(marginQuad[0].y, marginQuad[1].y, marginQuad[2]. y, marginQuad[3].y); 368 var anchorBottom = bounds.maxY;
433 var anchorLeft = Math.min(marginQuad[0].x, marginQuad[1].x, marginQuad[2].x, marginQuad[3].x); 369 var anchorLeft = bounds.minX;
434 370
435 const arrowHeight = 7; 371 const arrowHeight = 7;
436 var renderArrowUp = false; 372 var renderArrowUp = false;
437 var renderArrowDown = false; 373 var renderArrowDown = false;
438 374
439 var boxX = Math.max(2, anchorLeft); 375 var boxX = Math.max(2, anchorLeft);
440 if (boxX + titleWidth > canvasWidth) 376 if (boxX + titleWidth > canvasWidth)
441 boxX = canvasWidth - titleWidth - 2; 377 boxX = canvasWidth - titleWidth - 2;
442 378
443 var boxY; 379 var boxY;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 context.strokeStyle = "rgb(128, 128, 128)"; 415 context.strokeStyle = "rgb(128, 128, 128)";
480 context.stroke(); 416 context.stroke();
481 417
482 context.restore(); 418 context.restore();
483 419
484 elementTitle.style.visibility = "visible"; 420 elementTitle.style.visibility = "visible";
485 elementTitle.style.top = (boxY + 3) + "px"; 421 elementTitle.style.top = (boxY + 3) + "px";
486 elementTitle.style.left = (boxX + 3) + "px"; 422 elementTitle.style.left = (boxX + 3) + "px";
487 } 423 }
488 424
489 function _drawRulers(highlight, rulerAtRight, rulerAtBottom) 425 function _drawRulers(bounds, rulerAtRight, rulerAtBottom)
490 { 426 {
491 context.save(); 427 context.save();
492 var width = canvasWidth; 428 var width = canvasWidth;
493 var height = canvasHeight; 429 var height = canvasHeight;
494 context.strokeStyle = "rgba(128, 128, 128, 0.3)"; 430 context.strokeStyle = "rgba(128, 128, 128, 0.3)";
495 context.lineWidth = 1; 431 context.lineWidth = 1;
496 context.translate(0.5, 0.5); 432 context.translate(0.5, 0.5);
497 var leftmostXForY = {};
498 var rightmostXForY = {};
499 var topmostYForX = {};
500 var bottommostYForX = {};
501
502 for (var i = 0; i < highlight.quads.length; ++i) {
503 var quad = highlight.quads[i];
504 for (var j = 0; j < quad.length; ++j) {
505 var x = quad[j].x;
506 var y = quad[j].y;
507 leftmostXForY[Math.round(y)] = Math.min(leftmostXForY[y] || Number.M AX_VALUE, Math.round(quad[j].x));
508 rightmostXForY[Math.round(y)] = Math.max(rightmostXForY[y] || Number .MIN_VALUE, Math.round(quad[j].x));
509 topmostYForX[Math.round(x)] = Math.min(topmostYForX[x] || Number.MAX _VALUE, Math.round(quad[j].y));
510 bottommostYForX[Math.round(x)] = Math.max(bottommostYForX[x] || Numb er.MIN_VALUE, Math.round(quad[j].y));
511 }
512 }
513 433
514 if (rulerAtRight) { 434 if (rulerAtRight) {
515 for (var y in rightmostXForY) { 435 for (var y in bounds.rightmostXForY) {
516 context.beginPath(); 436 context.beginPath();
517 context.moveTo(width, y); 437 context.moveTo(width, y);
518 context.lineTo(rightmostXForY[y], y); 438 context.lineTo(bounds.rightmostXForY[y], y);
519 context.stroke(); 439 context.stroke();
520 } 440 }
521 } else { 441 } else {
522 for (var y in leftmostXForY) { 442 for (var y in bounds.leftmostXForY) {
523 context.beginPath(); 443 context.beginPath();
524 context.moveTo(0, y); 444 context.moveTo(0, y);
525 context.lineTo(leftmostXForY[y], y); 445 context.lineTo(bounds.leftmostXForY[y], y);
526 context.stroke(); 446 context.stroke();
527 } 447 }
528 } 448 }
529 449
530 if (rulerAtBottom) { 450 if (rulerAtBottom) {
531 for (var x in bottommostYForX) { 451 for (var x in bounds.bottommostYForX) {
532 context.beginPath(); 452 context.beginPath();
533 context.moveTo(x, height); 453 context.moveTo(x, height);
534 context.lineTo(x, topmostYForX[x]); 454 context.lineTo(x, bounds.topmostYForX[x]);
535 context.stroke(); 455 context.stroke();
536 } 456 }
537 } else { 457 } else {
538 for (var x in topmostYForX) { 458 for (var x in bounds.topmostYForX) {
539 context.beginPath(); 459 context.beginPath();
540 context.moveTo(x, 0); 460 context.moveTo(x, 0);
541 context.lineTo(x, topmostYForX[x]); 461 context.lineTo(x, bounds.topmostYForX[x]);
542 context.stroke(); 462 context.stroke();
543 } 463 }
544 } 464 }
545 465
546 context.restore(); 466 context.restore();
547 } 467 }
548 // CSS shapes 468
549 function drawPath(commands, fillColor) 469 function drawPath(commands, fillColor, outlineColor, bounds)
550 { 470 {
471 var commandsIndex = 0;
472 function extractPoints(count)
473 {
474 var points = [];
475
476 for (var i = 0; i < count; ++i) {
477 var x = Math.round(commands[commandsIndex++] * pageScaleFactor);
478 bounds.maxX = Math.max(bounds.maxX, x);
479 bounds.minX = Math.min(bounds.minX, x);
480
481 var y = Math.round(commands[commandsIndex++] * pageScaleFactor);
482 bounds.maxY = Math.max(bounds.maxY, y);
483 bounds.minY = Math.min(bounds.minY, y);
484
485 bounds.leftmostXForY[y] = Math.min(bounds.leftmostXForY[y] || Number .MAX_VALUE, x);
486 bounds.rightmostXForY[y] = Math.max(bounds.rightmostXForY[y] || Numb er.MIN_VALUE, x);
487 bounds.topmostYForX[x] = Math.min(bounds.topmostYForX[x] || Number.M AX_VALUE, y);
488 bounds.bottommostYForX[x] = Math.max(bounds.bottommostYForX[x] || Nu mber.MIN_VALUE, y);
489
490 points.push(x, y);
491 }
492 return points;
493 }
494
551 context.save(); 495 context.save();
552 context.beginPath(); 496 context.beginPath();
553 497
554 var commandsIndex = 0;
555 var commandsLength = commands.length; 498 var commandsLength = commands.length;
556 while (commandsIndex < commandsLength) { 499 while (commandsIndex < commandsLength) {
557 switch (commands[commandsIndex++]) { 500 switch (commands[commandsIndex++]) {
558 case "M": 501 case "M":
559 context.moveTo(commands[commandsIndex++], commands[commandsIndex++]) ; 502 context.moveTo.apply(context, extractPoints(1));
560 break; 503 break;
561 case "L": 504 case "L":
562 context.lineTo(commands[commandsIndex++], commands[commandsIndex++]) ; 505 context.lineTo.apply(context, extractPoints(1));
563 break; 506 break;
564 case "C": 507 case "C":
565 context.bezierCurveTo(commands[commandsIndex++], commands[commandsIn dex++], commands[commandsIndex++], 508 context.bezierCurveTo.apply(context, extractPoints(3));
566 commands[commandsIndex++], commands[commandsIn dex++], commands[commandsIndex++]);
567 break; 509 break;
568 case "Q": 510 case "Q":
569 context.quadraticCurveTo(commands[commandsIndex++], commands[command sIndex++], commands[commandsIndex++], 511 context.quadraticCurveTo.apply(context, extractPoints(4));
dgozman 2014/07/29 11:00:41 extractPoints(2)
570 commands[commandsIndex++]);
571 break; 512 break;
572 case "Z": 513 case "Z":
573 context.closePath(); 514 context.closePath();
574 break; 515 break;
575 } 516 }
576 } 517 }
577 context.closePath(); 518 context.closePath();
519 context.lineWidth = 0;
578 context.fillStyle = fillColor; 520 context.fillStyle = fillColor;
579 context.fill(); 521 context.fill();
580 522
523 if (outlineColor) {
524 context.lineWidth = 2;
525 context.strokeStyle = outlineColor;
526 context.stroke();
527 }
528
581 context.restore(); 529 context.restore();
582 } 530 }
583 531
584 function drawShapeHighlight(shapeInfo) 532 function drawHighlight(highlight)
585 { 533 {
586 if (shapeInfo.marginShape) 534 context.save();
587 drawPath(shapeInfo.marginShape, shapeMarginHighlightColor);
588 else
589 drawOutlinedQuad(shapeInfo.bounds, shapeHighlightColor, shapeHighlightCo lor);
590 535
591 if (shapeInfo.shape) 536 var bounds = {
592 drawPath(shapeInfo.shape, shapeHighlightColor); 537 minX: Number.MAX_VALUE,
593 else 538 minY: Number.MAX_VALUE,
594 drawOutlinedQuad(shapeInfo.bounds, shapeHighlightColor, shapeHighlightCo lor); 539 maxX: Number.MIN_VALUE,
595 } 540 maxY: Number.MIN_VALUE,
541 leftmostXForY: {},
542 rightmostXForY: {},
543 topmostYForX: {},
544 bottommostYForX: {}
545 };
596 546
597 function drawNodeHighlight(highlight) 547 for (var paths = highlight.paths.slice(); paths.length;) {
598 { 548 var path = paths.pop();
599 { 549 drawPath(path.path, path.fillColor, path.outlineColor, bounds);
600 for (var i = 0; i < highlight.quads.length; ++i) { 550 if (paths.length) {
601 var quad = highlight.quads[i]; 551 context.save();
602 for (var j = 0; j < quad.length; ++j) { 552 context.globalCompositeOperation = "destination-out";
603 quad[j].x = Math.round(quad[j].x * pageScaleFactor); 553 drawPath(paths[paths.length - 1].path, "red", null, bounds);
604 quad[j].y = Math.round(quad[j].y * pageScaleFactor); 554 context.restore();
605 }
606 } 555 }
607 } 556 }
608 557
609 if (!highlight.quads.length) { 558 var rulerAtRight = highlight.paths.length && highlight.showRulers && bounds. minX < 20 && bounds.maxX + 20 < canvasWidth;
610 if (highlight.showRulers) 559 var rulerAtBottom = highlight.paths.length && highlight.showRulers && bounds .minY < 20 && bounds.maxY + 20 < canvasHeight;
611 _drawGrid(false, false);
612 return;
613 }
614
615 context.save();
616
617 var quads = highlight.quads.slice();
618 var eventTargetQuad = quads.length >= 5 ? quads.pop() : null;
619 var contentQuad = quads.pop();
620 var paddingQuad = quads.pop();
621 var borderQuad = quads.pop();
622 var marginQuad = quads.pop();
623
624 var hasContent = contentQuad && highlight.contentColor !== transparentColor || highlight.contentOutlineColor !== transparentColor;
625 var hasPadding = paddingQuad && highlight.paddingColor !== transparentColor;
626 var hasBorder = borderQuad && highlight.borderColor !== transparentColor;
627 var hasMargin = marginQuad && highlight.marginColor !== transparentColor;
628 var hasEventTarget = eventTargetQuad && highlight.eventTargetColor !== trans parentColor;
629
630 var clipQuad;
631 if (hasMargin && (!hasBorder || !quadEquals(marginQuad, borderQuad))) {
632 drawOutlinedQuadWithClip(marginQuad, borderQuad, highlight.marginColor);
633 clipQuad = borderQuad;
634 }
635 if (hasBorder && (!hasPadding || !quadEquals(borderQuad, paddingQuad))) {
636 drawOutlinedQuadWithClip(borderQuad, paddingQuad, highlight.borderColor) ;
637 clipQuad = paddingQuad;
638 }
639 if (hasPadding && (!hasContent || !quadEquals(paddingQuad, contentQuad))) {
640 drawOutlinedQuadWithClip(paddingQuad, contentQuad, highlight.paddingColo r);
641 clipQuad = contentQuad;
642 }
643 if (hasContent)
644 drawOutlinedQuad(contentQuad, highlight.contentColor, highlight.contentO utlineColor);
645 if (hasEventTarget)
646 drawUnderlyingQuad(eventTargetQuad, highlight.eventTargetColor);
647
648 var width = canvasWidth;
649 var height = canvasHeight;
650 var minX = Number.MAX_VALUE, minY = Number.MAX_VALUE, maxX = Number.MIN_VALU E; maxY = Number.MIN_VALUE;
651 for (var i = 0; i < highlight.quads.length; ++i) {
652 var quad = highlight.quads[i];
653 for (var j = 0; j < quad.length; ++j) {
654 minX = Math.min(minX, quad[j].x);
655 maxX = Math.max(maxX, quad[j].x);
656 minY = Math.min(minY, quad[j].y);
657 maxY = Math.max(maxY, quad[j].y);
658 }
659 }
660
661 var rulerAtRight = highlight.showRulers && minX < 20 && maxX + 20 < width;
662 var rulerAtBottom = highlight.showRulers && minY < 20 && maxY + 20 < height;
663 560
664 if (highlight.showRulers) 561 if (highlight.showRulers)
665 _drawGrid(rulerAtRight, rulerAtBottom); 562 _drawGrid(rulerAtRight, rulerAtBottom);
666 if (highlight.showExtensionLines)
667 _drawRulers(highlight, rulerAtRight, rulerAtBottom);
668 if (highlight.elementInfo && highlight.elementInfo.shapeOutsideInfo)
669 drawShapeHighlight(highlight.elementInfo.shapeOutsideInfo);
670 _drawElementTitle(highlight);
671 563
564 if (highlight.paths.length) {
565 if (highlight.showExtensionLines)
566 _drawRulers(bounds, rulerAtRight, rulerAtBottom);
567
568 if (highlight.elementInfo)
569 _drawElementTitle(highlight.elementInfo, bounds);
570 }
672 context.restore(); 571 context.restore();
673 } 572 }
674 573
675 function drawQuadHighlight(highlight)
676 {
677 context.save();
678 drawOutlinedQuad(highlight.quads[0], highlight.contentColor, highlight.conte ntOutlineColor);
679 context.restore();
680 }
681
682 function setPlatform(platform) 574 function setPlatform(platform)
683 { 575 {
684 window.platform = platform; 576 window.platform = platform;
685 document.body.classList.add("platform-" + platform); 577 document.body.classList.add("platform-" + platform);
686 } 578 }
687 579
688 function dispatch(message) 580 function dispatch(message)
689 { 581 {
690 var functionName = message.shift(); 582 var functionName = message.shift();
691 window[functionName].apply(null, message); 583 window[functionName].apply(null, message);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 <div class="button" id="step-over-button" title="Step over next function cal l (F10)."><div class="glyph"></div></div> 633 <div class="button" id="step-over-button" title="Step over next function cal l (F10)."><div class="glyph"></div></div>
742 </div> 634 </div>
743 </body> 635 </body>
744 <canvas id="canvas" class="fill"></canvas> 636 <canvas id="canvas" class="fill"></canvas>
745 <div id="element-title"> 637 <div id="element-title">
746 <span id="tag-name"></span><span id="node-id"></span><span id="class-name"></s pan> 638 <span id="tag-name"></span><span id="node-id"></span><span id="class-name"></s pan>
747 <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> 639 <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>
748 </div> 640 </div>
749 <div id="log"></div> 641 <div id="log"></div>
750 </html> 642 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698