Initial Commit
This commit is contained in:
parent
950050ea38
commit
eb02c6f3bd
13 changed files with 718 additions and 0 deletions
80
experiment/DomContentScript/implementation.js
Normal file
80
experiment/DomContentScript/implementation.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
|
||||
|
||||
var { AppConstants } = ChromeUtils.importESModule("resource://gre/modules/AppConstants.sys.mjs");
|
||||
var DomContent_ESM = parseInt(AppConstants.MOZ_APP_VERSION, 10) >= 128;
|
||||
|
||||
var { ExtensionCommon } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/ExtensionCommon.sys.mjs"
|
||||
);
|
||||
|
||||
var { ExtensionUtils } = DomContent_ESM
|
||||
? ChromeUtils.importESModule("resource://gre/modules/ExtensionUtils.sys.mjs")
|
||||
: ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
|
||||
|
||||
var { ExtensionError } = ExtensionUtils;
|
||||
|
||||
var registeredWindows = new Map();
|
||||
|
||||
var DomContentScript = class extends ExtensionCommon.ExtensionAPI {
|
||||
constructor(extension) {
|
||||
super(extension);
|
||||
|
||||
this._windowListener = {
|
||||
// nsIWindowMediatorListener functions
|
||||
onOpenWindow(appWindow) {
|
||||
// A new window has opened.
|
||||
let domWindow = appWindow.docShell.domWindow;
|
||||
|
||||
/**
|
||||
* Set up listeners to run the callbacks on the given window.
|
||||
*
|
||||
* @param aWindow {nsIDOMWindow} The window to set up.
|
||||
* @param aID {String} Optional. ID of the new caller that has registered right now.
|
||||
*/
|
||||
domWindow.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
function() {
|
||||
// do stuff
|
||||
let windowChromeURL = domWindow.document.location.href;
|
||||
if (registeredWindows.has(windowChromeURL)) {
|
||||
let jsPath = registeredWindows.get(windowChromeURL);
|
||||
Services.scriptloader.loadSubScript(jsPath, domWindow, "UTF-8");
|
||||
}
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
},
|
||||
|
||||
onCloseWindow(appWindow) {
|
||||
// One of the windows has closed.
|
||||
let domWindow = appWindow.docShell.domWindow; // we don't need to do anything (script only loads once)
|
||||
},
|
||||
};
|
||||
|
||||
Services.wm.addListener(this._windowListener);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
onShutdown(isAppShutdown) {
|
||||
if (isAppShutdown) {
|
||||
return; // the application gets unloaded anyway
|
||||
}
|
||||
Services.wm.removeListener(this._windowListener);
|
||||
}
|
||||
|
||||
getAPI(context) {
|
||||
/** API IMPLEMENTATION **/
|
||||
return {
|
||||
DomContentScript: {
|
||||
// only returns something, if a user pref value is set
|
||||
registerWindow: async function (windowUrl,jsPath) {
|
||||
registeredWindows.set(windowUrl,jsPath);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
25
experiment/DomContentScript/schema.json
Normal file
25
experiment/DomContentScript/schema.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
[
|
||||
{
|
||||
"namespace": "DomContentScript",
|
||||
"functions": [
|
||||
{
|
||||
"name": "registerWindow",
|
||||
"type": "function",
|
||||
"async": true,
|
||||
"description": "Register a script for onDOMContentLoaded",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "windowUrl",
|
||||
"type": "string",
|
||||
"description": "chrome URL of the window "
|
||||
},
|
||||
{
|
||||
"name": "jsPath",
|
||||
"type": "string",
|
||||
"description": "chrome URL of the script"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
89
experiment/api.js
Normal file
89
experiment/api.js
Normal file
|
@ -0,0 +1,89 @@
|
|||
var { ExtensionCommon } = ChromeUtils.importESModule("resource://gre/modules/ExtensionCommon.sys.mjs");
|
||||
var { Services } = globalThis || ChromeUtils.importESModule("resource://gre/modules/Services.sys.mjs");
|
||||
var { MailServices } = ChromeUtils.importESModule("resource:///modules/MailServices.sys.mjs");
|
||||
|
||||
console.log("[ai-filter][api] Experiment API module loaded");
|
||||
|
||||
var resProto = Cc["@mozilla.org/network/protocol;1?name=resource"]
|
||||
.getService(Ci.nsISubstitutingProtocolHandler);
|
||||
|
||||
function registerResourceUrl(extension, namespace) {
|
||||
console.log(`[ai-filter][api] registerResourceUrl called for namespace="${namespace}"`);
|
||||
if (resProto.hasSubstitution(namespace)) {
|
||||
console.log(`[ai-filter][api] namespace="${namespace}" already registered, skipping`);
|
||||
return;
|
||||
}
|
||||
let uri = Services.io.newURI(".", null, extension.rootURI);
|
||||
console.log(`[ai-filter][api] setting substitution for "${namespace}" → ${uri.spec}`);
|
||||
resProto.setSubstitutionWithFlags(namespace, uri, resProto.ALLOW_CONTENT_ACCESS);
|
||||
}
|
||||
|
||||
var gTerm;
|
||||
var AIFilterMod;
|
||||
|
||||
var aiFilter = class extends ExtensionCommon.ExtensionAPI {
|
||||
async onStartup() {
|
||||
console.log("[ai-filter][api] onStartup()");
|
||||
let { extension } = this;
|
||||
|
||||
registerResourceUrl(extension, "aifilter");
|
||||
|
||||
|
||||
try {
|
||||
console.log("[ai-filter][api] importing ExpressionSearchFilter.jsm");
|
||||
AIFilterMod = ChromeUtils.import("resource://aifilter/modules/ExpressionSearchFilter.jsm");
|
||||
console.log("[ai-filter][api] ExpressionSearchFilter.jsm import succeeded");
|
||||
}
|
||||
catch (err) {
|
||||
console.error("[ai-filter][api] failed to import ExpressionSearchFilter.jsm:", err);
|
||||
}
|
||||
}
|
||||
|
||||
onShutdown(isAppShutdown) {
|
||||
console.log("[ai-filter][api] onShutdown(), isAppShutdown =", isAppShutdown);
|
||||
if (!isAppShutdown && resProto.hasSubstitution("aifilter")) {
|
||||
console.log("[ai-filter][api] removing substitution for namespace='aifilter'");
|
||||
resProto.setSubstitution("aifilter", null);
|
||||
}
|
||||
}
|
||||
|
||||
getAPI(context) {
|
||||
console.log("[ai-filter][api] getAPI()");
|
||||
return {
|
||||
aiFilter: {
|
||||
initConfig: async (config) => {
|
||||
try {
|
||||
if (AIFilterMod?.AIFilter?.setConfig) {
|
||||
AIFilterMod.AIFilter.setConfig(config);
|
||||
console.log("[ai-filter][api] configuration applied", config);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("[ai-filter][api] failed to apply config:", err);
|
||||
}
|
||||
},
|
||||
classify: (msg) => {
|
||||
console.log("[ai-filter][api] classify() called with msg:", msg);
|
||||
try {
|
||||
if (!gTerm) {
|
||||
console.log("[ai-filter][api] instantiating new ClassificationTerm");
|
||||
let mod = AIFilterMod || ChromeUtils.import("resource://aifilter/modules/ExpressionSearchFilter.jsm");
|
||||
gTerm = new mod.ClassificationTerm();
|
||||
}
|
||||
console.log("[ai-filter][api] calling gTerm.match()");
|
||||
let matchResult = gTerm.match(
|
||||
msg.msgHdr,
|
||||
msg.value,
|
||||
Ci.nsMsgSearchOp.Contains
|
||||
);
|
||||
console.log("[ai-filter][api] gTerm.match() returned:", matchResult);
|
||||
return matchResult;
|
||||
}
|
||||
catch (err) {
|
||||
console.error("[ai-filter][api] error in classify():", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
25
experiment/schema.json
Normal file
25
experiment/schema.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
[
|
||||
{
|
||||
"namespace": "aiFilter",
|
||||
"functions": [
|
||||
{
|
||||
"name": "initConfig",
|
||||
"type": "function",
|
||||
"async": true,
|
||||
"parameters": [
|
||||
{ "name": "config", "type": "any" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "classify",
|
||||
"type": "function",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "msg",
|
||||
"type": "any"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
Loading…
Add table
Add a link
Reference in a new issue