Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/devtools/server/actors/resources/storage/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 13 kB image not shown  

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


"use strict";

const { Actor } = require("resource://devtools/shared/protocol.js");
const specs = require("resource://devtools/shared/specs/storage.js");

loader.lazyRequireGetter(
  this,
  "naturalSortCaseInsensitive",
  "resource://devtools/shared/natural-sort.js",
  true
);

// Maximum number of cookies/local storage key-value-pairs that can be sent
// over the wire to the client in one request.
const MAX_STORE_OBJECT_COUNT = 50;
exports.MAX_STORE_OBJECT_COUNT = MAX_STORE_OBJECT_COUNT;

const DEFAULT_VALUE = "value";
exports.DEFAULT_VALUE = DEFAULT_VALUE;

// GUID to be used as a separator in compound keys. This must match the same
// constant in devtools/client/storage/ui.js,
// devtools/client/storage/test/head.js and
// devtools/server/tests/browser/head.js
const SEPARATOR_GUID = "{9d414cc5-8319-0a04-0586-c0a6ae01670a}";
exports.SEPARATOR_GUID = SEPARATOR_GUID;

class BaseStorageActor extends Actor {
  /**
   * Base class with the common methods required by all storage actors.
   *
   * This base class is missing a couple of required methods that should be
   * implemented seperately for each actor. They are namely:
   *   - observe : Method which gets triggered on the notification of the watched
   *               topic.
   *   - getNamesForHost : Given a host, get list of all known store names.
   *   - getValuesForHost : Given a host (and optionally a name) get all known
   *                        store objects.
   *   - toStoreObject : Given a store object, convert it to the required format
   *                     so that it can be transferred over wire.
   *   - populateStoresForHost : Given a host, populate the map of all store
   *                             objects for it
   *   - getFields: Given a subType(optional), get an array of objects containing
   *                column field info. The info includes,
   *                "name" is name of colume key.
   *                "editable" is 1 means editable field; 0 means uneditable.
   *
   * @param {string} typeName
   *        The typeName of the actor.
   */

  constructor(storageActor, typeName) {
    super(storageActor.conn, specs.childSpecs[typeName]);

    this.storageActor = storageActor;

    // Map keyed by host name whose values are nested Maps.
    // Nested maps are keyed by store names and values are store values.
    // Store values are specific to each sub class.
    // Map(host name => stores <Map(name => values )>)
    // Map(string => stores <Map(string => any )>)
    this.hostVsStores = new Map();

    this.onWindowReady = this.onWindowReady.bind(this);
    this.onWindowDestroyed = this.onWindowDestroyed.bind(this);
    this.storageActor.on("window-ready"this.onWindowReady);
    this.storageActor.on("window-destroyed"this.onWindowDestroyed);
  }

  destroy() {
    if (!this.storageActor) {
      return;
    }

    this.storageActor.off("window-ready"this.onWindowReady);
    this.storageActor.off("window-destroyed"this.onWindowDestroyed);

    this.hostVsStores.clear();

    super.destroy();

    this.storageActor = null;
  }

  /**
   * Returns a list of currently known hosts for the target window. This list
   * contains unique hosts from the window + all inner windows. If
   * this._internalHosts is defined then these will also be added to the list.
   */

  get hosts() {
    const hosts = new Set();
    for (const { location } of this.storageActor.windows) {
      const host = this.getHostName(location);

      if (host) {
        hosts.add(host);
      }
    }
    if (this._internalHosts) {
      for (const host of this._internalHosts) {
        hosts.add(host);
      }
    }
    return hosts;
  }

  /**
   * Returns all the windows present on the page. Includes main window + inner
   * iframe windows.
   */

  get windows() {
    return this.storageActor.windows;
  }

  /**
   * Converts the window.location object into a URL (e.g. http://domain.com).
   */

