-
Notifications
You must be signed in to change notification settings - Fork 1
/
autoconfig-uitextoverrider.js
146 lines (131 loc) · 5.37 KB
/
autoconfig-uitextoverrider.js
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Following variables must be predefined.
//
// var killedItems = [];
// var killedItemsWithDelay = [];
// var hiddenItemsWithDelay = [];
{// UI Text Overrider, for Firefox 52/Thunderbird 52 and later
let domain = 'extensions.uitextoverrider@clear-code.com.';
function setKillItemRule(aIdentifier, aSelector, aDelayed, aDisableCommand) {
lockPref(domain + aIdentifier, aSelector);
lockPref(domain + aIdentifier + ".disabled", "true");
lockPref(domain + aIdentifier + ".hidden", "true");
lockPref(domain + aIdentifier + ".readonly", "true");
if (aDisableCommand) {
lockPref(domain + aIdentifier + ".command", "");
lockPref(domain + aIdentifier + ".oncommand", "");
}
lockPref(domain + aIdentifier + ".always-hidden", "true");
lockPref(domain + aIdentifier + ".delayed", aDelayed == true);
}
setKillItemRule("killedItems", killedItems.join(","), false, true);
setKillItemRule("killedItemsWithDelay", killedItemsWithDelay.join(","), true, true);
setKillItemRule("hiddenItemsWithDelay", hiddenItemsWithDelay.join(","), true, false);
let { classes: Cc, interfaces: Ci, utils: Cu } = Components;
let { Services } = Cu.import('resource://gre/modules/Services.jsm', {});
let getDescendantPrefs = (aRoot) => {
return Services.prefs.getChildList(aRoot, {}).sort();
};
let getChildPrefs = (aRoot) => {
aRoot = aRoot.replace(/\.$/, '');
var foundChildren = {};
var possibleChildren = [];
getDescendantPrefs(aRoot)
.forEach(aPrefstring => {
let name = aPrefstring.replace(aRoot + '.', '');
let possibleChildKey = aRoot + '.' + name.split('.')[0];
if (possibleChildKey && !(possibleChildKey in foundChildren)) {
possibleChildren.push(possibleChildKey);
foundChildren[possibleChildKey] = true;
}
});
return possibleChildren.sort();
};
const STATE_HANDLED = 0;
const STATE_ONLOAD_FIRED = 1;
const STATE_DELAYED = 2;
let overrideUIText = (aWindow, aBaseKey, aState) => {
var selector = getPref(aBaseKey);
if (!selector)
return;
if (aWindow.document.documentElement.localName == 'prefwindow') {
aWindow.addEventListener('paneload', aEvent => {
overrideUIText(aWindow, aBaseKey, STATE_DELAYED);
}, false);
}
if (aWindow.location.href == 'about:blank' && aState == STATE_HANDLED) {
// When the chrome window is not loaded yet, we have to do following processes after loaded.
aWindow.addEventListener('load', aEvent => {
aWindow.addEventListener('MozAfterPaint', aEvent => {
overrideUIText(aWindow, aBaseKey, STATE_ONLOAD_FIRED);
}, { once: true });
}, { once: true });
return;
}
if (getPref(aBaseKey + '.delayed') && aState != STATE_DELAYED) {
if (aState == STATE_HANDLED) {
aWindow.addEventListener('load', function onLoad(aEvent) {
aWindow.removeEventListener('load', onLoad, false);
aWindow.addEventListener('MozAfterPaint', function onMozAfterPaint(aEvent) {
aWindow.removeEventListener('MozAfterPaint', onMozAfterPaint, false);
aWindow.setTimeout(() => {
overrideUIText(aWindow, aBaseKey, STATE_DELAYED);
}, 100);
}, false);
}, false);
} else {
aWindow.setTimeout(() => {
overrideUIText(aWindow, aBaseKey, STATE_DELAYED);
}, 100);
}
return;
}
try {
var targets = aWindow.document.querySelectorAll(selector);
// Services.console.logStringMessage(`${aState*} / ${selector} => ${targets.length}`);
if (!targets.length) {
Cu.reportError(new Error(`[uitextoverrider] no target found: ${selector} (${aWindow.location.href})`));
return;
}
var keys = getChildPrefs(`${aBaseKey}.`);
var attributes = [];
keys.forEach(aKey => {
var attribute = aKey.replace(`${aBaseKey}.`, '');
if (attribute == 'delayed')
return;
var value = getPref(aKey);
for (const target of targets) {
target.setAttribute(attribute, value);
attributes.push(attribute + '=' + value);
}
});
if (getPref(domain + 'debug')) {
Services.console.logStringMessage(`[uitextoverrider] ${targets.length} targets found: ${selector} => ${attributes.join(', ')} (${aWindow.location.href})`);
}
} catch(error) {
Cu.reportError(error);
}
};
let handleWindow = (aWindow) => {
getChildPrefs(domain).forEach(aBaseKey => {
overrideUIText(aWindow, aBaseKey, STATE_HANDLED);
});
};
let windows = Services.wm.getEnumerator(null);
while (windows.hasMoreElements()) {
handleWindow(windows.getNext().QueryInterface(Ci.nsIDOMWindow));
}
Services.ww.registerNotification({
observe(aSubject, aTopic, aData) {
if (aTopic == 'domwindowopened' &&
!aSubject
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.QueryInterface(Ci.nsIDocShellTreeNode || Ci.nsIDocShellTreeItem) // nsIDocShellTreeNode is merged to nsIDocShellTreeItem by https://bugzilla.mozilla.org/show_bug.cgi?id=331376
.QueryInterface(Ci.nsIDocShellTreeItem)
.parent)
aSubject.getInterface(Ci.nsIDOMWindow).addEventListener('DOMContentLoaded', aEvent => {
handleWindow(aEvent.target.defaultView);
}, { once: true });
}
});
}