mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
1908 lines
70 KiB
XML
1908 lines
70 KiB
XML
<?xml version="1.0"?>
|
|
<!-- ***** BEGIN LICENSE BLOCK *****
|
|
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
-
|
|
- The contents of this file are subject to the Mozilla Public License Version
|
|
- 1.1 (the "License"); you may not use this file except in compliance with
|
|
- the License. You may obtain a copy of the License at
|
|
- http://www.mozilla.org/MPL/
|
|
-
|
|
- Software distributed under the License is distributed on an "AS IS" basis,
|
|
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
- for the specific language governing rights and limitations under the
|
|
- License.
|
|
-
|
|
- The Original Code is the Extension Manager UI.
|
|
-
|
|
- The Initial Developer of the Original Code is
|
|
- the Mozilla Foundation.
|
|
- Portions created by the Initial Developer are Copyright (C) 2010
|
|
- the Initial Developer. All Rights Reserved.
|
|
-
|
|
- Contributor(s):
|
|
- Blair McBride <bmcbride@mozilla.com>
|
|
- David Dahl <ddahl@mozilla.com>
|
|
-
|
|
- Alternatively, the contents of this file may be used under the terms of
|
|
- either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
- in which case the provisions of the GPL or the LGPL are applicable instead
|
|
- of those above. If you wish to allow use of your version of this file only
|
|
- under the terms of either the GPL or the LGPL, and not to allow others to
|
|
- use your version of this file under the terms of the MPL, indicate your
|
|
- decision by deleting the provisions above and replace them with the notice
|
|
- and other provisions required by the LGPL or the GPL. If you do not delete
|
|
- the provisions above, a recipient may use your version of this file under
|
|
- the terms of any one of the MPL, the GPL or the LGPL.
|
|
-
|
|
- ***** END LICENSE BLOCK ***** -->
|
|
|
|
|
|
<!DOCTYPE page [
|
|
<!ENTITY % extensionsDTD SYSTEM "chrome://mozapps/locale/extensions/extensions.dtd">
|
|
%extensionsDTD;
|
|
]>
|
|
|
|
<bindings id="addonBindings"
|
|
xmlns="http://www.mozilla.org/xbl"
|
|
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
xmlns:xbl="http://www.mozilla.org/xbl">
|
|
|
|
|
|
<!-- Rating - displays current/average rating, allows setting user rating -->
|
|
<binding id="rating">
|
|
<content>
|
|
<xul:image class="star"
|
|
onmouseover="document.getBindingParent(this)._hover(1);"
|
|
onclick="document.getBindingParent(this).userRating = 1;"/>
|
|
<xul:image class="star"
|
|
onmouseover="document.getBindingParent(this)._hover(2);"
|
|
onclick="document.getBindingParent(this).userRating = 2;"/>
|
|
<xul:image class="star"
|
|
onmouseover="document.getBindingParent(this)._hover(3);"
|
|
onclick="document.getBindingParent(this).userRating = 3;"/>
|
|
<xul:image class="star"
|
|
onmouseover="document.getBindingParent(this)._hover(4);"
|
|
onclick="document.getBindingParent(this).userRating = 4;"/>
|
|
<xul:image class="star"
|
|
onmouseover="document.getBindingParent(this)._hover(5);"
|
|
onclick="document.getBindingParent(this).userRating = 5;"/>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
this._updateStars();
|
|
]]></constructor>
|
|
|
|
<property name="stars" readonly="true">
|
|
<getter><![CDATA[
|
|
return document.getAnonymousNodes(this);
|
|
]]></getter>
|
|
</property>
|
|
|
|
<property name="averageRating">
|
|
<getter><![CDATA[
|
|
if (this.hasAttribute("averagerating"))
|
|
return this.getAttribute("averagerating");
|
|
return -1;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
this.setAttribute("averagerating", val);
|
|
if (this.showRating == "average")
|
|
this._updateStars();
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="userRating">
|
|
<getter><![CDATA[
|
|
if (this.hasAttribute("userrating"))
|
|
return this.getAttribute("userrating");
|
|
return -1;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
if (this.showRating != "user")
|
|
return;
|
|
this.setAttribute("userrating", val);
|
|
if (this.showRating == "user")
|
|
this._updateStars();
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="showRating">
|
|
<getter><![CDATA[
|
|
if (this.hasAttribute("showrating"))
|
|
return this.getAttribute("showrating");
|
|
return "average";
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
if (val != "average" || val != "user")
|
|
throw new Error("Invalid value");
|
|
this.setAttribute("showrating", val);
|
|
this._updateStars();
|
|
]]></setter>
|
|
</property>
|
|
|
|
<method name="_updateStars">
|
|
<body><![CDATA[
|
|
var stars = this.stars;
|
|
var rating = this[this.showRating + "Rating"];
|
|
// average ratings can be non-whole numbers, round them so they
|
|
// match to their closest star
|
|
rating = Math.round(rating);
|
|
for (let i = 0; i < stars.length; i++)
|
|
stars[i].setAttribute("on", rating > i);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="_hover">
|
|
<parameter name="aScore"/>
|
|
<body><![CDATA[
|
|
if (this.showRating != "user")
|
|
return;
|
|
var stars = this.stars;
|
|
for (let i = 0; i < stars.length; i++)
|
|
stars[i].setAttribute("on", i <= (aScore -1));
|
|
]]></body>
|
|
</method>
|
|
|
|
</implementation>
|
|
|
|
<handlers>
|
|
<handler event="mouseout">
|
|
this._updateStars();
|
|
</handler>
|
|
</handlers>
|
|
</binding>
|
|
|
|
<!-- Download progress - shows graphical progress of download and any
|
|
related status message. -->
|
|
<binding id="download-progress">
|
|
<content>
|
|
<xul:stack flex="1">
|
|
<xul:hbox flex="1">
|
|
<xul:hbox class="start-cap"/>
|
|
<xul:progressmeter anonid="progress" class="progress" flex="1"
|
|
min="0" max="100"/>
|
|
<xul:hbox class="end-cap"/>
|
|
</xul:hbox>
|
|
<xul:hbox class="status-container">
|
|
<xul:spacer flex="1"/>
|
|
<xul:label anonid="status" class="status"/>
|
|
<xul:spacer flex="1"/>
|
|
<xul:button anonid="cancel-btn" class="cancel"
|
|
tooltiptext="&progress.cancel.tooltip;"
|
|
oncommand="document.getBindingParent(this).cancel();"/>
|
|
</xul:hbox>
|
|
</xul:stack>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
var progress = 0;
|
|
if (this.hasAttribute("progress"))
|
|
progress = parseInt(this.getAttribute("progress"));
|
|
this.progress = progress;
|
|
]]></constructor>
|
|
|
|
<field name="_progress">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "progress");
|
|
</field>
|
|
<field name="_cancel">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "cancel-btn");
|
|
</field>
|
|
<field name="_status">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "status");
|
|
</field>
|
|
|
|
<property name="progress">
|
|
<getter><![CDATA[
|
|
return this._progress.value;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
this._progress.value = val;
|
|
if (val == this._progress.max)
|
|
this.setAttribute("complete", true);
|
|
else
|
|
this.removeAttribute("complete");
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="maxProgress">
|
|
<getter><![CDATA[
|
|
return this._progress.max;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
if (val == -1) {
|
|
this._progress.mode = "undetermined";
|
|
} else {
|
|
this._progress.mode = "determined";
|
|
this._progress.max = val;
|
|
}
|
|
this.setAttribute("mode", this._progress.mode);
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="status">
|
|
<getter><![CDATA[
|
|
return this._status.value;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
this._status.value = val;
|
|
]]></setter>
|
|
</property>
|
|
|
|
<method name="cancel">
|
|
<body><![CDATA[
|
|
this.mInstall.cancel();
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- Sorters - displays and controls the sort state of a list. -->
|
|
<binding id="sorters">
|
|
<content orient="horizontal">
|
|
<xul:button anonid="name-btn" class="sorter"
|
|
label="&sort.name.label;" tooltiptext="&sort.name.tooltip;"
|
|
oncommand="this.parentNode._handleChange('name');"/>
|
|
<xul:button anonid="date-btn" class="sorter"
|
|
label="&sort.dateUpdated.label;"
|
|
tooltiptext="&sort.dateUpdated.tooltip;"
|
|
oncommand="this.parentNode._handleChange('updateDate');"/>
|
|
<xul:button anonid="price-btn" class="sorter" hidden="true"
|
|
label="&sort.price.label;"
|
|
tooltiptext="&sort.price.tooltip;"
|
|
oncommand="this.parentNode._handleChange('purchaseAmount');"/>
|
|
<xul:button anonid="relevance-btn" class="sorter" hidden="true"
|
|
label="&sort.relevance.label;"
|
|
tooltiptext="&sort.relevance.tooltip;"
|
|
oncommand="this.parentNode._handleChange('relevancescore');"/>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
if (!this.hasAttribute("sortby"))
|
|
this.setAttribute("sortby", "name");
|
|
|
|
if (this.getAttribute("showrelevance") == "true")
|
|
this._btnRelevance.hidden = false;
|
|
|
|
if (this.getAttribute("showprice") == "true")
|
|
this._btnPrice.hidden = false;
|
|
|
|
this._refreshState();
|
|
]]></constructor>
|
|
|
|
<field name="handler">null</field>
|
|
<field name="_btnName">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "name-btn");
|
|
</field>
|
|
<field name="_btnDate">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "date-btn");
|
|
</field>
|
|
<field name="_btnPrice">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "price-btn");
|
|
</field>
|
|
<field name="_btnRelevance">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "relevance-btn");
|
|
</field>
|
|
|
|
<property name="sortBy">
|
|
<getter><![CDATA[
|
|
return this.getAttribute("sortby");
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
if (val != this.sortBy) {
|
|
this.setAttribute("sortBy", val);
|
|
this._refreshState();
|
|
}
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="ascending">
|
|
<getter><![CDATA[
|
|
return (this.getAttribute("ascending") == "true");
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
val = !!val;
|
|
if (val != this.ascending) {
|
|
this.setAttribute("ascending", val);
|
|
this._refreshState();
|
|
}
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="showrelevance">
|
|
<getter><![CDATA[
|
|
return (this.getAttribute("showrelevance") == "true");
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
val = !!val;
|
|
this.setAttribute("showrelevance", val);
|
|
this._btnRelevance.hidden = !val;
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="showprice">
|
|
<getter><![CDATA[
|
|
return (this.getAttribute("showprice") == "true");
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
val = !!val;
|
|
this.setAttribute("showprice", val);
|
|
this._btnPrice.hidden = !val;
|
|
]]></setter>
|
|
</property>
|
|
|
|
<method name="setSort">
|
|
<parameter name="aSort"/>
|
|
<parameter name="aAscending"/>
|
|
<body><![CDATA[
|
|
var sortChanged = false;
|
|
if (aSort != this.sortBy) {
|
|
this.setAttribute("sortby", aSort);
|
|
sortChanged = true;
|
|
}
|
|
|
|
aAscending = !!aAscending;
|
|
if (this.ascending != aAscending) {
|
|
this.setAttribute("ascending", aAscending);
|
|
sortChanged = true;
|
|
}
|
|
|
|
if (sortChanged)
|
|
this._refreshState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="_handleChange">
|
|
<parameter name="aSort"/>
|
|
<body><![CDATA[
|
|
const ASCENDING_SORT_FIELDS = ["name", "purchaseAmount"];
|
|
|
|
// Toggle ascending if sort by is not changing, otherwise
|
|
// name sorting defaults to ascending, others to descending
|
|
if (aSort == this.sortBy)
|
|
this.ascending = !this.ascending;
|
|
else
|
|
this.setSort(aSort, ASCENDING_SORT_FIELDS.indexOf(aSort) >= 0);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="_refreshState">
|
|
<body><![CDATA[
|
|
var sortBy = this.sortBy;
|
|
var checkState = this.ascending ? 2 : 1;
|
|
|
|
if (sortBy == "name") {
|
|
this._btnName.checkState = checkState;
|
|
this._btnName.checked = true;
|
|
} else {
|
|
this._btnName.checkState = 0;
|
|
this._btnName.checked = false;
|
|
}
|
|
|
|
if (sortBy == "updateDate") {
|
|
this._btnDate.checkState = checkState;
|
|
this._btnDate.checked = true;
|
|
} else {
|
|
this._btnDate.checkState = 0;
|
|
this._btnDate.checked = false;
|
|
}
|
|
|
|
if (sortBy == "purchaseAmount") {
|
|
this._btnPrice.checkState = checkState;
|
|
this._btnPrice.checked = true;
|
|
} else {
|
|
this._btnPrice.checkState = 0;
|
|
this._btnPrice.checked = false;
|
|
}
|
|
|
|
if (sortBy == "relevancescore") {
|
|
this._btnRelevance.checkState = checkState;
|
|
this._btnRelevance.checked = true;
|
|
} else {
|
|
this._btnRelevance.checkState = 0;
|
|
this._btnRelevance.checked = false;
|
|
}
|
|
|
|
if (this.handler && "onSortChanged" in this.handler)
|
|
this.handler.onSortChanged(sortBy, this.ascending);
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- Categories list - displays the list of categories on the left pane. -->
|
|
<binding id="categories-list"
|
|
extends="chrome://global/content/bindings/richlistbox.xml#richlistbox">
|
|
<implementation>
|
|
<!-- This needs to be overridden to allow the fancy animation while not
|
|
allowing that item to be selected when hiding. -->
|
|
<method name="_canUserSelect">
|
|
<parameter name="aItem"/>
|
|
<body>
|
|
<![CDATA[
|
|
if (aItem.hasAttribute("disabled") &&
|
|
aItem.getAttribute("disabled") == "true")
|
|
return false;
|
|
var style = document.defaultView.getComputedStyle(aItem, "");
|
|
return style.display != "none" && style.visibility == "visible";
|
|
]]>
|
|
</body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- Category item - an item in the category list. -->
|
|
<binding id="category"
|
|
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
|
<content align="center">
|
|
<xul:image anonid="icon" class="category-icon"/>
|
|
<xul:label anonid="name" class="category-name" flex="1" xbl:inherits="value=name"/>
|
|
<xul:label anonid="badge" class="category-badge" xbl:inherits="value=count"/>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
if (!this.hasAttribute("count"))
|
|
this.setAttribute("count", 0);
|
|
]]></constructor>
|
|
|
|
<property name="badgeCount">
|
|
<getter><![CDATA[
|
|
return this.getAttribute("count");
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
if (this.getAttribute("count") == val)
|
|
return;
|
|
|
|
this.setAttribute("count", val);
|
|
var event = document.createEvent("Events");
|
|
event.initEvent("CategoryBadgeUpdated", true, true);
|
|
this.dispatchEvent(event);
|
|
]]></setter>
|
|
</property>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- Creator link - Name of a user/developer, providing a link if relevant. -->
|
|
<binding id="creator-link">
|
|
<content>
|
|
<xul:label anonid="label" value="&addon.createdBy.label;"/>
|
|
<xul:label anonid="creator-link" class="creator-link text-link"/>
|
|
<xul:label anonid="creator-name" class="creator-name"/>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
if (this.hasAttribute("nameonly") &&
|
|
this.getAttribute("nameonly") == "true") {
|
|
this._label.hidden = true;
|
|
}
|
|
]]></constructor>
|
|
|
|
<field name="_label">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "label");
|
|
</field>
|
|
<field name="_creatorLink">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "creator-link");
|
|
</field>
|
|
<field name="_creatorName">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "creator-name");
|
|
</field>
|
|
|
|
<method name="setCreator">
|
|
<parameter name="aCreator"/>
|
|
<parameter name="aHomepageURL"/>
|
|
<body><![CDATA[
|
|
if (!aCreator) {
|
|
this.collapsed = true;
|
|
return;
|
|
}
|
|
this.collapsed = false;
|
|
var url = aCreator.url || aHomepageURL;
|
|
var showLink = !!url;
|
|
if (showLink) {
|
|
this._creatorLink.value = aCreator.name;
|
|
this._creatorLink.href = url;
|
|
} else {
|
|
this._creatorName.value = aCreator.name;
|
|
}
|
|
this._creatorLink.hidden = !showLink;
|
|
this._creatorName.hidden = showLink;
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- Install status - Displays the status of an install/upgrade. -->
|
|
<binding id="install-status">
|
|
<content>
|
|
<xul:label anonid="message"/>
|
|
<xul:progressmeter anonid="progress" class="download-progress"/>
|
|
<xul:button anonid="purchase-remote-btn" hidden="true"
|
|
class="addon-control"
|
|
oncommand="document.getBindingParent(this).purchaseRemote();"/>
|
|
<xul:button anonid="install-remote-btn" hidden="true"
|
|
class="addon-control install" label="&addon.install.label;"
|
|
tooltiptext="&addon.install.tooltip;"
|
|
oncommand="document.getBindingParent(this).installRemote();"/>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
if (this.mInstall)
|
|
this.initWithInstall(this.mInstall);
|
|
else if (this.mControl.mAddon.install)
|
|
this.initWithInstall(this.mControl.mAddon.install);
|
|
else
|
|
this.refreshState();
|
|
]]></constructor>
|
|
|
|
<destructor><![CDATA[
|
|
if (this.mInstall)
|
|
this.mInstall.removeListener(this);
|
|
]]></destructor>
|
|
|
|
<field name="_message">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "message");
|
|
</field>
|
|
<field name="_progress">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "progress");
|
|
</field>
|
|
<field name="_purchaseRemote">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"purchase-remote-btn");
|
|
</field>
|
|
<field name="_installRemote">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"install-remote-btn");
|
|
</field>
|
|
<field name="_restartNeeded">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"restart-needed");
|
|
</field>
|
|
<field name="_undo">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"undo-btn");
|
|
</field>
|
|
|
|
<method name="initWithInstall">
|
|
<parameter name="aInstall"/>
|
|
<body><![CDATA[
|
|
if (this.mInstall) {
|
|
this.mInstall.removeListener(this);
|
|
this.mInstall = null;
|
|
}
|
|
this.mInstall = aInstall;
|
|
this._progress.mInstall = aInstall;
|
|
this.refreshState();
|
|
this.mInstall.addListener(this);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="refreshState">
|
|
<body><![CDATA[
|
|
var showInstallRemote = false;
|
|
var showPurchase = false;
|
|
|
|
if (this.mInstall) {
|
|
|
|
switch (this.mInstall.state) {
|
|
case AddonManager.STATE_AVAILABLE:
|
|
if (this.mControl.getAttribute("remote") != "true")
|
|
break;
|
|
|
|
this._progress.hidden = true;
|
|
showInstallRemote = true;
|
|
break;
|
|
case AddonManager.STATE_DOWNLOADING:
|
|
this.showMessage("installDownloading");
|
|
break;
|
|
case AddonManager.STATE_CHECKING:
|
|
this.showMessage("installVerifying");
|
|
break;
|
|
case AddonManager.STATE_DOWNLOADED:
|
|
this.showMessage("installDownloaded");
|
|
break;
|
|
case AddonManager.STATE_DOWNLOAD_FAILED:
|
|
// XXXunf expose what error occured (bug 553487)
|
|
this.showMessage("installDownloadFailed", true);
|
|
break;
|
|
case AddonManager.STATE_INSTALLING:
|
|
this.showMessage("installInstalling");
|
|
break;
|
|
case AddonManager.STATE_INSTALL_FAILED:
|
|
// XXXunf expose what error occured (bug 553487)
|
|
this.showMessage("installFailed", true);
|
|
break;
|
|
case AddonManager.STATE_CANCELLED:
|
|
this.showMessage("installCancelled", true);
|
|
break;
|
|
}
|
|
|
|
} else if (this.mControl.mAddon.purchaseURL) {
|
|
this._progress.hidden = true;
|
|
showPurchase = true;
|
|
this._purchaseRemote.label =
|
|
gStrings.ext.formatStringFromName("addon.purchase.label",
|
|
[this.mControl.mAddon.purchaseDisplayAmount], 1);
|
|
this._purchaseRemote.tooltiptext =
|
|
gStrings.ext.GetStringFromName("addon.purchase.tooltip");
|
|
}
|
|
|
|
this._purchaseRemote.hidden = !showPurchase;
|
|
this._installRemote.hidden = !showInstallRemote;
|
|
|
|
if ("refreshInfo" in this.mControl)
|
|
this.mControl.refreshInfo();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="showMessage">
|
|
<parameter name="aMsgId"/>
|
|
<parameter name="aHideProgress"/>
|
|
<body><![CDATA[
|
|
this._message.setAttribute("hidden", !aHideProgress);
|
|
this._progress.setAttribute("hidden", !!aHideProgress);
|
|
|
|
var msg = gStrings.ext.GetStringFromName(aMsgId);
|
|
if (aHideProgress)
|
|
this._message.value = msg;
|
|
else
|
|
this._progress.status = msg;
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="purchaseRemote">
|
|
<body><![CDATA[
|
|
openURL(this.mControl.mAddon.purchaseURL);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="installRemote">
|
|
<body><![CDATA[
|
|
if (this.mControl.getAttribute("remote") != "true")
|
|
return;
|
|
|
|
if (this.mControl.mAddon.eula) {
|
|
var data = {
|
|
addon: this.mControl.mAddon,
|
|
accepted: false
|
|
};
|
|
window.openDialog("chrome://mozapps/content/extensions/eula.xul", "_blank",
|
|
"chrome,dialog,modal,centerscreen,resizable=no", data);
|
|
if (!data.accepted)
|
|
return;
|
|
}
|
|
|
|
delete this.mControl.mAddon;
|
|
this.mControl.mInstall = this.mInstall;
|
|
this.mControl.setAttribute("status", "installing");
|
|
this.mInstall.install();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="undoAction">
|
|
<body><![CDATA[
|
|
if (!this.mAddon)
|
|
return;
|
|
var pending = this.mAddon.pendingOperations;
|
|
if (pending & AddonManager.PENDING_ENABLE)
|
|
this.mAddon.userDisabled = true;
|
|
else if (pending & AddonManager.PENDING_DISABLE)
|
|
this.mAddon.userDisabled = false;
|
|
this.refreshState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onDownloadStarted">
|
|
<body><![CDATA[
|
|
this.refreshState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onDownloadEnded">
|
|
<body><![CDATA[
|
|
this.refreshState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onDownloadFailed">
|
|
<body><![CDATA[
|
|
this.refreshState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onDownloadProgress">
|
|
<body><![CDATA[
|
|
this._progress.maxProgress = this.mInstall.maxProgress;
|
|
this._progress.progress = this.mInstall.progress;
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallStarted">
|
|
<body><![CDATA[
|
|
this._progress.progress = 0;
|
|
this.refreshState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallEnded">
|
|
<body><![CDATA[
|
|
this.refreshState();
|
|
if ("onInstallCompleted" in this.mControl)
|
|
this.mControl.onInstallCompleted();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallFailed">
|
|
<body><![CDATA[
|
|
this.refreshState();
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- Addon - base - parent binding of any item representing an addon. -->
|
|
<binding id="addon-base"
|
|
extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
|
<implementation>
|
|
<method name="hasPermission">
|
|
<parameter name="aPerm"/>
|
|
<body><![CDATA[
|
|
var perm = AddonManager["PERM_CAN_" + aPerm.toUpperCase()];
|
|
return !!(this.mAddon.permissions & perm);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="opRequiresRestart">
|
|
<parameter name="aOperation"/>
|
|
<body><![CDATA[
|
|
var operation = AddonManager["OP_NEEDS_RESTART_" + aOperation.toUpperCase()];
|
|
return !!(this.mAddon.operationsRequiringRestart & operation);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="isPending">
|
|
<parameter name="aAction"/>
|
|
<body><![CDATA[
|
|
var action = AddonManager["PENDING_" + aAction.toUpperCase()];
|
|
return !!(this.mAddon.pendingOperations & action);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onUninstalled">
|
|
<body><![CDATA[
|
|
this.parentNode.removeChild(this);
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- Addon - generic - A normal addon item, or an update to one -->
|
|
<binding id="addon-generic"
|
|
extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
|
|
<content>
|
|
<xul:hbox anonid="warning-container"
|
|
class="warning">
|
|
<xul:image class="warning-icon"/>
|
|
<xul:label anonid="warning" flex="1"/>
|
|
<xul:label anonid="warning-link" class="text-link"/>
|
|
<xul:button anonid="warning-btn" class="button-link"/>
|
|
<xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
|
|
</xul:hbox>
|
|
<xul:hbox anonid="error-container"
|
|
class="error">
|
|
<xul:image class="error-icon"/>
|
|
<xul:label anonid="error" flex="1"/>
|
|
<xul:label anonid="error-link" class="text-link"/>
|
|
<xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
|
|
</xul:hbox>
|
|
<xul:hbox anonid="pending-container"
|
|
class="pending">
|
|
<xul:image class="pending-icon"/>
|
|
<xul:label anonid="pending" flex="1"/>
|
|
<xul:button anonid="restart-btn" class="button-link"
|
|
label="&addon.restartNow.label;"
|
|
oncommand="document.getBindingParent(this).restart();"/>
|
|
<xul:button anonid="undo-btn" class="button-link"
|
|
label="&addon.undoAction.label;"
|
|
tooltipText="&addon.undoAction.tooltip;"
|
|
oncommand="document.getBindingParent(this).undo();"/>
|
|
<xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
|
|
</xul:hbox>
|
|
|
|
<xul:hbox class="content-container">
|
|
<xul:vbox class="icon-container">
|
|
<xul:image anonid="icon" class="icon"/>
|
|
</xul:vbox>
|
|
<xul:vbox class="content-inner-container" flex="1">
|
|
<xul:hbox class="basicinfo-container">
|
|
<xul:hbox class="name-container">
|
|
<xul:label anonid="name" class="name" crop="end" flex="1"
|
|
xbl:inherits="value=name,tooltiptext=name"/>
|
|
<xul:label anonid="version" class="version"/>
|
|
<xul:label class="disabled-postfix" value="&addon.disabled.postfix;"/>
|
|
<xul:label class="update-postfix" value="&addon.update.postfix;"/>
|
|
<xul:spacer flex="5000"/> <!-- Necessary to make the name crop -->
|
|
</xul:hbox>
|
|
<xul:label anonid="date-updated" class="date-updated"
|
|
unknown="&addon.unknownDate;"/>
|
|
</xul:hbox>
|
|
|
|
<xul:hbox class="advancedinfo-container" flex="1">
|
|
<xul:vbox class="description-outer-container" flex="1">
|
|
<xul:hbox class="description-container">
|
|
<xul:label anonid="description" class="description" crop="end" flex="1"/>
|
|
<xul:button anonid="details-btn" class="details button-link"
|
|
label="&addon.details.label;"
|
|
tooltiptext="&addon.details.tooltip;"
|
|
oncommand="document.getBindingParent(this).showInDetailView();"/>
|
|
<xul:spacer flex="5000"/> <!-- Necessary to make the description crop -->
|
|
</xul:hbox>
|
|
<xul:vbox anonid="relnotes-container" class="relnotes-container">
|
|
<xul:label class="relnotes-header" value="&addon.releaseNotes.label;"/>
|
|
<xul:label anonid="relnotes-loading" value="&addon.loadingReleaseNotes.label;"/>
|
|
<xul:label anonid="relnotes-error" hidden="true"
|
|
value="&addon.errorLoadingReleaseNotes.label;"/>
|
|
<xul:vbox anonid="relnotes" class="relnotes"/>
|
|
</xul:vbox>
|
|
<xul:hbox class="relnotes-toggle-container">
|
|
<xul:button anonid="relnotes-toggle-btn" class="relnotes-toggle"
|
|
hidden="true" label="&cmd.showReleaseNotes.label;"
|
|
tooltiptext="&cmd.showReleaseNotes.tooltip;"
|
|
showlabel="&cmd.showReleaseNotes.label;"
|
|
showtooltip="&cmd.showReleaseNotes.tooltip;"
|
|
hidelabel="&cmd.hideReleaseNotes.label;"
|
|
hidetooltip="&cmd.hideReleaseNotes.tooltip;"
|
|
oncommand="document.getBindingParent(this).toggleReleaseNotes();"/>
|
|
</xul:hbox>
|
|
</xul:vbox>
|
|
<xul:vbox class="status-control-wrapper">
|
|
<xul:hbox class="status-container">
|
|
<xul:hbox anonid="checking-update" hidden="true">
|
|
<xul:image class="spinner"/>
|
|
<xul:label value="&addon.checkingForUpdates.label;"/>
|
|
</xul:hbox>
|
|
<xul:vbox anonid="update-available" class="update-available"
|
|
hidden="true">
|
|
<xul:checkbox anonid="include-update" class="include-update"
|
|
label="&addon.includeUpdate.label;" checked="true"
|
|
oncommand="document.getBindingParent(this).onIncludeUpdateChanged();"/>
|
|
<xul:hbox class="update-info-container">
|
|
<xul:label class="update-available-notice"
|
|
value="&addon.updateAvailable.label;"/>
|
|
<xul:button anonid="update-btn" class="addon-control update"
|
|
label="&addon.updateNow.label;"
|
|
tooltiptext="&addon.updateNow.tooltip;"
|
|
oncommand="document.getBindingParent(this).upgrade();"/>
|
|
</xul:hbox>
|
|
</xul:vbox>
|
|
<xul:hbox anonid="install-status" class="install-status"
|
|
hidden="true"/>
|
|
</xul:hbox>
|
|
<xul:hbox anonid="control-container" class="control-container">
|
|
<xul:button anonid="preferences-btn"
|
|
class="addon-control preferences"
|
|
#ifdef XP_WIN
|
|
label="&cmd.showPreferencesWin.label;"
|
|
tooltiptext="&cmd.showPreferencesWin.tooltip;"
|
|
#else
|
|
label="&cmd.showPreferencesUnix.label;"
|
|
tooltiptext="&cmd.showPreferencesUnix.tooltip;"
|
|
#endif
|
|
oncommand="document.getBindingParent(this).showPreferences();"/>
|
|
<xul:button anonid="enable-btn" class="addon-control enable"
|
|
label="&cmd.enableAddon.label;"
|
|
oncommand="document.getBindingParent(this).userDisabled = false;"/>
|
|
<xul:button anonid="disable-btn" class="addon-control disable"
|
|
label="&cmd.disableAddon.label;"
|
|
oncommand="document.getBindingParent(this).userDisabled = true;"/>
|
|
<xul:button anonid="remove-btn" class="addon-control remove"
|
|
label="&cmd.uninstallAddon.label;"
|
|
oncommand="document.getBindingParent(this).uninstall();"/>
|
|
</xul:hbox>
|
|
</xul:vbox>
|
|
</xul:hbox>
|
|
</xul:vbox>
|
|
</xul:hbox>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
this._installStatus.mControl = this;
|
|
|
|
this.setAttribute("contextmenu", "addonitem-popup");
|
|
|
|
this._showStatus("none");
|
|
|
|
this._initWithAddon(this.mAddon);
|
|
|
|
gEventManager.registerAddonListener(this, this.mAddon.id);
|
|
]]></constructor>
|
|
|
|
<destructor><![CDATA[
|
|
gEventManager.unregisterAddonListener(this, this.mAddon.id);
|
|
]]></destructor>
|
|
|
|
<field name="_warningContainer">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"warning-container");
|
|
</field>
|
|
<field name="_warning">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"warning");
|
|
</field>
|
|
<field name="_warningLink">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"warning-link");
|
|
</field>
|
|
<field name="_warningBtn">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"warning-btn");
|
|
</field>
|
|
<field name="_errorContainer">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"error-container");
|
|
</field>
|
|
<field name="_error">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"error");
|
|
</field>
|
|
<field name="_errorLink">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"error-link");
|
|
</field>
|
|
<field name="_pendingContainer">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"pending-container");
|
|
</field>
|
|
<field name="_pending">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"pending");
|
|
</field>
|
|
<field name="_infoContainer">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"info-container");
|
|
</field>
|
|
<field name="_info">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"info");
|
|
</field>
|
|
<field name="_version">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "version");
|
|
</field>
|
|
<field name="_icon">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "icon");
|
|
</field>
|
|
<field name="_dateUpdated">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"date-updated");
|
|
</field>
|
|
<field name="_description">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"description");
|
|
</field>
|
|
<field name="_preferencesBtn">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"preferences-btn");
|
|
</field>
|
|
<field name="_enableBtn">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"enable-btn");
|
|
</field>
|
|
<field name="_disableBtn">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"disable-btn");
|
|
</field>
|
|
<field name="_removeBtn">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"remove-btn");
|
|
</field>
|
|
<field name="_updateBtn">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"update-btn");
|
|
</field>
|
|
<field name="_controlContainer">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"control-container");
|
|
</field>
|
|
<field name="_installStatus">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"install-status");
|
|
</field>
|
|
<field name="_checkingUpdate">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"checking-update");
|
|
</field>
|
|
<field name="_updateAvailable">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"update-available");
|
|
</field>
|
|
<field name="_includeUpdate">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"include-update");
|
|
</field>
|
|
<field name="_relNotesLoaded">false</field>
|
|
<field name="_relNotesToggle">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"relnotes-toggle-btn");
|
|
</field>
|
|
<field name="_relNotesLoading">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"relnotes-loading");
|
|
</field>
|
|
<field name="_relNotesError">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"relnotes-error");
|
|
</field>
|
|
<field name="_relNotesContainer">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"relnotes-container");
|
|
</field>
|
|
<field name="_relNotes">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"relnotes");
|
|
</field>
|
|
|
|
<property name="userDisabled">
|
|
<getter><![CDATA[
|
|
return this.mAddon.userDisabled;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
this.mAddon.userDisabled = val;
|
|
]]></setter>
|
|
</property>
|
|
|
|
<property name="includeUpdate">
|
|
<getter><![CDATA[
|
|
return this._includeUpdate.checked && !!this.mManualUpdate;
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
//XXXunf Eventually, we'll want to persist this for individual
|
|
// updates - see bug 594619.
|
|
this._includeUpdate.checked = !!val;
|
|
]]></setter>
|
|
</property>
|
|
|
|
<method name="_initWithAddon">
|
|
<parameter name="aAddon"/>
|
|
<body><![CDATA[
|
|
this.mAddon = aAddon;
|
|
|
|
this._installStatus.mAddon = this.mAddon;
|
|
this._updateDates();
|
|
this._updateState();
|
|
|
|
this.setAttribute("name", aAddon.name);
|
|
|
|
var iconURL = this.mAddon.iconURL;
|
|
if (iconURL)
|
|
this._icon.src = iconURL;
|
|
else
|
|
this._icon.src = null;
|
|
|
|
if (shouldShowVersionNumber(this.mAddon))
|
|
this._version.value = this.mAddon.version;
|
|
else
|
|
this._version.hidden = true;
|
|
|
|
if (this.mAddon.description)
|
|
this._description.value = this.mAddon.description;
|
|
else
|
|
this._description.hidden = true;
|
|
|
|
if (!("applyBackgroundUpdates" in this.mAddon) ||
|
|
(this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DISABLE ||
|
|
(this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
|
|
!AddonManager.autoUpdateDefault))) {
|
|
var self = this;
|
|
AddonManager.getAllInstalls(function(aInstallsList) {
|
|
// This can return after the binding has been destroyed,
|
|
// so try to detect that and return early
|
|
if (!("onNewInstall" in self))
|
|
return;
|
|
for (let i = 0; i < aInstallsList.length; i++) {
|
|
let install = aInstallsList[i];
|
|
if (install.existingAddon &&
|
|
install.existingAddon.id == self.mAddon.id &&
|
|
install.state == AddonManager.STATE_AVAILABLE) {
|
|
self.onNewInstall(install);
|
|
self.onIncludeUpdateChanged();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="_showStatus">
|
|
<parameter name="aType"/>
|
|
<body><![CDATA[
|
|
this._controlContainer.hidden = aType != "none" &&
|
|
!(aType == "update-available" && !this.hasAttribute("upgrade"));
|
|
|
|
this._installStatus.hidden = aType != "progress";
|
|
if (aType == "progress")
|
|
this._installStatus.refreshState();
|
|
this._checkingUpdate.hidden = aType != "checking-update";
|
|
this._updateAvailable.hidden = aType != "update-available";
|
|
this._relNotesToggle.hidden = !(this.mManualUpdate ?
|
|
this.mManualUpdate.releaseNotesURI :
|
|
this.mAddon.releaseNotesURI);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="_updateDates">
|
|
<body><![CDATA[
|
|
function formatDate(aDate) {
|
|
return Cc["@mozilla.org/intl/scriptabledateformat;1"]
|
|
.getService(Ci.nsIScriptableDateFormat)
|
|
.FormatDate("",
|
|
Ci.nsIScriptableDateFormat.dateFormatLong,
|
|
aDate.getFullYear(),
|
|
aDate.getMonth() + 1,
|
|
aDate.getDate()
|
|
);
|
|
}
|
|
|
|
if (this.mAddon.updateDate)
|
|
this._dateUpdated.value = formatDate(this.mAddon.updateDate);
|
|
else
|
|
this._dateUpdated.value = this._dateUpdated.getAttribute("unknown");
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="_updateState">
|
|
<body><![CDATA[
|
|
if (this.parentNode.selectedItem == this)
|
|
gViewController.updateCommands();
|
|
|
|
var pending = this.mAddon.pendingOperations;
|
|
if (pending != AddonManager.PENDING_NONE) {
|
|
this.removeAttribute("notification");
|
|
|
|
var pending = null;
|
|
["enable", "disable", "install", "uninstall", "upgrade"].forEach(function(aOp) {
|
|
if (this.isPending(aOp))
|
|
pending = aOp;
|
|
}, this);
|
|
|
|
this.setAttribute("pending", pending);
|
|
this._pending.textContent = gStrings.ext.formatStringFromName(
|
|
"notification." + pending,
|
|
[this.mAddon.name, gStrings.brandShortName], 2
|
|
);
|
|
} else {
|
|
this.removeAttribute("pending");
|
|
|
|
var isUpgrade = this.hasAttribute("upgrade");
|
|
var install = this._installStatus.mInstall;
|
|
|
|
if (install && install.state == AddonManager.STATE_DOWNLOAD_FAILED) {
|
|
this.setAttribute("notification", "warning");
|
|
this._warning.textContent = gStrings.ext.formatStringFromName(
|
|
"notification.downloadError",
|
|
[this.mAddon.name], 1
|
|
);
|
|
this._warningBtn.label = gStrings.ext.GetStringFromName("notification.downloadError.retry");
|
|
this._warningBtn.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
|
|
this._warningBtn.setAttribute("oncommand", "document.getBindingParent(this).retryInstall();");
|
|
this._warningBtn.hidden = false;
|
|
this._warningLink.hidden = true;
|
|
} else if (install && install.state == AddonManager.STATE_INSTALL_FAILED) {
|
|
this.setAttribute("notification", "warning");
|
|
this._warning.textContent = gStrings.ext.formatStringFromName(
|
|
"notification.installError",
|
|
[this.mAddon.name], 1
|
|
);
|
|
this._warningBtn.label = gStrings.ext.GetStringFromName("notification.installError.retry");
|
|
this._warningBtn.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
|
|
this._warningBtn.setAttribute("oncommand", "document.getBindingParent(this).retryInstall();");
|
|
this._warningBtn.hidden = false;
|
|
this._warningLink.hidden = true;
|
|
} else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
|
|
this.setAttribute("notification", "error");
|
|
this._error.textContent = gStrings.ext.formatStringFromName(
|
|
"notification.blocked",
|
|
[this.mAddon.name], 1
|
|
);
|
|
this._errorLink.value = gStrings.ext.GetStringFromName("notification.blocked.link");
|
|
this._errorLink.href = Services.urlFormatter.formatURLPref("extensions.blocklist.detailsURL");
|
|
this._errorLink.hidden = false;
|
|
} else if (!isUpgrade && !this.mAddon.isCompatible) {
|
|
this.setAttribute("notification", "warning");
|
|
this._warning.textContent = gStrings.ext.formatStringFromName(
|
|
"notification.incompatible",
|
|
[this.mAddon.name, gStrings.brandShortName, gStrings.appVersion], 3
|
|
);
|
|
this._warningLink.hidden = true;
|
|
this._warningBtn.hidden = true;
|
|
} else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED) {
|
|
this.setAttribute("notification", "warning");
|
|
this._warning.textContent = gStrings.ext.formatStringFromName(
|
|
"notification.softblocked",
|
|
[this.mAddon.name], 1
|
|
);
|
|
this._warningLink.value = gStrings.ext.GetStringFromName("notification.softblocked.link");
|
|
this._warningLink.href = Services.urlFormatter.formatURLPref("extensions.blocklist.detailsURL");
|
|
this._warningLink.hidden = false;
|
|
this._warningBtn.hidden = true;
|
|
} else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
|
|
this.setAttribute("notification", "warning");
|
|
this._warning.textContent = gStrings.ext.formatStringFromName(
|
|
"notification.outdated",
|
|
[this.mAddon.name], 1
|
|
);
|
|
this._warningLink.value = gStrings.ext.GetStringFromName("notification.outdated.link");
|
|
this._warningLink.href = Services.urlFormatter.formatURLPref("plugins.update.url");
|
|
this._warningLink.hidden = false;
|
|
this._warningBtn.hidden = true;
|
|
} else {
|
|
this.removeAttribute("notification");
|
|
}
|
|
}
|
|
|
|
this._preferencesBtn.hidden = !this.mAddon.optionsURL;
|
|
|
|
if (this.hasPermission("enable")) {
|
|
this._enableBtn.hidden = false;
|
|
let tooltip = gViewController.commands["cmd_enableItem"]
|
|
.getTooltip(this.mAddon);
|
|
this._enableBtn.setAttribute("tooltiptext", tooltip);
|
|
} else {
|
|
this._enableBtn.hidden = true;
|
|
}
|
|
|
|
if (this.hasPermission("disable")) {
|
|
this._disableBtn.hidden = false;
|
|
let tooltip = gViewController.commands["cmd_disableItem"]
|
|
.getTooltip(this.mAddon);
|
|
this._disableBtn.setAttribute("tooltiptext", tooltip);
|
|
} else {
|
|
this._disableBtn.hidden = true;
|
|
}
|
|
|
|
if (this.hasPermission("uninstall")) {
|
|
this._removeBtn.hidden = false;
|
|
let tooltip = gViewController.commands["cmd_uninstallItem"]
|
|
.getTooltip(this.mAddon);
|
|
this._removeBtn.setAttribute("tooltiptext", tooltip);
|
|
} else {
|
|
this._removeBtn.hidden = true;
|
|
}
|
|
|
|
this.setAttribute("active", this.mAddon.isActive);
|
|
|
|
var showProgress = this.mAddon.purchaseURL || (this.mAddon.install &&
|
|
this.mAddon.install.state != AddonManager.STATE_INSTALLED);
|
|
this._showStatus(showProgress ? "progress" : "none");
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="_updateUpgradeInfo">
|
|
<body><![CDATA[
|
|
// Only update the version string if we're displaying the upgrade info
|
|
if (this.hasAttribute("upgrade") && shouldShowVersionNumber(this.mAddon))
|
|
this._version.value = this.mManualUpdate.version;
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="_fetchReleaseNotes">
|
|
<parameter name="aURI"/>
|
|
<body><![CDATA[
|
|
var self = this;
|
|
if (!aURI || this._relNotesLoaded) {
|
|
sendToggleEvent();
|
|
return;
|
|
}
|
|
|
|
var relNotesData = null, transformData = null;
|
|
|
|
this._relNotesLoaded = true;
|
|
this._relNotesLoading.hidden = false;
|
|
this._relNotesError.hidden = true;
|
|
|
|
function sendToggleEvent() {
|
|
var event = document.createEvent("Events");
|
|
event.initEvent("RelNotesToggle", true, true);
|
|
self.dispatchEvent(event);
|
|
}
|
|
|
|
function showRelNotes() {
|
|
if (!relNotesData || !transformData)
|
|
return;
|
|
|
|
self._relNotesLoading.hidden = true;
|
|
|
|
var processor = Components.classes["@mozilla.org/document-transformer;1?type=xslt"]
|
|
.createInstance(Components.interfaces.nsIXSLTProcessor);
|
|
processor.flags |= Components.interfaces.nsIXSLTProcessorPrivate.DISABLE_ALL_LOADS;
|
|
|
|
processor.importStylesheet(transformData);
|
|
var fragment = processor.transformToFragment(relNotesData, document);
|
|
self._relNotes.appendChild(fragment);
|
|
if (self.hasAttribute("show-relnotes")) {
|
|
var container = self._relNotesContainer;
|
|
container.style.height = container.scrollHeight + "px";
|
|
}
|
|
sendToggleEvent();
|
|
}
|
|
|
|
function handleError() {
|
|
dataReq.abort();
|
|
styleReq.abort();
|
|
self._relNotesLoading.hidden = true;
|
|
self._relNotesError.hidden = false;
|
|
self._relNotesLoaded = false; // allow loading to be re-tried
|
|
sendToggleEvent();
|
|
}
|
|
|
|
function handleResponse(aEvent) {
|
|
var req = aEvent.target;
|
|
if (req.responseXML &&
|
|
req.responseXML.documentElement.namespaceURI != XMLURI_PARSE_ERROR) {
|
|
if (req == dataReq)
|
|
relNotesData = req.responseXML;
|
|
else
|
|
transformData = req.responseXML;
|
|
showRelNotes();
|
|
} else {
|
|
handleError();
|
|
}
|
|
}
|
|
|
|
var dataReq = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
|
.createInstance(Components.interfaces.nsIXMLHttpRequest);
|
|
dataReq.open("GET", aURI.spec, true);
|
|
dataReq.addEventListener("load", handleResponse, false);
|
|
dataReq.addEventListener("error", handleError, false);
|
|
dataReq.send(null);
|
|
|
|
var styleReq = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
|
.createInstance(Components.interfaces.nsIXMLHttpRequest);
|
|
styleReq.open("GET", UPDATES_RELEASENOTES_TRANSFORMFILE, true);
|
|
styleReq.addEventListener("load", handleResponse, false);
|
|
styleReq.addEventListener("error", handleError, false);
|
|
styleReq.send(null);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="toggleReleaseNotes">
|
|
<body><![CDATA[
|
|
if (this.hasAttribute("show-relnotes")) {
|
|
this._relNotesContainer.style.height = "0px";
|
|
this.removeAttribute("show-relnotes");
|
|
this._relNotesToggle.setAttribute(
|
|
"label",
|
|
this._relNotesToggle.getAttribute("showlabel")
|
|
);
|
|
this._relNotesToggle.setAttribute(
|
|
"tooltiptext",
|
|
this._relNotesToggle.getAttribute("showtooltip")
|
|
);
|
|
var event = document.createEvent("Events");
|
|
event.initEvent("RelNotesToggle", true, true);
|
|
this.dispatchEvent(event);
|
|
} else {
|
|
this._relNotesContainer.style.height = this._relNotesContainer.scrollHeight +
|
|
"px";
|
|
this.setAttribute("show-relnotes", true);
|
|
this._relNotesToggle.setAttribute(
|
|
"label",
|
|
this._relNotesToggle.getAttribute("hidelabel")
|
|
);
|
|
this._relNotesToggle.setAttribute(
|
|
"tooltiptext",
|
|
this._relNotesToggle.getAttribute("hidetooltip")
|
|
);
|
|
var uri = this.mManualUpdate ?
|
|
this.mManualUpdate.releaseNotesURI :
|
|
this.mAddon.releaseNotesURI;
|
|
this._fetchReleaseNotes(uri);
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="restart">
|
|
<body><![CDATA[
|
|
gViewController.commands["cmd_restartApp"].doCommand();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="undo">
|
|
<body><![CDATA[
|
|
gViewController.commands["cmd_cancelOperation"].doCommand(this.mAddon);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="uninstall">
|
|
<body><![CDATA[
|
|
// If uninstalling does not require a restart then just disable it
|
|
// and show the undo UI.
|
|
if (!this.opRequiresRestart("uninstall")) {
|
|
this.setAttribute("wasDisabled", this.mAddon.userDisabled);
|
|
|
|
// We must set userDisabled to true first, this will call
|
|
// _updateState which will clear any pending attribute set.
|
|
this.mAddon.userDisabled = true;
|
|
|
|
// This won't update any other add-on manager views (bug 582002)
|
|
this.setAttribute("pending", "uninstall");
|
|
} else {
|
|
this.mAddon.uninstall();
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="showPreferences">
|
|
<body><![CDATA[
|
|
gViewController.doCommand("cmd_showItemPreferences", this.mAddon);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="upgrade">
|
|
<body><![CDATA[
|
|
var install = this.mManualUpdate;
|
|
delete this.mManualUpdate;
|
|
install.install();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="retryInstall">
|
|
<body><![CDATA[
|
|
var install = this._installStatus.mInstall;
|
|
if (!install)
|
|
return;
|
|
if (install.state != AddonManager.STATE_DOWNLOAD_FAILED &&
|
|
install.state != AddonManager.STATE_INSTALL_FAILED)
|
|
return;
|
|
install.install();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="showInDetailView">
|
|
<body><![CDATA[
|
|
gViewController.loadView("addons://detail/" +
|
|
encodeURIComponent(this.mAddon.id));
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onIncludeUpdateChanged">
|
|
<body><![CDATA[
|
|
var event = document.createEvent("Events");
|
|
event.initEvent("IncludeUpdateChanged", true, true);
|
|
this.dispatchEvent(event);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onEnabling">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onEnabled">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onDisabling">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onDisabled">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onUninstalling">
|
|
<parameter name="aRestartRequired"/>
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onOperationCancelled">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onNoUpdateAvailable">
|
|
<body><![CDATA[
|
|
this._showStatus("none");
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onCheckingUpdate">
|
|
<body><![CDATA[
|
|
this._showStatus("checking-update");
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onCompatibilityUpdateAvailable">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onExternalInstall">
|
|
<parameter name="aAddon"/>
|
|
<parameter name="aExistingAddon"/>
|
|
<parameter name="aNeedsRestart"/>
|
|
<body><![CDATA[
|
|
if (aExistingAddon.id != this.mAddon.id)
|
|
return;
|
|
|
|
// If the install completed without needing a restart then switch to
|
|
// using the new Addon
|
|
if (!aNeedsRestart)
|
|
this._initWithAddon(aAddon);
|
|
else
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onNewInstall">
|
|
<parameter name="aInstall"/>
|
|
<body><![CDATA[
|
|
if (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_ENABLE)
|
|
return;
|
|
if (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
|
|
AddonManager.autoUpdateDefault)
|
|
return;
|
|
|
|
this.mManualUpdate = aInstall;
|
|
this._showStatus("update-available");
|
|
this._updateUpgradeInfo();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onDownloadStarted">
|
|
<parameter name="aInstall"/>
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
this._showStatus("progress");
|
|
this._installStatus.initWithInstall(aInstall);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallStarted">
|
|
<parameter name="aInstall"/>
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
this._showStatus("progress");
|
|
this._installStatus.initWithInstall(aInstall);
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallEnded">
|
|
<parameter name="aInstall"/>
|
|
<parameter name="aAddon"/>
|
|
<body><![CDATA[
|
|
// If the install completed without needing a restart then switch to
|
|
// using the new Addon
|
|
if (!(aAddon.pendingOperations & AddonManager.PENDING_INSTALL))
|
|
this._initWithAddon(aAddon);
|
|
else
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onDownloadFailed">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallFailed">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallCancelled">
|
|
<body><![CDATA[
|
|
this._updateState();
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
|
|
<handlers>
|
|
<handler event="click" button="0"><![CDATA[
|
|
switch (event.detail) {
|
|
case 1:
|
|
// Prevent double-click where the UI changes on the first click
|
|
this._lastClickTarget = event.originalTarget;
|
|
break;
|
|
case 2:
|
|
if (event.originalTarget.localName != 'button' &&
|
|
!event.originalTarget.classList.contains('text-link') &&
|
|
event.originalTarget == this._lastClickTarget) {
|
|
this.showInDetailView();
|
|
}
|
|
break;
|
|
}
|
|
]]></handler>
|
|
</handlers>
|
|
</binding>
|
|
|
|
|
|
<!-- Addon - uninstalled - An uninstalled addon that can be re-installed. -->
|
|
<binding id="addon-uninstalled"
|
|
extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
|
|
<content>
|
|
<xul:hbox class="pending">
|
|
<xul:image class="pending-icon"/>
|
|
<xul:label anonid="notice" flex="1"/>
|
|
<xul:button anonid="restart-btn" class="button-link"
|
|
label="&addon.restartNow.label;"
|
|
command="cmd_restartApp"/>
|
|
<xul:button anonid="undo-btn" class="button-link"
|
|
label="&addon.undoRemove.label;"
|
|
tooltiptext="&addon.undoRemove.tooltip;"
|
|
oncommand="document.getBindingParent(this).cancelUninstall();"/>
|
|
<xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
|
|
</xul:hbox>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
this._notice.textContent = gStrings.ext.formatStringFromName("uninstallNotice",
|
|
[this.mAddon.name],
|
|
1);
|
|
|
|
if (!this.isPending("uninstall"))
|
|
this._restartBtn.setAttribute("hidden", true);
|
|
|
|
gEventManager.registerAddonListener(this, this.mAddon.id);
|
|
]]></constructor>
|
|
|
|
<destructor><![CDATA[
|
|
gEventManager.unregisterAddonListener(this, this.mAddon.id);
|
|
]]></destructor>
|
|
|
|
<field name="_notice" readonly="true">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "notice");
|
|
</field>
|
|
<field name="_restartBtn" readonly="true">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "restart-btn");
|
|
</field>
|
|
|
|
<method name="cancelUninstall">
|
|
<body><![CDATA[
|
|
// This assumes that disabling does not require a restart when
|
|
// uninstalling doesn't. Things will still work if not, the add-on
|
|
// will just still be active until finally getting uninstalled.
|
|
|
|
if (this.isPending("uninstall"))
|
|
this.mAddon.cancelUninstall();
|
|
else if (this.getAttribute("wasDisabled") != "true")
|
|
this.mAddon.userDisabled = false;
|
|
|
|
this.removeAttribute("pending");
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onOperationCancelled">
|
|
<body><![CDATA[
|
|
if (!this.isPending("uninstall"))
|
|
this.removeAttribute("pending");
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onExternalInstall">
|
|
<parameter name="aAddon"/>
|
|
<parameter name="aExistingAddon"/>
|
|
<parameter name="aNeedsRestart"/>
|
|
<body><![CDATA[
|
|
if (aExistingAddon.id != this.mAddon.id)
|
|
return;
|
|
|
|
// Make sure any newly installed add-on has the correct disabled state
|
|
if (this.hasAttribute("wasDisabled"))
|
|
aAddon.userDisabled = this.getAttribute("wasDisabled") == "true";
|
|
|
|
// If the install completed without needing a restart then switch to
|
|
// using the new Addon
|
|
if (!aNeedsRestart)
|
|
this.mAddon = aAddon;
|
|
|
|
this.removeAttribute("pending");
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallStarted">
|
|
<parameter name="aInstall"/>
|
|
<body><![CDATA[
|
|
// Make sure any newly installed add-on has the correct disabled state
|
|
if (this.hasAttribute("wasDisabled"))
|
|
aInstall.addon.userDisabled = this.getAttribute("wasDisabled") == "true";
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="onInstallEnded">
|
|
<parameter name="aInstall"/>
|
|
<parameter name="aAddon"/>
|
|
<body><![CDATA[
|
|
// If the install completed without needing a restart then switch to
|
|
// using the new Addon
|
|
if (!(aAddon.pendingOperations & AddonManager.PENDING_INSTALL))
|
|
this.mAddon = aAddon;
|
|
|
|
this.removeAttribute("pending");
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
|
|
<!-- Addon - installing - an addon item that is currently being installed -->
|
|
<binding id="addon-installing"
|
|
extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
|
|
<content>
|
|
<xul:hbox anonid="warning-container" class="warning">
|
|
<xul:image class="warning-icon"/>
|
|
<xul:label anonid="warning" flex="1"/>
|
|
<xul:button anonid="warning-link" class="button-link"
|
|
oncommand="document.getBindingParent(this).retryInstall();"/>
|
|
<xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
|
|
</xul:hbox>
|
|
<xul:hbox class="content-container">
|
|
<xul:vbox class="icon-outer-container">
|
|
<xul:vbox class="icon-container">
|
|
<xul:image anonid="icon" class="icon"/>
|
|
</xul:vbox>
|
|
</xul:vbox>
|
|
<xul:vbox class="fade name-outer-container" flex="1">
|
|
<xul:hbox class="name-container">
|
|
<xul:label anonid="name" class="name" crop="end"/>
|
|
<xul:label anonid="version" class="version" hidden="true"/>
|
|
</xul:hbox>
|
|
</xul:vbox>
|
|
<xul:vbox class="install-status-container">
|
|
<xul:hbox anonid="install-status" class="install-status"/>
|
|
</xul:vbox>
|
|
</xul:hbox>
|
|
</content>
|
|
|
|
<implementation>
|
|
<constructor><![CDATA[
|
|
this._installStatus.mControl = this;
|
|
this._installStatus.mInstall = this.mInstall;
|
|
this.refreshInfo();
|
|
]]></constructor>
|
|
|
|
<field name="_icon">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "icon");
|
|
</field>
|
|
<field name="_name">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "name");
|
|
</field>
|
|
<field name="_version">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "version");
|
|
</field>
|
|
<field name="_warning">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "warning");
|
|
</field>
|
|
<field name="_warningLink">
|
|
document.getAnonymousElementByAttribute(this, "anonid", "warning-link");
|
|
</field>
|
|
<field name="_installStatus">
|
|
document.getAnonymousElementByAttribute(this, "anonid",
|
|
"install-status");
|
|
</field>
|
|
|
|
<method name="onInstallCompleted">
|
|
<body><![CDATA[
|
|
this.mAddon = this.mInstall.addon;
|
|
this.setAttribute("name", this.mAddon.name);
|
|
this.setAttribute("value", this.mAddon.id);
|
|
this.setAttribute("status", "installed");
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="refreshInfo">
|
|
<body><![CDATA[
|
|
this.mAddon = this.mAddon || this.mInstall.addon;
|
|
if (this.mAddon) {
|
|
this._icon.src = this.mAddon.iconURL ||
|
|
(this.mInstall ? this.mInstall.iconURL : "");
|
|
this._name.value = this.mAddon.name;
|
|
|
|
if (this.mAddon.version) {
|
|
this._version.value = this.mAddon.version;
|
|
this._version.hidden = false;
|
|
} else {
|
|
this._version.hidden = true;
|
|
}
|
|
|
|
} else {
|
|
this._icon.src = this.mInstall.iconURL;
|
|
// AddonInstall.name isn't always available - fallback to filename
|
|
if (this.mInstall.name) {
|
|
this._name.value = this.mInstall.name;
|
|
} else if (this.mInstall.sourceURI) {
|
|
var url = Components.classes["@mozilla.org/network/standard-url;1"]
|
|
.createInstance(Components.interfaces.nsIStandardURL);
|
|
url.init(url.URLTYPE_STANDARD, 80, this.mInstall.sourceURI.spec,
|
|
null, null);
|
|
url.QueryInterface(Components.interfaces.nsIURL);
|
|
this._name.value = url.fileName;
|
|
}
|
|
|
|
if (this.mInstall.version) {
|
|
this._version.value = this.mInstall.version;
|
|
this._version.hidden = false;
|
|
} else {
|
|
this._version.hidden = true;
|
|
}
|
|
}
|
|
|
|
if (this.mInstall.state == AddonManager.STATE_DOWNLOAD_FAILED) {
|
|
this.setAttribute("notification", "warning");
|
|
this._warning.textContent = gStrings.ext.formatStringFromName(
|
|
"notification.downloadError",
|
|
[this._name.value], 1
|
|
);
|
|
this._warningLink.label = gStrings.ext.GetStringFromName("notification.downloadError.retry");
|
|
this._warningLink.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
|
|
} else if (this.mInstall.state == AddonManager.STATE_INSTALL_FAILED) {
|
|
this.setAttribute("notification", "warning");
|
|
this._warning.textContent = gStrings.ext.formatStringFromName(
|
|
"notification.installError",
|
|
[this._name.value], 1
|
|
);
|
|
this._warningLink.label = gStrings.ext.GetStringFromName("notification.installError.retry");
|
|
this._warningLink.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
|
|
} else {
|
|
this.removeAttribute("notification");
|
|
}
|
|
]]></body>
|
|
</method>
|
|
|
|
<method name="retryInstall">
|
|
<body><![CDATA[
|
|
this.mInstall.install();
|
|
]]></body>
|
|
</method>
|
|
</implementation>
|
|
</binding>
|
|
|
|
<binding id="detail-row">
|
|
<content>
|
|
<xul:label class="detail-row-label" xbl:inherits="value=label"/>
|
|
<xul:label class="detail-row-value" xbl:inherits="value"/>
|
|
</content>
|
|
|
|
<implementation>
|
|
<property name="value">
|
|
<getter><![CDATA[
|
|
return this.getAttribute("value");
|
|
]]></getter>
|
|
<setter><![CDATA[
|
|
if (!val)
|
|
this.removeAttribute("value");
|
|
else
|
|
this.setAttribute("value", val);
|
|
]]></setter>
|
|
</property>
|
|
</implementation>
|
|
</binding>
|
|
|
|
</bindings>
|