  getHostName(location) {
    if (!location) {
      // Debugging a legacy Firefox extension... no hostname available and no
      // storage possible.
      return null;
    }

    if (this.storageActor.getHostName) {
      return this.storageActor.getHostName(location);
    }

    switch (location.protocol) {
      case "about:":
        return `${location.protocol}${location.pathname}`;
      case "chrome:":
        // chrome: URLs do not support storage of any type.
        return null;
      case "data:":
        // data: URLs do not support storage of any type.
        return null;
      case "file:":
        return `${location.protocol}//${location.pathname}`;
      case "javascript:":
        return location.href;
      case "moz-extension:":
        return location.origin;
      case "resource:":
        return `${location.origin}${location.pathname}`;
      default:
        // http: or unknown protocol.
        return `${location.protocol}//${location.host}`;
    }
  }

  /**
   * Populates a map of known hosts vs a map of stores vs value.
   */

  async populateStoresForHosts() {
    for (const host of this.hosts) {
      await this.populateStoresForHost(host);
    }
  }

  getNamesForHost(host) {
    return [...this.hostVsStores.get(host).keys()];
  }

  getValuesForHost(host, name) {
    if (name) {
      return [this.hostVsStores.get(host).get(name)];
    }
    return [...this.hostVsStores.get(host).values()];
  }

  getObjectsSize(host, names) {
    return names.length;
  }

  /**
   * When a new window is added to the page. This generally means that a new
   * iframe is created, or the current window is completely reloaded.
   *
   * @param {window} window
   *        The window which was added.
   */

  async onWindowReady(window) {
    if (!this.hostVsStores) {
      return;
    }
    const host = this.getHostName(window.location);
    if (host && !this.hostVsStores.has(host)) {
      await this.populateStoresForHost(host, window);
      if (!this.storageActor) {
        // The actor might be destroyed during populateStoresForHost.
        return;
      }

      const data = {};
      data[host] = this.getNamesForHost(host);
      this.storageActor.update("added"this.typeName, data);
    }
  }

  /**
   * When a window is removed from the page. This generally means that an
   * iframe was removed, or the current window reload is triggered.
   *
   * @param {window} window
   *        The window which was removed.
   * @param {Object} options
   * @param {Boolean} options.dontCheckHost
   *        If set to true, the function won't check if the host still is in this.hosts.
   *        This is helpful in the case of the StorageActorMock, as the `hosts` getter
   *        uses its `windows` getter, and at this point in time the window which is
   *        going to be destroyed still exists.
   */

  onWindowDestroyed(window, { dontCheckHost } = {}) {
    if (!this.hostVsStores) {
      return;
    }
    if (!window.location) {
      // Nothing can be done if location object is null
      return;
    }
    const host = this.getHostName(window.location);
    if (host && (!this.hosts.has(host) || dontCheckHost)) {
      this.hostVsStores.delete(host);
      const data = {};
      data[host] = [];
      this.storageActor.update("deleted"this.typeName, data);
    }
  }

  form() {
    const hosts = {};
    for (const host of this.hosts) {
      hosts[host] = [];
    }

    return {
      actor: this.actorID,
      hosts,
      traits: this._getTraits(),
    };
  }

  // Share getTraits for child classes overriding form()
  _getTraits() {
    return {
      // The supportsXXX traits are not related to backward compatibility
      // Different storage actor types implement different APIs, the traits
      // help the client to know what is supported or not.
      supportsAddItem: typeof this.addItem === "function",
      // Note: supportsRemoveItem and supportsRemoveAll are always defined
      // for all actors. See Bug 1655001.
      supportsRemoveItem: typeof this.removeItem === "function",
      supportsRemoveAll: typeof this.removeAll === "function",
      supportsRemoveAllSessionCookies:
        typeof this.removeAllSessionCookies === "function",
    };
  }

