!import
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1 //@line 40 "/home/visbrero/mnt/roisin/rev_control/hg/mozilla/toolkit/mozapps/extensions/content/extensions.js"
2
3 ///////////////////////////////////////////////////////////////////////////////
4 // Globals
5 const nsIExtensionManager = Components.interfaces.nsIExtensionManager;
6 const nsIUpdateItem = Components.interfaces.nsIUpdateItem;
7 const nsIFilePicker = Components.interfaces.nsIFilePicker;
8 const nsIIOService = Components.interfaces.nsIIOService;
9 const nsIFileProtocolHandler = Components.interfaces.nsIFileProtocolHandler;
10 const nsIURL = Components.interfaces.nsIURL;
11 const nsIAppStartup = Components.interfaces.nsIAppStartup;
12
13 var gView = null;
14 var gExtensionManager = null;
15 var gExtensionsView = null;
16 var gExtensionStrings = null;
17 var gCurrentTheme = "classic/1.0";
18 var gDefaultTheme = "classic/1.0";
19 var gDownloadManager = null;
20 var gObserverIndex = -1;
21 var gInSafeMode = false;
22 var gCheckCompat = true;
23 var gCheckUpdateSecurity = true;
24 var gUpdatesOnly = false;
25 var gAppID = "";
26 var gPref = null;
27 var gPriorityCount = 0;
28 var gInstalling = false;
29 var gPendingActions = false;
30 var gPlugins = null;
31 var gPluginsDS = null;
32 var gSearchDS = null;
33 var gAddonRepository = null;
34 var gShowGetAddonsPane = false;
35 var gRetrievedResults = false;
36 var gRecommendedAddons = null;
37 var gRDF = null;
38 var gPendingInstalls = {};
39 var gNewAddons = [];
40
41 const PREF_EM_CHECK_COMPATIBILITY = "extensions.checkCompatibility";
42 const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
43 const PREF_EXTENSIONS_GETMORETHEMESURL = "extensions.getMoreThemesURL";
44 const PREF_EXTENSIONS_GETMOREEXTENSIONSURL = "extensions.getMoreExtensionsURL";
45 const PREF_EXTENSIONS_GETMOREPLUGINSURL = "extensions.getMorePluginsURL";
46 const PREF_EXTENSIONS_DSS_ENABLED = "extensions.dss.enabled";
47 const PREF_EXTENSIONS_DSS_SWITCHPENDING = "extensions.dss.switchPending";
48 const PREF_EXTENSIONS_HIDE_INSTALL_BTN = "extensions.hideInstallButton";
49 const PREF_DSS_SKIN_TO_SELECT = "extensions.lastSelectedSkin";
50 const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
51 const PREF_UPDATE_NOTIFYUSER = "extensions.update.notifyUser";
52 const PREF_GETADDONS_SHOWPANE = "extensions.getAddons.showPane";
53 const PREF_GETADDONS_REPOSITORY = "extensions.getAddons.repository";
54 const PREF_GETADDONS_MAXRESULTS = "extensions.getAddons.maxResults";
55
56 const URI_GENERIC_ICON_XPINSTALL = "chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png";
57 const URI_GENERIC_ICON_THEME = "chrome://mozapps/skin/extensions/themeGeneric.png";
58
59 const RDFURI_ITEM_ROOT = "urn:mozilla:item:root";
60 const PREFIX_ITEM_URI = "urn:mozilla:item:";
61 const PREFIX_NS_EM = "http://www.mozilla.org/2004/em-rdf#";
62 const kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
63 const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"
64
65 const OP_NONE = "";
66 const OP_NEEDS_INSTALL = "needs-install";
67 const OP_NEEDS_UPGRADE = "needs-upgrade";
68 const OP_NEEDS_UNINSTALL = "needs-uninstall";
69 const OP_NEEDS_ENABLE = "needs-enable";
70 const OP_NEEDS_DISABLE = "needs-disable";
71
72 Components.utils.import("resource://gre/modules/PluralForm.jsm");
73 Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
74
75 ///////////////////////////////////////////////////////////////////////////////
76 // Utility Functions
setElementDisabledByID
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
77 function setElementDisabledByID(aID, aDoDisable) {
78 var element = document.getElementById(aID);
79 if (element) {
80 if (aDoDisable)
81 element.setAttribute("disabled", "true");
82 else
83 element.removeAttribute("disabled");
84 }
85 }
86
87 /**
88 * This returns the richlistitem element for the theme with the given
89 * internalName
90 */
getItemForInternalName
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
91 function getItemForInternalName(aInternalName) {
92 var property = gRDF.GetResource(PREFIX_NS_EM + "internalName");
93 var name = gRDF.GetLiteral(aInternalName);
94 var id = gExtensionManager.datasource.GetSource(property, name, true)
95 if (id && id instanceof Components.interfaces.nsIRDFResource)
96 return document.getElementById(id.ValueUTF8);
97 return null;
98 }
99
isSafeURI
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
100 function isSafeURI(aURI) {
101 try {
102 var uri = makeURI(aURI);
103 var scheme = uri.scheme;
104 } catch (ex) {}
105 return (uri && (scheme == "http" || scheme == "https" || scheme == "ftp"));
106 }
107
getBrandShortName
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
108 function getBrandShortName() {
109 var brandStrings = document.getElementById("brandStrings");
110 return brandStrings.getString("brandShortName");
111 }
112
getExtensionString
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
113 function getExtensionString(key, strings) {
114 if (strings)
115 return gExtensionStrings.getFormattedString(key, strings);
116 return gExtensionStrings.getString(key);
117 }
118
MessageButton
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
119 function MessageButton(aLabel, aAccesskey, aData) {
120 this.label = aLabel;
121 this.accessKey = aAccesskey;
122 this.data = aData || "addons-message-dismiss";
123 }
124 MessageButton.prototype = {
125 label: null,
126 accessKey: null,
127 data: null,
128
callback
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
129 callback: function (aNotification, aButton) {
130 var os = Components.classes["@mozilla.org/observer-service;1"]
131 .getService(Components.interfaces.nsIObserverService);
132 os.notifyObservers(null, "addons-message-notification", aButton.data);
133 aNotification.close();
134 return true;
135 }
136 };
137
showMessage
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
138 function showMessage(aIconURL, aMessage, aButtonLabel, aButtonAccesskey,
139 aShowCloseButton, aNotifyData) {
140 var addonsMsg = document.getElementById("addonsMsg");
141 var buttons = null;
142 if (aButtonLabel)
143 buttons = [new MessageButton(aButtonLabel, aButtonAccesskey, aNotifyData)];
144 var oldMessage = addonsMsg.getNotificationWithValue(aMessage);
145 if (oldMessage && oldMessage.parentNode)
146 addonsMsg.removeNotification(oldMessage);
147 if (addonsMsg.currentNotification)
148 gPriorityCount += 0.0001;
149 else
150 gPriorityCount = 0;
151 addonsMsg.appendNotification(aMessage, aMessage, aIconURL,
152 addonsMsg.PRIORITY_WARNING_LOW + gPriorityCount,
153 buttons).hideclose = !aShowCloseButton;
154 }
155
156 // dynamically creates a template
157 var AddonsViewBuilder = {
158 // if aActionList is null aBindingList will be used to generate actions
updateView
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
159 updateView: function(aRulesList, aURIList, aBindingList, aActionList)
160 {
161 var actionList = aActionList ? aActionList : aBindingList;
162
163 this.clearChildren(gExtensionsView);
164 var template = document.createElementNS(kXULNSURI, "template");
165 gExtensionsView.appendChild(template);
166 for (var i = 0; i < aRulesList.length; ++i)
167 template.appendChild(this.createRule(aRulesList[i], aURIList[i], aBindingList[i], actionList[i]));
168
169 gExtensionsView.builder.rebuild();
170 },
171
clearChildren
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
172 clearChildren: function(aEl)
173 {
174 while (aEl.hasChildNodes())
175 aEl.removeChild(aEl.lastChild);
176 },
177
createRule
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
178 createRule: function(aTriplesList, aURI, aBindingList, aActionList)
179 {
180 var rule = document.createElementNS(kXULNSURI, "rule");
181 var conditions = document.createElementNS(kXULNSURI, "conditions");
182 rule.appendChild(conditions);
183
184 var content = document.createElementNS(kXULNSURI, "content");
185 content.setAttribute("uri", "?uri");
186 conditions.appendChild(content);
187
188 var member = this.createMember("?uri", "?" + aURI);
189 conditions.appendChild(member);
190
191 for (var i = 0; i < aTriplesList.length; ++i)
192 conditions.appendChild(this.createTriple("?" + aURI, PREFIX_NS_EM + aTriplesList[i][0], aTriplesList[i][1], aTriplesList[i][2]));
193
194 var bindings = document.createElementNS(kXULNSURI, "bindings");
195 rule.appendChild(bindings);
196 for (i = 0; i < aBindingList.length; ++i)
197 bindings.appendChild(this.createBinding(aBindingList[i], aURI));
198
199 var action = document.createElementNS(kXULNSURI, "action");
200 rule.appendChild(action);
201 var extension = document.createElementNS(kXULNSURI, aURI);
202 action.appendChild(extension);
203 extension.setAttribute("uri", "?" + aURI);
204 for (i = 0; i < aActionList.length; ++i)
205 extension.setAttribute(aActionList[i][0], aActionList[i][1]);
206
207 return rule;
208 },
209
createTriple
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
210 createTriple: function(aSubject, aPredicate, aObject, aParseType)
211 {
212 var triple = document.createElementNS(kXULNSURI, "triple");
213 triple.setAttribute("subject", aSubject);
214 triple.setAttribute("predicate", aPredicate);
215 triple.setAttribute("object", aObject);
216 if (aParseType)
217 triple.setAttribute("parsetype", aParseType);
218 return triple;
219 },
220
createBinding
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
221 createBinding: function(aPredicateObjectList, aURI)
222 {
223 var binding = document.createElementNS(kXULNSURI, "binding");
224 binding.setAttribute("subject", "?" + aURI);
225 binding.setAttribute("predicate", PREFIX_NS_EM + aPredicateObjectList[0]);
226 binding.setAttribute("object", aPredicateObjectList[1]);
227 return binding;
228 },
229
createMember
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
230 createMember: function(aContainer, aChild)
231 {
232 var member = document.createElementNS(kXULNSURI, "member");
233 member.setAttribute("container", aContainer);
234 member.setAttribute("child", aChild);
235
236 return member;
237 }
238 };
239
showView
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
240 function showView(aView) {
241 if (gView == aView)
242 return;
243
244 updateLastSelected(aView);
245 gView = aView;
246
247 // Using disabled to represent add-on state in regards to the EM causes evil
248 // focus behavior when used as an element attribute when the element isn't
249 // really disabled.
250 var bindingList = [ [ ["aboutURL", "?aboutURL"],
251 ["addonID", "?addonID"],
252 ["availableUpdateURL", "?availableUpdateURL"],
253 ["availableUpdateVersion", "?availableUpdateVersion"],
254 ["blocklisted", "?blocklisted"],
255 ["compatible", "?compatible"],
256 ["description", "?description"],
257 ["downloadURL", "?downloadURL"],
258 ["isDisabled", "?isDisabled"],
259 ["hidden", "?hidden"],
260 ["homepageURL", "?homepageURL"],
261 ["iconURL", "?iconURL"],
262 ["internalName", "?internalName"],
263 ["locked", "?locked"],
264 ["name", "?name"],
265 ["optionsURL", "?optionsURL"],
266 ["opType", "?opType"],
267 ["plugin", "?plugin"],
268 ["previewImage", "?previewImage"],
269 ["satisfiesDependencies", "?satisfiesDependencies"],
270 ["providesUpdatesSecurely", "?providesUpdatesSecurely"],
271 ["type", "?type"],
272 ["updateable", "?updateable"],
273 ["updateURL", "?updateURL"],
274 ["version", "?version"] ] ];
275 var displays = [ "richlistitem" ];
276
277 var prefURL;
278 var showInstallFile = true;
279 try {
280 showInstallFile = !gPref.getBoolPref(PREF_EXTENSIONS_HIDE_INSTALL_BTN);
281 }
282 catch (e) { }
283 var showCheckUpdatesAll = true;
284 var showInstallUpdatesAll = false;
285 var showSkip = false;
286 var showContinue = false;
287 switch (aView) {
288 case "search":
289 var bindingList = [ [ ["action", "?action"],
290 ["addonID", "?addonID"],
291 ["description", "?description"],
292 ["eula", "?eula"],
293 ["homepageURL", "?homepageURL"],
294 ["iconURL", "?iconURL"],
295 ["name", "?name"],
296 ["previewImage", "?previewImage"],
297 ["rating", "?rating"],
298 ["addonType", "?addonType"],
299 ["thumbnailURL", "?thumbnailURL"],
300 ["version", "?version"],
301 ["xpiHash", "?xpiHash"],
302 ["xpiURL", "?xpiURL"],
303 ["typeName", "searchResult"] ],
304 [ ["type", "?type"],
305 ["typeName", "status"],
306 ["count", "?count"],
307 ["link", "?link" ] ] ];
308 var types = [ [ ["searchResult", "true", null] ],
309 [ ["statusMessage", "true", null] ] ];
310 var displays = [ "richlistitem", "vbox" ];
311 showCheckUpdatesAll = false;
312 document.getElementById("searchbox").disabled = isOffline("offlineSearchMsg");
313 break;
314 case "extensions":
315 prefURL = PREF_EXTENSIONS_GETMOREEXTENSIONSURL;
316 types = [ [ ["type", nsIUpdateItem.TYPE_EXTENSION, "Integer"] ] ];
317 break;
318 case "themes":
319 prefURL = PREF_EXTENSIONS_GETMORETHEMESURL;
320 types = [ [ ["type", nsIUpdateItem.TYPE_THEME, "Integer"] ] ];
321 break;
322 case "locales":
323 types = [ [ ["type", nsIUpdateItem.TYPE_LOCALE, "Integer"] ] ];
324 break;
325 case "plugins":
326 prefURL = PREF_EXTENSIONS_GETMOREPLUGINSURL;
327 types = [ [ ["plugin", "true", null] ] ];
328 showCheckUpdatesAll = false;
329 break;
330 case "updates":
331 document.getElementById("updates-view").hidden = false;
332 showInstallFile = false;
333 showCheckUpdatesAll = false;
334 showInstallUpdatesAll = true;
335 if (gUpdatesOnly)
336 showSkip = true;
337 bindingList = [ [ ["aboutURL", "?aboutURL"],
338 ["availableUpdateURL", "?availableUpdateURL"],
339 ["availableUpdateVersion", "?availableUpdateVersion"],
340 ["availableUpdateInfo", "?availableUpdateInfo"],
341 ["blocklisted", "?blocklisted"],
342 ["homepageURL", "?homepageURL"],
343 ["iconURL", "?iconURL"],
344 ["internalName", "?internalName"],
345 ["locked", "?locked"],
346 ["name", "?name"],
347 ["opType", "?opType"],
348 ["previewImage", "?previewImage"],
349 ["satisfiesDependencies", "?satisfiesDependencies"],
350 ["providesUpdatesSecurely", "?providesUpdatesSecurely"],
351 ["type", "?type"],
352 ["updateURL", "?updateURL"],
353 ["version", "?version"],
354 ["typeName", "update"] ] ];
355 types = [ [ ["availableUpdateVersion", "?availableUpdateVersion", null],
356 ["updateable", "true", null] ] ];
357 break;
358 case "installs":
359 document.getElementById("installs-view").hidden = false;
360 showInstallFile = false;
361 showCheckUpdatesAll = false;
362 showInstallUpdatesAll = false;
363 if (gUpdatesOnly)
364 showContinue = true;
365 bindingList = [ [ ["aboutURL", "?aboutURL"],
366 ["addonID", "?addonID"],
367 ["availableUpdateURL", "?availableUpdateURL"],
368 ["availableUpdateVersion", "?availableUpdateVersion"],
369 ["blocklisted", "?blocklisted"],
370 ["compatible", "?compatible"],
371 ["description", "?description"],
372 ["downloadURL", "?downloadURL"],
373 ["incompatibleUpdate", "?incompatibleUpdate"],
374 ["isDisabled", "?isDisabled"],
375 ["hidden", "?hidden"],
376 ["homepageURL", "?homepageURL"],
377 ["iconURL", "?iconURL"],
378 ["internalName", "?internalName"],
379 ["locked", "?locked"],
380 ["name", "?name"],
381 ["optionsURL", "?optionsURL"],
382 ["opType", "?opType"],
383 ["previewImage", "?previewImage"],
384 ["progress", "?progress"],
385 ["state", "?state"],
386 ["type", "?type"],
387 ["updateable", "?updateable"],
388 ["updateURL", "?updateURL"],
389 ["version", "?version"],
390 ["newVersion", "?newVersion"],
391 ["typeName", "install"] ] ];
392 types = [ [ ["state", "?state", null] ] ];
393 break;
394 }
395
396 var showGetMore = false;
397 var getMore = document.getElementById("getMore");
398 if (prefURL && !gShowGetAddonsPane) {
399 try {
400 getMore.setAttribute("value", getMore.getAttribute("value" + aView));
401 var getMoreURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
402 .getService(Components.interfaces.nsIURLFormatter)
403 .formatURLPref(prefURL);
404 getMore.setAttribute("getMoreURL", getMoreURL);
405 showGetMore = getMoreURL == "about:blank" ? false : true;
406 }
407 catch (e) { }
408 }
409 getMore.hidden = !showGetMore;
410
411 var isThemes = aView == "themes";
412
413 if (aView == "themes" || aView == "extensions") {
414 var el = document.getElementById("installFileButton");
415 el.setAttribute("tooltiptext", el.getAttribute(isThemes ? "tooltiptextthemes" :
416 "tooltiptextaddons"));
417 el = document.getElementById("checkUpdatesAllButton");
418 el.setAttribute("tooltiptext", el.getAttribute(isThemes ? "tooltiptextthemes" :
419 "tooltiptextaddons"));
420 }
421
422 document.getElementById("installFileButton").hidden = !showInstallFile;
423 document.getElementById("checkUpdatesAllButton").hidden = !showCheckUpdatesAll;
424 document.getElementById("installUpdatesAllButton").hidden = !showInstallUpdatesAll;
425 document.getElementById("skipDialogButton").hidden = !showSkip;
426 document.getElementById("continueDialogButton").hidden = !showContinue;
427 document.getElementById("themePreviewArea").hidden = !isThemes;
428 document.getElementById("themeSplitter").hidden = !isThemes;
429 document.getElementById("showUpdateInfoButton").hidden = aView != "updates";
430 document.getElementById("hideUpdateInfoButton").hidden = true;
431 document.getElementById("searchPanel").hidden = aView != "search";
432
433 AddonsViewBuilder.updateView(types, displays, bindingList, null);
434
435 if (aView == "updates" || aView == "installs")
436 gExtensionsView.selectedItem = gExtensionsView.children[0];
437
438 if (showSkip) {
439 var button = document.getElementById("installUpdatesAllButton");
440 button.setAttribute("default", "true");
anon:441:22
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
441 window.setTimeout(function () { button.focus(); }, 0);
442 } else
443 document.getElementById("installUpdatesAllButton").removeAttribute("default");
444
445 if (showContinue)
446 document.getElementById("continueDialogButton").setAttribute("default", "true");
447 else
448 document.getElementById("continueDialogButton").removeAttribute("default");
449
450 if (isThemes)
451 onAddonSelect();
452 updateGlobalCommands();
453 }
454
455 // manages the last-selected attribute for the view buttons and richlistbox
updateLastSelected
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
456 function updateLastSelected(aView) {
457 var viewGroup = document.getElementById("viewGroup");
458 if (viewGroup.hasAttribute("last-selected"))
459 var lastSelectedView = viewGroup.getAttribute("last-selected");
460
461 if (lastSelectedView && lastSelectedView == gView) {
462 var lastViewButton = document.getElementById(lastSelectedView + "-view");
463 if (lastViewButton.hasAttribute("persist")) {
464 if (gExtensionsView.selectedItem)
465 lastViewButton.setAttribute("last-selected", gExtensionsView.selectedItem.id);
466 else if (lastViewButton.hasAttribute("last-selected"))
467 lastViewButton.removeAttribute("last-selected");
468 }
469 }
470 var viewButton = document.getElementById(aView + "-view");
471 if (viewButton.hasAttribute("last-selected")) {
472 gExtensionsView.setAttribute("last-selected", viewButton.getAttribute("last-selected"));
473 }
474 else if (gExtensionsView.hasAttribute("last-selected")) {
475 gExtensionsView.clearSelection();
476 gExtensionsView.removeAttribute("last-selected");
477 }
478 viewGroup.selectedItem = viewButton;
479 // Only set last-selected for view buttons that have a persist attribute
480 // (e.g. they themselves persist the last selected add-on in the view).
481 // This prevents opening updates and installs views when they were the last
482 // view selected and instead this will open the previously selected
483 // extensions, themes, locales, plug-ins, etc. view.
484 if (viewButton.hasAttribute("persist"))
485 viewGroup.setAttribute("last-selected", aView);
486 }
487
LOG
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
488 function LOG(msg) {
489 dump("*** " + msg + "\n");
490 }
491
getIDFromResourceURI
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
492 function getIDFromResourceURI(aURI)
493 {
494 if (aURI.substring(0, PREFIX_ITEM_URI.length) == PREFIX_ITEM_URI)
495 return aURI.substring(PREFIX_ITEM_URI.length);
496 return aURI;
497 }
498
showProgressBar
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
499 function showProgressBar() {
500 var progressBox = document.getElementById("progressBox");
501 var height = document.defaultView.getComputedStyle(progressBox.parentNode, "")
502 .getPropertyValue("height");
503 progressBox.parentNode.style.height = height;
504 document.getElementById("viewGroup").hidden = true;
505 progressBox.hidden = false;
506 }
507
flushDataSource
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
508 function flushDataSource()
509 {
510 var rds = gExtensionManager.datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
511 if (rds)
512 rds.Flush();
513 }
514
noUpdatesDismiss
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
515 function noUpdatesDismiss(aEvent)
516 {
517 window.removeEventListener("select", noUpdatesDismiss, true);
518
519 var children = gExtensionsView.children;
520 for (var i = 0; i < children.length; ++i) {
521 var child = children[i];
522 if (child.hasAttribute("updateStatus"))
523 child.removeAttribute("updateStatus");
524 }
525
526 if (aEvent.target.localName != "notification")
527 document.getElementById("addonsMsg").removeCurrentNotification();
528 }
529
clearRestartMessage
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
530 function clearRestartMessage()
531 {
532 var children = gExtensionsView.children;
533 for (var i = 0; i < children.length; ++i) {
534 var item = children[i];
535 if (item.hasAttribute("oldDescription")) {
536 item.setAttribute("description", item.getAttribute("oldDescription"));
537 item.removeAttribute("oldDescription");
538 }
539 }
540 }
541
setRestartMessage
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
542 function setRestartMessage(aItem)
543 {
544 var themeName = aItem.getAttribute("name");
545 var restartMessage = getExtensionString("dssSwitchAfterRestart",
546 [getBrandShortName()]);
547 aItem.setAttribute("oldDescription", aItem.getAttribute("description"));
548 aItem.setAttribute("description", restartMessage);
549 }
550
551 // Removes any assertions in the datasource about a given resource
cleanResource
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
552 function cleanResource(ds, resource) {
553 // Remove outward arcs
554 var arcs = ds.ArcLabelsOut(resource);
555 while (arcs.hasMoreElements()) {
556 var arc = arcs.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
557 var targets = ds.GetTargets(resource, arc, true);
558 while (targets.hasMoreElements()) {
559 var value = targets.getNext().QueryInterface(Components.interfaces.nsIRDFNode);
560 if (value)
561 ds.Unassert(resource, arc, value);
562 }
563 }
564 }
565
566 // Wipes the datasource clean of assertions
cleanDataSource
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
567 function cleanDataSource(ds, rootctr) {
568 // Remove old entries from the list
569 var nodes = rootctr.GetElements();
570 while (nodes.hasMoreElements()) {
571 var node = nodes.getNext()
572 .QueryInterface(Components.interfaces.nsIRDFResource);
573 rootctr.RemoveElement(node, false);
574 cleanResource(ds, node);
575 }
576 }
577
578 // Displays the search status message
displaySearchThrobber
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
579 function displaySearchThrobber(aKey) {
580 var rdfCU = Components.classes["@mozilla.org/rdf/container-utils;1"]
581 .getService(Components.interfaces.nsIRDFContainerUtils);
582 var rootctr = rdfCU.MakeSeq(gSearchDS, gRDF.GetResource(RDFURI_ITEM_ROOT));
583
584 cleanDataSource(gSearchDS, rootctr);
585
586 var labelNode = gRDF.GetResource("urn:mozilla:addons:search:status:header");
587 rootctr.AppendElement(labelNode);
588 gSearchDS.Assert(labelNode,
589 gRDF.GetResource(PREFIX_NS_EM + "statusMessage"),
590 gRDF.GetLiteral("true"),
591 true);
592 gSearchDS.Assert(labelNode,
593 gRDF.GetResource(PREFIX_NS_EM + "type"),
594 gRDF.GetLiteral(aKey),
595 true);
596 }
597
598 // Clears the search box and updates the result list
resetSearch
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
599 function resetSearch() {
600 var searchbox = document.getElementById("searchbox");
601 searchbox.value = "";
602 searchbox.focus();
603 retrieveRepositoryAddons("");
604 }
605
606 // Searches for results
retrieveRepositoryAddons
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
607 function retrieveRepositoryAddons(aTerms) {
608 if (gAddonRepository.isSearching)
609 gAddonRepository.cancelSearch();
610 if (aTerms) {
611 displaySearchThrobber("retrieve-search");
612 gAddonRepository.searchAddons(aTerms,
613 gPref.getIntPref(PREF_GETADDONS_MAXRESULTS),
614 AddonSearchResults);
615 }
616 else {
617 if (gRecommendedAddons) {
618 displaySearchResults(gRecommendedAddons, -1, true);
619 }
620 else {
621 displaySearchThrobber("retrieve-recommended");
622 gAddonRepository.retrieveRecommendedAddons(gPref.getIntPref(PREF_GETADDONS_MAXRESULTS),
623 RecommendedSearchResults);
624 }
625 }
626 gRetrievedResults = true;
627 }
628
629 // Puts search results into the search datasource
displaySearchResults
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
630 function displaySearchResults(addons, count, isRecommended) {
631 var rdfCU = Components.classes["@mozilla.org/rdf/container-utils;1"]
632 .getService(Components.interfaces.nsIRDFContainerUtils);
633 var rootctr = rdfCU.MakeSeq(gSearchDS, gRDF.GetResource(RDFURI_ITEM_ROOT));
634
635 gSearchDS.beginUpdateBatch();
636
637 cleanDataSource(gSearchDS, rootctr);
638
639 if (isRecommended) {
640 var labelNode = gRDF.GetResource("urn:mozilla:addons:search:status:header");
641 rootctr.AppendElement(labelNode);
642 gSearchDS.Assert(labelNode,
643 gRDF.GetResource(PREFIX_NS_EM + "statusMessage"),
644 gRDF.GetLiteral("true"),
645 true);
646 gSearchDS.Assert(labelNode,
647 gRDF.GetResource(PREFIX_NS_EM + "type"),
648 gRDF.GetLiteral("header-recommended"),
649 true);
650
651 // Case insensitive sort
compare
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
652 function compare(a, b) {
653 if (a.name.toLowerCase() < b.name.toLowerCase())
654 return -1;
655 if (a.name.toLowerCase() > b.name.toLowerCase())
656 return 1;
657 return 0;
658 }
659 addons.sort(compare);
660 }
661
662 if (addons.length == 0 && (isRecommended || count > 0)) {
663 var labelNode = gRDF.GetResource("urn:mozilla:addons:search:status:noresults");
664 rootctr.AppendElement(labelNode);
665 gSearchDS.Assert(labelNode,
666 gRDF.GetResource(PREFIX_NS_EM + "statusMessage"),
667 gRDF.GetLiteral("true"),
668 true);
669 if (isRecommended) {
670 gSearchDS.Assert(labelNode,
671 gRDF.GetResource(PREFIX_NS_EM + "type"),
672 gRDF.GetLiteral("message-norecommended"),
673 true);
674 }
675 else {
676 gSearchDS.Assert(labelNode,
677 gRDF.GetResource(PREFIX_NS_EM + "type"),
678 gRDF.GetLiteral("message-nosearchresults"),
679 true);
680 }
681 }
682
683 var urlproperties = [ "iconURL", "homepageURL", "thumbnailURL", "xpiURL" ];
684 var properties = [ "name", "eula", "iconURL", "homepageURL", "thumbnailURL", "xpiURL", "xpiHash" ];
685 for (var i = 0; i < addons.length; i++) {
686 var addon = addons[i];
687 // Strip out any items with potentially unsafe urls
688 var unsafe = false;
689 for (var j = 0; j < urlproperties.length; j++) {
690 if (!isSafeURI(addon[urlproperties[j]])) {
691 unsafe = true;
692 break;
693 }
694 }
695 if (unsafe)
696 continue;
697
698 var resultNode = gRDF.GetResource("urn:mozilla:addons:search:" + addon.xpiURL);
699 gSearchDS.Assert(resultNode,
700 gRDF.GetResource(PREFIX_NS_EM + "addonID"),
701 gRDF.GetLiteral(addon.id),
702 true);
703 // Use the short summary for our "description"
704 gSearchDS.Assert(resultNode,
705 gRDF.GetResource(PREFIX_NS_EM + "description"),
706 gRDF.GetLiteral(addon.summary),
707 true);
708 gSearchDS.Assert(resultNode,
709 gRDF.GetResource(PREFIX_NS_EM + "addonType"),
710 gRDF.GetIntLiteral(addon.type),
711 true);
712 if (addon.rating >= 0) {
713 gSearchDS.Assert(resultNode,
714 gRDF.GetResource(PREFIX_NS_EM + "rating"),
715 gRDF.GetIntLiteral(addon.rating),
716 gRDF.GetIntLiteral(3),
717 true);
718 }
719
720 for (var j = 0; j < properties.length; j++) {
721 gSearchDS.Assert(resultNode,
722 gRDF.GetResource(PREFIX_NS_EM + properties[j]),
723 gRDF.GetLiteral(addon[properties[j]]),
724 true);
725 }
726 gSearchDS.Assert(resultNode,
727 gRDF.GetResource(PREFIX_NS_EM + "searchResult"),
728 gRDF.GetLiteral("true"),
729 true);
730 rootctr.AppendElement(resultNode);
731 }
732
733 labelNode = gRDF.GetResource("urn:mozilla:addons:search:status:footer");
734 rootctr.AppendElement(labelNode);
735 gSearchDS.Assert(labelNode,
736 gRDF.GetResource(PREFIX_NS_EM + "statusMessage"),
737 gRDF.GetLiteral("true"),
738 true);
739 if (isRecommended) {
740 gSearchDS.Assert(labelNode,
741 gRDF.GetResource(PREFIX_NS_EM + "type"),
742 gRDF.GetLiteral("footer-recommended"),
743 true);
744 var url = gAddonRepository.getRecommendedURL();
745 }
746 else {
747 gSearchDS.Assert(labelNode,
748 gRDF.GetResource(PREFIX_NS_EM + "type"),
749 gRDF.GetLiteral("footer-search"),
750 true);
751 gSearchDS.Assert(labelNode,
752 gRDF.GetResource(PREFIX_NS_EM + "count"),
753 gRDF.GetIntLiteral(count),
754 true);
755 var searchbox = document.getElementById("searchbox");
756 // The value attribute will be the persisted value of the last search run
757 url = gAddonRepository.getSearchURL(searchbox.getAttribute("value"));
758 }
759 gSearchDS.Assert(labelNode,
760 gRDF.GetResource(PREFIX_NS_EM + "link"),
761 gRDF.GetLiteral(url),
762 true);
763
764 gSearchDS.endUpdateBatch();
765 }
766
767 // Displays the search failure status message
displaySearchFailure
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
768 function displaySearchFailure(isRecommended) {
769 var rdfCU = Components.classes["@mozilla.org/rdf/container-utils;1"]
770 .getService(Components.interfaces.nsIRDFContainerUtils);
771 var rootctr = rdfCU.MakeSeq(gSearchDS, gRDF.GetResource(RDFURI_ITEM_ROOT));
772
773 cleanDataSource(gSearchDS, rootctr);
774
775 var labelNode = gRDF.GetResource("urn:mozilla:addons:search:status:header");
776 rootctr.AppendElement(labelNode);
777 gSearchDS.Assert(labelNode,
778 gRDF.GetResource(PREFIX_NS_EM + "statusMessage"),
779 gRDF.GetLiteral("true"),
780 true);
781 gSearchDS.Assert(labelNode,
782 gRDF.GetResource(PREFIX_NS_EM + "type"),
783 gRDF.GetLiteral(isRecommended ? "recommended-failure" : "search-failure"),
784 true);
785 }
786
787 // nsIAddonSearchResultsCallback for the recommended search
788 var RecommendedSearchResults = {
searchSucceeded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
789 searchSucceeded: function(aAddons, aAddonCount, aTotalResults) {
790 gRecommendedAddons = aAddons;
791 displaySearchResults(aAddons, aTotalResults, true);
792 },
793
searchFailed
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
794 searchFailed: function() {
795 displaySearchFailure(true);
796 }
797 }
798
799 // nsIAddonSearchResultsCallback for a standard search
800 var AddonSearchResults = {
searchSucceeded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
801 searchSucceeded: function(aAddons, aAddonCount, aTotalResults) {
802 displaySearchResults(aAddons, aTotalResults, false);
803 },
804
searchFailed
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
805 searchFailed: function() {
806 displaySearchFailure(false);
807 }
808 }
809
810 // Initialises the search repository and the results datasource
initSearchDS
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
811 function initSearchDS() {
812 var repository = "@mozilla.org/extensions/addon-repository;1";
813 try {
814 var repo = gPref.getCharPref(PREF_GETADDONS_REPOSITORY);
815 if (repo in Components.classes)
816 repository = repo;
817 } catch (e) { }
818 gAddonRepository = Components.classes[repository]
819 .createInstance(Components.interfaces.nsIAddonRepository);
820 var browseAddons = document.getElementById("browseAddons");
821 var homepage = gAddonRepository.homepageURL;
822 if (homepage)
823 browseAddons.setAttribute("homepageURL", homepage);
824 else
825 browseAddons.hidden = true;
826 gSearchDS = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"]
827 .createInstance(Components.interfaces.nsIRDFDataSource);
828 gExtensionsView.database.AddDataSource(gSearchDS);
829 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
830 .getService(nsIIOService);
831 if (!ioService.offline)
832 retrieveRepositoryAddons(document.getElementById("searchbox").value);
833 }
834
initPluginsDS
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
835 function initPluginsDS()
836 {
837 gPluginsDS = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"]
838 .createInstance(Components.interfaces.nsIRDFDataSource);
839 rebuildPluginsDS();
840 }
841
rebuildPluginsDS
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
842 function rebuildPluginsDS()
843 {
844 var phs = Components.classes["@mozilla.org/plugin/host;1"]
845 .getService(Components.interfaces.nsIPluginHost);
846 var plugins = phs.getPluginTags({ });
847 var rdfCU = Components.classes["@mozilla.org/rdf/container-utils;1"]
848 .getService(Components.interfaces.nsIRDFContainerUtils);
849 var rootctr = rdfCU.MakeSeq(gPluginsDS, gRDF.GetResource(RDFURI_ITEM_ROOT));
850 gPlugins = { };
851
852 // Running in a batch stops the template builder from running
853 gPluginsDS.beginUpdateBatch();
854
855 cleanDataSource(gPluginsDS, rootctr);
856
857 // Case insensitive sort
compare
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
858 function compare(a, b) {
859 if (a.name.toLowerCase() < b.name.toLowerCase())
860 return -1;
861 if (a.name.toLowerCase() > b.name.toLowerCase())
862 return 1;
863 return 0;
864 }
865 plugins.sort(compare);
866
867 for (var i = 0; i < plugins.length; i++) {
868 var plugin = plugins[i];
869 var name = plugin.name;
870 if (!(name in gPlugins))
871 gPlugins[name] = { };
872
873 // Removes all html markup in a plugin's description
874 var desc = plugin.description.replace(/<\/?[a-z][^>]*>/gi, " ");
875 if (!(desc in gPlugins[name])) {
876 var homepageURL = null;
877 // Some plugins (e.g. QuickTime) add an anchor to their description to
878 // provide a link to the plugin's homepage in about:plugins. This can be
879 // used to provide access to a plugins homepage in the add-ons mgr.
880 if (/<A\s+HREF=[^>]*>/i.test(plugin.description))
881 homepageURL = /<A\s+HREF=["']?([^>'"\s]*)/i.exec(plugin.description)[1];
882
883 gPlugins[name][desc] = { filename : plugin.filename,
884 homepageURL : homepageURL,
885 disabled : plugin.disabled,
886 blocklisted : plugin.blocklisted,
887 plugins : [] };
888 }
889 gPlugins[name][desc].plugins.push(plugin);
890 }
891
892 for (var pluginName in gPlugins) {
893 for (var pluginDesc in gPlugins[pluginName]) {
894 plugin = gPlugins[pluginName][pluginDesc];
895 var pluginNode = gRDF.GetResource(PREFIX_ITEM_URI + plugin.filename);
896 rootctr.AppendElement(pluginNode);
897 gPluginsDS.Assert(pluginNode,
898 gRDF.GetResource(PREFIX_NS_EM + "name"),
899 gRDF.GetLiteral(pluginName),
900 true);
901 gPluginsDS.Assert(pluginNode,
902 gRDF.GetResource(PREFIX_NS_EM + "addonID"),
903 gRDF.GetLiteral(plugin.filename),
904 true);
905 gPluginsDS.Assert(pluginNode,
906 gRDF.GetResource(PREFIX_NS_EM + "description"),
907 gRDF.GetLiteral(pluginDesc),
908 true);
909 if (plugin.homepageURL)
910 gPluginsDS.Assert(pluginNode,
911 gRDF.GetResource(PREFIX_NS_EM + "homepageURL"),
912 gRDF.GetLiteral(plugin.homepageURL),
913 true);
914 gPluginsDS.Assert(pluginNode,
915 gRDF.GetResource(PREFIX_NS_EM + "isDisabled"),
916 gRDF.GetLiteral((plugin.disabled ||
917 plugin.blocklisted) ? "true" : "false"),
918 true);
919 gPluginsDS.Assert(pluginNode,
920 gRDF.GetResource(PREFIX_NS_EM + "blocklisted"),
921 gRDF.GetLiteral(plugin.blocklisted ? "true" : "false"),
922 true);
923 gPluginsDS.Assert(pluginNode,
924 gRDF.GetResource(PREFIX_NS_EM + "compatible"),
925 gRDF.GetLiteral("true"),
926 true);
927 gPluginsDS.Assert(pluginNode,
928 gRDF.GetResource(PREFIX_NS_EM + "plugin"),
929 gRDF.GetLiteral("true"),
930 true);
931 }
932 }
933
934 gPluginsDS.endUpdateBatch();
935 }
936
togglePluginDisabled
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
937 function togglePluginDisabled(aName, aDesc)
938 {
939 var plugin = gPlugins[aName][aDesc];
940 plugin.disabled = !plugin.disabled;
941 for (var i = 0; i < plugin.plugins.length; ++i)
942 plugin.plugins[i].disabled = plugin.disabled;
943 var isDisabled = plugin.disabled || plugin.blocklisted;
944 gPluginsDS.Change(gRDF.GetResource(PREFIX_ITEM_URI + plugin.filename),
945 gRDF.GetResource(PREFIX_NS_EM + "isDisabled"),
946 gRDF.GetLiteral(isDisabled ? "false" : "true"),
947 gRDF.GetLiteral(isDisabled ? "true" : "false"));
948 gExtensionsViewController.onCommandUpdate();
949 gExtensionsView.selectedItem.focus();
950 }
951
952 ///////////////////////////////////////////////////////////////////////////////
953 // Startup, Shutdown
Startup
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
954 function Startup()
955 {
956 gExtensionStrings = document.getElementById("extensionsStrings");
957 gPref = Components.classes["@mozilla.org/preferences-service;1"]
958 .getService(Components.interfaces.nsIPrefBranch2);
959 var defaultPref = gPref.QueryInterface(Components.interfaces.nsIPrefService)
960 .getDefaultBranch(null);
961 try {
962 gCurrentTheme = gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
963 gDefaultTheme = defaultPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
964 if (gPref.getBoolPref(PREF_EXTENSIONS_DSS_SWITCHPENDING))
965 gCurrentTheme = gPref.getCharPref(PREF_DSS_SKIN_TO_SELECT);
966 }
967 catch (e) { }
968
969 gExtensionsView = document.getElementById("extensionsView");
970 gExtensionManager = Components.classes["@mozilla.org/extensions/manager;1"]
971 .getService(nsIExtensionManager);
972 var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
973 .getService(Components.interfaces.nsIXULAppInfo)
974 .QueryInterface(Components.interfaces.nsIXULRuntime);
975 gInSafeMode = appInfo.inSafeMode;
976 gAppID = appInfo.ID;
977
978 try {
979 gCheckCompat = gPref.getBoolPref(PREF_EM_CHECK_COMPATIBILITY);
980 } catch(e) { }
981
982 try {
983 gCheckUpdateSecurity = gPref.getBoolPref(PREF_EM_CHECK_UPDATE_SECURITY);
984 } catch(e) { }
985
986 gPref.addObserver(PREF_DSS_SKIN_TO_SELECT, gPrefObserver, false);
987 gPref.addObserver(PREF_GENERAL_SKINS_SELECTEDSKIN, gPrefObserver, false);
988
989 try {
990 gShowGetAddonsPane = gPref.getBoolPref(PREF_GETADDONS_SHOWPANE);
991 } catch(e) { }
992
993 // Sort on startup and anytime an add-on is installed or upgraded.
994 gExtensionManager.sortTypeByProperty(nsIUpdateItem.TYPE_ANY, "name", true);
995 // Extension Command Updating is handled by a command controller.
996 gExtensionsView.controllers.appendController(gExtensionsViewController);
997 gExtensionsView.addEventListener("select", onAddonSelect, false);
998
999 gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"]
1000 .getService(Components.interfaces.nsIRDFService);
1001
1002 initPluginsDS();
1003 gExtensionsView.database.AddDataSource(gPluginsDS);
1004 if (gShowGetAddonsPane)
1005 initSearchDS();
1006 gExtensionsView.database.AddDataSource(gExtensionManager.datasource);
1007 gExtensionsView.setAttribute("ref", RDFURI_ITEM_ROOT);
1008
1009 document.getElementById("search-view").hidden = !gShowGetAddonsPane;
1010 updateOptionalViews();
1011
1012 var viewGroup = document.getElementById("viewGroup");
1013
1014 gExtensionsView.focus();
1015 gExtensionsViewController.onCommandUpdate();
1016
1017 // Now look and see if we're being opened by XPInstall
1018 gDownloadManager = new XPInstallDownloadManager();
1019 var os = Components.classes["@mozilla.org/observer-service;1"]
1020 .getService(Components.interfaces.nsIObserverService);
1021 os.addObserver(gDownloadManager, "xpinstall-download-started", false);
1022 os.addObserver(gAddonsMsgObserver, "addons-message-notification", false);
1023 os.addObserver(gPluginObserver, "plugins-list-updated", false);
1024
1025 gObserverIndex = gExtensionManager.addInstallListener(gDownloadManager);
1026
1027 if (!gCheckCompat) {
1028 var msgText = getExtensionString("disabledCompatMsg");
1029 var buttonLabel = getExtensionString("enableButtonLabel");
1030 var buttonAccesskey = getExtensionString("enableButtonAccesskey");
1031 var notifyData = "addons-enable-compatibility";
1032 showMessage("chrome://mozapps/skin/extensions/question.png",
1033 msgText, buttonLabel, buttonAccesskey,
1034 true, notifyData);
1035 }
1036 if (!gCheckUpdateSecurity) {
1037 var defaultCheckSecurity = true;
1038 try {
1039 defaultCheckSecurity = defaultPref.getBoolPref(PREF_EM_CHECK_UPDATE_SECURITY);
1040 } catch (e) { }
1041
1042 // App has update security checking enabled by default so show warning
1043 if (defaultCheckSecurity) {
1044 var msgText = getExtensionString("disabledUpdateSecurityMsg");
1045 var buttonLabel = getExtensionString("enableButtonLabel");
1046 var buttonAccesskey = getExtensionString("enableButtonAccesskey");
1047 var notifyData = "addons-enable-updatesecurity";
1048 showMessage("chrome://mozapps/skin/extensions/question.png",
1049 msgText, buttonLabel, buttonAccesskey,
1050 true, notifyData);
1051 }
1052 }
1053 if (gInSafeMode) {
1054 showMessage("chrome://mozapps/skin/extensions/question.png",
1055 getExtensionString("safeModeMsg"),
1056 null, null, true, null);
1057 }
1058
1059 gExtensionsView.builder.addListener(TemplateBuilderListener);
1060
1061 if ("arguments" in window) {
1062 try {
1063 var params = window.arguments[0].QueryInterface(Components.interfaces.nsIDialogParamBlock);
1064 var manager = window.arguments[1].QueryInterface(Components.interfaces.nsIObserver);
1065 gDownloadManager.addDownloads(params, manager);
1066 }
1067 catch (e) {
1068 if (window.arguments[0] == "updates-only") {
1069 gUpdatesOnly = true;
1070 //@line 1113 "/home/visbrero/mnt/roisin/rev_control/hg/mozilla/toolkit/mozapps/extensions/content/extensions.js"
1071 document.getElementById("viewGroup").hidden = true;
1072 document.getElementById("extensionsView").setAttribute("norestart", "");
1073 showView("updates");
1074 showMessage("chrome://mozapps/skin/extensions/question.png",
1075 getExtensionString("newUpdatesAvailableMsg"),
1076 null, null, true, null);
1077 document.title = getExtensionString("newUpdateWindowTitle", [getBrandShortName()]);
1078 }
1079 else if (window.arguments.length == 2) {
1080 gNewAddons = window.arguments[1].split(",");
1081 var installMsg = PluralForm.get(gNewAddons.length, getExtensionString("newAddonsNotificationMsg2"));
1082 installMsg = installMsg.replace("%S", gNewAddons.length);
1083 showMessage("chrome://mozapps/skin/extensions/question.png", installMsg,
1084 null, null, true, null);
1085 var extensionCount = 0;
1086 var themeCount = 0;
1087 var localeCount = 0;
1088 for (var i = 0; i < gNewAddons.length; i++) {
1089 var item = gExtensionManager.getItemForID(gNewAddons[i]);
1090 switch (item.type) {
1091 case Components.interfaces.nsIUpdateItem.TYPE_EXTENSION:
1092 extensionCount++;
1093 break;
1094 case Components.interfaces.nsIUpdateItem.TYPE_THEME:
1095 themeCount++;
1096 break;
1097 case Components.interfaces.nsIUpdateItem.TYPE_LOCALE:
1098 localeCount++;
1099 break;
1100 }
1101 }
1102 if (themeCount > extensionCount && themeCount > localeCount)
1103 showView("themes");
1104 else if (localeCount > extensionCount && localeCount > themeCount)
1105 showView("locales");
1106 else
1107 showView("extensions");
1108 }
1109 else
1110 showView(window.arguments[0]);
1111 }
1112 }
1113 else if (viewGroup.hasAttribute("last-selected") &&
1114 document.getElementById(viewGroup.getAttribute("last-selected") + "-view") &&
1115 !document.getElementById(viewGroup.getAttribute("last-selected") + "-view").hidden)
1116 showView(viewGroup.getAttribute("last-selected"));
1117 else
1118 showView("search");
1119
1120 if (gExtensionsView.selectedItem)
1121 gExtensionsView.scrollBoxObject.scrollToElement(gExtensionsView.selectedItem);
1122
1123 gPref.setBoolPref(PREF_UPDATE_NOTIFYUSER, false);
1124
1125 if (gUpdatesOnly && gExtensionsView.children.length == 0)
1126 window.close();
1127 }
1128
Shutdown
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1129 function Shutdown()
1130 {
1131 gExtensionsView.builder.removeListener(TemplateBuilderListener);
1132
1133 gPref.removeObserver(PREF_DSS_SKIN_TO_SELECT, gPrefObserver);
1134 gPref.removeObserver(PREF_GENERAL_SKINS_SELECTEDSKIN, gPrefObserver);
1135 if (gAddonRepository && gAddonRepository.isSearching)
1136 gAddonRepository.cancelSearch();
1137
1138 gRDF = null;
1139 gPref = null;
1140 gExtensionsView.removeEventListener("select", onAddonSelect, false);
1141 gExtensionsView.database.RemoveDataSource(gExtensionManager.datasource);
1142
1143 gExtensionManager.removeInstallListenerAt(gObserverIndex);
1144
1145 var os = Components.classes["@mozilla.org/observer-service;1"]
1146 .getService(Components.interfaces.nsIObserverService);
1147 os.removeObserver(gAddonsMsgObserver, "addons-message-notification");
1148 os.removeObserver(gDownloadManager, "xpinstall-download-started");
1149 os.removeObserver(gPluginObserver, "plugins-list-updated");
1150 var currentNotification = document.getElementById("addonsMsg").currentNotification;
1151 if (currentNotification && currentNotification.value == "addons-no-updates")
1152 window.removeEventListener("select", noUpdatesDismiss, true);
1153 }
1154
1155 var TemplateBuilderListener = {
willRebuild
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1156 willRebuild: function(aBuilder) {
1157 },
1158
didRebuild
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1159 didRebuild: function(aBuilder) {
1160 // Display has been rebuilt, update necessary attributes
1161 if (gView == "extensions" || gView == "themes" || gView == "locales") {
1162 for (var i = 0; i < gNewAddons.length; i++) {
1163 var item = document.getElementById(PREFIX_ITEM_URI + gNewAddons[i]);
1164 if (item)
1165 item.setAttribute("newAddon", "true");
1166 }
1167 }
1168
1169 if (gView == "themes") {
1170 if (gPref.getBoolPref(PREF_EXTENSIONS_DSS_SWITCHPENDING)) {
1171 var item = getItemForInternalName(gCurrentTheme);
1172 if (item)
1173 setRestartMessage(item);
1174 }
1175 }
1176 },
1177
QueryInterface
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1178 QueryInterface: function (aIID)
1179 {
1180 if (!aIID.equals(Components.interfaces.nsIXULBuilderListener) &&
1181 !aIID.equals(Components.interfaces.nsISupports))
1182 throw Components.results.NS_ERROR_NO_INTERFACE;
1183 return this;
1184 }
1185 };
1186
1187 ///////////////////////////////////////////////////////////////////////////////
1188 //
1189 // XPInstall
1190 //
1191
getURLSpecFromFile
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1192 function getURLSpecFromFile(aFile)
1193 {
1194 var ioServ = Components.classes["@mozilla.org/network/io-service;1"]
1195 .getService(nsIIOService);
1196 var fph = ioServ.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler);
1197 return fph.getURLSpecFromFile(aFile);
1198 }
1199
XPInstallDownloadManager
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1200 function XPInstallDownloadManager()
1201 {
1202 }
1203
1204 XPInstallDownloadManager.prototype = {
observe
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1205 observe: function (aSubject, aTopic, aData)
1206 {
1207 switch (aTopic) {
1208 case "xpinstall-download-started":
1209 var params = aSubject.QueryInterface(Components.interfaces.nsISupportsArray);
1210 var paramBlock = params.GetElementAt(0).QueryInterface(Components.interfaces.nsISupportsInterfacePointer);
1211 paramBlock = paramBlock.data.QueryInterface(Components.interfaces.nsIDialogParamBlock);
1212 var manager = params.GetElementAt(1).QueryInterface(Components.interfaces.nsISupportsInterfacePointer);
1213 manager = manager.data.QueryInterface(Components.interfaces.nsIObserver);
1214 this.addDownloads(paramBlock, manager);
1215 break;
1216 }
1217 },
1218
addDownloads
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1219 addDownloads: function (aParams, aManager)
1220 {
1221 var numXPInstallItems = aParams.GetInt(1);
1222 var items = [];
1223 var switchPane = false;
1224 for (var i = 0; i < numXPInstallItems;) {
1225 var displayName = aParams.GetString(i++);
1226 var url = aParams.GetString(i++);
1227 var iconURL = aParams.GetString(i++);
1228 var uri = Components.classes["@mozilla.org/network/io-service;1"]
1229 .getService(nsIIOService).newURI(url, null, null);
1230 var isTheme = uri.QueryInterface(nsIURL).fileExtension.toLowerCase() == "jar";
1231 if (!iconURL) {
1232 iconURL = isTheme ? "chrome://mozapps/skin/extensions/themeGeneric.png" :
1233 "chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png";
1234 }
1235
1236 var type = isTheme ? nsIUpdateItem.TYPE_THEME : nsIUpdateItem.TYPE_EXTENSION;
1237 var item = Components.classes["@mozilla.org/updates/item;1"]
1238 .createInstance(Components.interfaces.nsIUpdateItem);
1239 item.init(url, " ", "app-profile", "", "", displayName, url, "", iconURL, "", "", type, "");
1240 items.push(item);
1241
1242 // Advance the enumerator
1243 var certName = aParams.GetString(i++);
1244
1245 // Check whether the install was triggered from the Get Add-ons pane.
1246 if (url in gPendingInstalls) {
1247 // Update the installation status
1248 gSearchDS.Assert(gRDF.GetResource(gPendingInstalls[url]),
1249 gRDF.GetResource(PREFIX_NS_EM + "action"),
1250 gRDF.GetLiteral("installing"),
1251 true);
1252 delete gPendingInstalls[url];
1253 }
1254 else {
1255 switchPane = true;
1256 }
1257 }
1258
1259 gInstalling = true;
1260 gExtensionManager.addDownloads(items, items.length, aManager);
1261 updateOptionalViews();
1262 updateGlobalCommands();
1263 // Only switch to the installs pane if there was an not started by the
1264 // Get Add-ons pane
1265 if (switchPane)
1266 showView("installs");
1267 },
1268
getElementForAddon
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1269 getElementForAddon: function(aAddon)
1270 {
1271 var element = document.getElementById(PREFIX_ITEM_URI + aAddon.id);
1272 if (aAddon.id == aAddon.xpiURL)
1273 element = document.getElementById(aAddon.xpiURL);
1274 return element;
1275 },
1276
1277 /////////////////////////////////////////////////////////////////////////////
1278 // nsIAddonInstallListener
onDownloadStarted
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1279 onDownloadStarted: function(aAddon)
1280 {
1281 },
1282
onDownloadEnded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1283 onDownloadEnded: function(aAddon)
1284 {
1285 },
1286
onInstallStarted
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1287 onInstallStarted: function(aAddon)
1288 {
1289 },
1290
onCompatibilityCheckStarted
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1291 onCompatibilityCheckStarted: function(aAddon)
1292 {
1293 },
1294
onCompatibilityCheckEnded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1295 onCompatibilityCheckEnded: function(aAddon, aStatus)
1296 {
1297 },
1298
onInstallEnded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1299 onInstallEnded: function(aAddon, aStatus)
1300 {
1301 // From nsInstall.h
1302 // USER_CANCELLED = -210
1303 // All other xpinstall errors are <= -200
1304 // Any errors from the EM will have been displayed directly by the EM
1305 if (aStatus > -200 || aStatus == -210)
1306 return;
1307
1308 var xpinstallStrings = document.getElementById("xpinstallStrings");
1309 try {
1310 var msg = xpinstallStrings.getString("error" + aStatus);
1311 }
1312 catch (e) {
1313 msg = xpinstallStrings.getFormattedString("unknown.error", [aStatus]);
1314 }
1315 var title = getExtensionString("errorInstallTitle");
1316 var message = getExtensionString("errorInstallMsg", [getBrandShortName(),
1317 aAddon.xpiURL, msg]);
1318 var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
1319 .getService(Components.interfaces.nsIPromptService);
1320 ps.alert(window, title, message + "\n" + aStatus);
1321 },
1322
onInstallsCompleted
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1323 onInstallsCompleted: function()
1324 {
1325 gInstalling = false;
1326 gExtensionManager.sortTypeByProperty(nsIUpdateItem.TYPE_ANY, "name", true);
1327 if (gUpdatesOnly) {
1328 setElementDisabledByID("cmd_continue", false);
1329 document.getElementById("continueDialogButton").focus();
1330 }
1331 else {
1332 updateOptionalViews();
1333 updateGlobalCommands();
1334 }
1335 },
1336
1337 _urls: { },
onDownloadProgress
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1338 onDownloadProgress: function (aAddon, aValue, aMaxValue)
1339 {
1340 var element = this.getElementForAddon(aAddon);
1341 if (!element)
1342 return;
1343 var percent = Math.round((aValue / aMaxValue) * 100);
1344 if (percent > 1 && !(aAddon.xpiURL in this._urls))
1345 this._urls[aAddon.xpiURL] = true;
1346
1347 var statusPrevious = element.getAttribute("status");
1348 var statusCurrent = DownloadUtils.getTransferTotal(aValue, aMaxValue);
1349 if (statusCurrent != statusPrevious)
1350 element.setAttribute("status", statusCurrent);
1351 },
1352
1353 /////////////////////////////////////////////////////////////////////////////
1354 // nsISupports
QueryInterface
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1355 QueryInterface: function (aIID)
1356 {
1357 if (!aIID.equals(Components.interfaces.nsIAddonInstallListener) &&
1358 !aIID.equals(Components.interfaces.nsISupports))
1359 throw Components.results.NS_ERROR_NO_INTERFACE;
1360 return this;
1361 }
1362 };
1363
1364 ///////////////////////////////////////////////////////////////////////////////
1365 //
1366 // Update Listener
1367 //
UpdateCheckListener
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1368 function UpdateCheckListener() {
1369 }
1370 UpdateCheckListener.prototype = {
1371 _updateFound: false,
1372 _totalCount: 0,
1373 _completedCount: 0,
1374
1375 /**
1376 * See nsIExtensionManager.idl
1377 */
onUpdateStarted
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1378 onUpdateStarted: function() {
1379 gExtensionsView.setAttribute("update-operation", "checking");
1380 gExtensionsViewController.onCommandUpdate();
1381 updateGlobalCommands();
1382 this._totalCount = gExtensionsView.children.length;
1383 },
1384
1385 /**
1386 * See nsIExtensionManager.idl
1387 */
onUpdateEnded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1388 onUpdateEnded: function() {
1389 if (!document)
1390 return;
1391 document.getElementById("progressBox").hidden = true;
1392 var viewGroup = document.getElementById("viewGroup");
1393 viewGroup.hidden = false;
1394 gExtensionsView.removeAttribute("update-operation");
1395 gExtensionsViewController.onCommandUpdate();
1396 updateOptionalViews();
1397 updateGlobalCommands();
1398 if (this._updateFound)
1399 showView("updates");
1400 else {
1401 showMessage("chrome://mozapps/skin/extensions/question.png",
1402 getExtensionString("noUpdatesMsg"),
1403 null, null, true, "addons-no-updates");
1404 window.addEventListener("select", noUpdatesDismiss, true);
1405 }
1406 },
1407
1408 /**
1409 * See nsIExtensionManager.idl
1410 */
onAddonUpdateStarted
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1411 onAddonUpdateStarted: function(addon) {
1412 if (!document)
1413 return;
1414 var element = document.getElementById(PREFIX_ITEM_URI + addon.id);
1415 element.setAttribute("loading", "true");
1416 element.setAttribute("updateStatus", getExtensionString("updatingMsg"));
1417 },
1418
1419 /**
1420 * See nsIExtensionManager.idl
1421 */
onAddonUpdateEnded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1422 onAddonUpdateEnded: function(addon, status) {
1423 if (!document)
1424 return;
1425 var element = document.getElementById(PREFIX_ITEM_URI + addon.id);
1426 element.removeAttribute("loading");
1427 const nsIAUCL = Components.interfaces.nsIAddonUpdateCheckListener;
1428 switch (status) {
1429 case nsIAUCL.STATUS_UPDATE:
1430 var statusMsg = getExtensionString("updateAvailableMsg", [addon.version]);
1431 this._updateFound = true;
1432 break;
1433 case nsIAUCL.STATUS_VERSIONINFO:
1434 statusMsg = getExtensionString("updateCompatibilityMsg");
1435 break;
1436 case nsIAUCL.STATUS_FAILURE:
1437 var name = element.getAttribute("name");
1438 statusMsg = getExtensionString("updateErrorMessage", [name]);
1439 break;
1440 case nsIAUCL.STATUS_DISABLED:
1441 name = element.getAttribute("name");
1442 statusMsg = getExtensionString("updateDisabledMessage", [name]);
1443 break;
1444 case nsIAUCL.STATUS_APP_MANAGED:
1445 case nsIAUCL.STATUS_NO_UPDATE:
1446 statusMsg = getExtensionString("updateNoUpdateMsg");
1447 break;
1448 case nsIAUCL.STATUS_NOT_MANAGED:
1449 statusMsg = getExtensionString("updateNotManagedMessage", [getBrandShortName()]);
1450 break;
1451 case nsIAUCL.STATUS_READ_ONLY:
1452 statusMsg = getExtensionString("updateReadOnlyMessage");
1453 break;
1454 default:
1455 statusMsg = getExtensionString("updateNoUpdateMsg");
1456 }
1457 element.setAttribute("updateStatus", statusMsg);
1458 ++this._completedCount;
1459 document.getElementById("progressStatus").value = getExtensionString("finishedUpdateCheck", [addon.name]);
1460 document.getElementById("addonsProgress").value = Math.ceil((this._completedCount / this._totalCount) * 100);
1461 },
1462
1463 /**
1464 * See nsISupports.idl
1465 */
QueryInterface
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1466 QueryInterface: function(iid) {
1467 if (!iid.equals(Components.interfaces.nsIAddonUpdateCheckListener) &&
1468 !iid.equals(Components.interfaces.nsISupports))
1469 throw Components.results.NS_ERROR_NO_INTERFACE;
1470 return this;
1471 }
1472 };
1473
1474
1475 ///////////////////////////////////////////////////////////////////////////////
1476 //
1477 // View Event Handlers
1478 //
onViewDoubleClick
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1479 function onViewDoubleClick(aEvent)
1480 {
1481 if (aEvent.button != 0 || !gExtensionsView.selectedItem)
1482 return;
1483
1484 switch (gView) {
1485 case "extensions":
1486 gExtensionsViewController.doCommand('cmd_options');
1487 break;
1488 case "themes":
1489 gExtensionsViewController.doCommand('cmd_useTheme');
1490 break;
1491 case "updates":
1492 gExtensionsViewController.doCommand('cmd_includeUpdate');
1493 break;
1494 }
1495 }
1496
onAddonSelect
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1497 function onAddonSelect(aEvent)
1498 {
1499 var viewButton = document.getElementById("viewGroup").selectedItem;
1500 if (viewButton.hasAttribute("persist") && gExtensionsView.selectedItem)
1501 viewButton.setAttribute("last-selected", gExtensionsView.selectedItem.id);
1502
1503 if (!document.getElementById("themePreviewArea").hidden) {
1504 var previewImageDeck = document.getElementById("previewImageDeck");
1505 if (gView == "themes") {
1506 var previewImage = document.getElementById("previewImage");
1507 if (!gExtensionsView.selectedItem) {
1508 previewImageDeck.selectedIndex = 0;
1509 if (previewImage.hasAttribute("src"))
1510 previewImage.removeAttribute("src");
1511 }
1512 else {
1513 var url = gExtensionsView.selectedItem.getAttribute("previewImage");
1514 if (url) {
1515 previewImageDeck.selectedIndex = 2;
1516 previewImage.setAttribute("src", url);
1517 }
1518 else {
1519 previewImageDeck.selectedIndex = 1;
1520 if (previewImage.hasAttribute("src"))
1521 previewImage.removeAttribute("src");
1522 }
1523 }
1524 }
1525 else if (gView == "updates") {
1526 UpdateInfoLoader.cancelLoad();
1527 if (!gExtensionsView.selectedItem) {
1528 previewImageDeck.selectedIndex = 3;
1529 }
1530 else {
1531 var uri = gExtensionsView.selectedItem.getAttribute("availableUpdateInfo");
1532 if (isSafeURI(uri))
1533 UpdateInfoLoader.loadInfo(uri);
1534 else
1535 previewImageDeck.selectedIndex = 4;
1536 }
1537 }
1538 }
1539 }
1540
1541 /**
1542 * Manages the retrieval of update information and the xsl stylesheet
1543 * used to format the inforation into chrome.
1544 */
1545 var UpdateInfoLoader = {
1546 _stylesheet: null,
1547 _styleRequest: null,
1548 _infoDocument: null,
1549 _infoRequest: null,
1550
1551 // Called once both stylesheet and info requests have completed
displayInfo
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1552 displayInfo: function()
1553 {
1554 var processor = Components.classes["@mozilla.org/document-transformer;1?type=xslt"]
1555 .createInstance(Components.interfaces.nsIXSLTProcessor);
1556 processor.flags |= Components.interfaces.nsIXSLTProcessorPrivate.DISABLE_ALL_LOADS;
1557
1558 processor.importStylesheet(this._stylesheet);
1559 var fragment = processor.transformToFragment(this._infoDocument, document);
1560 document.getElementById("infoDisplay").appendChild(fragment);
1561 document.getElementById("previewImageDeck").selectedIndex = 7;
1562 },
1563
onStylesheetLoaded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1564 onStylesheetLoaded: function(event)
1565 {
1566 var request = event.target;
1567 this._styleRequest = null;
1568 this._stylesheet = request.responseXML;
1569
1570 if (!this._stylesheet ||
1571 this._stylesheet.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
1572 (request.status != 200 && request.status != 0)) {
1573 // The stylesheet load failing is a bad sign
1574 document.getElementById("previewImageDeck").selectedIndex = 6;
1575 return;
1576 }
1577
1578 if (this._infoDocument)
1579 this.displayInfo();
1580 },
1581
onInfoLoaded
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1582 onInfoLoaded: function(event)
1583 {
1584 var request = event.target;
1585 this._infoRequest = null;
1586 this._infoDocument = request.responseXML;
1587
1588 if (!this._infoDocument ||
1589 this._infoDocument.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
1590 (request.status != 200 && request.status != 0)) {
1591 // Should attempt to parse request.responseText with the html parser
1592 document.getElementById("previewImageDeck").selectedIndex = 6;
1593 return;
1594 }
1595
1596 if (this._stylesheet)
1597 this.displayInfo();
1598 },
1599
onError
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1600 onError: function(event)
1601 {
1602 if (event.request == this._infoRequest)
1603 this._infoRequest = null;
1604 else // Means the stylesheet load has failed which is pretty bad news
1605 this.cancelRequest();
1606
1607 document.getElementById("previewImageDeck").selectedIndex = 6;
1608 },
1609
loadInfo
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1610 loadInfo: function(url)
1611 {
1612 this.cancelLoad();
1613 this._infoDocument = null;
1614 document.getElementById("previewImageDeck").selectedIndex = 5;
1615 var display = document.getElementById("infoDisplay");
1616 while (display.lastChild)
1617 display.removeChild(display.lastChild);
1618
1619 this._infoRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
1620 .createInstance(Components.interfaces.nsIXMLHttpRequest);
1621 this._infoRequest.open("GET", url, true);
1622
1623 var self = this;
anon:1624:32
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1624 this._infoRequest.onerror = function(event) { self.onError(event); };
anon:1625:31
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1625 this._infoRequest.onload = function(event) { self.onInfoLoaded(event); };
1626 this._infoRequest.send(null);
1627
1628 // We may have the stylesheet cached from a previous load, or may still be
1629 // loading it.
1630 if (this._stylesheet || this._styleRequest)
1631 return;
1632
1633 this._styleRequest = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
1634 .createInstance(Components.interfaces.nsIXMLHttpRequest);
1635 this._styleRequest.open("GET", "chrome://mozapps/content/extensions/updateinfo.xsl", true);
1636 this._styleRequest.overrideMimeType("text/xml");
1637
anon:1638:33
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1638 this._styleRequest.onerror = function(event) { self.onError(event); };
anon:1639:32
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1639 this._styleRequest.onload = function(event) { self.onStylesheetLoaded(event); };
1640 this._styleRequest.send(null);
1641 },
1642
cancelLoad
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1643 cancelLoad: function()
1644 {
1645 // Leave the stylesheet loader running, there's a good chance we'll need it
1646 if (this._infoRequest)
1647 this._infoRequest.abort();
1648 this._infoRequest = null;
1649 }
1650 }
1651
1652 ///////////////////////////////////////////////////////////////////////////////
1653 // View Context Menus
1654 var gAddonContextMenus = ["menuitem_useTheme", "menuitem_options", "menuitem_homepage",
1655 "menuitem_about", "menuseparator_1", "menuitem_uninstall",
1656 "menuitem_cancelUninstall", "menuitem_cancelInstall",
1657 "menuitem_cancelUpgrade", "menuitem_checkUpdate",
1658 "menuitem_enable", "menuitem_disable"];
1659 var gUpdateContextMenus = ["menuitem_homepage", "menuitem_about", "menuseparator_1",
1660 "menuitem_installUpdate", "menuitem_includeUpdate"];
1661 // For Firefox don't display context menuitems that can open a browser window.
1662 var gUpdateContextMenusNoBrowser = ["menuitem_installUpdate", "menuitem_includeUpdate"];
1663 var gInstallContextMenus = ["menuitem_homepage", "menuitem_about"];
1664 var gSearchContextMenus = ["menuitem_learnMore", "menuitem_installSearchResult"];
1665
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1666 function buildContextMenu(aEvent)
1667 {
1668 var popup = document.getElementById("addonContextMenu");
1669 var selectedItem = gExtensionsView.selectedItem;
1670 if (aEvent.target !== popup || !selectedItem)
1671 return false;
1672
1673 while (popup.hasChildNodes())
1674 popup.removeChild(popup.firstChild);
1675
1676 switch (gView) {
1677 case "search":
1678 var menus = gSearchContextMenus;
1679 break;
1680 case "extensions":
1681 case "themes":
1682 case "locales":
1683 case "plugins":
1684 menus = gAddonContextMenus;
1685 break;
1686 case "updates":
1687 menus = gUpdateContextMenus;
1688 break;
1689 case "installs":
1690 menus = gInstallContextMenus;
1691 break;
1692 }
1693
1694 for (var i = 0; i < menus.length; ++i) {
1695 var clonedMenu = document.getElementById(menus[i]).cloneNode(true);
1696 clonedMenu.id = clonedMenu.id + "_clone";
1697 popup.appendChild(clonedMenu);
1698 }
1699
1700 // All views support about
1701 var menuitem_about = document.getElementById("menuitem_about_clone");
1702 var name = selectedItem ? selectedItem.getAttribute("name") : "";
1703 menuitem_about.setAttribute("label", getExtensionString("aboutAddon", [name]));
1704
1705 /* When an update or install is pending allow canceling the update or install
1706 and don't allow uninstall. When an uninstall is pending allow canceling the
1707 uninstall.*/
1708 if (gView != "updates" && gView != "installs") {
1709 var canEnable = gExtensionsViewController.isCommandEnabled("cmd_cancelUninstall");
1710 document.getElementById("menuitem_cancelUninstall_clone").hidden = !canEnable;
1711 var canCancelInstall = gExtensionsViewController.isCommandEnabled("cmd_cancelInstall");
1712 document.getElementById("menuitem_cancelInstall_clone").hidden = !canCancelInstall;
1713 var canCancelUpgrade = gExtensionsViewController.isCommandEnabled("cmd_cancelUpgrade");
1714 document.getElementById("menuitem_cancelUpgrade_clone").hidden = !canCancelUpgrade;
1715 document.getElementById("menuitem_uninstall_clone").hidden = canEnable || canCancelInstall || canCancelUpgrade;
1716 }
1717
1718 switch (gView) {
1719 case "extensions":
1720 canEnable = gExtensionsViewController.isCommandEnabled("cmd_reallyEnable");
1721 document.getElementById("menuitem_enable_clone").hidden = !canEnable;
1722 document.getElementById("menuitem_disable_clone").hidden = canEnable;
1723 document.getElementById("menuitem_useTheme_clone").hidden = true;
1724 break;
1725 case "themes":
1726 var enableMenu = document.getElementById("menuitem_enable_clone");
1727 if (!selectedItem.isCompatible || selectedItem.isBlocklisted ||
1728 !selectedItem.satisfiesDependencies || selectedItem.isDisabled)
1729 // don't let the user activate incompatible themes, but show a (disabled) Enable
1730 // menuitem to give visual feedback; it's disabled because cmd_enable returns false
1731 enableMenu.hidden = false;
1732 else
1733 enableMenu.hidden = true;
1734 document.getElementById("menuitem_options_clone").hidden = true;
1735 document.getElementById("menuitem_disable_clone").hidden = true;
1736 break;
1737 case "plugins":
1738 document.getElementById("menuitem_about_clone").hidden = true;
1739 document.getElementById("menuitem_uninstall_clone").hidden = true;
1740 document.getElementById("menuitem_checkUpdate_clone").hidden = true;
1741 case "locales":
1742 canEnable = gExtensionsViewController.isCommandEnabled("cmd_reallyEnable");
1743 document.getElementById("menuitem_enable_clone").hidden = !canEnable;
1744 document.getElementById("menuitem_disable_clone").hidden = canEnable;
1745 document.getElementById("menuitem_useTheme_clone").hidden = true;
1746 document.getElementById("menuitem_options_clone").hidden = true;
1747 break;
1748 case "updates":
1749 var includeUpdate = document.getAnonymousElementByAttribute(selectedItem, "anonid", "includeUpdate");
1750 var menuitem_includeUpdate = document.getElementById("menuitem_includeUpdate_clone");
1751 menuitem_includeUpdate.setAttribute("checked", includeUpdate.checked ? "true" : "false");
1752 break;
1753 case "installs":
1754 break;
1755 }
1756
1757 return true;
1758 }
1759
1760 ///////////////////////////////////////////////////////////////////////////////
1761 // Drag and Drop
1762
1763 var gExtensionsDNDObserver =
1764 {
1765 _ioServ: null,
1766 _canDrop: false,
1767
_ensureServices
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1768 _ensureServices: function ()
1769 {
1770 if (!this._ioServ)
1771 this._ioServ = Components.classes["@mozilla.org/network/io-service;1"]
1772 .getService(nsIIOService);
1773 },
1774
1775 // returns a JS object whose properties are used by xpinstall
_getDataFromDragSession
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1776 _getDataFromDragSession: function (aDragSession, aPosition)
1777 {
1778 var fileData = { };
1779 // if this fails we do not have valid data to drop
1780 try {
1781 var xfer = Components.classes["@mozilla.org/widget/transferable;1"]
1782 .createInstance(Components.interfaces.nsITransferable);
1783 xfer.addDataFlavor("text/x-moz-url");
1784 xfer.addDataFlavor("application/x-moz-file", "nsIFile");
1785 aDragSession.getData(xfer, aPosition);
1786
1787 var flavour = { }, data = { }, length = { };
1788 xfer.getAnyTransferData(flavour, data, length);
1789 var selectedFlavour = this.getSupportedFlavours().flavourTable[flavour.value];
1790 var xferData = new FlavourData(data.value, length.value, selectedFlavour);
1791
1792 var fileURL = transferUtils.retrieveURLFromData(xferData.data,
1793 xferData.flavour.contentType);
1794 fileData.fileURL = fileURL;
1795
1796 var uri = this._ioServ.newURI(fileURL, null, null);
1797 var url = uri.QueryInterface(nsIURL);
1798 fileData.fileName = url.fileName;
1799
1800 switch (url.fileExtension) {
1801 case "xpi":
1802 fileData.type = nsIUpdateItem.TYPE_EXTENSION;
1803 break;
1804 case "jar":
1805 fileData.type = nsIUpdateItem.TYPE_THEME;
1806 break;
1807 default:
1808 return null;
1809 }
1810 }
1811 catch (e) {
1812 return null;
1813 }
1814
1815 return fileData;
1816 },
1817
canDrop
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1818 canDrop: function (aEvent, aDragSession) { return this._canDrop; },
1819
onDragEnter
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1820 onDragEnter: function (aEvent, aDragSession)
1821 {
1822 // XXXrstrong - bug 269568, GTK2 drag and drop is returning invalid data for
1823 // dragenter and dragover. To workaround this we always set canDrop to true
1824 // and just use the xfer data returned in ondrop which is valid.
1825 //@line 1868 "/home/visbrero/mnt/roisin/rev_control/hg/mozilla/toolkit/mozapps/extensions/content/extensions.js"
1826 this._ensureServices();
1827
1828 var count = aDragSession.numDropItems;
1829 for (var i = 0; i < count; ++i) {
1830 var fileData = this._getDataFromDragSession(aDragSession, i);
1831 if (!fileData) {
1832 this._canDrop = false;
1833 return;
1834 }
1835 }
1836 //@line 1879 "/home/visbrero/mnt/roisin/rev_control/hg/mozilla/toolkit/mozapps/extensions/content/extensions.js"
1837 this._canDrop = true;
1838 },
1839
onDragOver
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1840 onDragOver: function (aEvent, aFlavor, aDragSession) { },
1841
onDrop
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1842 onDrop: function(aEvent, aXferData, aDragSession)
1843 {
1844 if (!isXPInstallEnabled())
1845 return;
1846
1847 this._ensureServices();
1848
1849 var xpinstallObj = { };
1850 var themes = { };
1851 var xpiCount = 0;
1852 var themeCount = 0;
1853
1854 var count = aDragSession.numDropItems;
1855 for (var i = 0; i < count; ++i) {
1856 var fileData = this._getDataFromDragSession(aDragSession, i);
1857 if (!fileData)
1858 continue;
1859
1860 xpinstallObj[fileData.fileName] = {
1861 URL: fileData.fileURL,
toString
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1862 toString: function() { return this.URL; }
1863 };
1864 ++xpiCount;
1865 if (fileData.type == nsIUpdateItem.TYPE_THEME)
1866 xpinstallObj[fileData.fileName].IconURL = URI_GENERIC_ICON_THEME;
1867 else
1868 xpinstallObj[fileData.fileName].IconURL = URI_GENERIC_ICON_XPINSTALL;
1869 }
1870
1871 if (xpiCount > 0)
1872 InstallTrigger.install(xpinstallObj);
1873 },
1874 _flavourSet: null,
getSupportedFlavours
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1875 getSupportedFlavours: function ()
1876 {
1877 if (!this._flavourSet) {
1878 this._flavourSet = new FlavourSet();
1879 this._flavourSet.appendFlavour("text/x-moz-url");
1880 this._flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
1881 }
1882 return this._flavourSet;
1883 }
1884 };
1885
1886 ///////////////////////////////////////////////////////////////////////////////
1887 // Notification Messages
1888 const gAddonsMsgObserver = {
observe
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1889 observe: function (aSubject, aTopic, aData)
1890 {
1891 switch (aData) {
1892 case "addons-enable-xpinstall":
1893 gPref.setBoolPref("xpinstall.enabled", true);
1894 break;
1895 case "addons-enable-compatibility":
1896 gPref.clearUserPref(PREF_EM_CHECK_COMPATIBILITY);
1897 gCheckCompat = true;
1898 break;
1899 case "addons-enable-updatesecurity":
1900 gPref.clearUserPref(PREF_EM_CHECK_UPDATE_SECURITY);
1901 gCheckUpdateSecurity = true;
1902 break;
1903 case "addons-no-updates":
1904 var children = gExtensionsView.children;
1905 for (var i = 0; i < children.length; ++i) {
1906 var child = children[i];
1907 if (child.hasAttribute("updateStatus"))
1908 child.removeAttribute("updateStatus");
1909 }
1910 break;
1911 case "addons-go-online":
1912 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
1913 .getService(nsIIOService);
1914 ioService.offline = false;
1915 // If no results have been retrieved start pulling some
1916 if (!gRetrievedResults)
1917 retrieveRepositoryAddons(document.getElementById("searchbox").value);
1918 if (gView == "search")
1919 document.getElementById("searchbox").disabled = false;
1920 break;
1921 case "addons-message-dismiss":
1922 break;
1923 case "addons-restart-app":
1924 restartApp();
1925 break;
1926 }
1927 if (gExtensionsView.selectedItem)
1928 gExtensionsView.selectedItem.focus();
1929 }
1930 };
1931
1932 const gPrefObserver = {
observe
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1933 observe: function (aSubject, aTopic, aData)
1934 {
1935 if (aData == PREF_GENERAL_SKINS_SELECTEDSKIN) {
1936 // Changed as the result of a dynamic theme switch
1937 gCurrentTheme = gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
1938 }
1939 else if (aData == PREF_DSS_SKIN_TO_SELECT) {
1940 // Either a new skin has been selected or the switch has been cancelled
1941 if (gPref.getBoolPref(PREF_EXTENSIONS_DSS_SWITCHPENDING))
1942 gCurrentTheme = gPref.getCharPref(PREF_DSS_SKIN_TO_SELECT);
1943 else
1944 gCurrentTheme = gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
1945 updateOptionalViews();
1946 updateGlobalCommands();
1947 }
1948 }
1949 };
1950
1951 const gPluginObserver = {
observe
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1952 observe: function (aSubject, aTopic, aData)
1953 {
1954 rebuildPluginsDS();
1955 }
1956 };
1957
isXPInstallEnabled
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1958 function isXPInstallEnabled() {
1959 var enabled = false;
1960 var locked = false;
1961 try {
1962 enabled = gPref.getBoolPref("xpinstall.enabled");
1963 if (enabled)
1964 return true;
1965 locked = gPref.prefIsLocked("xpinstall.enabled");
1966 }
1967 catch (e) { }
1968
1969 var msgText = getExtensionString(locked ? "xpinstallDisabledMsgLocked" :
1970 "xpinstallDisabledMsg");
1971 var buttonLabel = locked ? null : getExtensionString("enableButtonLabel");
1972 var buttonAccesskey = locked ? null : getExtensionString("enableButtonAccesskey");
1973 var notifyData = locked ? null : "addons-enable-xpinstall";
1974 showMessage("chrome://mozapps/skin/extensions/question.png",
1975 msgText, buttonLabel, buttonAccesskey,
1976 !locked, notifyData);
1977 return false;
1978 }
1979
isOffline
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1980 function isOffline(messageKey) {
1981 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
1982 .getService(nsIIOService);
1983 if (ioService.offline) {
1984 showMessage("chrome://mozapps/skin/extensions/question.png",
1985 getExtensionString(messageKey, [getBrandShortName()]),
1986 getExtensionString("goOnlineButtonLabel"),
1987 getExtensionString("goOnlineButtonAccesskey"),
1988 true, "addons-go-online");
1989 }
1990 return ioService.offline;
1991 }
1992
1993 ///////////////////////////////////////////////////////////////////////////////
1994 // Command Updating and Command Handlers
1995
canWriteToLocation
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
1996 function canWriteToLocation(element)
1997 {
1998 var installLocation = null;
1999 if (element) {
2000 var id = getIDFromResourceURI(element.id)
2001 installLocation = gExtensionManager.getInstallLocation(id);
2002 }
2003 return installLocation ? installLocation.canAccess : false;
2004 }
2005
enableRestartButton
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2006 function enableRestartButton() {
2007 var addonsMsg = document.getElementById("addonsMsg");
2008 var notification = addonsMsg.getNotificationWithValue("restart-app");
2009 if (!notification) {
2010 var appname = getBrandShortName();
2011 var message = getExtensionString("restartMessage", [appname]);
2012 var buttons = [ new MessageButton(getExtensionString("restartButton", [appname]),
2013 getExtensionString("restartAccessKey"),
2014 "addons-restart-app") ];
2015 addonsMsg.appendNotification(message, "restart-app",
2016 "chrome://mozapps/skin/extensions/question.png",
2017 addonsMsg.PRIORITY_WARNING_HIGH, buttons);
2018 }
2019 }
2020
disableRestartButton
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2021 function disableRestartButton() {
2022 var addonsMsg = document.getElementById("addonsMsg");
2023 var notification = addonsMsg.getNotificationWithValue("restart-app");
2024 if (notification)
2025 notification.close();
2026 }
2027
updateOptionalViews
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2028 function updateOptionalViews() {
2029 var ds = gExtensionsView.database;
2030 var ctr = Components.classes["@mozilla.org/rdf/container;1"]
2031 .createInstance(Components.interfaces.nsIRDFContainer);
2032 ctr.Init(ds, gRDF.GetResource(RDFURI_ITEM_ROOT));
2033 var elements = ctr.GetElements();
2034 var showLocales = false;
2035 var showUpdates = false;
2036 var showInstalls = gInstalling;
2037 gPendingActions = false;
2038
2039 var stateArc = gRDF.GetResource(PREFIX_NS_EM + "state");
2040 var opTypeArc = gRDF.GetResource(PREFIX_NS_EM + "opType");
2041
2042 while (elements.hasMoreElements()) {
2043 var e = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
2044 if (!showLocales) {
2045 var typeArc = gRDF.GetResource(PREFIX_NS_EM + "type");
2046 var type = ds.GetTarget(e, typeArc, true);
2047 if (type && type instanceof Components.interfaces.nsIRDFInt) {
2048 if (type.Value & nsIUpdateItem.TYPE_LOCALE)
2049 showLocales = true;
2050 }
2051 }
2052
2053 if (!gInstalling || !showInstalls) {
2054 var state = ds.GetTarget(e, stateArc, true);
2055 if (state) {
2056 showInstalls = true;
2057 if (state instanceof Components.interfaces.nsIRDFLiteral &&
2058 state.Value != "success" && state.Value != "failure")
2059 gInstalling = true;
2060 }
2061 }
2062
2063 if (!gPendingActions) {
2064 var opType = ds.GetTarget(e, opTypeArc, true);
2065 if (opType) {
2066 if (opType instanceof Components.interfaces.nsIRDFLiteral &&
2067 opType.Value != OP_NONE)
2068 gPendingActions = true;
2069 }
2070 }
2071
2072 if (!showUpdates) {
2073 var updateURLArc = gRDF.GetResource(PREFIX_NS_EM + "availableUpdateURL");
2074 var updateURL = ds.GetTarget(e, updateURLArc, true);
2075 if (updateURL) {
2076 var updateableArc = gRDF.GetResource(PREFIX_NS_EM + "updateable");
2077 var updateable = ds.GetTarget(e, updateableArc, true);
2078 updateable = updateable.QueryInterface(Components.interfaces.nsIRDFLiteral);
2079 if (updateable.Value == "true")
2080 showUpdates = true;
2081 }
2082 }
2083 }
2084 document.getElementById("locales-view").hidden = !showLocales;
2085 document.getElementById("updates-view").hidden = !showUpdates;
2086 document.getElementById("installs-view").hidden = !showInstalls;
2087 }
2088
updateGlobalCommands
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2089 function updateGlobalCommands() {
2090 var disableInstallFile = false;
2091 var disableUpdateCheck = true;
2092 var disableInstallUpdate = true;
2093
2094 if (gExtensionsView.hasAttribute("update-operation")) {
2095 disableInstallFile = true;
2096 disableRestartButton();
2097 }
2098 else if (gView == "updates") {
2099 disableInstallUpdate = false;
2100 disableRestartButton();
2101 }
2102 else {
2103 var children = gExtensionsView.children;
2104 for (var i = 0; i < children.length; ++i) {
2105 if (children[i].getAttribute("updateable") == "true") {
2106 disableUpdateCheck = false;
2107 break;
2108 }
2109 }
2110
2111 if (!gInstalling &&
2112 (gPendingActions || gPref.getBoolPref(PREF_EXTENSIONS_DSS_SWITCHPENDING)))
2113 enableRestartButton();
2114 else
2115 disableRestartButton();
2116 }
2117
2118 setElementDisabledByID("cmd_checkUpdatesAll", disableUpdateCheck);
2119 setElementDisabledByID("cmd_installUpdatesAll", disableInstallUpdate);
2120 setElementDisabledByID("cmd_installFile", disableInstallFile);
2121 }
2122
showUpdateInfo
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2123 function showUpdateInfo()
2124 {
2125 document.getElementById("themePreviewArea").hidden = false;
2126 document.getElementById("themeSplitter").hidden = false;
2127 document.getElementById("showUpdateInfoButton").hidden = true;
2128 document.getElementById("hideUpdateInfoButton").hidden = false;
2129 onAddonSelect();
2130 }
2131
hideUpdateInfo
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2132 function hideUpdateInfo()
2133 {
2134 UpdateInfoLoader.cancelLoad();
2135 document.getElementById("themePreviewArea").hidden = true;
2136 document.getElementById("themeSplitter").hidden = true;
2137 document.getElementById("showUpdateInfoButton").hidden = false;
2138 document.getElementById("hideUpdateInfoButton").hidden = true;
2139 }
2140
checkUpdatesAll
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2141 function checkUpdatesAll() {
2142 if (isOffline("offlineUpdateMsg"))
2143 return;
2144
2145 if (!isXPInstallEnabled())
2146 return;
2147
2148 // To support custom views we check the add-ons displayed in the list
2149 var items = [];
2150 var children = gExtensionsView.children;
2151 for (var i = 0; i < children.length; ++i) {
2152 if (children[i].getAttribute("updateable") != "false")
2153 items.push(gExtensionManager.getItemForID(getIDFromResourceURI(children[i].id)));
2154 }
2155
2156 if (items.length > 0) {
2157 showProgressBar();
2158 var listener = new UpdateCheckListener();
2159 gExtensionManager.update(items, items.length,
2160 nsIExtensionManager.UPDATE_CHECK_NEWVERSION,
2161 listener);
2162 }
2163 if (gExtensionsView.selectedItem)
2164 gExtensionsView.selectedItem.focus();
2165
2166 gPref.setBoolPref(PREF_UPDATE_NOTIFYUSER, false);
2167 }
2168
installUpdatesAll
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2169 function installUpdatesAll() {
2170 if (isOffline("offlineUpdateMsg"))
2171 return;
2172
2173 if (!isXPInstallEnabled())
2174 return;
2175
2176 if (gUpdatesOnly) {
2177 var notifications = document.getElementById("addonsMsg");
2178 if (notifications.currentNotification)
2179 notifications.removeCurrentNotification();
2180 }
2181
2182 var items = [];
2183 var children = gExtensionsView.children;
2184 for (var i = 0; i < children.length; ++i) {
2185 var includeUpdate = document.getAnonymousElementByAttribute(children[i], "anonid", "includeUpdate");
2186 if (includeUpdate && includeUpdate.checked)
2187 items.push(gExtensionManager.getItemForID(getIDFromResourceURI(children[i].id)));
2188 }
2189 if (items.length > 0) {
2190 gInstalling = true;
2191 gExtensionManager.addDownloads(items, items.length, null);
2192 showView("installs");
2193 // Remove the updates view if there are no add-ons left to update
2194 updateOptionalViews();
2195 updateGlobalCommands();
2196 }
2197 }
2198
restartApp
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2199 function restartApp() {
2200
2201 // Notify all windows that an application quit has been requested.
2202 var os = Components.classes["@mozilla.org/observer-service;1"]
2203 .getService(Components.interfaces.nsIObserverService);
2204 var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
2205 .createInstance(Components.interfaces.nsISupportsPRBool);
2206 os.notifyObservers(cancelQuit, "quit-application-requested", "restart");
2207
2208 // Something aborted the quit process.
2209 if (cancelQuit.data)
2210 return;
2211
2212 Components.classes["@mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup)
2213 .quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit);
2214 }
2215
installWithFilePicker
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2216 function installWithFilePicker() {
2217 if (!isXPInstallEnabled())
2218 return;
2219
2220 if (gView == "themes")
2221 installSkin();
2222 else
2223 installExtension();
2224 }
2225
closeEM
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2226 function closeEM() {
2227 closeWindow(true);
2228 }
2229
confirmOperation
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2230 function confirmOperation(aName, aTitle, aQueryMsg, aAcceptBtn, aCancelBtn,
2231 aWarnMsg, aDependantItems) {
2232 var params = {
2233 message2: getExtensionString(aQueryMsg, [aName]),
2234 title: getExtensionString(aTitle, [aName]),
2235 buttons: {
2236 accept: { label: getExtensionString(aAcceptBtn) },
2237 cancel: { label: getExtensionString(aCancelBtn), focused: true }
2238 }
2239 }
2240 if (aDependantItems.length > 0)
2241 params.message1 = getExtensionString(aWarnMsg, [aName]);
2242 var names = [];
2243 for (var i = 0; i < aDependantItems.length; ++i)
2244 names.push(aDependantItems[i].name + " " + aDependantItems[i].version);
2245
2246 window.openDialog("chrome://mozapps/content/extensions/list.xul", "",
2247 "titlebar,modal,centerscreen", names, params);
2248 return params.result == "accept";
2249 }
2250
installCallback
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2251 function installCallback(item, status) {
2252 var resultNode = gRDF.GetResource(item.id);
2253 var actionArc = gRDF.GetResource(PREFIX_NS_EM + "action");
2254
2255 // Strip out old status
2256 var targets = gSearchDS.GetTargets(resultNode, actionArc, true);
2257 while (targets.hasMoreElements()) {
2258 var value = targets.getNext().QueryInterface(Components.interfaces.nsIRDFNode);
2259 if (value)
2260 gSearchDS.Unassert(resultNode, actionArc, value);
2261 }
2262
2263 if (status == -210) {
2264 // User cancelled
2265 if (item.getAttribute("xpiURL") in gPendingInstalls)
2266 delete gPendingInstalls[item.getAttribute("xpiURL")];
2267 return;
2268 }
2269 if (status < 0) {
2270 // Some other failure
2271 gSearchDS.Assert(resultNode,
2272 actionArc,
2273 gRDF.GetLiteral("failed"),
2274 true);
2275 }
2276 else {
2277 // Success
2278 gSearchDS.Assert(resultNode,
2279 actionArc,
2280 gRDF.GetLiteral("installed"),
2281 true);
2282 }
2283 }
2284
2285 var gExtensionsViewController = {
supportsCommand
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2286 supportsCommand: function (aCommand)
2287 {
2288 var commandNode = document.getElementById(aCommand);
2289 return commandNode && (commandNode.parentNode == document.getElementById("extensionsCommands"));
2290 },
2291
isCommandEnabled
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2292 isCommandEnabled: function (aCommand)
2293 {
2294 var selectedItem = gExtensionsView.selectedItem;
2295 if (!selectedItem)
2296 return false;
2297
2298 if (selectedItem.hasAttribute("downloadURL") &&
2299 selectedItem.getAttribute("downloadURL") != "") {
2300 if (aCommand == "cmd_uninstall")
2301 return true;
2302 return false;
2303 }
2304 switch (aCommand) {
2305 case "cmd_installSearchResult":
2306 return true;
2307 case "cmd_useTheme":
2308 return selectedItem.type == nsIUpdateItem.TYPE_THEME &&
2309 !selectedItem.isDisabled &&
2310 selectedItem.opType != OP_NEEDS_UNINSTALL &&
2311 gCurrentTheme != selectedItem.getAttribute("internalName");
2312 case "cmd_options":
2313 return selectedItem.type == nsIUpdateItem.TYPE_EXTENSION &&
2314 !selectedItem.isDisabled &&
2315 !gInSafeMode &&
2316 !selectedItem.opType &&
2317 selectedItem.getAttribute("optionsURL") != "";
2318 case "cmd_about":
2319 return selectedItem.opType != OP_NEEDS_INSTALL &&
2320 selectedItem.getAttribute("plugin") != "true";
2321 case "cmd_homepage":
2322 return selectedItem.getAttribute("homepageURL") != "";
2323 case "cmd_uninstall":
2324 return (selectedItem.type != nsIUpdateItem.TYPE_THEME ||
2325 selectedItem.type == nsIUpdateItem.TYPE_THEME &&
2326 selectedItem.getAttribute("internalName") != gDefaultTheme) &&
2327 selectedItem.opType != OP_NEEDS_UNINSTALL &&
2328 selectedItem.getAttribute("locked") != "true" &&
2329 canWriteToLocation(selectedItem) &&
2330 !gExtensionsView.hasAttribute("update-operation");
2331 case "cmd_cancelUninstall":
2332 return selectedItem.opType == OP_NEEDS_UNINSTALL;
2333 case "cmd_cancelInstall":
2334 return selectedItem.opType == OP_NEEDS_INSTALL;
2335 case "cmd_cancelUpgrade":
2336 return selectedItem.opType == OP_NEEDS_UPGRADE;
2337 case "cmd_checkUpdate":
2338 return selectedItem.getAttribute("updateable") != "false" &&
2339 !gExtensionsView.hasAttribute("update-operation");
2340 case "cmd_installUpdate":
2341 return selectedItem.hasAttribute("availableUpdateURL") &&
2342 !gExtensionsView.hasAttribute("update-operation");
2343 case "cmd_includeUpdate":
2344 return selectedItem.hasAttribute("availableUpdateURL") &&
2345 !gExtensionsView.hasAttribute("update-operation");
2346 case "cmd_reallyEnable":
2347 // controls whether to show Enable or Disable in extensions' context menu
2348 return selectedItem.isDisabled &&
2349 selectedItem.opType != OP_NEEDS_ENABLE ||
2350 selectedItem.opType == OP_NEEDS_DISABLE;
2351 case "cmd_enable":
2352 return selectedItem.type != nsIUpdateItem.TYPE_THEME &&
2353 (selectedItem.isDisabled ||
2354 (!selectedItem.opType ||
2355 selectedItem.opType == "needs-disable")) &&
2356 !selectedItem.isBlocklisted &&
2357 (!gCheckUpdateSecurity || selectedItem.providesUpdatesSecurely) &&
2358 (!gCheckCompat || selectedItem.isCompatible) &&
2359 selectedItem.satisfiesDependencies &&
2360 !gExtensionsView.hasAttribute("update-operation");
2361 case "cmd_disable":
2362 return selectedItem.type != nsIUpdateItem.TYPE_THEME &&
2363 (!selectedItem.isDisabled &&
2364 !selectedItem.opType ||
2365 selectedItem.opType == OP_NEEDS_ENABLE) &&
2366 !selectedItem.isBlocklisted &&
2367 selectedItem.satisfiesDependencies &&
2368 !gExtensionsView.hasAttribute("update-operation");
2369 }
2370 return false;
2371 },
2372
doCommand
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2373 doCommand: function (aCommand)
2374 {
2375 if (this.isCommandEnabled(aCommand))
2376 this.commands[aCommand](gExtensionsView.selectedItem);
2377 },
2378
onCommandUpdate
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2379 onCommandUpdate: function ()
2380 {
2381 var extensionsCommands = document.getElementById("extensionsCommands");
2382 for (var i = 0; i < extensionsCommands.childNodes.length; ++i)
2383 this.updateCommand(extensionsCommands.childNodes[i]);
2384 },
2385
updateCommand
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2386 updateCommand: function (command)
2387 {
2388 if (this.isCommandEnabled(command.id))
2389 command.removeAttribute("disabled");
2390 else
2391 command.setAttribute("disabled", "true");
2392 },
2393
2394 commands: {
cmd_installSearchResult
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2395 cmd_installSearchResult: function (aSelectedItem)
2396 {
2397 if (!isXPInstallEnabled())
2398 return;
2399
2400 if (aSelectedItem.hasAttribute("eula")) {
2401 var eula = {
2402 name: aSelectedItem.getAttribute("name"),
2403 text: aSelectedItem.getAttribute("eula"),
2404 accepted: false
2405 };
2406 window.openDialog("chrome://mozapps/content/extensions/eula.xul", "_blank",
2407 "chrome,dialog,modal,centerscreen,resizable=no", eula);
2408 if (!eula.accepted)
2409 return;
2410 }
2411
2412 var details = {
2413 URL: aSelectedItem.getAttribute("xpiURL"),
2414 Hash: aSelectedItem.getAttribute("xpiHash"),
2415 IconURL: aSelectedItem.getAttribute("iconURL"),
toString
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2416 toString: function () { return this.URL; }
2417 };
2418 var params = [];
2419 params[aSelectedItem.getAttribute("name")] = details;
2420
2421 gSearchDS.Assert(gRDF.GetResource(aSelectedItem.id),
2422 gRDF.GetResource(PREFIX_NS_EM + "action"),
2423 gRDF.GetLiteral("connecting"),
2424 true);
2425 // Remember this install so we can update the status when install starts
2426 gPendingInstalls[details.URL] = aSelectedItem.id;
anon:2427:37
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2427 InstallTrigger.install(params, function(url, status) { installCallback(aSelectedItem, status); });
2428 },
2429
cmd_close
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2430 cmd_close: function (aSelectedItem)
2431 {
2432 closeWindow(true);
2433 },
2434
cmd_useTheme
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2435 cmd_useTheme: function (aSelectedItem)
2436 {
2437 gCurrentTheme = aSelectedItem.getAttribute("internalName");
2438
2439 // If choosing the current skin just reset the pending change
2440 if (gCurrentTheme == gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN)) {
2441 gPref.clearUserPref(PREF_EXTENSIONS_DSS_SWITCHPENDING);
2442 gPref.clearUserPref(PREF_DSS_SKIN_TO_SELECT);
2443 clearRestartMessage();
2444 }
2445 else {
2446 if (gPref.getBoolPref(PREF_EXTENSIONS_DSS_ENABLED)) {
2447 gPref.setCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN, gCurrentTheme);
2448 }
2449 else {
2450 // Theme change will happen on next startup, this flag tells
2451 // the Theme Manager that it needs to show "This theme will
2452 // be selected after a restart" text in the selected theme
2453 // item.
2454 gPref.setBoolPref(PREF_EXTENSIONS_DSS_SWITCHPENDING, true);
2455 gPref.setCharPref(PREF_DSS_SKIN_TO_SELECT, gCurrentTheme);
2456 clearRestartMessage();
2457 setRestartMessage(aSelectedItem);
2458 }
2459 }
2460
2461 // Flush preference change to disk
2462 gPref.QueryInterface(Components.interfaces.nsIPrefService)
2463 .savePrefFile(null);
2464
2465 // disable the useThemeButton
2466 gExtensionsViewController.onCommandUpdate();
2467 },
2468
cmd_options
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2469 cmd_options: function (aSelectedItem)
2470 {
2471 if (!aSelectedItem) return;
2472 var optionsURL = aSelectedItem.getAttribute("optionsURL");
2473 if (optionsURL == "")
2474 return;
2475
2476 var windows = Components.classes['@mozilla.org/appshell/window-mediator;1']
2477 .getService(Components.interfaces.nsIWindowMediator)
2478 .getEnumerator(null);
2479 while (windows.hasMoreElements()) {
2480 var win = windows.getNext();
2481 if (win.document.documentURI == optionsURL) {
2482 win.focus();
2483 return;
2484 }
2485 }
2486
2487 var features;
2488 try {
2489 var instantApply = gPref.getBoolPref("browser.preferences.instantApply");
2490 features = "chrome,titlebar,toolbar,centerscreen" + (instantApply ? ",dialog=no" : ",modal");
2491 }
2492 catch (e) {
2493 features = "chrome,titlebar,toolbar,centerscreen,modal";
2494 }
2495 openDialog(optionsURL, "", features);
2496 },
2497
cmd_homepage
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2498 cmd_homepage: function (aSelectedItem)
2499 {
2500 if (!aSelectedItem) return;
2501 var homepageURL = aSelectedItem.getAttribute("homepageURL");
2502 // only allow http(s) homepages
2503 if (isSafeURI(homepageURL))
2504 openURL(homepageURL);
2505 },
2506
cmd_about
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2507 cmd_about: function (aSelectedItem)
2508 {
2509 if (!aSelectedItem) return;
2510 var aboutURL = aSelectedItem.getAttribute("aboutURL");
2511 if (aboutURL != "")
2512 openDialog(aboutURL, "", "chrome,centerscreen,modal");
2513 else
2514 openDialog("chrome://mozapps/content/extensions/about.xul", "", "chrome,centerscreen,modal", aSelectedItem.id, gExtensionsView.database);
2515 },
2516
cmd_checkUpdate
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2517 cmd_checkUpdate: function (aSelectedItem)
2518 {
2519 if (isOffline("offlineUpdateMsg"))
2520 return;
2521
2522 if (!isXPInstallEnabled())
2523 return;
2524
2525 var id = getIDFromResourceURI(aSelectedItem.id);
2526 var items = [gExtensionManager.getItemForID(id)];
2527 var listener = new UpdateCheckListener();
2528 gExtensionManager.update(items, items.length,
2529 nsIExtensionManager.UPDATE_CHECK_NEWVERSION,
2530 listener);
2531 },
2532
cmd_installUpdate
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2533 cmd_installUpdate: function (aSelectedItem)
2534 {
2535 if (isOffline("offlineUpdateMsg"))
2536 return;
2537
2538 if (!isXPInstallEnabled())
2539 return;
2540
2541 showView("installs");
2542 var item = gExtensionManager.getItemForID(getIDFromResourceURI(aSelectedItem.id));
2543 gInstalling = true;
2544 gExtensionManager.addDownloads([item], 1, null);
2545 // Remove the updates view if there are no add-ons left to update
2546 updateOptionalViews();
2547 updateGlobalCommands();
2548 },
2549
cmd_includeUpdate
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2550 cmd_includeUpdate: function (aSelectedItem)
2551 {
2552 var includeUpdate = document.getAnonymousElementByAttribute(aSelectedItem, "anonid", "includeUpdate");
2553 includeUpdate.checked = !includeUpdate.checked;
2554 },
2555
cmd_uninstall
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2556 cmd_uninstall: function (aSelectedItem)
2557 {
2558 // Confirm the uninstall
2559 var name = aSelectedItem.getAttribute("name");
2560 var id = getIDFromResourceURI(aSelectedItem.id);
2561 var dependentItems = gExtensionManager.getDependentItemListForID(id, true, { });
2562 var result = confirmOperation(name, "uninstallTitle", "uninstallQueryMessage",
2563 "uninstallButton", "cancelButton",
2564 "uninstallWarnDependMsg", dependentItems);
2565 if (!result)
2566 return;
2567
2568 if (aSelectedItem.type == nsIUpdateItem.TYPE_THEME) {
2569 var theme = aSelectedItem.getAttribute("internalName");
2570 var selectedTheme = gPref.getCharPref(PREF_GENERAL_SKINS_SELECTEDSKIN);
2571 if (theme == gCurrentTheme) {
2572 if (gPref.getBoolPref(PREF_EXTENSIONS_DSS_SWITCHPENDING)) {
2573 var item = getItemForInternalName(selectedTheme);
2574 if (item && item.getAttribute("opType") == OP_NEEDS_UNINSTALL) {
2575 // We're uninstalling the theme to be switched to, but the current
2576 // theme is already marked for uninstall so switch to the default
2577 // theme
2578 this.cmd_useTheme(document.getElementById(PREFIX_ITEM_URI + "{972ce4c6-7e08-4474-a285-3208198ce6fd}"));
2579 }
2580 else {
2581 // The theme being uninstalled is the theme to be changed to on
2582 // restart so clear the pending theme change.
2583 gPref.clearUserPref(PREF_EXTENSIONS_DSS_SWITCHPENDING);
2584 gPref.clearUserPref(PREF_DSS_SKIN_TO_SELECT);
2585 clearRestartMessage();
2586 }
2587 }
2588 else {
2589 // The theme being uninstalled is the current theme, we need to reselect
2590 // the default.
2591 this.cmd_useTheme(document.getElementById(PREFIX_ITEM_URI + "{972ce4c6-7e08-4474-a285-3208198ce6fd}"));
2592 }
2593 }
2594
2595 // If the theme is not the current theme then it will vanish and nothing
2596 // will be selected so update the selection now.
2597 if (theme != selectedTheme) {
2598 if (!gExtensionsView.goDown())
2599 gExtensionsView.goUp();
2600 }
2601 }
2602 gExtensionManager.uninstallItem(getIDFromResourceURI(aSelectedItem.id));
2603 gExtensionsViewController.onCommandUpdate();
2604 if (gExtensionsView.selectedItem)
2605 gExtensionsView.selectedItem.focus();
2606 updateOptionalViews();
2607 updateGlobalCommands();
2608 },
2609
cmd_cancelUninstall
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2610 cmd_cancelUninstall: function (aSelectedItem)
2611 {
2612 gExtensionManager.cancelUninstallItem(getIDFromResourceURI(aSelectedItem.id));
2613 gExtensionsViewController.onCommandUpdate();
2614 gExtensionsView.selectedItem.focus();
2615 updateOptionalViews();
2616 updateGlobalCommands();
2617 },
2618
cmd_cancelInstall
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2619 cmd_cancelInstall: function (aSelectedItem)
2620 {
2621 var name = aSelectedItem.getAttribute("name");
2622 var result = false;
2623 // Confirm cancelling the operation
2624 switch (aSelectedItem.opType)
2625 {
2626 case OP_NEEDS_INSTALL:
2627 result = confirmOperation(name, "cancelInstallTitle", "cancelInstallQueryMessage",
2628 "cancelInstallButton", "cancelCancelInstallButton",
2629 null, []);
2630 break;
2631 case OP_NEEDS_UPGRADE:
2632 result = confirmOperation(name, "cancelUpgradeTitle", "cancelUpgradeQueryMessage",
2633 "cancelUpgradeButton", "cancelCancelUpgradeButton",
2634 null, []);
2635 break;
2636 }
2637 if (!result)
2638 return;
2639
2640 var id = getIDFromResourceURI(aSelectedItem.id);
2641 gExtensionManager.cancelInstallItem(id);
2642 if (gSearchDS) {
2643 // Check for a search result for this entry
2644 var searchResult = gSearchDS.GetSource(gRDF.GetResource(PREFIX_NS_EM + "addonID"),
2645 gRDF.GetLiteral(id),
2646 true);
2647 if (searchResult) {
2648 // Remove the installed status
2649 gSearchDS.Unassert(searchResult,
2650 gRDF.GetResource(PREFIX_NS_EM + "action"),
2651 gRDF.GetLiteral("installed"),
2652 true);
2653 }
2654 }
2655 gExtensionsViewController.onCommandUpdate();
2656 gExtensionsView.selectedItem.focus();
2657 updateOptionalViews();
2658 updateGlobalCommands();
2659 },
2660
cmd_cancelUpgrade
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2661 cmd_cancelUpgrade: function (aSelectedItem)
2662 {
2663 this.cmd_cancelInstall(aSelectedItem);
2664 },
2665
cmd_disable
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2666 cmd_disable: function (aSelectedItem)
2667 {
2668 if (aSelectedItem.getAttribute("plugin") == "true") {
2669 var name = aSelectedItem.getAttribute("name");
2670 var desc = aSelectedItem.getAttribute("description");
2671 togglePluginDisabled(name, desc);
2672 return;
2673 }
2674
2675 var id = getIDFromResourceURI(aSelectedItem.id);
2676 var dependentItems = gExtensionManager.getDependentItemListForID(id, false, { });
2677
2678 if (dependentItems.length > 0) {
2679 name = aSelectedItem.getAttribute("name");
2680 var result = confirmOperation(name, "disableTitle", "disableQueryMessage",
2681 "disableButton", "cancelButton",
2682 "disableWarningDependMessage", dependentItems);
2683 if (!result)
2684 return;
2685 }
2686 gExtensionManager.disableItem(id);
2687 gExtensionsViewController.onCommandUpdate();
2688 gExtensionsView.selectedItem.focus();
2689 updateOptionalViews();
2690 updateGlobalCommands();
2691 },
2692
cmd_enable
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2693 cmd_enable: function (aSelectedItem)
2694 {
2695 if (aSelectedItem.getAttribute("plugin") == "true") {
2696 var name = aSelectedItem.getAttribute("name");
2697 var desc = aSelectedItem.getAttribute("description");
2698 togglePluginDisabled(name, desc);
2699 return;
2700 }
2701
2702 gExtensionManager.enableItem(getIDFromResourceURI(aSelectedItem.id));
2703 gExtensionsViewController.onCommandUpdate();
2704 gExtensionsView.selectedItem.focus();
2705 updateOptionalViews();
2706 updateGlobalCommands();
2707 }
2708 }
2709 };
2710
2711 //////////////////////////////////////////////////////////////////////////
2712 // functions to support installing of themes in apps other than firefox //
2713 //////////////////////////////////////////////////////////////////////////
installSkin
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2714 function installSkin()
2715 {
2716 // 1) Prompt the user for the location of the theme to install.
2717 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
2718 fp.init(window, getExtensionString("installThemePickerTitle"), nsIFilePicker.modeOpen);
2719 fp.appendFilter(getExtensionString("themesFilter"), "*.jar");
2720 fp.appendFilters(nsIFilePicker.filterAll);
2721
2722 var ret = fp.show();
2723 if (ret == nsIFilePicker.returnOK)
2724 {
2725 var ioService = Components.classes['@mozilla.org/network/io-service;1'].getService(nsIIOService);
2726 var fileProtocolHandler =
2727 ioService.getProtocolHandler("file").QueryInterface(nsIFileProtocolHandler);
2728 var url = fileProtocolHandler.newFileURI(fp.file).QueryInterface(nsIURL);
2729 InstallTrigger.installChrome(InstallTrigger.SKIN, url.spec, decodeURIComponent(url.fileBaseName));
2730 }
2731 }
2732
installExtension
(0 calls, 0 incl. v-uS, 0 excl. v-uS)
2733 function installExtension()
2734 {
2735 var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
2736 fp.init(window, getExtensionString("installExtensionPickerTitle"), nsIFilePicker.modeOpen);
2737 fp.appendFilter(getExtensionString("extensionFilter"), "*.xpi");
2738 fp.appendFilters(nsIFilePicker.filterAll);
2739
2740 var ret = fp.show();
2741 if (ret == nsIFilePicker.returnOK)
2742 {
2743 var ioService = Components.classes['@mozilla.org/network/io-service;1'].getService(nsIIOService);
2744 var fileProtocolHandler =
2745 ioService.getProtocolHandler("file").QueryInterface(nsIFileProtocolHandler);
2746 var url = fileProtocolHandler.newFileURI(fp.file).QueryInterface(nsIURL);
2747 var xpi = {};
2748 xpi[decodeURIComponent(url.fileBaseName)] = url.spec;
2749 InstallTrigger.install(xpi);
2750 }
2751 }