Example #1
0
exports.testReloadAll = function*(assert) {
  const parentPath = join(tmpdir(), "toolkit-require-reload-parent.js");
  const childPath = join(tmpdir(), "toolkit-require-reload-child.js");

  const parentURI = fromFilename(parentPath);
  const childURI = fromFilename(childPath);

  yield write(childPath, `exports.name = () => "child"`);
  yield write(parentPath, `const child = require("./toolkit-require-reload-child");
                           exports.greet = () => "Hello " + child.name();`);

  const parent1 = toolkit.require(parentURI);
  assert.equal(parent1.greet(), "Hello child");

  yield write(childPath, `exports.name = () => "father"`);
  yield write(parentPath, `const child = require("./toolkit-require-reload-child");
                           exports.greet = () => "Hello " + child.name() + "!";`);

  const parent2 = toolkit.require(parentURI, {reload: true});
  assert.equal(parent2.greet(), "Hello child!",
               "only parent changes were picked up");
  assert.ok(Cu.isDeadWrapper(parent1.greet), "previous parent was unloaded");

  const parent3 = toolkit.require(parentURI, {reload: true, all: true});
  assert.equal(parent3.greet(), "Hello father!",
               "all changes were picked up");
  assert.ok(Cu.isDeadWrapper(parent2.greet), "previous parent was unloaded");

  yield remove(childPath);
  yield remove(parentPath);
};
Example #2
0
/**
 * Returns the grid fragment array with all the grid fragment data stringifiable.
 *
 * @param  {Object} fragments
 *         Grid fragment object.
 * @return {Array} representation with the grid fragment data stringifiable.
 */
function getStringifiableFragments(fragments = []) {
  if (fragments[0] && Cu.isDeadWrapper(fragments[0])) {
    return {};
  }

  return fragments.map(getStringifiableFragment);
}
Example #3
0
/**
 * Returns true if a DOM node is "valid", where "valid" means that the node isn't a dead
 * object wrapper, is still attached to a document, and is of a given type.
 * @param {DOMNode} node
 * @param {Number} nodeType Optional, defaults to ELEMENT_NODE
 * @return {Boolean}
 */
function isNodeValid(node, nodeType = Node.ELEMENT_NODE) {
  // Is it still alive?
  if (!node || Cu.isDeadWrapper(node)) {
    return false;
  }

  // Is it of the right type?
  if (node.nodeType !== nodeType) {
    return false;
  }

  // Is its document accessible?
  const doc = node.ownerDocument;
  if (!doc || !doc.defaultView) {
    return false;
  }

  // Is the node connected to the document? Using getBindingParent adds
  // support for anonymous elements generated by a node in the document.
  const bindingParent = getRootBindingParent(node);
  if (!doc.documentElement.contains(bindingParent)) {
    return false;
  }

  return true;
}
        get: () => {
          if (selectedDOMNode && !Cu.isDeadWrapper(selectedDOMNode)) {
            return dbgWindow.makeDebuggeeValue(selectedDOMNode);
          }

          return undefined;
        },
Example #5
0
function nodeDocument(node) {
  if (Cu.isDeadWrapper(node)) {
    return null;
  }
  return node.ownerDocument ||
         (node.nodeType == Node.DOCUMENT_NODE ? node : null);
}
 /**
  * Some nodes (e.g. inside of <template> tags) don't have a documentElement or an
  * ownerGlobal and can't be watched by this helper.
  */
 _isValidNode(nodeActor) {
   const node = nodeActor.rawNode;
   return !Cu.isDeadWrapper(node) &&
          node.ownerGlobal &&
          node.ownerDocument &&
          node.ownerDocument.documentElement;
 }
Example #7
0
function isNodeValid(node) {
  // Is it null or dead?
  if (!node || Cu.isDeadWrapper(node)) {
    return false;
  }

  // Is it an element node
  if (node.nodeType !== node.ELEMENT_NODE) {
    return false;
  }

  // Is the document inaccessible?
  let doc = node.ownerDocument;
  if (!doc || !doc.defaultView) {
    return false;
  }

  // Is the node connected to the document? Using getBindingParent adds
  // support for anonymous elements generated by a node in the document.
  let bindingParent = getRootBindingParent(node);
  if (!doc.documentElement.contains(bindingParent)) {
    return false;
  }

  return true;
}
Example #8
0
/**
 * Stringify CSS Grid data as returned by node.getGridFragments.
 * This is useful to compare grid state at each update and redraw the highlighter if
 * needed.
 *
 * @param  {Object} Grid Fragments
 * @return {String} representation of the CSS grid fragment data.
 */
function stringifyGridFragments(fragments = []) {
  if (fragments[0] && Cu.isDeadWrapper(fragments[0])) {
    return {};
  }

  return JSON.stringify(fragments.map(getStringifiableFragment));
}
Example #9
0
 destroy: function() {
   // Only try to disconnect the observer if it's not already dead (i.e. if the
   // container view hasn't navigated since).
   if (this.observer && !Cu.isDeadWrapper(this.observer)) {
     this.observer.disconnect();
   }
   this.tabActor = this.player = this.node = this.styles = this.observer = null;
   Actor.prototype.destroy.call(this);
 },
