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