How to trigger plugin automatically on document load?

How can i trigger “Start” function automatically on document load?? and the manual button should also be available… is there way to seperate if its automatically triggered or manually triggered??

Hello @anand.mainali

If you want to leave the plugin available in the Plugins tab, i.e. without using isSystem, then you should use onDocumentContentReady event and wrap your code in it.

@Constantine i’ve tried this:

  window.Asc.plugin.init = function () {
    main("manuallyClicked");
  };

  window.Asc.plugin.button = function () {
    this.executeCommand("close", "");
  };

Asc.plugin.attachEvent("onDocumentContentReady", () => {
  main("automaticallyTriggered");
});

but its working when i add below code in config but its triggering both init & onDocumentContentReady:

"plugins": {
     "autostart": [
          "asc.{0616AE85-5DBE-4B6B-A0A9-4555555555}"
      ]
}

I wanted to seperate the event if its manually clicked or automatically triggered.

plugins.autostart simply runs the main functionality of the plugin once editor is ready.

This sample does not invoke the event, it is incorrect usage. Here is an example for the reference:

window.Asc.plugin.event_onDocumentContentReady = function() {
    var oProperties = {
        "searchString"  : "ONLYOFFICE",
        "replaceString" : "ONLYOFFICE is cool",
        "matchCase"     : false
    };

    window.Asc.plugin.executeMethod("SearchAndReplace", [oProperties], function() {
            window.Asc.plugin.executeCommand("close", "");
    });
};

@Constantine i’ve tried the above solution but still its not working… its triggered when start button is clicked… i’ve added the event on config as well.

