Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  PageInfoChild.sys.mjs   Sprache: unbekannt

 
/* 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/. */

const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
  E10SUtils: "resource://gre/modules/E10SUtils.sys.mjs",
  PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
  setTimeout: "resource://gre/modules/Timer.sys.mjs",
});

export class PageInfoChild extends JSWindowActorChild {
  async receiveMessage(message) {
    let window = this.contentWindow;
    let document = window.document;

    //Handles two different types of messages: one for general info (PageInfo:getData)
    //and one for media info (PageInfo:getMediaData)
    switch (message.name) {
      case "PageInfo:getData": {
        return Promise.resolve({
          metaViewRows: this.getMetaInfo(document),
          docInfo: this.getDocumentInfo(document),
          windowInfo: this.getWindowInfo(window),
        });
      }
      case "PageInfo:getMediaData": {
        return Promise.resolve({
          mediaItems: await this.getDocumentMedia(document),
        });
      }
      case "PageInfo:getPartitionKey": {
        return Promise.resolve({
          partitionKey: await this.getPartitionKey(document),
        });
      }
    }

    return undefined;
  }

  getPartitionKey(document) {
    let partitionKey = document.cookieJarSettings.partitionKey;
    return partitionKey;
  }

  getMetaInfo(document) {
    let metaViewRows = [];

    // Get the meta tags from the page.
    let metaNodes = document.getElementsByTagName("meta");

    for (let metaNode of metaNodes) {
      metaViewRows.push([
        metaNode.name ||
          metaNode.httpEquiv ||
          metaNode.getAttribute("property"),
        metaNode.content,
      ]);
    }

    return metaViewRows;
  }

  getWindowInfo(window) {
    let windowInfo = {};
    windowInfo.isTopWindow = window == window.top;

    let hostName = null;
    try {
      hostName = Services.io.newURI(window.location.href).displayHost;
    } catch (exception) {}

    windowInfo.hostName = hostName;
    return windowInfo;
  }

  getDocumentInfo(document) {
    let docInfo = {};
    docInfo.title = document.title;
    docInfo.location = document.location.toString();
    try {
      docInfo.location = Services.io.newURI(
        document.location.toString()
      ).displaySpec;
    } catch (exception) {}
    docInfo.referrer = document.referrer;
    try {
      if (document.referrer) {
        docInfo.referrer = Services.io.newURI(document.referrer).displaySpec;
      }
    } catch (exception) {}
    docInfo.compatMode = document.compatMode;
    docInfo.contentType = document.contentType;
    docInfo.characterSet = document.characterSet;
    docInfo.lastModified = document.lastModified;
    docInfo.principal = document.nodePrincipal;
    docInfo.cookieJarSettings = lazy.E10SUtils.serializeCookieJarSettings(
      document.cookieJarSettings
    );

    let documentURIObject = {};
    documentURIObject.spec = document.documentURIObject.spec;
    docInfo.documentURIObject = documentURIObject;

    docInfo.isContentWindowPrivate =
      lazy.PrivateBrowsingUtils.isContentWindowPrivate(document.ownerGlobal);

    return docInfo;
  }

  /**
   * Returns an array that stores all mediaItems found in the document
   * Calls getMediaItems for all nodes within the constructed tree walker and forms
   * resulting array.
   */
  async getDocumentMedia(document) {
    let nodeCount = 0;
    let content = document.ownerGlobal;
    let iterator = document.createTreeWalker(
      document,
      content.NodeFilter.SHOW_ELEMENT
    );

    let totalMediaItems = [];

    while (iterator.nextNode()) {
      let mediaItems = this.getMediaItems(document, iterator.currentNode);

      if (++nodeCount % 500 == 0) {
        // setTimeout every 500 elements so we don't keep blocking the content process.
        await new Promise(resolve => lazy.setTimeout(resolve, 10));
      }
      totalMediaItems.push(...mediaItems);
    }

    return totalMediaItems;
  }

