Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/gfx/layers/layerviewer/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 27 kB image not shown  

Quelle  layerTreeView.js   Sprache: JAVA

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


function toFixed(num, fixed) {
  fixed = fixed || 0;
  fixed = Math.pow(10, fixed);
  return Math.floor(num * fixed) / fixed;
}
function createElement(name, props) {
  var el = document.createElement(name);

  for (var key in props) {
    if (key === "style") {
      for (var styleName in props.style) {
        el.style[styleName] = props.style[styleName];
      }
    } else {
      el[key] = props[key];
    }
  }

  return el;
}

function parseDisplayList(lines) {
  var root = {
    line: "DisplayListRoot 0",
    name: "DisplayListRoot",
    address: "0x0",
    frame: "Root",
    children: [],
  };

  var objectAtIndentation = {
    "-1": root,
  };

  for (var i = 0; i < lines.length; i++) {
    var line = lines[i];

    var layerObject = {
      line,
      children: [],
    };
    if (!root) {
      root = layerObject;
    }

    var matches = line.match(
      "(\\s*)(\\w+)\\sp=(\\w+)\\sf=(.*?)\\((.*?)\\)\\s(z=(\\w+)\\s)?(.*?)?( layer=(\\w+))?$"
    );
    if (!matches) {
      dump("Failed to match: " + line + "\n");
      continue;
    }

    var indentation = Math.floor(matches[1].length / 2);
    objectAtIndentation[indentation] = layerObject;
    var parent = objectAtIndentation[indentation - 1];
    if (parent) {
      parent.children.push(layerObject);
    }

    layerObject.name = matches[2];
    layerObject.address = matches[3]; // Use 0x prefix to be consistent with layer dump
    layerObject.frame = matches[4];
    layerObject.contentDescriptor = matches[5];
    layerObject.z = matches[7];
    var rest = matches[8];
    if (matches[10]) {
      // WrapList don't provide a layer
      layerObject.layer = matches[10];
    }
    layerObject.rest = rest;

    // the content node name doesn't have a prefix, this makes the parsing easier
    rest = "content" + rest;

    var nesting = 0;
    var startIndex;
    var lastSpace = -1;
    for (var j = 0; j < rest.length; j++) {
      if (rest.charAt(j) == "(") {
        nesting++;
        if (nesting == 1) {
          startIndex = j;
        }
      } else if (rest.charAt(j) == ")") {
        nesting--;
        if (nesting == 0) {
          var name = rest.substring(lastSpace + 1, startIndex);
          var value = rest.substring(startIndex + 1, j);

          var rectMatches = value.match("^(.*?),(.*?),(.*?),(.*?)$");
          if (rectMatches) {
            layerObject[name] = [
              parseFloat(rectMatches[1]),
              parseFloat(rectMatches[2]),
              parseFloat(rectMatches[3]),
              parseFloat(rectMatches[4]),
            ];
          } else {
            layerObject[name] = value;
          }
        }
      } else if (nesting == 0 && rest.charAt(j) == " ") {
        lastSpace = j;
      }
    }
    // dump("FIELDS: " + JSON.stringify(fields) + "\n");
  }
  return root;
}

function trim(s) {
  return (s || "").replace(/^\s+|\s+$/g, "");
}