Example #10
0
CssLogic.getComputedStyle = function(node) {
  if (!node ||
      Cu.isDeadWrapper(node) ||
      node.nodeType !== nodeConstants.ELEMENT_NODE ||
      !node.ownerGlobal) {
    return null;
  }

  const {bindingElement, pseudo} = CssLogic.getBindingElementAndPseudo(node);
  return node.ownerGlobal.getComputedStyle(bindingElement, pseudo);
};
Example #11
0
  isNode: function() {
    if (!this._nodeFront) {
      return false;
    }

    // As long as tools are still accessing node.rawNode(),
    // this needs to stay here.
    if (this._node && Cu.isDeadWrapper(this._node)) {
      return false;
    }

    return true;
  },
Example #12
0
  getJQuery(node) {
    if (Cu.isDeadWrapper(node)) {
      return null;
    }

    const global = this.unwrap(node.ownerGlobal);
    if (!global) {
      return null;
    }

    const hasJQuery = global.jQuery && global.jQuery.fn && global.jQuery.fn.jquery;

    if (hasJQuery) {
      return global.jQuery;
    }
    return null;
  }
Example #13
0
  destroy: function() {
    protocol.Actor.prototype.destroy.call(this);

    if (this.mutationObserver) {
      if (!Cu.isDeadWrapper(this.mutationObserver)) {
        this.mutationObserver.disconnect();
      }
      this.mutationObserver = null;
    }

    if (this.slotchangeListener) {
      if (!InspectorActorUtils.isNodeDead(this)) {
        this.rawNode.removeEventListener("slotchange", this.slotchangeListener);
      }
      this.slotchangeListener = null;
    }

    this.rawNode = null;
    this.walker = null;
  },
Example #14
0
/**
 * Wrapper for inDeepTreeWalker.  Adds filtering to the traversal methods.
 * See inDeepTreeWalker for more information about the methods.
 *
 * @param {DOMNode} node
 * @param {Window} rootWin
 * @param {Object}
 *        - {Number} whatToShow
 *          See nodeFilterConstants / inIDeepTreeWalker for options.
 *        - {Function} filter
 *          A custom filter function Taking in a DOMNode and returning an Int. See
 *          WalkerActor.nodeFilter for an example.
 *        - {String} skipTo
 *          Either SKIP_TO_PARENT or SKIP_TO_SIBLING. If the provided node is not
 *          compatible with the filter function for this walker, try to find a compatible
 *          one either in the parents or in the siblings of the node.
 *        - {Boolean} showAnonymousContent
 *          Pass true to let the walker return and traverse anonymous content.
 *          When navigating host elements to which shadow DOM is attached, the light tree
 *          will be visible only to a walker with showAnonymousContent=false. The shadow
 *          tree will only be visible to a walker with showAnonymousContent=true.
 */
function DocumentWalker(node, rootWin,
  {
    whatToShow = nodeFilterConstants.SHOW_ALL,
    filter = standardTreeWalkerFilter,
    skipTo = SKIP_TO_PARENT,
    showAnonymousContent = true
  } = {}) {
  if (Cu.isDeadWrapper(rootWin) || !rootWin.location) {
    throw new Error("Got an invalid root window in DocumentWalker");
  }

  this.walker = Cc["@mozilla.org/inspector/deep-tree-walker;1"]
    .createInstance(Ci.inIDeepTreeWalker);
  this.walker.showAnonymousContent = showAnonymousContent;
  this.walker.showSubDocuments = true;
  this.walker.showDocumentsAsNodes = true;
  this.walker.init(rootWin.document, whatToShow);
  this.filter = filter;

  // Make sure that the walker knows about the initial node (which could
  // be skipped due to a filter).
  this.walker.currentNode = this.getStartingNode(node, skipTo);
}
Example #15
0
exports.testReload = function*(assert) {
  const modulePath = join(tmpdir(), "toolkit-require-reload.js");
  const moduleURI = fromFilename(modulePath);

  yield write(modulePath, `exports.version = () => 1;`);

  const v1 = toolkit.require(moduleURI);

  assert.equal(v1.version(), 1, "module exports version");

  yield write(modulePath, `exports.version = () => 2;`);

  assert.equal(v1, toolkit.require(moduleURI),
               "require does not reload modules");

  const v2 = toolkit.require(moduleURI, {reload: true});
  assert.equal(v2.version(), 2, "module was updated");

  assert.ok(Cu.isDeadWrapper(v1.version),
            "previous module was unloaded");

  yield remove(modulePath);
};
Example #16
0
  getAllocations: expectState("attached", function() {
    if (this.dbg.memory.allocationsLogOverflowed) {
      // Since the last time we drained the allocations log, there have been
      // more allocations than the log's capacity, and we lost some data. There
      // isn't anything actionable we can do about this, but put a message in
      // the browser console so we at least know that it occurred.
      reportException("MemoryBridge.prototype.getAllocations",
                      "Warning: allocations log overflowed and lost some data.");
    }

    const allocations = this.dbg.memory.drainAllocationsLog();
    const packet = {
      allocations: [],
      allocationsTimestamps: [],
      allocationSizes: [],
    };
    for (const { frame: stack, timestamp, size } of allocations) {
      if (stack && Cu.isDeadWrapper(stack)) {
        continue;
      }

      // Safe because SavedFrames are frozen/immutable.
      const waived = Cu.waiveXrays(stack);

      // Ensure that we have a form, size, and index for new allocations
      // because we potentially haven't seen some or all of them yet. After this
      // loop, we can rely on the fact that every frame we deal with already has
      // its metadata stored.
      const index = this._frameCache.addFrame(waived);

      packet.allocations.push(index);
      packet.allocationsTimestamps.push(timestamp);
      packet.allocationSizes.push(size);
    }

    return this._frameCache.updateFramePacket(packet);
  }, "getting allocations"),