  getMediaItems(document, elem) {
    // Check for images defined in CSS (e.g. background, borders)
    let computedStyle = elem.ownerGlobal.getComputedStyle(elem);
    // A node can have multiple media items associated with it - for example,
    // multiple background images.
    let mediaItems = [];
    let content = document.ownerGlobal;

    let addMedia = (url, type, alt, el, isBg, altNotProvided = false) => {
      let element = this.serializeElementInfo(document, url, el, isBg);
      mediaItems.push({
        url,
        type,
        alt,
        altNotProvided,
        element,
        isBg,
      });
    };

    if (computedStyle) {
      let addImgFunc = (type, urls) => {
        for (let url of urls) {
          addMedia(url, type, "", elem, true, true);
        }
      };
      // FIXME: This is missing properties. See the implementation of
      // getCSSImageURLs for a list of properties.
      //
      // If you don't care about the message you can also pass "all" here and
      // get all the ones the browser knows about.
      addImgFunc("bg-img", computedStyle.getCSSImageURLs("background-image"));
      addImgFunc(
        "border-img",
        computedStyle.getCSSImageURLs("border-image-source")
      );
      addImgFunc("list-img", computedStyle.getCSSImageURLs("list-style-image"));
      addImgFunc("cursor", computedStyle.getCSSImageURLs("cursor"));
    }

    // One swi^H^H^Hif-else to rule them all.
    if (content.HTMLImageElement.isInstance(elem)) {
      addMedia(
        elem.currentSrc,
        "img",
        elem.getAttribute("alt"),
        elem,
        false,
        !elem.hasAttribute("alt")
      );
    } else if (content.SVGImageElement.isInstance(elem)) {
      try {
        // Note: makeURLAbsolute will throw if either the baseURI is not a valid URI
        //       or the URI formed from the baseURI and the URL is not a valid URI.
        if (elem.href.baseVal) {
          let href = Services.io.newURI(
            elem.href.baseVal,
            null,
            Services.io.newURI(elem.baseURI)
          ).spec;
          addMedia(href, "img", "", elem, false);
        }
      } catch (e) {}
    } else if (content.HTMLVideoElement.isInstance(elem)) {
      addMedia(elem.currentSrc, "video", "", elem, false);
    } else if (content.HTMLAudioElement.isInstance(elem)) {
      addMedia(elem.currentSrc, "audio", "", elem, false);
    } else if (content.HTMLLinkElement.isInstance(elem)) {
      if (elem.rel && /\bicon\b/i.test(elem.rel)) {
        addMedia(elem.href, "link", "", elem, false);
      }
    } else if (
      content.HTMLInputElement.isInstance(elem) ||
      content.HTMLButtonElement.isInstance(elem)
    ) {
      if (elem.type.toLowerCase() == "image") {
        addMedia(
          elem.src,
          "input",
          elem.getAttribute("alt"),
          elem,
          false,
          !elem.hasAttribute("alt")
        );
      }
    } else if (content.HTMLObjectElement.isInstance(elem)) {
      addMedia(elem.data, "object", this.getValueText(elem), elem, false);
    } else if (content.HTMLEmbedElement.isInstance(elem)) {
      addMedia(elem.src, "embed", "", elem, false);
    }

    return mediaItems;
  }

  /**
   * Set up a JSON element object with all the instanceOf and other infomation that
   * makePreview in pageInfo.js uses to figure out how to display the preview.
   */