  /**
   * Returns a list of requested store objects. Maximum values returned are
   * MAX_STORE_OBJECT_COUNT. This method returns paginated values whose
   * starting index and total size can be controlled via the options object
   *
   * @param {string} host
   *        The host name for which the store values are required.
   * @param {array:string} names
   *        Array containing the names of required store objects. Empty if all
   *        items are required.
   * @param {object} options
   *        Additional options for the request containing following
   *        properties:
   *         - offset {number} : The begin index of the returned array amongst
   *                  the total values
   *         - size {number} : The number of values required.
   *         - sortOn {string} : The values should be sorted on this property.
   *         - index {string} : In case of indexed db, the IDBIndex to be used
   *                 for fetching the values.
   *         - sessionString {string} : Client-side value of storage-expires-session
   *                         l10n string. Since this function can be called from both
   *                         the client and the server, and given that client and
   *                         server might have different locales, we can't compute
   *                         the localized string directly from here.
   * @return {object} An object containing following properties:
   *          - offset - The actual offset of the returned array. This might
   *                     be different from the requested offset if that was
   *                     invalid
   *          - total - The total number of entries possible.
   *          - data - The requested values.
   */

  async getStoreObjects(host, names, options = {}) {
    const offset = options.offset || 0;
    let size = options.size || MAX_STORE_OBJECT_COUNT;
    if (size > MAX_STORE_OBJECT_COUNT) {
      size = MAX_STORE_OBJECT_COUNT;
    }
    const sortOn = options.sortOn || "name";

    const toReturn = {
      offset,
      total: 0,
      data: [],
    };

    let principal = null;
    if (this.typeName === "indexedDB") {
      // We only acquire principal when the type of the storage is indexedDB
      // because the principal only matters the indexedDB.
      const win = this.storageActor.getWindowFromHost(host);
      principal = this.getPrincipal(win);
    }

    if (names) {
      for (const name of names) {
        const values = await this.getValuesForHost(
          host,
          name,
          options,
          this.hostVsStores,
          principal
        );

        const { result, objectStores } = values;

        if (result && typeof result.objectsSize !== "undefined") {
          for (const { key, count } of result.objectsSize) {
            this.objectsSize[key] = count;
          }
        }

        if (result) {
          toReturn.data.push(...result.data);
        } else if (objectStores) {
          toReturn.data.push(...objectStores);
        } else {
          toReturn.data.push(...values);
        }
      }

      if (this.typeName === "Cache") {
        // Cache storage contains several items per name but misses a custom
        // `getObjectsSize` implementation, as implemented for IndexedDB.
        // See Bug 1745242.
        toReturn.total = toReturn.data.length;
      } else {
        toReturn.total = this.getObjectsSize(host, names, options);
      }
    } else {
      let obj = await this.getValuesForHost(
        host,
        undefined,
        undefined,
        this.hostVsStores,
        principal
      );
      if (obj.dbs) {
        obj = obj.dbs;
      }

      toReturn.total = obj.length;
      toReturn.data = obj;
    }

    if (offset > toReturn.total) {
      // In this case, toReturn.data is an empty array.
      toReturn.offset = toReturn.total;
      toReturn.data = [];
    } else {
      // We need to use natural sort before slicing.
      const sorted = toReturn.data.sort((a, b) => {
        return naturalSortCaseInsensitive(
          a[sortOn],
          b[sortOn],
          options.sessionString
        );
      });
      let sliced;
      if (this.typeName === "indexedDB") {
        // indexedDB's getValuesForHost never returns *all* values available but only
        // a slice, starting at the expected offset. Therefore the result is already
        // sliced as expected.
        sliced = sorted;
      } else {
        sliced = sorted.slice(offset, offset + size);
      }
      toReturn.data = sliced.map(a => this.toStoreObject(a));
    }

    return toReturn;
  }

  getPrincipal(win) {
    if (win) {
      return win.document.effectiveStoragePrincipal;
    }
    // We are running in the browser toolbox and viewing system DBs so we
    // need to use system principal.
    return Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
  }
}
exports.BaseStorageActor = BaseStorageActor;

Messung V0.5
C=92 H=96 G=93

¤ Dauer der Verarbeitung: 0.30 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.