function getDataURI(str) {
  if (str.indexOf("data:image/png;base64,") == 0) {
    return str;
  }

  var matches = str.match(
    "data:image/lz4bgra;base64,([0-9]+),([0-9]+),([0-9]+),(.*)"
  );
  if (!matches) {
    return null;
  }

  var canvas = document.createElement("canvas");
  var w = parseInt(matches[1]);
  var stride = parseInt(matches[2]);
  var h = parseInt(matches[3]);
  canvas.width = w;
  canvas.height = h;

  // TODO handle stride

  var binary_string = window.atob(matches[4]);
  var len = binary_string.length;
  var bytes = new Uint8Array(len);
  var decoded = new Uint8Array(stride * h);
  for (var i = 0; i < len; i++) {
    var ascii = binary_string.charCodeAt(i);
    bytes[i] = ascii;
  }

  var ctxt = canvas.getContext("2d");
  var out = ctxt.createImageData(w, h);
  // This is actually undefined throughout the tree and it isn't clear what it
  // should be. Since this is only development code, leave it alone for now.
  // eslint-disable-next-line no-undef
  LZ4_uncompressChunk(bytes, decoded);

  for (var x = 0; x < w; x++) {
    for (var y = 0; y < h; y++) {
      out.data[4 * x + 4 * y * w + 0] = decoded[4 * x + y * stride + 2];
      out.data[4 * x + 4 * y * w + 1] = decoded[4 * x + y * stride + 1];
      out.data[4 * x + 4 * y * w + 2] = decoded[4 * x + y * stride + 0];
      out.data[4 * x + 4 * y * w + 3] = decoded[4 * x + y * stride + 3];
    }
  }

  ctxt.putImageData(out, 0, 0);
  return canvas.toDataURL();
}

