Commit 0d9fb502 authored by Shane Caraveo's avatar Shane Caraveo
Browse files

Bug 1748562 support persistent listeners in omnibox api r=rpl

parent e65e56a1
Loading
Loading
Loading
Loading
+80 −49
Original line number Diff line number Diff line
@@ -12,7 +12,70 @@ ChromeUtils.defineModuleGetter(
  "resource://gre/modules/ExtensionSearchHandler.jsm"
);

this.omnibox = class extends ExtensionAPI {
this.omnibox = class extends ExtensionAPIPersistent {
  PERSISTENT_EVENTS = {
    onInputStarted({ fire }) {
      let { extension } = this;
      let listener = eventName => {
        fire.sync();
      };
      extension.on(ExtensionSearchHandler.MSG_INPUT_STARTED, listener);
      return {
        unregister() {
          extension.off(ExtensionSearchHandler.MSG_INPUT_STARTED, listener);
        },
        convert(_fire) {
          fire = _fire;
        },
      };
    },
    onInputCancelled({ fire }) {
      let { extension } = this;
      let listener = eventName => {
        fire.sync();
      };
      extension.on(ExtensionSearchHandler.MSG_INPUT_CANCELLED, listener);
      return {
        unregister() {
          extension.off(ExtensionSearchHandler.MSG_INPUT_CANCELLED, listener);
        },
        convert(_fire) {
          fire = _fire;
        },
      };
    },
    onInputEntered({ fire }) {
      let { extension } = this;
      let listener = (eventName, text, disposition) => {
        fire.sync(text, disposition);
      };
      extension.on(ExtensionSearchHandler.MSG_INPUT_ENTERED, listener);
      return {
        unregister() {
          extension.off(ExtensionSearchHandler.MSG_INPUT_ENTERED, listener);
        },
        convert(_fire) {
          fire = _fire;
        },
      };
    },
    onInputChanged({ fire }) {
      let { extension } = this;
      let listener = (eventName, text, id) => {
        fire.sync(text, id);
      };
      extension.on(ExtensionSearchHandler.MSG_INPUT_CHANGED, listener);
      return {
        unregister() {
          extension.off(ExtensionSearchHandler.MSG_INPUT_CHANGED, listener);
        },
        convert(_fire) {
          fire = _fire;
        },
      };
    },
  };

  onManifestEntry(entryName) {
    let { extension } = this;
    let { manifest } = extension;
@@ -32,7 +95,6 @@ this.omnibox = class extends ExtensionAPI {
  }

  getAPI(context) {
    let { extension } = context;
    return {
      omnibox: {
        setDefaultSuggestion: suggestion => {
@@ -49,47 +111,30 @@ this.omnibox = class extends ExtensionAPI {

        onInputStarted: new EventManager({
          context,
          name: "omnibox.onInputStarted",
          register: fire => {
            let listener = eventName => {
              fire.sync();
            };
            extension.on(ExtensionSearchHandler.MSG_INPUT_STARTED, listener);
            return () => {
              extension.off(ExtensionSearchHandler.MSG_INPUT_STARTED, listener);
            };
          },
          module: "omnibox",
          event: "onInputStarted",
          extensionApi: this,
        }).api(),

        onInputCancelled: new EventManager({
          context,
          name: "omnibox.onInputCancelled",
          register: fire => {
            let listener = eventName => {
              fire.sync();
            };
            extension.on(ExtensionSearchHandler.MSG_INPUT_CANCELLED, listener);
            return () => {
              extension.off(
                ExtensionSearchHandler.MSG_INPUT_CANCELLED,
                listener
              );
            };
          },
          module: "omnibox",
          event: "onInputCancelled",
          extensionApi: this,
        }).api(),

        onInputEntered: new EventManager({
          context,
          name: "omnibox.onInputEntered",
          register: fire => {
            let listener = (eventName, text, disposition) => {
              fire.sync(text, disposition);
            };
            extension.on(ExtensionSearchHandler.MSG_INPUT_ENTERED, listener);
            return () => {
              extension.off(ExtensionSearchHandler.MSG_INPUT_ENTERED, listener);
            };
          },
          module: "omnibox",
          event: "onInputEntered",
          extensionApi: this,
        }).api(),

        onInputChanged: new EventManager({
          context,
          module: "omnibox",
          event: "onInputChanged",
          extensionApi: this,
        }).api(),

        // Internal APIs.
@@ -105,20 +150,6 @@ this.omnibox = class extends ExtensionAPI {
            // has already invalidated the callback when asynchronously providing suggestions.
          }
        },

        onInputChanged: new EventManager({
          context,
          name: "omnibox.onInputChanged",
          register: fire => {
            let listener = (eventName, text, id) => {
              fire.sync(text, id);
            };
            extension.on(ExtensionSearchHandler.MSG_INPUT_CHANGED, listener);
            return () => {
              extension.off(ExtensionSearchHandler.MSG_INPUT_CHANGED, listener);
            };
          },
        }).api(),
      },
    };
  }
+69 −2
Original line number Diff line number Diff line
@@ -6,11 +6,11 @@ const { UrlbarTestUtils } = ChromeUtils.import(
  "resource://testing-common/UrlbarTestUtils.jsm"
);

const keyword = "VeryUniqueKeywordThatDoesNeverMatchAnyTestUrl";

add_task(async function() {
  // This keyword needs to be unique to prevent history entries from unrelated
  // tests from appearing in the suggestions list.
  let keyword = "VeryUniqueKeywordThatDoesNeverMatchAnyTestUrl";

  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      omnibox: {
@@ -368,3 +368,70 @@ add_task(async function() {
  await extension2.unload();
  await extension.unload();
});

add_task(async function test_omnibox_event_page() {
  await SpecialPowers.pushPrefEnv({
    set: [["extensions.eventPages.enabled", true]],
  });

  let extension = ExtensionTestUtils.loadExtension({
    useAddonManager: "permanent",
    manifest: {
      applications: { gecko: { id: "eventpage@omnibox" } },
      omnibox: {
        keyword: keyword,
      },
      background: { persistent: false },
    },
    background() {
      browser.omnibox.onInputStarted.addListener(() => {
        browser.test.sendMessage("onInputStarted");
      });
      browser.omnibox.onInputEntered.addListener(() => {});
      browser.omnibox.onInputChanged.addListener(() => {});
      browser.omnibox.onInputCancelled.addListener(() => {});
      browser.test.sendMessage("ready");
    },
  });

  const EVENTS = [
    "onInputStarted",
    "onInputEntered",
    "onInputChanged",
    "onInputCancelled",
  ];

  await extension.startup();
  await extension.awaitMessage("ready");
  for (let event of EVENTS) {
    assertPersistentListeners(extension, "omnibox", event, {
      primed: false,
    });
  }

  // test events waken background
  await extension.terminateBackground();
  for (let event of EVENTS) {
    assertPersistentListeners(extension, "omnibox", event, {
      primed: true,
    });
  }

  // Activate the keyword by typing a space.
  // Expect onInputStarted to fire.
  gURLBar.focus();
  gURLBar.value = keyword;
  EventUtils.sendString(" ");

  await extension.awaitMessage("ready");
  await extension.awaitMessage("onInputStarted");
  ok(true, "persistent event woke background");
  for (let event of EVENTS) {
    assertPersistentListeners(extension, "omnibox", event, {
      primed: false,
    });
  }

  await extension.unload();
  await SpecialPowers.popPrefEnv();
});