Initial working state
This commit is contained in:
commit
cbdd1e3231
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*.xpi
|
||||||
|
*.zip
|
17
Makefile
Normal file
17
Makefile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# Build extension package
|
||||||
|
#
|
||||||
|
VERSION = 2.0
|
||||||
|
SOURCES = manifest.json data/* icons/*
|
||||||
|
PACKAGE = ../emptyem-$(VERSION).xpi
|
||||||
|
EXCLUDES = Makefile README.md *.DS_Store
|
||||||
|
|
||||||
|
build: $(PACKAGE)
|
||||||
|
@echo "Done"
|
||||||
|
|
||||||
|
$(PACKAGE): $(SOURCES)
|
||||||
|
zip -r -FS $(PACKAGE) * -x $(EXCLUDES)
|
||||||
|
@echo "Built $(PACKAGE)"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm $(PACKAGE)
|
25
README.md
Normal file
25
README.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# Empty 'em
|
||||||
|
|
||||||
|
This is a simple Thunderbird extension that empties all _Junk_ and _Trash_
|
||||||
|
folders. The extension provides a menu item (`Tools` -> `Empty 'em`) and a
|
||||||
|
toolbar button to do so.
|
||||||
|
|
||||||
|
## Background
|
||||||
|
|
||||||
|
In Thunderbird, I usually have around half-a-dozen email accounts set up. Most
|
||||||
|
of them [Gmail](http://gmail.com) accounts. Very often, Gmail's Junk filter
|
||||||
|
catches tons of Junk email and populates the _Junk_ folders in Thunderbird.
|
||||||
|
After manually cleaning up the _Inbox_ folders and deleting unwanted email, the
|
||||||
|
_Trash_ folders are also populated.
|
||||||
|
|
||||||
|
Manually going through all the _Junk_ and _Trash_ folders to empty them, is
|
||||||
|
tedious.
|
||||||
|
|
||||||
|
That is what prompted me to write this extension. I hope someone out there
|
||||||
|
finds it helpful too.
|
||||||
|
|
||||||
|
# References
|
||||||
|
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Thunderbird_extensions
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Thunderbird_extensions/Demo_Addon
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Thunderbird_extensions/Building_a_Thunderbird_extension
|
21
RESEARCH.md
Normal file
21
RESEARCH.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# About New WebExtensions API
|
||||||
|
|
||||||
|
## IRC: inforation from #maildev
|
||||||
|
|
||||||
|
11:21:30 : moz_mma : In Thunderbird 64.0a1, using ChromeUtils.import() in webextension results in "ReferenceError: ChromeUtils is not defined" error. Any pointers?
|
||||||
|
12:00:15 : &Fallen : moz_mma: unless you are in an WebExtensions Experiment context, ChromeUtils and all the chrome code is not available
|
||||||
|
you need to make due with the APIs available, and create wrappers for APIs that are missing
|
||||||
|
12:04:25 : moz_mma : Fallen, how do I get in WebExtensions Experiment context?
|
||||||
|
12:04:45 : &Fallen : moz_mma: https://github.com/thundernest/tb-web-ext-experiments/ explains it mostly
|
||||||
|
for the cloudfile experiment, you would have access in e.g. https://github.com/thundernest/tb-web-ext-experiments/blob/master/cloudfile/cloudfile-api/api.js but not https://github.com/thundernest/tb-web-ext-experiments/blob/master/cloudfile/background/background.js
|
||||||
|
please be sure to read the intro to that repo so you know what the APIs should look like
|
||||||
|
12:07:30 : moz_mma : Thanks Fallen
|
||||||
|
12:14:03 : +aceman : Fallen: the ChromeUtils question above
|
||||||
|
|
||||||
|
## Demo add-on
|
||||||
|
|
||||||
|
https://developer.mozilla.org/en-US/docs/Mozilla/Thunderbird/Thunderbird_extensions/Demo_Addon
|
||||||
|
|
||||||
|
## Utils in comm-central mailnews/base
|
||||||
|
|
||||||
|
https://github.com/mozilla/releases-comm-central/tree/master/mailnews/base/util
|
17
data/actions.js
Normal file
17
data/actions.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Empty 'em actions
|
||||||
|
//
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Browser actions
|
||||||
|
function emptyEm() {
|
||||||
|
console.log("Empty-em: Emptying.. Start");
|
||||||
|
browser.folder_actions.emptyTrashFolders();
|
||||||
|
browser.folder_actions.emptyJunkFolders();
|
||||||
|
console.log("Empty-em: Emptying.. Done");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handlers
|
||||||
|
browser.browserAction.onClicked.addListener(emptyEm);
|
||||||
|
|
||||||
|
// vim: ts=2 sw=2 sts=2 et
|
13
data/jquery-ui.min.js
vendored
Normal file
13
data/jquery-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
data/jquery.min.js
vendored
Normal file
4
data/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
125
data/options.html
Normal file
125
data/options.html
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
.option-cont {
|
||||||
|
display: inline-box;
|
||||||
|
vertical-align: top;
|
||||||
|
padding-top: 1.2em;
|
||||||
|
padding-bottom: 1.2em;
|
||||||
|
border-bottom: thin solid #ddd;
|
||||||
|
}
|
||||||
|
.option-info {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
|
width: 400px;
|
||||||
|
}
|
||||||
|
.option-val {
|
||||||
|
display: inline-block;
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
.option-head {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: medium;
|
||||||
|
}
|
||||||
|
.option-desc {
|
||||||
|
font-size: small;
|
||||||
|
margin-top: 1.2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div style="width: 600px">
|
||||||
|
<label>
|
||||||
|
<div class="option-cont">
|
||||||
|
<div class="option-info">
|
||||||
|
<div class="option-head">Override folder's confirmation setting</div>
|
||||||
|
<div class="option-desc">
|
||||||
|
By default, Thunderbird will prompt you to confirm deletion of selected
|
||||||
|
folders. Check this box to override this and suppress the conform
|
||||||
|
dialog
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option-val">
|
||||||
|
<input type="checkbox" id="overrideDeleteConfirm" style="margin-bottom:1em"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<div class="option-cont">
|
||||||
|
<div class="option-info">
|
||||||
|
<div class="option-head">Include Trash folders</div>
|
||||||
|
<div class="option-desc">
|
||||||
|
Include Trash folders in the process of emptying
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option-val">
|
||||||
|
<input type="checkbox" id="selectTrashDelete" style="margin-bottom:1em"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<div class="option-cont">
|
||||||
|
<div class="option-info">
|
||||||
|
<div class="option-head">Include Junk folders</div>
|
||||||
|
<div class="option-desc">
|
||||||
|
Include Junk folders in the process of emptying
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option-val">
|
||||||
|
<input type="checkbox" id="selectJunkDelete" style="margin-bottom:1em"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<div class="option-cont">
|
||||||
|
<div class="option-info">
|
||||||
|
<div class="option-head">Enable console debug messages</div>
|
||||||
|
<div class="option-desc">
|
||||||
|
Check this box to enable debug messages in Error Console. Provide
|
||||||
|
these messages along with bug reports you file
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option-val">
|
||||||
|
<input type="checkbox" id="consoleDebug" style="margin-bottom:1em"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<div class="option-cont">
|
||||||
|
<div class="option-info">
|
||||||
|
<div class="option-head">Disable done notification</div>
|
||||||
|
<div class="option-desc">
|
||||||
|
Check this box to disable notification that appears after all
|
||||||
|
configured folders have been emptied
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option-val">
|
||||||
|
<input type="checkbox" id="disableDoneNotification" style="margin-bottom:1em"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<div class="option-cont">
|
||||||
|
<div class="option-info">
|
||||||
|
<div class="option-head">Also compact emptied folders</div>
|
||||||
|
<div class="option-desc">
|
||||||
|
Also compact the folder that was emptied
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option-val">
|
||||||
|
<input type="checkbox" id="alsoCompact" style="margin-bottom:1em"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="jquery.min.js"></script>
|
||||||
|
<script src="options.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
3
data/options.js
Normal file
3
data/options.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// -----------------------------------------------
|
||||||
|
// Options UI and handling
|
||||||
|
// -----------------------------------------------
|
192
folder_actions-api/api.js
Normal file
192
folder_actions-api/api.js
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
ChromeUtils.import("resource:///modules/MailServices.jsm");
|
||||||
|
ChromeUtils.import("resource:///modules/iteratorUtils.jsm");
|
||||||
|
ChromeUtils.import("resource:///modules/folderUtils.jsm");
|
||||||
|
|
||||||
|
// API provider for Folder Actions
|
||||||
|
class FolderActionsProvider extends ExtensionCommon.EventEmitter {
|
||||||
|
constructor(extension) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.extension = extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
get type() {
|
||||||
|
return this.extension.id;
|
||||||
|
}
|
||||||
|
get displayName() {
|
||||||
|
return this.extension.manifest.folder_actions.name;
|
||||||
|
}
|
||||||
|
get iconClass() {
|
||||||
|
let { icon } = ExtensionParent.IconDetails.getPreferredIcon(this.extension.manifest.icons, this.extension, 32);
|
||||||
|
return this.extension.getURL(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
register() {
|
||||||
|
let uuidgen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
|
||||||
|
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||||
|
let contractID = "@mozilla.org/mail/folder_actions;1?type=" + this.extension.id.replace(/@/g, "-");
|
||||||
|
let self = this;
|
||||||
|
|
||||||
|
// unregisterFactory does not clear the contract id from Components.classes, therefore re-use
|
||||||
|
// the class id from the unregistered factory
|
||||||
|
if (contractID in Cc) {
|
||||||
|
this.classID = Components.ID(Cc[contractID].number);
|
||||||
|
} else {
|
||||||
|
this.classID = Components.ID(uuidgen.generateUUID().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
let factory = {
|
||||||
|
QueryInterface: ChromeUtils.generateQI([Ci.nsIFactory]),
|
||||||
|
|
||||||
|
createInstance: function(outer, iid) {
|
||||||
|
if (outer !== null) {
|
||||||
|
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.QueryInterface(iid);
|
||||||
|
},
|
||||||
|
|
||||||
|
lockFactory: function(doLock) {
|
||||||
|
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.factory = factory.QueryInterface(Ci.nsIFactory);
|
||||||
|
|
||||||
|
registrar.registerFactory(
|
||||||
|
this.classID, `Cloud file provider for ${this.extension.id}`, contractID, this.factory
|
||||||
|
);
|
||||||
|
|
||||||
|
XPCOMUtils.categoryManager.addCategoryEntry(
|
||||||
|
"cloud-files", this.extension.id, contractID, false, true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
unregister() {
|
||||||
|
let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||||
|
|
||||||
|
registrar.unregisterFactory(this.classID, this.factory);
|
||||||
|
XPCOMUtils.categoryManager.deleteCategoryEntry("cloud-files", this.extension.id, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FolderActionsProvider.prototype.QueryInterface = ChromeUtils.generateQI([Ci.nsIMsgFolderActionsProvider]);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementation of folder_actions API
|
||||||
|
//
|
||||||
|
this.folder_actions = class extends ExtensionAPI {
|
||||||
|
async onManifestEntry(entryName) {
|
||||||
|
if (entryName == "folder_actions" && !this.provider) {
|
||||||
|
this.provider = new FolderActionsProvider(this.extension);
|
||||||
|
this.provider.register();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onShutdown() {
|
||||||
|
if (this.provider) {
|
||||||
|
this.provider.unregister();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getFolderInfo() {
|
||||||
|
let data = [];
|
||||||
|
|
||||||
|
toArray(fixIterator(MailServices.accounts.accounts,Components.interfaces.nsIMsgAccount)).map(function(account) {
|
||||||
|
let info = {
|
||||||
|
server: null,
|
||||||
|
type: null,
|
||||||
|
emails: [],
|
||||||
|
trashFolder: null,
|
||||||
|
junkFolder: null,
|
||||||
|
name: null,
|
||||||
|
};
|
||||||
|
let server = account.incomingServer;
|
||||||
|
|
||||||
|
let find_flagged_folders = function(folder,inf) {
|
||||||
|
if (folder.getFlag(Ci.nsMsgFolderFlags.Trash)) {
|
||||||
|
console.log("Folder: " + folder.URI + " has Trash flag ");
|
||||||
|
inf.trashFolder = folder;
|
||||||
|
console.log(folder);
|
||||||
|
} else if (folder.getFlag(Ci.nsMsgFolderFlags.Junk)) {
|
||||||
|
console.log("Folder: " + folder.URI + " has Junk flag ");
|
||||||
|
inf.junkFolder = folder;
|
||||||
|
console.log(folder);
|
||||||
|
} else {
|
||||||
|
if (folder.hasSubFolders) {
|
||||||
|
toArray(fixIterator(folder.subFolders, Ci.nsMsgFolder)).map(function (f) {
|
||||||
|
find_flagged_folders(f,inf);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (server) {
|
||||||
|
info.server = server.prettyName;
|
||||||
|
info.type = server.type;
|
||||||
|
if (info.type != "none") {
|
||||||
|
find_flagged_folders(server.rootFolder,info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toArray(fixIterator(account.identities, Ci.nsIMsgIdentity)).map(function(id) {
|
||||||
|
if (id.email) info.emails.push(id.email);
|
||||||
|
});
|
||||||
|
data.push(info);
|
||||||
|
});
|
||||||
|
console.log(data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
getAPI(context) {
|
||||||
|
const EventManager = ExtensionCommon.EventManager;
|
||||||
|
let self = this;
|
||||||
|
let mw = Components.classes["@mozilla.org/messenger/msgwindow;1"]
|
||||||
|
.createInstance(Components.interfaces.nsIMsgWindow);;
|
||||||
|
|
||||||
|
return {
|
||||||
|
folder_actions: {
|
||||||
|
emptyFolder: function(folderName) {
|
||||||
|
let finfo = self.getFolderInfo();
|
||||||
|
},
|
||||||
|
emptyTrashFolders: function() {
|
||||||
|
let finfo = self.getFolderInfo();
|
||||||
|
finfo.map(function(info) {
|
||||||
|
if (info.trashFolder) {
|
||||||
|
console.log("emptyTrashFolders: Considering " + info.trashFolder.URI);
|
||||||
|
console.log("emptyTrashFolders: canDeleteMessages? " + info.trashFolder.canDeleteMessages);
|
||||||
|
console.log("emptyTrashFolders: hasSubFolders? " + info.trashFolder.hasSubFolders);
|
||||||
|
console.log(info.trashFolder);
|
||||||
|
info.trashFolder.emptyTrash(null,null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
emptyJunkFolders: function() {
|
||||||
|
let finfo = self.getFolderInfo();
|
||||||
|
finfo.map(function(info) {
|
||||||
|
if (info.junkFolder) {
|
||||||
|
console.log("emptyTrashFolders: Considering " + info.junkFolder.URI);
|
||||||
|
console.log("emptyTrashFolders: canDeleteMessages? " + info.junkFolder.canDeleteMessages);
|
||||||
|
console.log("emptyTrashFolders: hasSubFolders? " + info.junkFolder.hasSubFolders);
|
||||||
|
console.log(info.junkFolder);
|
||||||
|
var junk_msgs = Cc["@mozilla.org/array;1"]
|
||||||
|
.createInstance(Ci.nsIMutableArray);
|
||||||
|
var enumerator = info.junkFolder.messages;
|
||||||
|
while (enumerator.hasMoreElements())
|
||||||
|
{
|
||||||
|
var msg_hdr = enumerator.getNext().QueryInterface(Ci.nsIMsgDBHdr);
|
||||||
|
junk_msgs.appendElement(msg_hdr, false);
|
||||||
|
}
|
||||||
|
if (junk_msgs.length) {
|
||||||
|
info.junkFolder.deleteMessages(junk_msgs, mw, false, false, null, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// vim: ts=2 sw=2 sts=2 et
|
78
folder_actions-api/schema.json
Normal file
78
folder_actions-api/schema.json
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"namespace": "manifest",
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"$extend": "WebExtensionManifest",
|
||||||
|
"properties": {
|
||||||
|
"folder_actions": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": { "$ref": "UnrecognizedProperty" },
|
||||||
|
"properties": {
|
||||||
|
"name": { "type": "string", "preprocess": "localize" }
|
||||||
|
},
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"namespace": "folder_actions",
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"name": "onEmptyFolder",
|
||||||
|
"type": "function",
|
||||||
|
"description": "Fired when a folder is emptied",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "folderName",
|
||||||
|
"$ref": "MailFolder",
|
||||||
|
"description": "The folder to be emptied"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
{
|
||||||
|
"id": "MailFolder",
|
||||||
|
"type": "object",
|
||||||
|
"description": "Information about a mail folder",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "Name of the folder to be emptied"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"functions": [
|
||||||
|
{
|
||||||
|
"name": "emptyFolder",
|
||||||
|
"type": "function",
|
||||||
|
"description": "Empties specified mail folder",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "folderName",
|
||||||
|
"$ref": "MailFolder",
|
||||||
|
"description": "The mail folder to empty"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "emptyTrashFolders",
|
||||||
|
"type": "function",
|
||||||
|
"description": "Empties Trash folders in all accounts",
|
||||||
|
"parameters": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "emptyJunkFolders",
|
||||||
|
"type": "function",
|
||||||
|
"description": "Empties Junk folders in all accounts",
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
// vim: ts=2 sw=2 sts=2 et
|
BIN
icons/button.png
Normal file
BIN
icons/button.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
BIN
icons/icon.png
Normal file
BIN
icons/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
53
manifest.json
Normal file
53
manifest.json
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "Empty 'em",
|
||||||
|
"version": "2.0",
|
||||||
|
"description": "Empty all your Trash and Junk folders in one fell swoop!",
|
||||||
|
"homepage_url": "https://github.com/asolkar/emptyem",
|
||||||
|
|
||||||
|
"icons": {
|
||||||
|
"256": "icons/icon.png"
|
||||||
|
},
|
||||||
|
|
||||||
|
"applications": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "@emptyem",
|
||||||
|
"strict_min_version": "63.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"16": "icons/icon.png",
|
||||||
|
"32": "icons/icon.png"
|
||||||
|
},
|
||||||
|
"default_title": "Empty 'em"
|
||||||
|
},
|
||||||
|
|
||||||
|
// "folder_actions": {
|
||||||
|
// "name": "EmptyEm"
|
||||||
|
// },
|
||||||
|
|
||||||
|
"options_ui": {
|
||||||
|
"page": "data/options.html"
|
||||||
|
},
|
||||||
|
|
||||||
|
"background": {
|
||||||
|
"scripts": ["data/actions.js"]
|
||||||
|
},
|
||||||
|
|
||||||
|
"experiment_apis": {
|
||||||
|
"folder_actions": {
|
||||||
|
"schema": "folder_actions-api/schema.json",
|
||||||
|
"parent": {
|
||||||
|
"scopes": ["addon_parent"],
|
||||||
|
"script": "folder_actions-api/api.js",
|
||||||
|
"paths": [
|
||||||
|
["folder_actions"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// vim: ts=2 sw=2 sts=2 et
|
Loading…
Reference in New Issue
Block a user