{
    "name"       : "Add",
    "guid"       : "asc.{0616AE85-5DBE-4B6B-A0A9-555C4FZZZZZZ}",
    "baseUrl"    : "",
    "variations" : [
        {
            "description"         : "Add",
            "url"                 : "index.html",
            "icons"               : ["resources/img/icon.png"],
            "isViewer"            : false,
            "EditorsSupport"      : ["word"],
            "isVisual"            : false,
            "isModal"             : false,
            "isInsideMode"        : false,
            "initDataType"        : "none",
            "initData": "",
            "isUpdateOleOnResize" : true,
            "size"                : [ 400, 120 ],
            "buttons"             : [],
            "events" : ["onDocumentContentReady"]
        }
}

Can you share function that is used for Start button of your plugin for better understanding of your design?

Here’s my code for the plugin:

(function (window, undefined) {
  // Wrap the async check in a function
  function checkContentControls() {
    return new Promise((resolve, reject) => {
      window.Asc.plugin.executeMethod(
        "GetAllContentControls",
        [],
        (controls) => {
          if (controls.length > 0) {
            let remaining = controls.length;
            controls.forEach((control) => {
              window.Asc.plugin.executeMethod(
                "RemoveContentControls",
                [[{ InternalId: control.InternalId }]],
                () => {
                  remaining--;
                  if (remaining === 0) {
                    resolve(true);
                  }
                }
              );
            });
          } else {
            resolve(true);
          }
        }
      );
    });
  }

  function cleanHtmlContent(html) {
    // Remove classes and other unwanted attributes
    return html.replace(/class="[a-zA-Z0-9-:;+"\/=]*"/g, "");
  }

  async function main(manuallyClicked) {
    const shouldProceed = await checkContentControls();
    if (!shouldProceed) {
      console.log("Exiting due to existing content controls.");
      window.Asc.plugin.executeCommand("close", "");
      return; // Exit the function
    }

    const urlObj = new URL(document.referrer);

    const parentOrigin = urlObj.searchParams.get("parentOrigin");

    var controlData = Asc.plugin.info.options;
    var documentVersion = controlData.documentVersion;
    var templateId = controlData.templateId;

    const apiUrl = `${parentOrigin}/api/editor/${templateId}/getData`;

    // Prepare the form data
    const formData = new FormData();

    var currentLang = window.Asc.plugin.info.lang;

    var shortLang = currentLang.split("-")[0];

    formData.append("lang", shortLang);
    formData.append("automated_document_control", manuallyClicked);
    formData.append("version", documentVersion);

    const response = await fetch(apiUrl, {
      method: "POST",
      body: formData,
    });

    if (!response.ok) {
      console.error("Error fetching data:", response.statusText);
      window.Asc.plugin.executeCommand("close", "");
      return;
    }

    const data = await response.json();
    let text = cleanHtmlContent(data.htmlContent);

    // Add required HTML structure
    const temp = text.indexOf("<p") === -1 ? "\r\n" : "";
    if (text !== "") text = `<html><body>${temp}${text}</body></html>`;
    window.Asc.plugin.executeMethod("MoveCursorToStart", [], () => {
      window.Asc.plugin.executeMethod("AddContentControl", [
        1,
        { Id: 1, Tag: "documentVersions", Lock: 3 },
      ]); // Adds unlocked content control
      window.Asc.plugin.executeMethod("PasteHtml", [text]); // Pastes HTML

      window.Asc.plugin.onMethodReturn = function () {
        // Once previous PasteHtml method has finished, sets up a lock on inserted content control
        if (window.Asc.plugin.info.methodName == "PasteHtml") {
          window.Asc.plugin.callCommand(function () {
            var oDocument = Api.GetDocument();
            var aContentControls =
              oDocument.GetContentControlsByTag("documentVersions");
            aContentControls[0].SetLock("sdtContentLocked"); // Full lock
            window.Asc.plugin.executeCommand("close", "");
          });
        }
        window.Asc.plugin.executeCommand("close", "");
      };
    });
  }

  window.Asc.plugin.init = function () {
    main(true);
  };

  window.Asc.plugin.event_onDocumentContentReady = function () {
    //      main(false);
    console.log("document ready");
  };

  window.Asc.plugin.button = function () {
    this.executeCommand("close", "");
  };
})(window, undefined);

In your example init is separated from event. No wonder that init is not called automatically when document content is ready.

Since init, as stated in the documentation, is called when plugin launched, then in your case you are indeed calling init manually, as the event stays out of scope.

You should try defining the event inside the init, for instance, like that:

window.Asc.plugin.init = function () {
  window.Asc.plugin.event_onDocumentContentReady = function () {
    var oProperties = {
      "searchString": "ONLYOFFICE",
      "replaceString": "ONLYOFFICE is cool",
      "matchCase": false
    };

    window.Asc.plugin.executeMethod("SearchAndReplace", [oProperties], function () {
      window.Asc.plugin.executeCommand("close", "");
    });
  };
};

This is just an example.

That way, once event is triggered by, generally, loading document content, your plugin will call init function automatically.

@Constantine

Also, is there any example to search the text [Logo] and replace it with image and align it center of the document??

But i want to execute the function after the editor is loaded & also when manually clicked in plugin. With your solution it’ll only trigger the event_onDocumentContentReady when start button is clicked.

I understand. The point is, sorry if I wasn’t clear, that with autostart and onDocumentContentReady event you can achieve this. Think of it as plugin waits for the command to automatically run the plugin, but to make it run after the document is loaded you need to wrap your init function into the event listener so that when editor initializes and even triggers the function is getting executed.

For instance, with all above mentioned:

  1. Set up correctly init function;
  2. Wrap main code of init into onDocumentContentReady;
  3. Define autostart of your plugin.

That way it will run automatically once document is loaded. Honestly, onDocumentContentReady event may not be necessary, it just specified at which step to execute plugin functionality. You still can run plugin commands via buttons after that.

@Constantine thank you for the quick reply. but i want to also distinguish the event if its automatically triggered or manually clicked by user…

Not quite following the concept of such decision, but considering that autostart is the only option here, you need decide how to handle plugin pre-initialization of the editor.

You need to somehow add up a criteria or check in your storage application under which editor will be launched with autostart or without it. This is purely your task, not much I can help you with from plugin perspective. Basically, buttons will be always available for your plugin, unless you make it system or hidden, but to autostart it or not can be handled only from initialization config.

Hi @Constantine ,

Is there any way to send status back to editor so i can check if “SearchAndReplace” is completed or not??
I want to show custom loader in reactjs until the “SearchAndReplace” is completed in docx.

Please start a new topic on this query as it does not belong to the initial topic about plugin autostart. We will review it separately to avoid mixing up topics. Thank you.