Example #17
0
const propagateOnContext = (item, data) =>
  each(child => child[onContext](data), item.state.children);

const isContextMatch = item => !item[isMatching] || item[isMatching]();

// For whatever reason addWeakMessageListener does not seems to work as our
// instance seems to dropped even though it's alive. This is simple workaround
// to avoid dead object excetptions.
const WeakMessageListener = function(receiver, handler="receiveMessage") {
  this.receiver = receiver
  this.handler = handler
};
WeakMessageListener.prototype = {
  constructor: WeakMessageListener,
  receiveMessage(message) {
    if (Cu.isDeadWrapper(this.receiver)) {
      message.target.messageManager.removeMessageListener(message.name, this);
    }
    else {
      this.receiver[this.handler](message);
    }
  }
};

const OVERFLOW_THRESH = "extensions.addon-sdk.context-menu.overflowThreshold";
const onMessage = Symbol("context-menu/message-listener");
const onPreferceChange = Symbol("context-menu/preference-change");
const ContextMenuExtension = Class({
  extends: Component,
  initialize: Component,
  setup() {
Example #18
0
      getAttribute: name => this.getAttributeForElement(id, name),
      removeAttribute: name => this.removeAttributeForElement(id, name),
      hasAttribute: name => this.hasAttributeForElement(id, name),
      getCanvasContext: type => this.getCanvasContext(id, type),
      addEventListener: (type, handler) => {
        return this.addEventListenerForElement(id, type, handler);
      },
      removeEventListener: (type, handler) => {
        return this.removeEventListenerForElement(id, type, handler);
      },
      classList
    };
  },

  get content() {
    if (!this._content || Cu.isDeadWrapper(this._content)) {
      return null;
    }
    return this._content;
  },

  /**
   * The canvasFrame anonymous content container gets zoomed in/out with the
   * page. If this is unwanted, i.e. if you want the inserted element to remain
   * unzoomed, then this method can be used.
   *
   * Consumers of the CanvasFrameAnonymousContentHelper should call this method,
   * it isn't executed automatically. Typically, AutoRefreshHighlighter can call
   * it when _update is executed.
   *
   * The matching element will be scaled down or up by 1/zoomLevel (using css
Example #19
0
 stopAnimationPlayerUpdates: method(function() {
   if (this.observer && !Cu.isDeadWrapper(this.observer)) {
     this.observer.disconnect();
   }
 }, {
Example #20
0
 _stopRefreshLoop: function () {
   if (this.rafID && !Cu.isDeadWrapper(this.rafWin)) {
     this.rafWin.cancelAnimationFrame(this.rafID);
   }
   this.rafID = this.rafWin = null;
 },
Example #21
0
 getXPath: function() {
   if (Cu.isDeadWrapper(this.rawNode)) {
     return "";
   }
   return getXPath(this.rawNode);
 },
Example #22
0
 getUniqueSelector: function() {
   if (Cu.isDeadWrapper(this.rawNode)) {
     return "";
   }
   return findCssSelector(this.rawNode);
 },
Example #23
0
function isNodeDead(node) {
  return !node || (node.rawNode && Cu.isDeadWrapper(node.rawNode));
}
Example #24
0
  get isInitialized() {
    return this._win || this._tabActor;
  },

  get isXUL() {
    return isXUL(this.window);
  },

  get window() {
    if (!this.isInitialized) {
      throw new Error("Initialize HighlighterEnvironment with a tabActor " +
        "or window first");
    }
    let win = this._tabActor ? this._tabActor.window : this._win;

    return Cu.isDeadWrapper(win) ? null : win;
  },

  get document() {
    return this.window && this.window.document;
  },

  get docShell() {
    return this.window &&
           this.window.QueryInterface(Ci.nsIInterfaceRequestor)
                      .getInterface(Ci.nsIWebNavigation)
                      .QueryInterface(Ci.nsIDocShell);
  },

  get webProgress() {
    return this.docShell &&