quicktext icon indicating copy to clipboard operation
quicktext copied to clipboard

Quicktext v6 (Milesteone 2): Modified script support

Open jobisoft opened this issue 8 months ago • 85 comments

Quicktext v6 has reached its second milestone in being converted to the WebExtension technology. The ultimate goals of this effort are described in the announcement for the first milestone. Everything mentioned there is still important, so if you have not read that, please do so soon.

One major change in v6 is the new script engine. Quicktext v5 executed scripts with system privileges and just like Quicktext itself, scripts had full access to the user's computer and could do everything. This is no longer the case for Quicktext v6.

TL;DR - What changed?

The following properties have been moved:

  • this.mVariables -> this.quicktext.variables
  • this.mQuicktext.get_<tag>([...]) -> await this.quicktext.getTag("<tag>", ...)

Example:

let rcpt = await this.quicktext.getTag('to', 'lastname');`

The following property has been removed:

  • this.mWindow

Quicktext scripts now run with reduced privileges and can no longer use core functions of the compose window, or access its DOM elements. Most things formaly done via this.mWindow.* can still be achieved via this.compose.* (internal scripts) or via messenger.compose.* (external scripts).

Internal scripts

These scripts are how we used to define scripts in the "Scripts" tab of the Quicktext Manager UI. Internal scripts run with minimal privileges, but Quicktext exposes a subset of the official WebExtension APIs:

The methods of this.compose.* differ from the methods of the official compose API: The first tabId parameter must not be specified, as the methods available to internal scripts will always act on the current compose window.

Note: The WebExtension APIs are used by add-on developers, are well documented and aim to be stable. That means scripts will not break anymore when a new version of Thunderbird is released.

To see everything that is available to internal scripts, use the following script and check the result printed to the error comsole:

console.log(this)

Currently, this will return something like the following:

Example

The AddRecipients community script now has to look like this:

  let type = this.quicktext.variables[0];
  let adresses = this.quicktext.variables[1].split(';');

  if (!type || !["to", "cc", "bcc", "reply-to"].includes(type)) {
    return;
  }

  if (type == "reply-to") {
    type = "replyTo";
  }

  let details = await this.compose.getComposeDetails();
  let recipients = new Set([...details[type], ...adresses].map(e => e.trim()));
  await this.compose.setComposeDetails({
    [type]: Array.from(recipients)
  });

Scripts no longer manipulate the compose fields directly, but can use getComposeDetails() to pull information from the composer and setComposeDetails() to update properties of the composer.

External scripts

There will be cases, where the API methods available to internal scripts will be insufficient. Furthermore, there might even be cases where scripts still need to do everything. Both scenarios can be solved by external scripts.

An external script is shipped in a separate add-on. Since it can be executed natively, it can use all WebExtension APIs. For advanced use-cases, such an external script add-on can even include an Experiment and have full access to the user's system again.

We created the Quicktext Community Scripts Add-on which provides most of the former community scripts. This does not only serve as a blueprint for custom script add-ons, but is intended to provide script support for the most common use-cases. Instead of manually maintaining scripts, users can install the Community Script Add-on.

If the Quicktext Community Script Add-on is installed, any of its stored scripts can be used in Quicktext via the CSCRIPT tag. Its first parameter is the name of the requested script, followed by variables passed into the script. The tag to execute its AddRecipients script has to look as follows:

[[CSCRIPT=AddRecipients|to|[email protected]]]

In order to execute scripts of a custom script add-on, Quicktext needs to know the add-on's id. This is accomplished through the ESCRIPT tag. Since the id of the Community Script Add-on is [email protected], its AddRecipients script can also be executed via:

[[[email protected]|AddRecipients|to|[email protected]]]

The first parameter is the id of the script add-on, the second parameter is the name of the requested script, followed by variables passed into the script.

Need more help?

The converted community scripts shipped with the Quicktext Community Scripts Add-on should give you an idea how to convert your scripts.

jobisoft avatar Apr 08 '25 07:04 jobisoft

Stupid question, but : _To see what is available for you, execute the following script:

console.log(this)_

How can I execute this script ?

I have the impression that I have to make the transition slowly, otherwise things will go wrong at all.

weksupport avatar Apr 10 '25 08:04 weksupport

Stupid question, but : _To see what is available for you, execute the following script:

console.log(this)_

How can I execute this script ?

I have the impression that I have to make the transition slowly, otherwise things will go wrong at all.

Not a stupid question. You create a new script called for example test with only console.log(this) in it, and then you include that script in a new or existing template via the script tag. The script is then executed, when you include the template in a message.

jobisoft avatar Apr 10 '25 08:04 jobisoft

I believe the question of the OP was: Where can I type the command? There must be a window, a prompt, some place to do so. I wouldn't know, either. Although I'm not quite a novice user I hope all of this and the previous post isn't relevant for me, I believe I couldn't do all this conversion stuff. In my Quicktext settings window, I have only templates on the second tab. On the first tab I think there is nothing relevant (just top left two boxes checked) and on the third tab I don't have scripts. My text templates will be retained without any need for me to do anything - right?

j-schneid avatar Apr 17 '25 20:04 j-schneid

My text templates will be retained without any need for me to do anything - right?

Correct. This is only relevant if you have scripts.

Here is a screenshot of the command saved as a script:

Image

jobisoft avatar Apr 17 '25 22:04 jobisoft

I would be interested in feedback from those, who were able to convert their scripts, or who are struggling. I currently have no information at all.

Thanks!

jobisoft avatar Apr 18 '25 07:04 jobisoft

Image

Image

When I 'run' ConsoleLog2 : Image

I don't know what is wrong.

We are now in a beta situation. Is it perhaps an idea to describe a procedure for the 'normal' user later on how to switch. I read about exporting first otherwise you will lose everything. Or will a silent transition be possible later on?

weksupport avatar Apr 18 '25 08:04 weksupport

Uh, that is unexpected. It should work like that. What version of TB, what version of Quicktext?

jobisoft avatar Apr 18 '25 15:04 jobisoft

Ah, you tried to execute console.log(this) in Quicktext v5. That does not work. This entire issue is about Quicktext v6, and how to convert the scripts from v5 to v6. None of what is written here applies to v5.

FYI: To see the console entries, open it via the Hamburger Menu -> Tools -> Developer Tools or Press CTRL+SHIFT+J in Thunderbirds main window

jobisoft avatar Apr 18 '25 16:04 jobisoft

We are now in a beta situation. Is it perhaps an idea to describe a procedure for the 'normal' user later on how to switch. I read about exporting first otherwise you will lose everything. Or will a silent transition be possible later on?

The storage system changes. Quicktext v5 stored its config files directly on your hard disc, while Quicktext v6 stores them in a dedicates add-on storage. I do not delete the data from your local disc. So if you switch from v5 to v6 and decide to go back to v5, everything will be exactly as before you switched from v5 to v6.

Quicktext v6 will read the old v5 config data and convert it as needed and store it in the dedicated add-on storage. If you uninstall Quicktext v6, the data in the dedicated add-on storage will be deleted as well. So once you are beyond "trying it out", and actually converted your scripts to work with v6, you should export them before uninstalling v6.

Everyone using scripts should convert their scripts now. If I push v6 to everyone, old scripts will stop working, and you will be left with a broken workflow. There will be at least one more "milestone" message for milestone 3. I think I might suppress further notifications for users who do not have scripts, to not confuse them.

jobisoft avatar Apr 18 '25 16:04 jobisoft

Oke.. I dragged 6.3.* to Thunderbird 128.9.2esr and installed the newest version. When I do some commands, the <BR> comes in my email, where it was HTML - a new line. Of is the newest version not for 128.9.2esr ?

weksupport avatar Apr 19 '25 08:04 weksupport

Oke.. I dragged 6.3.* to Thunderbird 128.9.2esr and installed the newest version. When I do some commands, the comes in my email, where it was HTML - a new line. Of is the newest version not for 128.9.2esr ?

Can you append a screenshot so I can see what you mean? If you primary language is German, you could also write in German.

jobisoft avatar Apr 19 '25 08:04 jobisoft

I am Dutch and not good at languages, I try my best, but German is not a good alternative.

What I mean, when typing a shortcut, I always got:

Greetings,

Werner

and now I get

Image

so then quickly back to 5.20 and it worked fine again. However, after a restart of TB the shortcuts no longer work. Yes through the menus but not through the shortcuts.

(Google Vertaal)

weksupport avatar Apr 19 '25 12:04 weksupport

However, after a restart of TB the shortcuts no longer work. Yes through the menus but not through the shortcuts.

Euhh. Sorry..... default was Tab for activating a keyword, I used ENTER, so changing TAB in ENTER, it works fine (v5)

weksupport avatar Apr 19 '25 13:04 weksupport

Can you please provide a screenshot of the actual template? This part:

Image

jobisoft avatar Apr 19 '25 16:04 jobisoft

Image

thus you'll see the HTML instead of the result <br> etc.

and I tested some other :

Image

It was this code, I assume : [[SCRIPT=Identity|setIdentity|id41]]

weksupport avatar Apr 19 '25 19:04 weksupport

@weksupport : I created a dedicated issue for your newline issue. Let's discuss it there: https://github.com/jobisoft/quicktext/issues/456

I already asked follow-up questions in that issue.

Your second report is indeed about a script, that needs to be converted. Can you post the full script here?

jobisoft avatar Apr 20 '25 09:04 jobisoft

Template [[SCRIPT=Identity|setIdentity|id41]]

Script

let action      = this.mVariables[0];
let setIdentity = this.mVariables[1];


if(action == "getAllIdentities") {
  let identityList = this.mWindow.document.getElementById("msgIdentity");
  let identities   = identityList.getElementsByAttribute("identitykey", "*");
  let result       = "";

  for(let identity of identities) {
    result += identity.getAttribute("identitykey") + " - " + identity.getAttribute("label") + "\r\n";
  }
  return result;
}

if(action == "getCurrentIdentity") {
  let identityList = this.mWindow.document.getElementById("msgIdentity");
  let identities   = identityList.getElementsByAttribute("identitykey", "*");
  let result       = "";

  for(let identity of identities) {
    if(identity.getAttribute("selected") != "true") continue;
    result += identity.getAttribute("identitykey") + " - " + identity.getAttribute("label") + "\r\n";
  }
  return result;

}

if(action == "setIdentity") {
  // Since switching the signature loses the caret position, we record it
  // and restore it later.
  let selection = this.mWindow.gMsgCompose.editor.selection;
  let range = selection.getRangeAt(0);
  let start = range.startOffset;
  let startNode = range.startContainer;

  this.mWindow.gMsgCompose.editor.enableUndo(false);

  let identityList = this.mWindow.document.getElementById("msgIdentity");
  identityList.selectedItem = identityList.getElementsByAttribute("identitykey", setIdentity)[0];
  this.mWindow.LoadIdentity(false);

  this.mWindow.gMsgCompose.editor.enableUndo(true);
  this.mWindow.gMsgCompose.editor.resetModificationCount();
  selection.collapse(startNode, start);
}
return "";

weksupport avatar Apr 20 '25 14:04 weksupport

Template [[SCRIPT=Identity|setIdentity|id41]]

Script

let action      = this.mVariables[0];
let setIdentity = this.mVariables[1];


...

That is the community identity script. As I wrote earlier, I converted all community scripts already. You have two options.

1. Use the Community Script Add-on

  • install the community script add-on: https://github.com/jobisoft/quicktext/releases/download/v6.3.4/quicktext-community-scripts_1_1.xpi (linked in the assets section from the release page)
  • replace your SCRIPT tag line by [[CSCRIPT=Identity|setIdentity|id41]] (the CSCRIPT tag will pull the script from the community script add-on)
  • Delete your old copy of the script from the Quicktext manager

2. Update your own copy of the script

  • The wiki community scripts page has not yet been updated, and the converted scripts only exist in the community script add-on.
  • Download the add-on and unpack it (it is a zip file)
  • Open the file scripts.mjs
  • Search for the Identity function and copy its content and replace your old scripts with the copied content.

jobisoft avatar Apr 20 '25 21:04 jobisoft

@weksupport : Were you able to get the converted script running?

jobisoft avatar Apr 21 '25 11:04 jobisoft

Sorry for my delayed response, work continues and testing with something that doesn't really work yet, means that I'm sticking with the old in most places.

Today I installed Thunderbird Portable in one place, version 138.0 with add-on QuickText Community Scripts and Quicktext 6.3.4

I'm still searching a bit, probably I wanted to combine a few things. If I start with CSCRIPT now, it seems to work (the first tests done).

I've also tried cutting and pasting certain scripts and calling them via ESCRIPT, but that hasn't worked yet.

weksupport avatar Apr 30 '25 13:04 weksupport

I am trying out the new version 6.3.4 and I am having trouble. I copied the code of the CleanSubject.mjs community script into a new script called "Clean Subject" . I then created a template with [[SCRIPT=Clean Subject]] in the body of the template. I tried the template in a new email with the subject "Re: test" I am getting the following error: [Clean Subject] There was an error in your Quicktext script: Error: export declarations may only appear at top level of a module

bakejerry avatar May 20 '25 19:05 bakejerry

You only need to include/copy what is inside the function definition.

jobisoft avatar May 20 '25 20:05 jobisoft

I just manually installed 6.3.4 from the xpi since version 5 didn't run anymore on current TB 139.0 (May, 28th 2025). For me version 6 works totally fine, and I am so happy that there is a working version for current TB, but two things:

  • If I insert "Text" - let's say Hallo - then right behind my own text there is always a tailing blank added that simply isn't there in my quicktext template.
  • If I insert "HTML" that contains markup - let's say <div>Hallo</div> - then not only a tailing blank is added, but a carriage return and in the new line a blank.

I don't remember version 5 behaving this way, so I guess these unwanted additional blanks and new lines are a problem of version 6 that you will want to fix.

Greetings and thanks for your really great work! -doffine

doffine avatar May 28 '25 11:05 doffine

I don't remember version 5 behaving this way, so I guess these unwanted additional blanks and new lines are a problem of version 6 that you will want to fix.

Version 5.21 does ! Version 5.20 doesn't.

weksupport avatar May 28 '25 12:05 weksupport

@jobisoft Any way you could include a converted template for the old TemplatebyType script? I find myself using that the most, but cannot figure out what I am doing wrong with v6. Thanks for all the work you've put into this project.

obsolete-al avatar Jun 06 '25 19:06 obsolete-al

In v6.3.5 the function 'Export template' will not produce an export file.

seppduschinger avatar Jun 14 '25 10:06 seppduschinger

After i had changed the function 'writeFileToDisc' in utils.mjs the file will be produced,

export async function writeFileToDisc(data, filename) { const blob = new Blob([data], { type: "application/json" }); const url = URL.createObjectURL(blob);

try {
    function handleChanged(delta) {
        if (delta.state && delta.state.current === "complete") {
            console.log(`Download ${delta.id} has completed.`);
            URL.revokeObjectURL(url);
        }
    }
    browser.downloads.onChanged.addListener(handleChanged);
    await browser.downloads.download({
        url: url,
        filename: filename,
        saveAs: true,
    });
} catch (error) {
    console.error("Error downloading the file:", error);
    const url = URL.createObjectURL(blob);
}

}

seppduschinger avatar Jun 14 '25 10:06 seppduschinger

The Thunderbird 140 ESR is available!🥳

Maybe we have a compatible/Stable Quicktext Version 6 or so too this Week when the new ESR is available on all Sources. Than can this maybe implemented in the Plugin itself for all Plugin User.

Revan335 avatar Jul 02 '25 20:07 Revan335

I use Thunderbird in version 140.1 64Bit, Quicktext in version 6.3.11.1. When I try to execute the new version of the "ToNickname.mjs" script, I get the error message "[ToNickname] An error has occurred in your Quicktext script: Error. export declarations may only appear at top level of a module"

Although I have used the version from the “quicktext-community-scripts.xpi”

2. Update your own copy of the script

  • The wiki community scripts page has not yet been updated, and the converted scripts only exist in the community script add-on.
  • Download the add-on and unpack it (it is a zip file)
  • Open the file scripts.mjs
  • Search for the Identity function and copy its content and replace your old scripts with the copied content.

M3NSC4 avatar Jul 22 '25 19:07 M3NSC4

I use Thunderbird in version 140.1 64Bit, Quicktext in version 6.3.11.1. When I try to execute the new version of the "ToNickname.mjs" script, I get the error message "[ToNickname] An error has occurred in your Quicktext script: Error. export declarations may only appear at top level of a module"

Although I have used the version from the “quicktext-community-scripts.xpi”

2. Update your own copy of the script

  • The wiki community scripts page has not yet been updated, and the converted scripts only exist in the community script add-on.
  • Download the add-on and unpack it (it is a zip file)
  • Open the file scripts.mjs
  • Search for the Identity function and copy its content and replace your old scripts with the copied content.

https://github.com/jobisoft/quicktext/issues/451#issuecomment-2895715652

bakejerry avatar Jul 22 '25 19:07 bakejerry