function parseLayers(layersDumpLines) {
  function parseMatrix2x3(str) {
    str = trim(str);

    // Something like '[ 1 0; 0 1; 0 158; ]'
    var matches = str.match("^\\[ (.*?) (.*?); (.*?) (.*?); (.*?) (.*?); \\]$");
    if (!matches) {
      return null;
    }

    var matrix = [
      [parseFloat(matches[1]), parseFloat(matches[2])],
      [parseFloat(matches[3]), parseFloat(matches[4])],
      [parseFloat(matches[5]), parseFloat(matches[6])],
    ];

    return matrix;
  }
  function parseColor(str) {
    str = trim(str);

    // Something like 'rgba(0, 0, 0, 0)'
    var colorMatches = str.match("^rgba\\((.*), (.*), (.*), (.*)\\)$");
    if (!colorMatches) {
      return null;
    }

    var color = {
      r: colorMatches[1],
      g: colorMatches[2],
      b: colorMatches[3],
      a: colorMatches[4],
    };
    return color;
  }
  function parseFloat_cleo(str) {
    str = trim(str);

    // Something like 2.000
    if (parseFloat(str) == str) {
      return parseFloat(str);
    }

    return null;
  }
  function parseRect2D(str) {
    str = trim(str);

    // Something like '(x=0, y=0, w=2842, h=158)'
    var rectMatches = str.match("^\\(x=(.*?), y=(.*?), w=(.*?), h=(.*?)\\)$");
    if (!rectMatches) {
      return null;
    }

    var rect = [
      parseFloat(rectMatches[1]),
      parseFloat(rectMatches[2]),
      parseFloat(rectMatches[3]),
      parseFloat(rectMatches[4]),
    ];
    return rect;
  }
  function parseRegion(str) {
    str = trim(str);

    // Something like '< (x=0, y=0, w=2842, h=158); (x=0, y=1718, w=2842, h=500); >'
    if (str.charAt(0) != "<" || str.charAt(str.length - 1) != ">") {
      return null;
    }

    var region = [];
    str = trim(str.substring(1, str.length - 1));
    while (str != "") {
      var rectMatches = str.match(
        "^\\(x=(.*?), y=(.*?), w=(.*?), h=(.*?)\\);(.*)$"
      );
      if (!rectMatches) {
        return null;
      }

      var rect = [
        parseFloat(rectMatches[1]),
        parseFloat(rectMatches[2]),
        parseFloat(rectMatches[3]),
        parseFloat(rectMatches[4]),
      ];
      str = trim(rectMatches[5]);
      region.push(rect);
    }
    return region;
  }

  var LAYERS_LINE_REGEX = "(\\s*)(\\w+)\\s\\((\\w+)\\)(.*)";

  var root;
  var objectAtIndentation = [];
  for (var i = 0; i < layersDumpLines.length; i++) {
    // Something like 'ThebesLayerComposite (0x12104cc00) [shadow-visible=< (x=0, y=0, w=1920, h=158); >] [visible=< (x=0, y=0, w=1920, h=158); >] [opaqueContent] [valid=< (x=0, y=0, w=1920, h=2218); >]'
    var line = layersDumpLines[i].name || layersDumpLines[i];

    var tileMatches = line.match("(\\s*)Tile \\(x=(.*), y=(.*)\\): (.*)");
    if (tileMatches) {
      let indentation = Math.floor(matches[1].length / 2);
      var x = tileMatches[2];
      var y = tileMatches[3];
      var dataUri = tileMatches[4];
      let parent = objectAtIndentation[indentation - 1];
      var tiles = parent.tiles || {};

      tiles[x] = tiles[x] || {};
      tiles[x][y] = dataUri;

      parent.tiles = tiles;

      continue;
    }

    var surfaceMatches = line.match("(\\s*)Surface: (.*)");
    if (surfaceMatches) {
      let indentation = Math.floor(matches[1].length / 2);
      let parent =
        objectAtIndentation[indentation - 1] ||
        objectAtIndentation[indentation - 2];

      var surfaceURI = surfaceMatches[2];
      if (parent.surfaceURI != null) {
        console.log(
          "error: surfaceURI already set for this layer " + parent.line
        );
      }
      parent.surfaceURI = surfaceURI;

      // Look for the buffer-rect offset
      var contentHostLine =
        layersDumpLines[i - 2].name || layersDumpLines[i - 2];
      let matches = contentHostLine.match(LAYERS_LINE_REGEX);
      if (matches) {
        var contentHostRest = matches[4];
        parent.contentHostProp = {};
        parseProperties(contentHostRest, parent.contentHostProp);
      }

      continue;
    }

    var layerObject = {
      line,
      children: [],
    };
    if (!root) {
      root = layerObject;
    }

    let matches = line.match(LAYERS_LINE_REGEX);
    if (!matches) {
      continue// Something like a texturehost dump. Safe to ignore
    }

    if (
      matches[2].includes("TiledContentHost") ||
      matches[2].includes("ContentHost") ||
      matches[2].includes("ContentClient") ||
      matches[2].includes("MemoryTextureHost") ||
      matches[2].includes("ImageHost")
    ) {
      continue// We're already pretty good at visualizing these
    }

    var indentation = Math.floor(matches[1].length / 2);
    objectAtIndentation[indentation] = layerObject;
    for (var c = indentation + 1; c < objectAtIndentation.length; c++) {
      objectAtIndentation[c] = null;
    }
    if (indentation > 0) {
      var parent = objectAtIndentation[indentation - 1];
      while (!parent) {
        indentation--;
        parent = objectAtIndentation[indentation - 1];
      }

      parent.children.push(layerObject);
    }

    layerObject.name = matches[2];
    layerObject.address = matches[3];

    var rest = matches[4];

    function parseProperties(rest, layerObject) {
      var fields = [];
      var nesting = 0;
      var startIndex;
      for (let j = 0; j < rest.length; j++) {
        if (rest.charAt(j) == "[") {
          nesting++;
          if (nesting == 1) {
            startIndex = j;
          }
        } else if (rest.charAt(j) == "]") {
          nesting--;
          if (nesting == 0) {
            fields.push(rest.substring(startIndex + 1, j));
          }
        }
      }

      for (let j = 0; j < fields.length; j++) {
        // Something like 'valid=< (x=0, y=0, w=1920, h=2218); >' or 'opaqueContent'
        var field = fields[j];
        // dump("FIELD: " + field + "\n");
        var parts = field.split("=", 2);
        var fieldName = parts[0];
        rest = field.substring(fieldName.length + 1);
        if (parts.length == 1) {
          layerObject[fieldName] = "true";
          layerObject[fieldName].type = "bool";
          continue;
        }
        var float = parseFloat_cleo(rest);
        if (float) {
          layerObject[fieldName] = float;
          layerObject[fieldName].type = "float";
          continue;
        }
        var region = parseRegion(rest);
        if (region) {
          layerObject[fieldName] = region;
          layerObject[fieldName].type = "region";
          continue;
        }
        var rect = parseRect2D(rest);
        if (rect) {
          layerObject[fieldName] = rect;
          layerObject[fieldName].type = "rect2d";
          continue;
        }
        var matrix = parseMatrix2x3(rest);
        if (matrix) {
          layerObject[fieldName] = matrix;
          layerObject[fieldName].type = "matrix2x3";
          continue;
        }
        var color = parseColor(rest);
        if (color) {
          layerObject[fieldName] = color;
          layerObject[fieldName].type = "color";
          continue;
        }
        if (rest[0] == "{" && rest[rest.length - 1] == "}") {
          var object = {};
          parseProperties(rest.substring(1, rest.length - 2).trim(), object);
          layerObject[fieldName] = object;
          layerObject[fieldName].type = "object";
          continue;
        }
        fieldName = fieldName.split(" ")[0];
        layerObject[fieldName] = rest[0];
        layerObject[fieldName].type = "string";
      }
    }
    parseProperties(rest, layerObject);

    if (!layerObject["shadow-transform"]) {
      // No shadow transform = identify
      layerObject["shadow-transform"] = [
        [1, 0],
        [0, 1],
        [0, 0],
      ];
    }

    // Compute screenTransformX/screenTransformY
    // TODO Fully support transforms
    if (layerObject["shadow-transform"] && layerObject.transform) {
      layerObject["screen-transform"] = [
        layerObject["shadow-transform"][2][0],
        layerObject["shadow-transform"][2][1],
      ];
      var currIndentation = indentation - 1;
      while (currIndentation >= 0) {
        var transform =
          objectAtIndentation[currIndentation]["shadow-transform"] ||
          objectAtIndentation[currIndentation].transform;
        if (transform) {
          layerObject["screen-transform"][0] += transform[2][0];
          layerObject["screen-transform"][1] += transform[2][1];
        }
        currIndentation--;
      }
    }

    // dump("Fields: " + JSON.stringify(fields) + "\n");
  }
  root.compositeTime = layersDumpLines.compositeTime;
  // dump("OBJECTS: " + JSON.stringify(root) + "\n");
  return root;
}
function populateLayers(
  root,
  displayList,
  pane,
  previewParent,
  hasSeenRoot,
  contentScale,
  rootPreviewParent
) {
  contentScale = contentScale || 1;
  rootPreviewParent = rootPreviewParent || previewParent;

  function getDisplayItemForLayer(displayList) {
    var items = [];
    if (!displayList) {
      return items;
    }
    if (displayList.layer == root.address) {
      items.push(displayList);
    }
    for (var i = 0; i < displayList.children.length; i++) {
      var subDisplayItems = getDisplayItemForLayer(displayList.children[i]);
      for (let j = 0; j < subDisplayItems.length; j++) {
        items.push(subDisplayItems[j]);
      }
    }
    return items;
  }
  var elem = createElement("div", {
    className: "layerObjectDescription",
    textContent: root.line,
    style: {
      whiteSpace: "pre",
    },
    onmouseover() {
      if (this.layerViewport) {
        this.layerViewport.classList.add("layerHover");
      }
    },
    onmouseout() {
      if (this.layerViewport) {
        this.layerViewport.classList.remove("layerHover");
      }
    },
  });
  var icon = createElement("img", {
    src: "show.png",
    style: {
      width: "12px",
      height: "12px",
      marginLeft: "4px",
      marginRight: "4px",
      cursor: "pointer",
    },
    onclick() {
      if (this.layerViewport) {
        if (this.layerViewport.style.visibility == "hidden") {
          this.layerViewport.style.visibility = "";
          this.src = "show.png";
        } else {
          this.layerViewport.style.visibility = "hidden";
          this.src = "hide.png";
        }
      }
    },
  });
  elem.insertBefore(icon, elem.firstChild);
  pane.appendChild(elem);

  if (root["shadow-visible"] || root.visible) {
    var visibleRegion = root["shadow-visible"] || root.visible;
    var layerViewport = createElement("div", {
      id: root.address + "_viewport",
      style: {
        position: "absolute",
        pointerEvents: "none",
      },
    });
    elem.layerViewport = layerViewport;
    icon.layerViewport = layerViewport;
    var layerViewportMatrix = [1, 0, 0, 1, 0, 0];
    if (root["shadow-clip"] || root.clip) {
      var clip = root["shadow-clip"] || root.clip;
      var clipElem = createElement("div", {
        id: root.address + "_clip",
        style: {
          left: clip[0] + "px",
          top: clip[1] + "px",
          width: clip[2] + "px",
          height: clip[3] + "px",
          position: "absolute",
          overflow: "hidden",
          pointerEvents: "none",
        },
      });
      layerViewportMatrix[4] += -clip[0];
      layerViewportMatrix[5] += -clip[1];
      layerViewport.style.transform =
        "translate(-" + clip[0] + "px, -" + clip[1] + "px)";
    }
    if (root["shadow-transform"] || root.transform) {
      var matrix = root["shadow-transform"] || root.transform;
      layerViewportMatrix[0] = matrix[0][0];
      layerViewportMatrix[1] = matrix[0][1];
      layerViewportMatrix[2] = matrix[1][0];
      layerViewportMatrix[3] = matrix[1][1];
      layerViewportMatrix[4] += matrix[2][0];
      layerViewportMatrix[5] += matrix[2][1];
    }
    layerViewport.style.transform =
      "matrix(" +
      layerViewportMatrix[0] +
      "," +
      layerViewportMatrix[1] +
      "," +
      layerViewportMatrix[2] +
      "," +
      layerViewportMatrix[3] +
      "," +
      layerViewportMatrix[4] +
      "," +
      layerViewportMatrix[5] +
      ")";
    if (!hasSeenRoot) {
      hasSeenRoot = true;
      layerViewport.style.transform =
        "scale(" + 1 / contentScale + "," + 1 / contentScale + ")";
    }
    if (clipElem) {
      previewParent.appendChild(clipElem);
      clipElem.appendChild(layerViewport);
    } else {
      previewParent.appendChild(layerViewport);
    }
    previewParent = layerViewport;
    for (let i = 0; i < visibleRegion.length; i++) {
      let rect2d = visibleRegion[i];
      var layerPreview = createElement("div", {
        id: root.address + "_visible_part" + i + "-" + visibleRegion.length,
        className: "layerPreview",
        style: {
          position: "absolute",
          left: rect2d[0] + "px",
          top: rect2d[1] + "px",
          width: rect2d[2] + "px",
          height: rect2d[3] + "px",
          overflow: "hidden",
          border: "solid 1px black",
          background:
            'url("noise.png"), linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.2))',
        },
      });
      layerViewport.appendChild(layerPreview);

      function isInside(rect1, rect2) {
        if (
          rect1[0] + rect1[2] < rect2[0] &&
          rect2[0] + rect2[2] < rect1[0] &&
          rect1[1] + rect1[3] < rect2[1] &&
          rect2[1] + rect2[3] < rect1[1]
        ) {
          return true;
        }
        return true;
      }

      var hasImg = false;
      // Add tile img objects for this part
      var previewOffset = rect2d;

      if (root.tiles) {
        hasImg = true;
        for (var x in root.tiles) {
          for (var y in root.tiles[x]) {
            if (isInside(rect2d, [x, y, 512, 512])) {
              var tileImgElem = createElement("img", {
                src: getDataURI(root.tiles[x][y]),
                style: {
                  position: "absolute",
                  left: x - previewOffset[0] + "px",
                  top: y - previewOffset[1] + "px",
                  pointerEvents: "auto",
                },
              });
              layerPreview.appendChild(tileImgElem);
            }
          }
        }
        layerPreview.style.background = "";
      } else if (root.surfaceURI) {
        hasImg = true;
        var offsetX = 0;
        var offsetY = 0;
        if (root.contentHostProp && root.contentHostProp["buffer-rect"]) {
          offsetX = root.contentHostProp["buffer-rect"][0];
          offsetY = root.contentHostProp["buffer-rect"][1];
        }
        var surfaceImgElem = createElement("img", {
          src: getDataURI(root.surfaceURI),
          style: {
            position: "absolute",
            left: offsetX - previewOffset[0] + "px",
            top: offsetY - previewOffset[1] + "px",
            pointerEvents: "auto",
          },
        });
        layerPreview.appendChild(surfaceImgElem);
        layerPreview.style.background = "";
      } else if (root.color) {
        hasImg = true;
        layerPreview.style.background =
          "rgba(" +
          root.color.r +
          ", " +
          root.color.g +
          ", " +
          root.color.b +
          ", " +
          root.color.a +
          ")";
      }

      if (hasImg || true) {
        layerPreview.mouseoverElem = elem;
        layerPreview.onmouseenter = function () {
          this.mouseoverElem.onmouseover();
        };
        layerPreview.onmouseout = function () {
          this.mouseoverElem.onmouseout();
        };
      }
    }

    var layerDisplayItems = getDisplayItemForLayer(displayList);
    for (let i = 0; i < layerDisplayItems.length; i++) {
      var displayItem = layerDisplayItems[i];
      var displayElem = createElement("div", {
        className: "layerObjectDescription",
        textContent: " " + trim(displayItem.line),
        style: {
          whiteSpace: "pre",
        },
        displayItem,
        layerViewport,
        onmouseover() {
          if (this.diPreview) {
            this.diPreview.classList.add("displayHover");

            var description = "";
            if (this.displayItem.contentDescriptor) {
              description += "Content: " + this.displayItem.contentDescriptor;
            } else {
              description += "Content: Unknown";
            }
            description +=
              "
Item: "
 +
              this.displayItem.name +
              " (" +
              this.displayItem.address +
              ")";
            description +=
              "
Layer: "
 + root.name + " (" + root.address + ")";
            if (this.displayItem.frame) {
              description += "
Frame: "
 + this.displayItem.frame;
            }
            if (this.displayItem.layerBounds) {
              description +=
                "
Bounds: ["
 +
                toFixed(this.displayItem.layerBounds[0] / 60, 2) +
                ", " +
                toFixed(this.displayItem.layerBounds[1] / 60, 2) +
                ", " +
                toFixed(this.displayItem.layerBounds[2] / 60, 2) +
                ", " +
                toFixed(this.displayItem.layerBounds[3] / 60, 2) +
                "] (CSS Pixels)";
            }
            if (this.displayItem.z) {
              description += "
Z: "
 + this.displayItem.z;
            }
            // At the end
            if (this.displayItem.rest) {
              description += "
"
 + this.displayItem.rest;
            }

            var box = this.diPreview.getBoundingClientRect();
            this.diPreview.tooltip = createElement("div", {
              className: "csstooltip",
              innerHTML: description,
              style: {
                top:
                  Math.min(
                    box.bottom,
                    document.documentElement.clientHeight - 150
                  ) + "px",
                left: box.left + "px",
              },
            });

            document.body.appendChild(this.diPreview.tooltip);
          }
        },
        onmouseout() {
          if (this.diPreview) {
            this.diPreview.classList.remove("displayHover");
            document.body.removeChild(this.diPreview.tooltip);
          }
        },
      });

      icon = createElement("img", {
        style: {
          width: "12px",
          height: "12px",
          marginLeft: "4px",
          marginRight: "4px",
        },
      });
      displayElem.insertBefore(icon, displayElem.firstChild);
      pane.appendChild(displayElem);
      // bounds doesn't adjust for within the layer. It's not a bad fallback but
      // will have the wrong offset
      let rect2d = displayItem.layerBounds || displayItem.bounds;
      if (rect2d) {
        // This doesn't place them corectly
        var appUnitsToPixels = 60 / contentScale;
        let diPreview = createElement("div", {
          id: "displayitem_" + displayItem.content + "_" + displayItem.address,
          className: "layerPreview",
          style: {
            position: "absolute",
            left: rect2d[0] / appUnitsToPixels + "px",
            top: rect2d[1] / appUnitsToPixels + "px",
            width: rect2d[2] / appUnitsToPixels + "px",
            height: rect2d[3] / appUnitsToPixels + "px",
            border: "solid 1px gray",
            pointerEvents: "auto",
          },
          displayElem,
          onmouseover() {
            this.displayElem.onmouseover();
          },
          onmouseout() {
            this.displayElem.onmouseout();
          },
        });

        layerViewport.appendChild(diPreview);
        displayElem.diPreview = diPreview;
      }
    }
  }

  for (var i = 0; i < root.children.length; i++) {
    populateLayers(
      root.children[i],
      displayList,
      pane,
      previewParent,
      hasSeenRoot,
      contentScale,
      rootPreviewParent
    );
  }
}

// This function takes a stdout snippet and finds the frames
function parseMultiLineDump(log) {
  var container = createElement("div", {
    style: {
      height: "100%",
      position: "relative",
    },
  });

  var layerManagerFirstLine = "[a-zA-Z]*LayerManager \\(.*$\n";
  var nextLineStartWithSpace = "([ \\t].*$\n)*";
  var layersRegex = "(" + layerManagerFirstLine + nextLineStartWithSpace + ")";

  var startLine = "Painting --- after optimization:\n";
  var endLine = "Painting --- layer tree:";
  var displayListRegex = "(" + startLine + "(.*\n)*?" + endLine + ")";

  var regex = new RegExp(layersRegex + "|" + displayListRegex, "gm");
  var matches = log.match(regex);
  console.log(matches);
  window.matches = matches;

  var matchList = createElement("span", {
    style: {
      height: "95%",
      width: "10%",
      position: "relative",
      border: "solid black 2px",
      display: "inline-block",
      float"left",
      overflow: "auto",
    },
  });
  container.appendChild(matchList);
  var contents = createElement("span", {
    style: {
      height: "95%",
      width: "88%",
      display: "inline-block",
    },
    textContent: "Click on a frame on the left to view the layer tree",
  });
  container.appendChild(contents);

  var lastDisplayList = null;
  var frameID = 1;
  for (let i = 0; i < matches.length; i++) {
    var currMatch = matches[i];

    if (currMatch.indexOf(startLine) == 0) {
      // Display list match
      var matchLines = matches[i].split("\n");
      lastDisplayList = parseDisplayList(matchLines);
    } else {
      // Layer tree match:
      let displayList = lastDisplayList;
      lastDisplayList = null;
      var currFrameDiv = createElement("a", {
        style: {
          padding: "3px",
          display: "block",
        },
        href: "#",
        textContent: "LayerTree " + frameID++,
        onclick() {
          contents.innerHTML = "";
          var matchLines = matches[i].split("\n");
          var dumpDiv = parseDump(matchLines, displayList);
          contents.appendChild(dumpDiv);
        },
      });
      matchList.appendChild(currFrameDiv);
    }
  }

  return container;
}

function parseDump(log, displayList, compositeTitle, compositeTime) {
  compositeTitle |= "";
  compositeTime |= 0;

  var container = createElement("div", {
    style: {
      background: "white",
      height: "100%",
      position: "relative",
    },
  });

  if (compositeTitle == null && compositeTime == null) {
    var titleDiv = createElement("div", {
      className: "treeColumnHeader",
      style: {
        width: "100%",
      },
      textContent:
        compositeTitle +
        (compositeTitle ? " (near " + compositeTime.toFixed(0) + " ms)" : ""),
    });
    container.appendChild(titleDiv);
  }

  var mainDiv = createElement("div", {
    style: {
      position: "absolute",
      top: "16px",
      left: "0px",
      right: "0px",
      bottom: "0px",
    },
  });
  container.appendChild(mainDiv);

  var layerListPane = createElement("div", {
    style: {
      cssFloat: "left",
      height: "100%",
      width: "300px",
      overflowY: "scroll",
    },
  });
  mainDiv.appendChild(layerListPane);

  var previewDiv = createElement("div", {
    style: {
      position: "absolute",
      left: "300px",
      right: "0px",
      top: "0px",
      bottom: "0px",
      overflow: "auto",
    },
  });
  mainDiv.appendChild(previewDiv);

  var root = parseLayers(log);
  populateLayers(root, displayList, layerListPane, previewDiv);
  return container;
}

Messung V0.5
C=97 H=88 G=92

¤ Dauer der Verarbeitung: 0.16 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.