1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
/**
* Replacements for Components.manager.addBootstrappedManifestLocation and
* Components.manager.removeBootstrappedManifestLocation, which have been nixed
* in mozilla142. Copyright 2025 Tobias Girstmair <https://gir.st/>, MPLv2.
*/
const ZipReader = Components.Constructor(
"@mozilla.org/libjar/zip-reader;1",
"nsIZipReader",
"open"
);
const ScriptableInputStream = Components.Constructor(
"@mozilla.org/scriptableinputstream;1",
"nsIScriptableInputStream",
"init"
);
const FileOutputStream = Components.Constructor(
"@mozilla.org/network/file-output-stream;1",
"nsIFileOutputStream",
"init"
);
export class LegacyFoxUtils {
static addBootstrappedManifestLocation(file, addon, uriMaker) {
// read chrome.manifest from .jar (or unpacked addon)
let zipReader = new ZipReader(file);
let istream = new ScriptableInputStream(zipReader.getInputStream("chrome.manifest"));
let manifestContents = istream.read(zipReader.getEntry("chrome.manifest").realSize);
// replace chrome:// and resource:// URIs with absolute paths to JAR
manifestContents = manifestContents
.split("\n")
.map(absolutizePaths.bind(null, uriMaker, file))
.join("\n");
// we store the temporary file in the user's profile, in a subdirectory
// analogous to webExtension's "browser-extension-data".
let manifest = Services.dirsvc.get('ProfD', Ci.nsIFile)
manifest.append('legacy-extension-data');
manifest.append(addon.id);
manifest.exists() || manifest.create(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
manifest.append('chrome.manifest'); /* created or truncated by ostream */
// write modified chrome.manifest to profile directory
let ostream = new FileOutputStream(manifest, -1, -1, 0);
ostream.write(manifestContents, manifestContents.length);
ostream.close();
// let Firefox read and parse it
Components.manager.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(manifest);
}
static removeBootstrappedManifestLocation(addon) {
let manifestDir = Services.dirsvc.get('ProfD', Ci.nsIFile)
manifestDir.append('legacy-extension-data');
manifestDir.append(addon.id);
manifestDir.exists() && manifestDir.remove(/*recursive=*/true);
Cc['@mozilla.org/chrome/chrome-registry;1']
.getService(Ci.nsIXULChromeRegistry).checkForNewChrome();
}
}
function absolutizePaths(uriMaker, file, line) {
const manifestMethodPathLocation = {
content: 2, // content packagename uri/to/files/ [flags]
locale: 3, // locale packagename localename uri/to/files/ [flags]
skin: 3, // skin packagename skinname uri/to/files/ [flags]
resource: 2 // resource aliasname uri/to/files/ [flags]
};
let words = line.trim().split(/\s+/);
const index = manifestMethodPathLocation[words[0]];
if (index) {
words[index] = uriMaker(file, words[index]).spec;
line = words.join(" ");
}
return line;
}
|