Non-normal context does not activate non-normal commands

Using PluginBase.util.enterContext to enter a context does not show the commands in the help menu.

For example this plugin has one command which is non-normal and only active in context “somecontext”. It the beginning, context is switched to ["somecontext"] without Normal context. This renders the command not showing in the command list in the help

PluginBase.util.enterContext(["somecontext"]);

export default <IPluginBase & IPlugin>{
  ...PluginBase,
  ...{
    niceName: "SomePlugin",
    description: 'A "SomePlugin" plugin that works on the example.com domain.',
    match: /.*\.example.com/,
    version: "1.0.0",
    commands: [
      {
        name: "Some::Non-normal",
        match: "hello example",
        context: "somecontext",
        normal: false,
        pageFn: () => {
          console.log("hello example");
        }
      }
    ]
  }
};

help-widget-non-normal

1 Like

enterContext actually enters only the context given. So you would need to include “normal” in the params if you use that and still want the Normal context. I will rename it to replaceContext to be more clear. If you just want to add a context, you should use addContext.

PluginBase.util.enterContext(["somecontext"]);

This doesn’t really make sense in the global scope. It should be in init. With those changes, when you go to example.com, it should work :+1:

Sorry for not being specific.

What I wanted is to have only [“somecontext”], not [“Normal”, “somecontext”].

Since the command “Some::Normal” has normal: false and context: "somecontext", I expected that the command will show on the help menu. Was that the wrong assumption regarding how context work?

OK, then your use of enterContext is fine. The problem with using it in global scope remains. Try putting it in init. And also, what URL are you opening the help on?

I used this one on netflix, of course with /.*\.netflix.com/ as the match field value.
I’ll try putting it on init. But in my implementation, it would be calling PluginBase.util.enterContext on certain events like window.addEventListener("popstate", () => { PluginBase.util.enterContext([...]) })

those window listeners should be put in init and they should be removed in destroy that way they’re deactivated when LipSurf is turned off.

Ok. I understand the init and destroy.

But the problem remains. The command with normal: false does not work at all even when the correct context is entered.

I can reproduce it with this.

// lipsurf-plugins/src/HelloWorld/HelloWorld.ts
/// <reference types="lipsurf-types/exatension"/>
declare const PluginBase: IPluginBase;

const contextSwitcher = (() => {

  const contextIsNormal = () => {
    const context = PluginBase.util.getContext();
    return context.length === 1 && context.includes("Normal");
  };

  let enabled = false;

  return {
    /**
     * Enter context ["helloworldcontext"] whenever
     * the browser navigates to:
     * "https://docs.lipsurf.com/api-reference/command"
     *
     * Enter context ["Normal", "helloworldcontext"] whenever
     * the browser navigates to:
     * "https://docs.lipsurf.com/api-reference/plugin"
     */
    enable: async () => {
      enabled = true;
      while (enabled || !contextIsNormal()) {
        switch (true) {
          case window.location.href.startsWith(
            "https://docs.lipsurf.com/api-reference/plugin"
          ): {
            PluginBase.util.enterContext(["Normal", "helloworldcontext"]);
            break;
          }
          case window.location.href.startsWith(
            "https://docs.lipsurf.com/api-reference/command"
          ): {
            PluginBase.util.enterContext(["helloworldcontext"]);
            break;
          }
          default: {
            PluginBase.util.enterContext(["Normal"]);
            break;
          }
        }

        await new Promise(resolve => setTimeout(resolve, 1000));
      }
    },
    /**
     * Disable the location checker and enter the context ["Normal"].
     */
    disable: () => {
      PluginBase.util.enterContext(["Normal"]);
      enabled = false;
    }
  };
})();

export default <IPluginBase & IPlugin>{
  ...PluginBase,
  ...{
    niceName: "Hello World",
    description: 'A "hello world" plugin that works on the lipsurf.com domain.',
    // a RegEx that must match against the current tab's url for the plugin to be active (all of it's commands minus global commands)
    match: /.*\.lipsurf.com/,
    version: "1.0.0",
    init: () => contextSwitcher.enable(),
    destroy: () => contextSwitcher.disable(),

    commands: [
      {
        name: "RespondNonNormal",
        description:
          "Respond with something incredibly insightful to the user.",
        match: "hello",
        pageFn: function() {
          alert("Context: helloworldcontext. Normal: false");
        },

        /**
         * Should work when context is ["helloworldcontext"]
         * But it does not
         */
        context: "helloworldcontext",
        normal: false
      },
      {
        name: "RespondNormal",
        description:
          "Respond with something incredibly insightful to the user.",
        match: "world",
        pageFn: function() {
          alert("Context: helloworldcontext. Normal: true");
        },

        /**
         * Works when context is ["Normal","helloworldcontext"]
         */
        context: "helloworldcontext"
      }
    ]
  }
};

1 Like

Actually the command context property has been deprecated. I have fixed the docs. Can you try it with the plugin-level contexts property? https://docs.lipsurf.com/api-reference/plugin.html#contexts-2

It works! Perfect!
The commands with normal: false now shows up!

1 Like