remote/domain/Page.jsm
author Andreas Tolfsen <ato@sny.no>
Thu, 21 Feb 2019 13:01:23 +0000
changeset 521100 59da827edf02
parent 521078 d7e26a1b6ef7
permissions -rw-r--r--
bug 1523104: remote: drop protocol schema validation; r=ochameau

/* 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";

var EXPORTED_SYMBOLS = ["Page"];

const {Domain} = ChromeUtils.import("chrome://remote/content/Domain.jsm");
const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
const {UnsupportedError} = ChromeUtils.import("chrome://remote/content/Error.jsm");

class Page extends Domain {
  constructor(session, target) {
    super(session, target);
    this.enabled = false;
  }

  destructor() {
    this.disable();
  }

  QueryInterface(iid) {
    if (iid.equals(Ci.nsIWebProgressListener) ||
      iid.equals(Ci.nsISupportsWeakReference) ||
      iid.equals(Ci.nsIObserver)) {
      return this;
    }
    throw Cr.NS_ERROR_NO_INTERFACE;
  }

  // commands

  async enable() {
    if (!this.enabled) {
      this.enabled = true;
      this.chromeEventHandler.addEventListener("DOMContentLoaded", this,
        {mozSystemGroup: true});
      this.chromeEventHandler.addEventListener("pageshow", this,
        {mozSystemGroup: true});
    }
  }

  disable() {
    if (this.enabled) {
      this.chromeEventHandler.removeEventListener("DOMContentLoaded", this,
        {mozSystemGroup: true});
      this.chromeEventHandler.removeEventListener("pageshow", this,
        {mozSystemGroup: true});
      this.enabled = false;
    }
  }

  async navigate({url, referrer, transitionType, frameId} = {}) {
    if (frameId) {
      throw new UnsupportedError("frameId not supported");
    }

    const opts = {
      loadFlags: transitionToLoadFlag(transitionType),
      referrerURI: referrer,
      triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
    };
    this.docShell.QueryInterface(Ci.nsIWebNavigation);
    this.docShell.loadURI(url, opts);

    return {frameId: "42"};
  }

  url() {
    return this.content.location.href;
  }

  handleEvent({type}) {
    const timestamp = Date.now();

    switch (type) {
    case "DOMContentLoaded":
      this.emit("Page.domContentEventFired", {timestamp});
      break;

    case "pageshow":
      this.emit("Page.loadEventFired", {timestamp});
      break;
    }
  }
}

function transitionToLoadFlag(transitionType) {
  switch (transitionType) {
  case "reload":
    return Ci.nsIWebNavigation.LOAD_FLAG_IS_REFRESH;
  case "link":
  default:
    return Ci.nsIWebNavigation.LOAD_FLAG_IS_LINK;
  }
}