  serializeElementInfo(document, url, item, isBG) {
    let result = {};
    let content = document.ownerGlobal;

    let imageText;
    if (
      !isBG &&
      !content.SVGImageElement.isInstance(item) &&
      !content.ImageDocument.isInstance(document)
    ) {
      imageText = item.title || item.alt;

      if (!imageText && !content.HTMLImageElement.isInstance(item)) {
        imageText = this.getValueText(item);
      }
    }

    result.imageText = imageText;
    result.longDesc = item.longDesc;
    result.numFrames = 1;

    if (
      content.HTMLObjectElement.isInstance(item) ||
      content.HTMLEmbedElement.isInstance(item) ||
      content.HTMLLinkElement.isInstance(item)
    ) {
      result.mimeType = item.type;
    }

    if (
      !result.mimeType &&
      !isBG &&
      item instanceof Ci.nsIImageLoadingContent
    ) {
      // Interface for image loading content.
      let imageRequest = item.getRequest(
        Ci.nsIImageLoadingContent.CURRENT_REQUEST
      );
      if (imageRequest) {
        result.mimeType = imageRequest.mimeType;
        let image =
          !(imageRequest.imageStatus & imageRequest.STATUS_ERROR) &&
          imageRequest.image;
        if (image) {
          result.numFrames = image.numFrames;
        }
      }
    }

    // If we have a data url, get the MIME type from the url.
    if (!result.mimeType && url.startsWith("data:")) {
      let dataMimeType = /^data:(image\/[^;,]+)/i.exec(url);
      if (dataMimeType) {
        result.mimeType = dataMimeType[1].toLowerCase();
      }
    }

    result.HTMLLinkElement = content.HTMLLinkElement.isInstance(item);
    result.HTMLInputElement = content.HTMLInputElement.isInstance(item);
    result.HTMLImageElement = content.HTMLImageElement.isInstance(item);
    result.HTMLObjectElement = content.HTMLObjectElement.isInstance(item);
    result.SVGImageElement = content.SVGImageElement.isInstance(item);
    result.HTMLVideoElement = content.HTMLVideoElement.isInstance(item);
    result.HTMLAudioElement = content.HTMLAudioElement.isInstance(item);

    if (isBG) {
      // Items that are showing this image as a background
      // image might not necessarily have a width or height,
      // so we'll dynamically generate an image and send up the
      // natural dimensions.
      let img = content.document.createElement("img");
      img.src = url;
      result.naturalWidth = img.naturalWidth;
      result.naturalHeight = img.naturalHeight;
    } else if (!content.SVGImageElement.isInstance(item)) {
      // SVG items do not have integer values for height or width,
      // so we must handle them differently in order to correctly
      // serialize

      // Otherwise, we can use the current width and height
      // of the image.
      result.width = item.width;
      result.height = item.height;
    }

    if (content.SVGImageElement.isInstance(item)) {
      result.SVGImageElementWidth = item.width.baseVal.value;
      result.SVGImageElementHeight = item.height.baseVal.value;
    }

    result.baseURI = item.baseURI;

    return result;
  }

  // Other Misc Stuff
  // Modified from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html
  // parse a node to extract the contents of the node
  getValueText(node) {
    let valueText = "";
    let content = node.ownerGlobal;

    // Form input elements don't generally contain information that is useful to our callers, so return nothing.
    if (
      content.HTMLInputElement.isInstance(node) ||
      content.HTMLSelectElement.isInstance(node) ||
      content.HTMLTextAreaElement.isInstance(node)
    ) {
      return valueText;
    }

    // Otherwise recurse for each child.
    let length = node.childNodes.length;

    for (let i = 0; i < length; i++) {
      let childNode = node.childNodes[i];
      let nodeType = childNode.nodeType;

      // Text nodes are where the goods are.
      if (nodeType == content.Node.TEXT_NODE) {
        valueText += " " + childNode.nodeValue;
      } else if (nodeType == content.Node.ELEMENT_NODE) {
        // And elements can have more text inside them.
        // Images are special, we want to capture the alt text as if the image weren't there.
        if (content.HTMLImageElement.isInstance(childNode)) {
          valueText += " " + this.getAltText(childNode);
        } else {
          valueText += " " + this.getValueText(childNode);
        }
      }
    }

    return this.stripWS(valueText);
  }

  // Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html.
  // Traverse the tree in search of an img or area element and grab its alt tag.
  getAltText(node) {
    let altText = "";

    if (node.alt) {
      return node.alt;
    }
    let length = node.childNodes.length;
    for (let i = 0; i < length; i++) {
      if ((altText = this.getAltText(node.childNodes[i]) != undefined)) {
        // stupid js warning...
        return altText;
      }
    }
    return "";
  }

  // Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html.
  // Strip leading and trailing whitespace, and replace multiple consecutive whitespace characters with a single space.
  stripWS(text) {
    let middleRE = /\s+/g;
    let endRE = /(^\s+)|(\s+$)/g;

    text = text.replace(middleRE, " ");
    return text.replace(endRE, "");
  }
}

[ Dauer der Verarbeitung: 0.39 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge