toolkit/mozapps/extensions/content/extensions.xml

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 <?xml version="1.0"?>
     2 <!-- This Source Code Form is subject to the terms of the Mozilla Public
     3    - License, v. 2.0. If a copy of the MPL was not distributed with this
     4    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
     7 <!DOCTYPE page [
     8 <!ENTITY % extensionsDTD SYSTEM "chrome://mozapps/locale/extensions/extensions.dtd">
     9 %extensionsDTD;
    10 ]>
    12 <bindings id="addonBindings"
    13           xmlns="http://www.mozilla.org/xbl"
    14           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    15           xmlns:xbl="http://www.mozilla.org/xbl">
    18   <!-- Rating - displays current/average rating, allows setting user rating -->
    19   <binding id="rating">
    20     <content>
    21       <xul:image class="star"
    22                  onmouseover="document.getBindingParent(this)._hover(1);"
    23                  onclick="document.getBindingParent(this).userRating = 1;"/>
    24       <xul:image class="star"
    25                  onmouseover="document.getBindingParent(this)._hover(2);"
    26                  onclick="document.getBindingParent(this).userRating = 2;"/>
    27       <xul:image class="star"
    28                  onmouseover="document.getBindingParent(this)._hover(3);"
    29                  onclick="document.getBindingParent(this).userRating = 3;"/>
    30       <xul:image class="star"
    31                  onmouseover="document.getBindingParent(this)._hover(4);"
    32                  onclick="document.getBindingParent(this).userRating = 4;"/>
    33       <xul:image class="star"
    34                  onmouseover="document.getBindingParent(this)._hover(5);"
    35                  onclick="document.getBindingParent(this).userRating = 5;"/>
    36     </content>
    38     <implementation>
    39       <constructor><![CDATA[
    40         this._updateStars();
    41       ]]></constructor>
    43       <property name="stars" readonly="true">
    44         <getter><![CDATA[
    45           return document.getAnonymousNodes(this);
    46         ]]></getter>
    47       </property>
    49       <property name="averageRating">
    50         <getter><![CDATA[
    51           if (this.hasAttribute("averagerating"))
    52             return this.getAttribute("averagerating");
    53           return -1;
    54         ]]></getter>
    55         <setter><![CDATA[
    56           this.setAttribute("averagerating", val);
    57           if (this.showRating == "average")
    58             this._updateStars();
    59         ]]></setter>
    60       </property>
    62       <property name="userRating">
    63         <getter><![CDATA[
    64           if (this.hasAttribute("userrating"))
    65             return this.getAttribute("userrating");
    66           return -1;
    67         ]]></getter>
    68         <setter><![CDATA[
    69           if (this.showRating != "user")
    70             return;
    71           this.setAttribute("userrating", val);
    72           if (this.showRating == "user")
    73             this._updateStars();
    74         ]]></setter>
    75       </property>
    77       <property name="showRating">
    78         <getter><![CDATA[
    79           if (this.hasAttribute("showrating"))
    80             return this.getAttribute("showrating");
    81           return "average";
    82         ]]></getter>
    83         <setter><![CDATA[
    84           if (val != "average" || val != "user")
    85             throw Components.Exception("Invalid value", Components.results.NS_ERROR_ILLEGAL_VALUE);
    86           this.setAttribute("showrating", val);
    87           this._updateStars();
    88         ]]></setter>
    89       </property>
    91       <method name="_updateStars">
    92         <body><![CDATA[
    93           var stars = this.stars;
    94           var rating = this[this.showRating + "Rating"];
    95           // average ratings can be non-whole numbers, round them so they
    96           // match to their closest star
    97           rating = Math.round(rating);
    98           for (let i = 0; i < stars.length; i++)
    99             stars[i].setAttribute("on", rating > i);
   100         ]]></body>
   101       </method>
   103       <method name="_hover">
   104         <parameter name="aScore"/>
   105         <body><![CDATA[
   106           if (this.showRating != "user")
   107             return;
   108           var stars = this.stars;
   109           for (let i = 0; i < stars.length; i++)
   110             stars[i].setAttribute("on", i <= (aScore -1));
   111         ]]></body>
   112       </method>
   114     </implementation>
   116     <handlers>
   117       <handler event="mouseout">
   118         this._updateStars();
   119       </handler>
   120     </handlers>
   121   </binding>
   123   <!-- Download progress - shows graphical progress of download and any
   124        related status message. -->
   125   <binding id="download-progress">
   126     <content>
   127       <xul:stack flex="1">
   128         <xul:hbox flex="1">
   129           <xul:hbox class="start-cap"/>
   130           <xul:progressmeter anonid="progress" class="progress" flex="1"
   131                              min="0" max="100"/>
   132           <xul:hbox class="end-cap"/>
   133         </xul:hbox>
   134         <xul:hbox class="status-container">
   135           <xul:spacer flex="1"/>
   136           <xul:label anonid="status" class="status"/>
   137           <xul:spacer flex="1"/>
   138           <xul:button anonid="cancel-btn" class="cancel"
   139                       tooltiptext="&progress.cancel.tooltip;"
   140                       oncommand="document.getBindingParent(this).cancel();"/>
   141         </xul:hbox>
   142       </xul:stack>
   143     </content>
   145     <implementation>
   146       <constructor><![CDATA[
   147         var progress = 0;
   148         if (this.hasAttribute("progress"))
   149           progress = parseInt(this.getAttribute("progress"));
   150         this.progress = progress;
   151       ]]></constructor>
   153       <field name="_progress">
   154         document.getAnonymousElementByAttribute(this, "anonid", "progress");
   155       </field>
   156       <field name="_cancel">
   157         document.getAnonymousElementByAttribute(this, "anonid", "cancel-btn");
   158       </field>
   159       <field name="_status">
   160         document.getAnonymousElementByAttribute(this, "anonid", "status");
   161       </field>
   163       <property name="progress">
   164         <getter><![CDATA[
   165           return this._progress.value;
   166         ]]></getter>
   167         <setter><![CDATA[
   168           this._progress.value = val;
   169           if (val == this._progress.max)
   170             this.setAttribute("complete", true);
   171           else
   172             this.removeAttribute("complete");
   173         ]]></setter>
   174       </property>
   176       <property name="maxProgress">
   177         <getter><![CDATA[
   178           return this._progress.max;
   179         ]]></getter>
   180         <setter><![CDATA[
   181           if (val == -1) {
   182             this._progress.mode = "undetermined";
   183           } else {
   184             this._progress.mode = "determined";
   185             this._progress.max = val;
   186           }
   187           this.setAttribute("mode", this._progress.mode);
   188         ]]></setter>
   189       </property>
   191       <property name="status">
   192         <getter><![CDATA[
   193           return this._status.value;
   194         ]]></getter>
   195         <setter><![CDATA[
   196           this._status.value = val;
   197         ]]></setter>
   198       </property>
   200       <method name="cancel">
   201         <body><![CDATA[
   202           this.mInstall.cancel();
   203         ]]></body>
   204       </method>
   205     </implementation>
   206   </binding>
   209   <!-- Sorters - displays and controls the sort state of a list. -->
   210   <binding id="sorters">
   211     <content orient="horizontal">
   212       <xul:button anonid="name-btn" class="sorter"
   213                   label="&sort.name.label;" tooltiptext="&sort.name.tooltip;"
   214                   oncommand="this.parentNode._handleChange('name');"/>
   215       <xul:button anonid="date-btn" class="sorter"
   216                   label="&sort.dateUpdated.label;"
   217                   tooltiptext="&sort.dateUpdated.tooltip;"
   218                   oncommand="this.parentNode._handleChange('updateDate');"/>
   219       <xul:button anonid="price-btn" class="sorter" hidden="true"
   220                   label="&sort.price.label;"
   221                   tooltiptext="&sort.price.tooltip;"
   222                   oncommand="this.parentNode._handleChange('purchaseAmount');"/>
   223       <xul:button anonid="relevance-btn" class="sorter" hidden="true"
   224                   label="&sort.relevance.label;"
   225                   tooltiptext="&sort.relevance.tooltip;"
   226                   oncommand="this.parentNode._handleChange('relevancescore');"/>
   227     </content>
   229     <implementation>
   230       <constructor><![CDATA[
   231         if (!this.hasAttribute("sortby"))
   232           this.setAttribute("sortby", "name");
   234         if (this.getAttribute("showrelevance") == "true")
   235           this._btnRelevance.hidden = false;
   237         if (this.getAttribute("showprice") == "true")
   238           this._btnPrice.hidden = false;
   240         this._refreshState();
   241       ]]></constructor>
   243       <field name="handler">null</field>
   244       <field name="_btnName">
   245         document.getAnonymousElementByAttribute(this, "anonid", "name-btn");
   246       </field>
   247       <field name="_btnDate">
   248         document.getAnonymousElementByAttribute(this, "anonid", "date-btn");
   249       </field>
   250       <field name="_btnPrice">
   251         document.getAnonymousElementByAttribute(this, "anonid", "price-btn");
   252       </field>
   253       <field name="_btnRelevance">
   254         document.getAnonymousElementByAttribute(this, "anonid", "relevance-btn");
   255       </field>
   257       <property name="sortBy">
   258         <getter><![CDATA[
   259           return this.getAttribute("sortby");
   260         ]]></getter>
   261         <setter><![CDATA[
   262           if (val != this.sortBy) {
   263             this.setAttribute("sortBy", val);
   264             this._refreshState();
   265           }
   266         ]]></setter>
   267       </property>
   269       <property name="ascending">
   270         <getter><![CDATA[
   271           return (this.getAttribute("ascending") == "true");
   272         ]]></getter>
   273         <setter><![CDATA[
   274           val = !!val;
   275           if (val != this.ascending) {
   276             this.setAttribute("ascending", val);
   277             this._refreshState();
   278           }
   279         ]]></setter>
   280       </property>
   282       <property name="showrelevance">
   283         <getter><![CDATA[
   284           return (this.getAttribute("showrelevance") == "true");
   285         ]]></getter>
   286         <setter><![CDATA[
   287           val = !!val;
   288           this.setAttribute("showrelevance", val);
   289           this._btnRelevance.hidden = !val;
   290         ]]></setter>
   291       </property>
   293       <property name="showprice">
   294         <getter><![CDATA[
   295           return (this.getAttribute("showprice") == "true");
   296         ]]></getter>
   297         <setter><![CDATA[
   298           val = !!val;
   299           this.setAttribute("showprice", val);
   300           this._btnPrice.hidden = !val;
   301         ]]></setter>
   302       </property>
   304       <method name="setSort">
   305         <parameter name="aSort"/>
   306         <parameter name="aAscending"/>
   307         <body><![CDATA[
   308           var sortChanged = false;
   309           if (aSort != this.sortBy) {
   310             this.setAttribute("sortby", aSort);
   311             sortChanged = true;
   312           }
   314           aAscending = !!aAscending;
   315           if (this.ascending != aAscending) {
   316             this.setAttribute("ascending", aAscending);
   317             sortChanged = true;
   318           }
   320           if (sortChanged)
   321             this._refreshState();
   322         ]]></body>
   323       </method>
   325       <method name="_handleChange">
   326         <parameter name="aSort"/>
   327         <body><![CDATA[
   328           const ASCENDING_SORT_FIELDS = ["name", "purchaseAmount"];
   330           // Toggle ascending if sort by is not changing, otherwise
   331           // name sorting defaults to ascending, others to descending
   332           if (aSort == this.sortBy)
   333             this.ascending = !this.ascending;
   334           else
   335             this.setSort(aSort, ASCENDING_SORT_FIELDS.indexOf(aSort) >= 0);
   336         ]]></body>
   337       </method>
   339       <method name="_refreshState">
   340         <body><![CDATA[
   341           var sortBy = this.sortBy;
   342           var checkState = this.ascending ? 2 : 1;
   344           if (sortBy == "name") {
   345             this._btnName.checkState = checkState;
   346             this._btnName.checked = true;
   347           } else {
   348             this._btnName.checkState = 0;
   349             this._btnName.checked = false;
   350           }
   352           if (sortBy == "updateDate") {
   353             this._btnDate.checkState = checkState;
   354             this._btnDate.checked = true;
   355           } else {
   356             this._btnDate.checkState = 0;
   357             this._btnDate.checked = false;
   358           }
   360           if (sortBy == "purchaseAmount") {
   361             this._btnPrice.checkState = checkState;
   362             this._btnPrice.checked = true;
   363           } else {
   364             this._btnPrice.checkState = 0;
   365             this._btnPrice.checked = false;
   366           }
   368           if (sortBy == "relevancescore") {
   369             this._btnRelevance.checkState = checkState;
   370             this._btnRelevance.checked = true;
   371           } else {
   372             this._btnRelevance.checkState = 0;
   373             this._btnRelevance.checked = false;
   374           }
   376           if (this.handler && "onSortChanged" in this.handler)
   377             this.handler.onSortChanged(sortBy, this.ascending);
   378         ]]></body>
   379       </method>
   380     </implementation>
   381   </binding>
   384   <!-- Categories list - displays the list of categories on the left pane. -->
   385   <binding id="categories-list"
   386            extends="chrome://global/content/bindings/richlistbox.xml#richlistbox">
   387     <implementation>
   388       <!-- This needs to be overridden to allow the fancy animation while not
   389            allowing that item to be selected when hiding.  -->
   390       <method name="_canUserSelect">
   391         <parameter name="aItem"/>
   392         <body>
   393         <![CDATA[
   394           if (aItem.hasAttribute("disabled") &&
   395               aItem.getAttribute("disabled") == "true")
   396             return false;
   397           var style = document.defaultView.getComputedStyle(aItem, "");
   398           return style.display != "none" && style.visibility == "visible";
   399         ]]>
   400         </body>
   401       </method>
   402     </implementation>
   403   </binding>
   406   <!-- Category item - an item in the category list. -->
   407   <binding id="category"
   408            extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
   409     <content align="center">
   410       <xul:image anonid="icon" class="category-icon"/>
   411       <xul:label anonid="name" class="category-name" flex="1" xbl:inherits="value=name"/>
   412       <xul:label anonid="badge" class="category-badge" xbl:inherits="value=count"/>
   413     </content>
   415     <implementation>
   416       <constructor><![CDATA[
   417         if (!this.hasAttribute("count"))
   418           this.setAttribute("count", 0);
   419       ]]></constructor>
   421       <property name="badgeCount">
   422         <getter><![CDATA[
   423           return this.getAttribute("count");
   424         ]]></getter>
   425         <setter><![CDATA[
   426           if (this.getAttribute("count") == val)
   427             return;
   429           this.setAttribute("count", val);
   430           var event = document.createEvent("Events");
   431           event.initEvent("CategoryBadgeUpdated", true, true);
   432           this.dispatchEvent(event);
   433         ]]></setter>
   434       </property>
   435     </implementation>
   436   </binding>
   439   <!-- Creator link - Name of a user/developer, providing a link if relevant. -->
   440   <binding id="creator-link">
   441     <content>
   442       <xul:label anonid="label" value="&addon.createdBy.label;"/>
   443       <xul:label anonid="creator-link" class="creator-link text-link"/>
   444       <xul:label anonid="creator-name" class="creator-name"/>
   445     </content>
   447     <implementation>
   448       <constructor><![CDATA[
   449         if (this.hasAttribute("nameonly") &&
   450             this.getAttribute("nameonly") == "true") {
   451           this._label.hidden = true;
   452         }
   453       ]]></constructor>
   455       <field name="_label">
   456         document.getAnonymousElementByAttribute(this, "anonid", "label");
   457       </field>
   458       <field name="_creatorLink">
   459         document.getAnonymousElementByAttribute(this, "anonid", "creator-link");
   460       </field>
   461       <field name="_creatorName">
   462         document.getAnonymousElementByAttribute(this, "anonid", "creator-name");
   463       </field>
   465       <method name="setCreator">
   466         <parameter name="aCreator"/>
   467         <parameter name="aHomepageURL"/>
   468         <body><![CDATA[
   469           if (!aCreator) {
   470             this.collapsed = true;
   471             return;
   472           }
   473           this.collapsed = false;
   474           var url = aCreator.url || aHomepageURL;
   475           var showLink = !!url;
   476           if (showLink) {
   477             this._creatorLink.value = aCreator.name;
   478             this._creatorLink.href = url;
   479           } else {
   480             this._creatorName.value = aCreator.name;
   481           }
   482           this._creatorLink.hidden = !showLink;
   483           this._creatorName.hidden = showLink;
   484         ]]></body>
   485       </method>
   486     </implementation>
   487   </binding>
   490   <!-- Install status - Displays the status of an install/upgrade. -->
   491   <binding id="install-status">
   492     <content>
   493       <xul:label anonid="message"/>
   494       <xul:progressmeter anonid="progress" class="download-progress"/>
   495       <xul:button anonid="purchase-remote-btn" hidden="true"
   496                   class="addon-control"
   497                   oncommand="document.getBindingParent(this).purchaseRemote();"/>
   498       <xul:button anonid="install-remote-btn" hidden="true"
   499                   class="addon-control install" label="&addon.install.label;"
   500                   tooltiptext="&addon.install.tooltip;"
   501                   oncommand="document.getBindingParent(this).installRemote();"/>
   502     </content>
   504     <implementation>
   505       <constructor><![CDATA[
   506         if (this.mInstall)
   507           this.initWithInstall(this.mInstall);
   508         else if (this.mControl.mAddon.install)
   509           this.initWithInstall(this.mControl.mAddon.install);
   510         else
   511           this.refreshState();
   512       ]]></constructor>
   514       <destructor><![CDATA[
   515         if (this.mInstall)
   516           this.mInstall.removeListener(this);
   517       ]]></destructor>
   519       <field name="_message">
   520         document.getAnonymousElementByAttribute(this, "anonid", "message");
   521       </field>
   522       <field name="_progress">
   523         document.getAnonymousElementByAttribute(this, "anonid", "progress");
   524       </field>
   525       <field name="_purchaseRemote">
   526         document.getAnonymousElementByAttribute(this, "anonid",
   527                                                 "purchase-remote-btn");
   528       </field>
   529       <field name="_installRemote">
   530         document.getAnonymousElementByAttribute(this, "anonid",
   531                                                 "install-remote-btn");
   532       </field>
   533       <field name="_restartNeeded">
   534         document.getAnonymousElementByAttribute(this, "anonid",
   535                                                 "restart-needed");
   536       </field>
   537       <field name="_undo">
   538         document.getAnonymousElementByAttribute(this, "anonid",
   539                                                 "undo-btn");
   540       </field>
   542       <method name="initWithInstall">
   543         <parameter name="aInstall"/>
   544         <body><![CDATA[
   545           if (this.mInstall) {
   546             this.mInstall.removeListener(this);
   547             this.mInstall = null;
   548           }
   549           this.mInstall = aInstall;
   550           this._progress.mInstall = aInstall;
   551           this.refreshState();
   552           this.mInstall.addListener(this);
   553         ]]></body>
   554       </method>
   556       <method name="refreshState">
   557         <body><![CDATA[
   558           var showInstallRemote = false;
   559           var showPurchase = false;
   561           if (this.mInstall) {
   563             switch (this.mInstall.state) {
   564               case AddonManager.STATE_AVAILABLE:
   565                 if (this.mControl.getAttribute("remote") != "true")
   566                   break;
   568                 this._progress.hidden = true;
   569                 showInstallRemote = true;
   570                 break;
   571               case AddonManager.STATE_DOWNLOADING:
   572                 this.showMessage("installDownloading");
   573                 break;
   574               case AddonManager.STATE_CHECKING:
   575                 this.showMessage("installVerifying");
   576                 break;
   577               case AddonManager.STATE_DOWNLOADED:
   578                 this.showMessage("installDownloaded");
   579                 break;
   580               case AddonManager.STATE_DOWNLOAD_FAILED:
   581                 // XXXunf expose what error occured (bug 553487)
   582                 this.showMessage("installDownloadFailed", true);
   583                 break;
   584               case AddonManager.STATE_INSTALLING:
   585                 this.showMessage("installInstalling");
   586                 break;
   587               case AddonManager.STATE_INSTALL_FAILED:
   588                 // XXXunf expose what error occured (bug 553487)
   589                 this.showMessage("installFailed", true);
   590                 break;
   591               case AddonManager.STATE_CANCELLED:
   592                 this.showMessage("installCancelled", true);
   593                 break;
   594             }
   596           } else if (this.mControl.mAddon.purchaseURL) {
   597             this._progress.hidden = true;
   598             showPurchase = true;
   599             this._purchaseRemote.label =
   600               gStrings.ext.formatStringFromName("addon.purchase.label",
   601                 [this.mControl.mAddon.purchaseDisplayAmount], 1);
   602             this._purchaseRemote.tooltiptext =
   603               gStrings.ext.GetStringFromName("addon.purchase.tooltip");
   604           }
   606           this._purchaseRemote.hidden = !showPurchase;
   607           this._installRemote.hidden = !showInstallRemote;
   609           if ("refreshInfo" in this.mControl)
   610             this.mControl.refreshInfo();
   611         ]]></body>
   612       </method>
   614       <method name="showMessage">
   615         <parameter name="aMsgId"/>
   616         <parameter name="aHideProgress"/>
   617         <body><![CDATA[
   618           this._message.setAttribute("hidden", !aHideProgress);
   619           this._progress.setAttribute("hidden", !!aHideProgress);
   621           var msg = gStrings.ext.GetStringFromName(aMsgId);
   622           if (aHideProgress)
   623             this._message.value = msg;
   624           else
   625             this._progress.status = msg;
   626         ]]></body>
   627       </method>
   629       <method name="purchaseRemote">
   630         <body><![CDATA[
   631           openURL(this.mControl.mAddon.purchaseURL);
   632         ]]></body>
   633       </method>
   635       <method name="installRemote">
   636         <body><![CDATA[
   637           if (this.mControl.getAttribute("remote") != "true")
   638             return;
   640           if (this.mControl.mAddon.eula) {
   641             var data = {
   642               addon: this.mControl.mAddon,
   643               accepted: false
   644             };
   645             window.openDialog("chrome://mozapps/content/extensions/eula.xul", "_blank",
   646                               "chrome,dialog,modal,centerscreen,resizable=no", data);
   647             if (!data.accepted)
   648               return;
   649           }
   651           delete this.mControl.mAddon;
   652           this.mControl.mInstall = this.mInstall;
   653           this.mControl.setAttribute("status", "installing");
   654           this.mInstall.install();
   655         ]]></body>
   656       </method>
   658       <method name="undoAction">
   659         <body><![CDATA[
   660           if (!this.mAddon)
   661             return;
   662           var pending = this.mAddon.pendingOperations;
   663           if (pending & AddonManager.PENDING_ENABLE)
   664             this.mAddon.userDisabled = true;
   665           else if (pending & AddonManager.PENDING_DISABLE)
   666             this.mAddon.userDisabled = false;
   667           this.refreshState();
   668         ]]></body>
   669       </method>
   671       <method name="onDownloadStarted">
   672         <body><![CDATA[
   673           this.refreshState();
   674         ]]></body>
   675       </method>
   677       <method name="onDownloadEnded">
   678         <body><![CDATA[
   679           this.refreshState();
   680         ]]></body>
   681       </method>
   683       <method name="onDownloadFailed">
   684         <body><![CDATA[
   685           this.refreshState();
   686         ]]></body>
   687       </method>
   689       <method name="onDownloadProgress">
   690         <body><![CDATA[
   691           this._progress.maxProgress = this.mInstall.maxProgress;
   692           this._progress.progress = this.mInstall.progress;
   693         ]]></body>
   694       </method>
   696       <method name="onInstallStarted">
   697         <body><![CDATA[
   698           this._progress.progress = 0;
   699           this.refreshState();
   700         ]]></body>
   701       </method>
   703       <method name="onInstallEnded">
   704         <body><![CDATA[
   705           this.refreshState();
   706           if ("onInstallCompleted" in this.mControl)
   707             this.mControl.onInstallCompleted();
   708         ]]></body>
   709       </method>
   711       <method name="onInstallFailed">
   712         <body><![CDATA[
   713           this.refreshState();
   714         ]]></body>
   715       </method>
   716     </implementation>
   717   </binding>
   720   <!-- Addon - base - parent binding of any item representing an addon. -->
   721   <binding id="addon-base"
   722            extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
   723     <implementation>
   724       <method name="hasPermission">
   725         <parameter name="aPerm"/>
   726         <body><![CDATA[
   727           var perm = AddonManager["PERM_CAN_" + aPerm.toUpperCase()];
   728           return !!(this.mAddon.permissions & perm);
   729         ]]></body>
   730       </method>
   732       <method name="opRequiresRestart">
   733         <parameter name="aOperation"/>
   734         <body><![CDATA[
   735           var operation = AddonManager["OP_NEEDS_RESTART_" + aOperation.toUpperCase()];
   736           return !!(this.mAddon.operationsRequiringRestart & operation);
   737         ]]></body>
   738       </method>
   740       <method name="isPending">
   741         <parameter name="aAction"/>
   742         <body><![CDATA[
   743           var action = AddonManager["PENDING_" + aAction.toUpperCase()];
   744           return !!(this.mAddon.pendingOperations & action);
   745         ]]></body>
   746       </method>
   748       <method name="onUninstalled">
   749         <body><![CDATA[
   750           this.parentNode.removeChild(this);
   751         ]]></body>
   752       </method>
   753     </implementation>
   754   </binding>
   757   <!-- Addon - generic - A normal addon item, or an update to one -->
   758   <binding id="addon-generic"
   759            extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
   760     <content>
   761       <xul:hbox anonid="warning-container"
   762                 class="warning">
   763         <xul:image class="warning-icon"/>
   764         <xul:label anonid="warning" flex="1"/>
   765         <xul:label anonid="warning-link" class="text-link"/>
   766         <xul:button anonid="warning-btn" class="button-link"/>
   767         <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
   768       </xul:hbox>
   769       <xul:hbox anonid="error-container"
   770                 class="error">
   771         <xul:image class="error-icon"/>
   772         <xul:label anonid="error" flex="1"/>
   773         <xul:label anonid="error-link" class="text-link"/>
   774         <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
   775       </xul:hbox>
   776       <xul:hbox anonid="pending-container"
   777                 class="pending">
   778         <xul:image class="pending-icon"/>
   779         <xul:label anonid="pending" flex="1"/>
   780         <xul:button anonid="restart-btn" class="button-link"
   781                     label="&addon.restartNow.label;"
   782                     oncommand="document.getBindingParent(this).restart();"/>
   783         <xul:button anonid="undo-btn" class="button-link"
   784                     label="&addon.undoAction.label;"
   785                     tooltipText="&addon.undoAction.tooltip;"
   786                     oncommand="document.getBindingParent(this).undo();"/>
   787         <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
   788       </xul:hbox>
   790       <xul:hbox class="content-container">
   791         <xul:vbox class="icon-container">
   792           <xul:image anonid="icon" class="icon"/>
   793         </xul:vbox>
   794         <xul:vbox class="content-inner-container" flex="1">
   795           <xul:hbox class="basicinfo-container">
   796               <xul:hbox class="name-container">
   797                 <xul:label anonid="name" class="name" crop="end" flex="1"
   798                            xbl:inherits="value=name,tooltiptext=name"/>
   799                 <xul:label anonid="version" class="version"/>
   800                 <xul:label class="disabled-postfix" value="&addon.disabled.postfix;"/>
   801                 <xul:label class="update-postfix" value="&addon.update.postfix;"/>
   802                 <xul:spacer flex="5000"/> <!-- Necessary to make the name crop -->
   803               </xul:hbox>
   804             <xul:label anonid="date-updated" class="date-updated"
   805                        unknown="&addon.unknownDate;"/>
   806           </xul:hbox>
   807           <xul:hbox class="experiment-container">
   808             <svg width="6" height="6" viewBox="0 0 6 6" version="1.1"
   809                  xmlns="http://www.w3.org/2000/svg"
   810                  class="experiment-bullet-container">
   811               <circle cx="3" cy="3" r="3" class="experiment-bullet"/>
   812             </svg>
   813             <xul:label anonid="experiment-state" class="experiment-state"/>
   814             <xul:label anonid="experiment-time" class="experiment-time"/>
   815           </xul:hbox>
   817           <xul:hbox class="advancedinfo-container" flex="1">
   818             <xul:vbox class="description-outer-container" flex="1">
   819               <xul:hbox class="description-container">
   820                 <xul:label anonid="description" class="description" crop="end" flex="1"/>
   821                 <xul:button anonid="details-btn" class="details button-link"
   822                             label="&addon.details.label;"
   823                             tooltiptext="&addon.details.tooltip;"
   824                             oncommand="document.getBindingParent(this).showInDetailView();"/>
   825                 <xul:spacer flex="5000"/> <!-- Necessary to make the description crop -->
   826               </xul:hbox>
   827               <xul:vbox anonid="relnotes-container" class="relnotes-container">
   828                 <xul:label class="relnotes-header" value="&addon.releaseNotes.label;"/>
   829                 <xul:label anonid="relnotes-loading" value="&addon.loadingReleaseNotes.label;"/>
   830                 <xul:label anonid="relnotes-error" hidden="true"
   831                            value="&addon.errorLoadingReleaseNotes.label;"/>
   832                 <xul:vbox anonid="relnotes" class="relnotes"/>
   833               </xul:vbox>
   834               <xul:hbox class="relnotes-toggle-container">
   835                 <xul:button anonid="relnotes-toggle-btn" class="relnotes-toggle"
   836                             hidden="true" label="&cmd.showReleaseNotes.label;"
   837                             tooltiptext="&cmd.showReleaseNotes.tooltip;"
   838                             showlabel="&cmd.showReleaseNotes.label;"
   839                             showtooltip="&cmd.showReleaseNotes.tooltip;"
   840                             hidelabel="&cmd.hideReleaseNotes.label;"
   841                             hidetooltip="&cmd.hideReleaseNotes.tooltip;"
   842                             oncommand="document.getBindingParent(this).toggleReleaseNotes();"/>
   843               </xul:hbox>
   844             </xul:vbox>
   845             <xul:vbox class="status-control-wrapper">
   846               <xul:hbox class="status-container">
   847                 <xul:hbox anonid="checking-update" hidden="true">
   848                   <xul:image class="spinner"/>
   849                   <xul:label value="&addon.checkingForUpdates.label;"/>
   850                 </xul:hbox>
   851                 <xul:vbox anonid="update-available" class="update-available"
   852                           hidden="true">
   853                   <xul:checkbox anonid="include-update" class="include-update"
   854                                 label="&addon.includeUpdate.label;" checked="true"
   855                                 oncommand="document.getBindingParent(this).onIncludeUpdateChanged();"/>
   856                   <xul:hbox class="update-info-container">
   857                     <xul:label class="update-available-notice"
   858                                value="&addon.updateAvailable.label;"/>
   859                     <xul:button anonid="update-btn" class="addon-control update"
   860                                 label="&addon.updateNow.label;"
   861                                 tooltiptext="&addon.updateNow.tooltip;"
   862                                 oncommand="document.getBindingParent(this).upgrade();"/>
   863                   </xul:hbox>
   864                 </xul:vbox>
   865                 <xul:hbox anonid="install-status" class="install-status"
   866                           hidden="true"/>
   867               </xul:hbox>
   868               <xul:hbox anonid="control-container" class="control-container">
   869                 <xul:button anonid="preferences-btn"
   870                             class="addon-control preferences"
   871 #ifdef XP_WIN
   872                             label="&cmd.showPreferencesWin.label;"
   873                             tooltiptext="&cmd.showPreferencesWin.tooltip;"
   874 #else
   875                             label="&cmd.showPreferencesUnix.label;"
   876                             tooltiptext="&cmd.showPreferencesUnix.tooltip;"
   877 #endif
   878                             oncommand="document.getBindingParent(this).showPreferences();"/>
   879                             <!-- label="&cmd.debugAddon.label;" -->
   880                 <xul:button anonid="debug-btn" class="addon-control debug"
   881                             label="&cmd.debugAddon.label;"
   882                             oncommand="document.getBindingParent(this).debug();"/>
   884                 <xul:button anonid="enable-btn"  class="addon-control enable"
   885                             label="&cmd.enableAddon.label;"
   886                             oncommand="document.getBindingParent(this).userDisabled = false;"/>
   887                 <xul:button anonid="disable-btn" class="addon-control disable"
   888                             label="&cmd.disableAddon.label;"
   889                             oncommand="document.getBindingParent(this).userDisabled = true;"/>
   890                 <xul:button anonid="remove-btn" class="addon-control remove"
   891                             label="&cmd.uninstallAddon.label;"
   892                             oncommand="document.getBindingParent(this).uninstall();"/>
   893                 <xul:menulist anonid="state-menulist"
   894                               class="addon-control state"
   895                               tooltiptext="&cmd.stateMenu.tooltip;">
   896                   <xul:menupopup>
   897                     <xul:menuitem anonid="ask-to-activate-menuitem"
   898                                   class="addon-control"
   899                                   label="&cmd.askToActivate.label;"
   900                                   tooltiptext="&cmd.askToActivate.tooltip;"
   901                                   oncommand="document.getBindingParent(this).userDisabled = AddonManager.STATE_ASK_TO_ACTIVATE;"/>
   902                     <xul:menuitem anonid="always-activate-menuitem"
   903                                   class="addon-control"
   904                                   label="&cmd.alwaysActivate.label;"
   905                                   tooltiptext="&cmd.alwaysActivate.tooltip;"
   906                                   oncommand="document.getBindingParent(this).userDisabled = false;"/>
   907                     <xul:menuitem anonid="never-activate-menuitem"
   908                                   class="addon-control"
   909                                   label="&cmd.neverActivate.label;"
   910                                   tooltiptext="&cmd.neverActivate.tooltip;"
   911                                   oncommand="document.getBindingParent(this).userDisabled = true;"/>
   912                   </xul:menupopup>
   913                 </xul:menulist>
   914               </xul:hbox>
   915             </xul:vbox>
   916           </xul:hbox>
   917         </xul:vbox>
   918       </xul:hbox>
   919     </content>
   921     <implementation>
   922       <constructor><![CDATA[
   923         this._installStatus.mControl = this;
   925         this.setAttribute("contextmenu", "addonitem-popup");
   927         this._showStatus("none");
   929         this._initWithAddon(this.mAddon);
   931         gEventManager.registerAddonListener(this, this.mAddon.id);
   932       ]]></constructor>
   934       <destructor><![CDATA[
   935         gEventManager.unregisterAddonListener(this, this.mAddon.id);
   936       ]]></destructor>
   938       <field name="_warningContainer">
   939         document.getAnonymousElementByAttribute(this, "anonid",
   940                                                 "warning-container");
   941       </field>
   942       <field name="_warning">
   943         document.getAnonymousElementByAttribute(this, "anonid",
   944                                                 "warning");
   945       </field>
   946       <field name="_warningLink">
   947         document.getAnonymousElementByAttribute(this, "anonid",
   948                                                 "warning-link");
   949       </field>
   950       <field name="_warningBtn">
   951         document.getAnonymousElementByAttribute(this, "anonid",
   952                                                 "warning-btn");
   953       </field>
   954       <field name="_errorContainer">
   955         document.getAnonymousElementByAttribute(this, "anonid",
   956                                                 "error-container");
   957       </field>
   958       <field name="_error">
   959         document.getAnonymousElementByAttribute(this, "anonid",
   960                                                 "error");
   961       </field>
   962       <field name="_errorLink">
   963         document.getAnonymousElementByAttribute(this, "anonid",
   964                                                 "error-link");
   965       </field>
   966       <field name="_pendingContainer">
   967         document.getAnonymousElementByAttribute(this, "anonid",
   968                                                 "pending-container");
   969       </field>
   970       <field name="_pending">
   971         document.getAnonymousElementByAttribute(this, "anonid",
   972                                                 "pending");
   973       </field>
   974       <field name="_infoContainer">
   975         document.getAnonymousElementByAttribute(this, "anonid",
   976                                                 "info-container");
   977       </field>
   978       <field name="_info">
   979         document.getAnonymousElementByAttribute(this, "anonid",
   980                                                 "info");
   981       </field>
   982       <field name="_version">
   983         document.getAnonymousElementByAttribute(this, "anonid", "version");
   984       </field>
   985       <field name="_experimentState">
   986         document.getAnonymousElementByAttribute(this, "anonid", "experiment-state");
   987       </field>
   988       <field name="_experimentTime">
   989         document.getAnonymousElementByAttribute(this, "anonid", "experiment-time");
   990       </field>
   991       <field name="_icon">
   992         document.getAnonymousElementByAttribute(this, "anonid", "icon");
   993       </field>
   994       <field name="_dateUpdated">
   995         document.getAnonymousElementByAttribute(this, "anonid",
   996                                                 "date-updated");
   997       </field>
   998       <field name="_description">
   999         document.getAnonymousElementByAttribute(this, "anonid",
  1000                                                 "description");
  1001       </field>
  1002       <field name="_stateMenulist">
  1003         document.getAnonymousElementByAttribute(this, "anonid",
  1004                                                 "state-menulist");
  1005       </field>
  1006       <field name="_askToActivateMenuitem">
  1007         document.getAnonymousElementByAttribute(this, "anonid",
  1008                                                 "ask-to-activate-menuitem");
  1009       </field>
  1010       <field name="_alwaysActivateMenuitem">
  1011         document.getAnonymousElementByAttribute(this, "anonid",
  1012                                                 "always-activate-menuitem");
  1013       </field>
  1014       <field name="_neverActivateMenuitem">
  1015         document.getAnonymousElementByAttribute(this, "anonid",
  1016                                                 "never-activate-menuitem");
  1017       </field>
  1018       <field name="_preferencesBtn">
  1019         document.getAnonymousElementByAttribute(this, "anonid",
  1020                                                 "preferences-btn");
  1021       </field>
  1022       <field name="_enableBtn">
  1023         document.getAnonymousElementByAttribute(this, "anonid",
  1024                                                 "enable-btn");
  1025       </field>
  1026       <field name="_debugBtn">
  1027         document.getAnonymousElementByAttribute(this, "anonid",
  1028                                                 "debug-btn");
  1029       </field>
  1030       <field name="_disableBtn">
  1031         document.getAnonymousElementByAttribute(this, "anonid",
  1032                                                 "disable-btn");
  1033       </field>
  1034       <field name="_removeBtn">
  1035         document.getAnonymousElementByAttribute(this, "anonid",
  1036                                                 "remove-btn");
  1037       </field>
  1038       <field name="_updateBtn">
  1039         document.getAnonymousElementByAttribute(this, "anonid",
  1040                                                 "update-btn");
  1041       </field>
  1042       <field name="_controlContainer">
  1043         document.getAnonymousElementByAttribute(this, "anonid",
  1044                                                 "control-container");
  1045       </field>
  1046       <field name="_installStatus">
  1047         document.getAnonymousElementByAttribute(this, "anonid",
  1048                                                 "install-status");
  1049       </field>
  1050       <field name="_checkingUpdate">
  1051         document.getAnonymousElementByAttribute(this, "anonid",
  1052                                                 "checking-update");
  1053       </field>
  1054       <field name="_updateAvailable">
  1055         document.getAnonymousElementByAttribute(this, "anonid",
  1056                                                 "update-available");
  1057       </field>
  1058       <field name="_includeUpdate">
  1059         document.getAnonymousElementByAttribute(this, "anonid",
  1060                                                 "include-update");
  1061       </field>
  1062       <field name="_relNotesLoaded">false</field>
  1063       <field name="_relNotesToggle">
  1064         document.getAnonymousElementByAttribute(this, "anonid",
  1065                                                 "relnotes-toggle-btn");
  1066       </field>
  1067       <field name="_relNotesLoading">
  1068         document.getAnonymousElementByAttribute(this, "anonid",
  1069                                                 "relnotes-loading");
  1070       </field>
  1071       <field name="_relNotesError">
  1072         document.getAnonymousElementByAttribute(this, "anonid",
  1073                                                 "relnotes-error");
  1074       </field>
  1075       <field name="_relNotesContainer">
  1076         document.getAnonymousElementByAttribute(this, "anonid",
  1077                                                 "relnotes-container");
  1078       </field>
  1079       <field name="_relNotes">
  1080         document.getAnonymousElementByAttribute(this, "anonid",
  1081                                                 "relnotes");
  1082       </field>
  1084       <property name="userDisabled">
  1085         <getter><![CDATA[
  1086           return this.mAddon.userDisabled;
  1087         ]]></getter>
  1088         <setter><![CDATA[
  1089           this.mAddon.userDisabled = val;
  1090         ]]></setter>
  1091       </property>
  1093       <property name="includeUpdate">
  1094         <getter><![CDATA[
  1095           return this._includeUpdate.checked && !!this.mManualUpdate;
  1096         ]]></getter>
  1097         <setter><![CDATA[
  1098           //XXXunf Eventually, we'll want to persist this for individual
  1099           //       updates - see bug 594619.
  1100           this._includeUpdate.checked = !!val;
  1101         ]]></setter>
  1102       </property>
  1104       <method name="_initWithAddon">
  1105         <parameter name="aAddon"/>
  1106         <body><![CDATA[
  1107           this.mAddon = aAddon;
  1109           this._installStatus.mAddon = this.mAddon;
  1110           this._updateDates();
  1111           this._updateState();
  1113           this.setAttribute("name", aAddon.name);
  1115           var iconURL = this.mAddon.iconURL;
  1116           if (iconURL)
  1117             this._icon.src = iconURL;
  1118           else
  1119             this._icon.src = "";
  1121           if (shouldShowVersionNumber(this.mAddon))
  1122             this._version.value = this.mAddon.version;
  1123           else
  1124             this._version.hidden = true;
  1126           if (this.mAddon.description)
  1127             this._description.value = this.mAddon.description;
  1128           else
  1129             this._description.hidden = true;
  1131           if (!("applyBackgroundUpdates" in this.mAddon) ||
  1132               (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DISABLE ||
  1133                (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
  1134                 !AddonManager.autoUpdateDefault))) {
  1135             var self = this;
  1136             AddonManager.getAllInstalls(function(aInstallsList) {
  1137               // This can return after the binding has been destroyed,
  1138               // so try to detect that and return early
  1139               if (!("onNewInstall" in self))
  1140                 return;
  1141               for (let install of aInstallsList) {
  1142                 if (install.existingAddon &&
  1143                     install.existingAddon.id == self.mAddon.id &&
  1144                     install.state == AddonManager.STATE_AVAILABLE) {
  1145                   self.onNewInstall(install);
  1146                   self.onIncludeUpdateChanged();
  1149             });
  1151         ]]></body>
  1152       </method>
  1154       <method name="_showStatus">
  1155         <parameter name="aType"/>
  1156         <body><![CDATA[
  1157           this._controlContainer.hidden = aType != "none" &&
  1158                                           !(aType == "update-available" && !this.hasAttribute("upgrade"));
  1160           this._installStatus.hidden = aType != "progress";
  1161           if (aType == "progress")
  1162             this._installStatus.refreshState();
  1163           this._checkingUpdate.hidden = aType != "checking-update";
  1164           this._updateAvailable.hidden = aType != "update-available";
  1165           this._relNotesToggle.hidden = !(this.mManualUpdate ?
  1166                                           this.mManualUpdate.releaseNotesURI :
  1167                                           this.mAddon.releaseNotesURI);
  1168         ]]></body>
  1169       </method>
  1171       <method name="_updateDates">
  1172         <body><![CDATA[
  1173           function formatDate(aDate) {
  1174             return Cc["@mozilla.org/intl/scriptabledateformat;1"]
  1175                      .getService(Ci.nsIScriptableDateFormat)
  1176                      .FormatDate("",
  1177                                  Ci.nsIScriptableDateFormat.dateFormatLong,
  1178                                  aDate.getFullYear(),
  1179                                  aDate.getMonth() + 1,
  1180                                  aDate.getDate()
  1181                                  );
  1184           if (this.mAddon.updateDate)
  1185             this._dateUpdated.value = formatDate(this.mAddon.updateDate);
  1186           else
  1187             this._dateUpdated.value = this._dateUpdated.getAttribute("unknown");
  1188         ]]></body>
  1189       </method>
  1191       <method name="_updateState">
  1192         <body><![CDATA[
  1193           if (this.parentNode.selectedItem == this)
  1194             gViewController.updateCommands();
  1196           var pending = this.mAddon.pendingOperations;
  1197           if (pending != AddonManager.PENDING_NONE) {
  1198             this.removeAttribute("notification");
  1200             var pending = null;
  1201             const PENDING_OPERATIONS = ["enable", "disable", "install",
  1202                                         "uninstall", "upgrade"];
  1203             for (let op of PENDING_OPERATIONS) {
  1204               if (this.isPending(op))
  1205                 pending = op;
  1208             this.setAttribute("pending", pending);
  1209             this._pending.textContent = gStrings.ext.formatStringFromName(
  1210               "notification." + pending,
  1211               [this.mAddon.name, gStrings.brandShortName], 2
  1212             );
  1213           } else {
  1214             this.removeAttribute("pending");
  1216             var isUpgrade = this.hasAttribute("upgrade");
  1217             var install = this._installStatus.mInstall;
  1219             if (install && install.state == AddonManager.STATE_DOWNLOAD_FAILED) {
  1220               this.setAttribute("notification", "warning");
  1221               this._warning.textContent = gStrings.ext.formatStringFromName(
  1222                 "notification.downloadError",
  1223                 [this.mAddon.name], 1
  1224               );
  1225               this._warningBtn.label = gStrings.ext.GetStringFromName("notification.downloadError.retry");
  1226               this._warningBtn.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
  1227               this._warningBtn.setAttribute("oncommand", "document.getBindingParent(this).retryInstall();");
  1228               this._warningBtn.hidden = false;
  1229               this._warningLink.hidden = true;
  1230             } else if (install && install.state == AddonManager.STATE_INSTALL_FAILED) {
  1231               this.setAttribute("notification", "warning");
  1232               this._warning.textContent = gStrings.ext.formatStringFromName(
  1233                 "notification.installError",
  1234                 [this.mAddon.name], 1
  1235               );
  1236               this._warningBtn.label = gStrings.ext.GetStringFromName("notification.installError.retry");
  1237               this._warningBtn.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
  1238               this._warningBtn.setAttribute("oncommand", "document.getBindingParent(this).retryInstall();");
  1239               this._warningBtn.hidden = false;
  1240               this._warningLink.hidden = true;
  1241             } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
  1242               this.setAttribute("notification", "error");
  1243               this._error.textContent = gStrings.ext.formatStringFromName(
  1244                 "notification.blocked",
  1245                 [this.mAddon.name], 1
  1246               );
  1247               this._errorLink.value = gStrings.ext.GetStringFromName("notification.blocked.link");
  1248               this._errorLink.href = this.mAddon.blocklistURL;
  1249               this._errorLink.hidden = false;
  1250             } else if ((!isUpgrade && !this.mAddon.isCompatible) && (AddonManager.checkCompatibility
  1251             || (this.mAddon.blocklistState != Ci.nsIBlocklistService.STATE_SOFTBLOCKED))) {
  1252               this.setAttribute("notification", "warning");
  1253               this._warning.textContent = gStrings.ext.formatStringFromName(
  1254                 "notification.incompatible",
  1255                 [this.mAddon.name, gStrings.brandShortName, gStrings.appVersion], 3
  1256               );
  1257               this._warningLink.hidden = true;
  1258               this._warningBtn.hidden = true;
  1259             } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED) {
  1260               this.setAttribute("notification", "warning");
  1261               this._warning.textContent = gStrings.ext.formatStringFromName(
  1262                 "notification.softblocked",
  1263                 [this.mAddon.name], 1
  1264               );
  1265               this._warningLink.value = gStrings.ext.GetStringFromName("notification.softblocked.link");
  1266               this._warningLink.href = this.mAddon.blocklistURL;
  1267               this._warningLink.hidden = false;
  1268               this._warningBtn.hidden = true;
  1269             } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
  1270               this.setAttribute("notification", "warning");
  1271               this._warning.textContent = gStrings.ext.formatStringFromName(
  1272                 "notification.outdated",
  1273                 [this.mAddon.name], 1
  1274               );
  1275               this._warningLink.value = gStrings.ext.GetStringFromName("notification.outdated.link");
  1276               this._warningLink.href = Services.urlFormatter.formatURLPref("plugins.update.url");
  1277               this._warningLink.hidden = false;
  1278               this._warningBtn.hidden = true;
  1279             } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
  1280               this.setAttribute("notification", "error");
  1281               this._error.textContent = gStrings.ext.formatStringFromName(
  1282                 "notification.vulnerableUpdatable",
  1283                 [this.mAddon.name], 1
  1284               );
  1285               this._errorLink.value = gStrings.ext.GetStringFromName("notification.vulnerableUpdatable.link");
  1286               this._errorLink.href = this.mAddon.blocklistURL;
  1287               this._errorLink.hidden = false;
  1288             } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) {
  1289               this.setAttribute("notification", "error");
  1290               this._error.textContent = gStrings.ext.formatStringFromName(
  1291                 "notification.vulnerableNoUpdate",
  1292                 [this.mAddon.name], 1
  1293               );
  1294               this._errorLink.value = gStrings.ext.GetStringFromName("notification.vulnerableNoUpdate.link");
  1295               this._errorLink.href = this.mAddon.blocklistURL;
  1296               this._errorLink.hidden = false;
  1297             } else {
  1298               this.removeAttribute("notification");
  1302           this._preferencesBtn.hidden = (!this.mAddon.optionsURL) ||
  1303                                         this.mAddon.optionsType == AddonManager.OPTIONS_TYPE_INLINE_INFO;
  1305           let addonType = AddonManager.addonTypes[this.mAddon.type];
  1306           if (addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE &&
  1307               (this.hasPermission("ask_to_activate") ||
  1308                this.hasPermission("enable") ||
  1309                this.hasPermission("disable"))) {
  1310             this._enableBtn.disabled = true;
  1311             this._disableBtn.disabled = true;
  1312             this._askToActivateMenuitem.disabled = !this.hasPermission("ask_to_activate");
  1313             this._alwaysActivateMenuitem.disabled = !this.hasPermission("enable");
  1314             this._neverActivateMenuitem.disabled = !this.hasPermission("disable");
  1315             if (this.mAddon.userDisabled === true) {
  1316               this._stateMenulist.selectedItem = this._neverActivateMenuitem;
  1317             } else if (this.mAddon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) {
  1318               this._stateMenulist.selectedItem = this._askToActivateMenuitem;
  1319             } else {
  1320               this._stateMenulist.selectedItem = this._alwaysActivateMenuitem;
  1322             this._stateMenulist.selectedItem.disabled = false;
  1323             this._stateMenulist.disabled = false;
  1324           } else {
  1325             this._stateMenulist.disabled = true;
  1326             if (this.hasPermission("enable")) {
  1327               this._enableBtn.hidden = false;
  1328               let tooltip = gViewController.commands["cmd_enableItem"]
  1329                                            .getTooltip(this.mAddon);
  1330               this._enableBtn.setAttribute("tooltiptext", tooltip);
  1331             } else {
  1332               this._enableBtn.hidden = true;
  1335             if (this.hasPermission("disable")) {
  1336               this._disableBtn.hidden = false;
  1337               let tooltip = gViewController.commands["cmd_disableItem"]
  1338                                            .getTooltip(this.mAddon);
  1339               this._disableBtn.setAttribute("tooltiptext", tooltip);
  1340             } else {
  1341               this._disableBtn.hidden = true;
  1345           if (this.hasPermission("uninstall")) {
  1346             this._removeBtn.hidden = false;
  1347             let tooltip = gViewController.commands["cmd_uninstallItem"]
  1348                                          .getTooltip(this.mAddon);
  1349             this._removeBtn.setAttribute("tooltiptext", tooltip);
  1350           } else {
  1351             this._removeBtn.hidden = true;
  1354           this.setAttribute("active", this.mAddon.isActive);
  1356           var showProgress = this.mAddon.purchaseURL || (this.mAddon.install &&
  1357                              this.mAddon.install.state != AddonManager.STATE_INSTALLED);
  1358           this._showStatus(showProgress ? "progress" : "none");
  1360           let debuggable = this.mAddon.isDebuggable &&
  1361                            Services.prefs.getBoolPref('devtools.chrome.enabled') &&
  1362                            Services.prefs.getBoolPref('devtools.debugger.remote-enabled');
  1364           this._debugBtn.disabled = this._debugBtn.hidden = !debuggable
  1366           if (this.mAddon.type == "experiment") {
  1367             this.removeAttribute("notification");
  1368             let prefix = "experiment.";
  1369             let active = this.mAddon.isActive;
  1371             if (!showProgress) {
  1372               let stateKey = prefix + "state." + (active ? "active" : "complete");
  1373               this._experimentState.value = gStrings.ext.GetStringFromName(stateKey);
  1375               let now = Date.now();
  1376               let end = this.endDate;
  1377               let days = Math.abs(end - now) / (24 * 60 * 60 * 1000);
  1379               let timeKey = prefix + "time.";
  1380               let timeMessage;
  1382               if (days < 1) {
  1383                 timeKey += (active ? "endsToday" : "endedToday");
  1384                 timeMessage = gStrings.ext.GetStringFromName(timeKey);
  1385               } else {
  1386                 timeKey += (active ? "daysRemaining" : "daysPassed");
  1387                 days = Math.round(days);
  1388                 let timeString = gStrings.ext.GetStringFromName(timeKey);
  1389                 timeMessage = PluralForm.get(days, timeString)
  1390                                         .replace("#1", days);
  1393               this._experimentTime.value = timeMessage;
  1396         ]]></body>
  1397       </method>
  1399       <method name="_updateUpgradeInfo">
  1400         <body><![CDATA[
  1401           // Only update the version string if we're displaying the upgrade info
  1402           if (this.hasAttribute("upgrade") && shouldShowVersionNumber(this.mAddon))
  1403             this._version.value = this.mManualUpdate.version;
  1404         ]]></body>
  1405       </method>
  1407       <method name="_fetchReleaseNotes">
  1408         <parameter name="aURI"/>
  1409         <body><![CDATA[
  1410           var self = this;
  1411           if (!aURI || this._relNotesLoaded) {
  1412             sendToggleEvent();
  1413             return;
  1416           var relNotesData = null, transformData = null;
  1418           this._relNotesLoaded = true;
  1419           this._relNotesLoading.hidden = false;
  1420           this._relNotesError.hidden = true;
  1422           function sendToggleEvent() {
  1423             var event = document.createEvent("Events");
  1424             event.initEvent("RelNotesToggle", true, true);
  1425             self.dispatchEvent(event);
  1428           function showRelNotes() {
  1429             if (!relNotesData || !transformData)
  1430               return;
  1432             self._relNotesLoading.hidden = true;
  1434             var processor = Components.classes["@mozilla.org/document-transformer;1?type=xslt"]
  1435                                       .createInstance(Components.interfaces.nsIXSLTProcessor);
  1436             processor.flags |= Components.interfaces.nsIXSLTProcessorPrivate.DISABLE_ALL_LOADS;
  1438             processor.importStylesheet(transformData);
  1439             var fragment = processor.transformToFragment(relNotesData, document);
  1440             self._relNotes.appendChild(fragment);
  1441             if (self.hasAttribute("show-relnotes")) {
  1442               var container = self._relNotesContainer;
  1443               container.style.height = container.scrollHeight + "px";
  1445             sendToggleEvent();
  1448           function handleError() {
  1449             dataReq.abort();
  1450             styleReq.abort();
  1451             self._relNotesLoading.hidden = true;
  1452             self._relNotesError.hidden = false;
  1453             self._relNotesLoaded = false; // allow loading to be re-tried
  1454             sendToggleEvent();
  1457           function handleResponse(aEvent) {
  1458             var req = aEvent.target;
  1459             var ct = req.getResponseHeader("content-type");
  1460             if ((!ct || ct.indexOf("text/html") < 0) &&
  1461                 req.responseXML &&
  1462                 req.responseXML.documentElement.namespaceURI != XMLURI_PARSE_ERROR) {
  1463               if (req == dataReq)
  1464                 relNotesData = req.responseXML;
  1465               else
  1466                 transformData = req.responseXML;
  1467               showRelNotes();
  1468             } else {
  1469               handleError();
  1473           var dataReq = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
  1474                               .createInstance(Components.interfaces.nsIXMLHttpRequest);
  1475           dataReq.open("GET", aURI.spec, true);
  1476           dataReq.addEventListener("load", handleResponse, false);
  1477           dataReq.addEventListener("error", handleError, false);
  1478           dataReq.send(null);
  1480           var styleReq = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
  1481                               .createInstance(Components.interfaces.nsIXMLHttpRequest);
  1482           styleReq.open("GET", UPDATES_RELEASENOTES_TRANSFORMFILE, true);
  1483           styleReq.addEventListener("load", handleResponse, false);
  1484           styleReq.addEventListener("error", handleError, false);
  1485           styleReq.send(null);
  1486         ]]></body>
  1487       </method>
  1489       <method name="toggleReleaseNotes">
  1490         <body><![CDATA[
  1491           if (this.hasAttribute("show-relnotes")) {
  1492             this._relNotesContainer.style.height = "0px";
  1493             this.removeAttribute("show-relnotes");
  1494             this._relNotesToggle.setAttribute(
  1495               "label",
  1496               this._relNotesToggle.getAttribute("showlabel")
  1497             );
  1498             this._relNotesToggle.setAttribute(
  1499               "tooltiptext",
  1500               this._relNotesToggle.getAttribute("showtooltip")
  1501             );
  1502             var event = document.createEvent("Events");
  1503             event.initEvent("RelNotesToggle", true, true);
  1504             this.dispatchEvent(event);
  1505           } else {
  1506             this._relNotesContainer.style.height = this._relNotesContainer.scrollHeight +
  1507                                                    "px";
  1508             this.setAttribute("show-relnotes", true);
  1509             this._relNotesToggle.setAttribute(
  1510               "label",
  1511               this._relNotesToggle.getAttribute("hidelabel")
  1512             );
  1513             this._relNotesToggle.setAttribute(
  1514               "tooltiptext",
  1515               this._relNotesToggle.getAttribute("hidetooltip")
  1516             );
  1517             var uri = this.mManualUpdate ?
  1518                       this.mManualUpdate.releaseNotesURI :
  1519                       this.mAddon.releaseNotesURI;
  1520             this._fetchReleaseNotes(uri);
  1522         ]]></body>
  1523       </method>
  1525       <method name="restart">
  1526         <body><![CDATA[
  1527           gViewController.commands["cmd_restartApp"].doCommand();
  1528         ]]></body>
  1529       </method>
  1531       <method name="undo">
  1532         <body><![CDATA[
  1533           gViewController.commands["cmd_cancelOperation"].doCommand(this.mAddon);
  1534         ]]></body>
  1535       </method>
  1537       <method name="uninstall">
  1538         <body><![CDATA[
  1539           // If uninstalling does not require a restart then just disable it
  1540           // and show the undo UI.
  1541           if (!this.opRequiresRestart("uninstall")) {
  1542             this.setAttribute("wasDisabled", this.mAddon.userDisabled);
  1544             // We must set userDisabled to true first, this will call
  1545             // _updateState which will clear any pending attribute set.
  1546             this.mAddon.userDisabled = true;
  1548             // This won't update any other add-on manager views (bug 582002)
  1549             this.setAttribute("pending", "uninstall");
  1550           } else {
  1551             this.mAddon.uninstall();
  1553         ]]></body>
  1554       </method>
  1556       <method name="debug">
  1557         <body><![CDATA[
  1558           gViewController.doCommand("cmd_debugItem", this.mAddon);
  1559         ]]></body>
  1560       </method>
  1562       <method name="showPreferences">
  1563         <body><![CDATA[
  1564           gViewController.doCommand("cmd_showItemPreferences", this.mAddon);
  1565         ]]></body>
  1566       </method>
  1568       <method name="upgrade">
  1569         <body><![CDATA[
  1570           var install = this.mManualUpdate;
  1571           delete this.mManualUpdate;
  1572           install.install();
  1573         ]]></body>
  1574       </method>
  1576       <method name="retryInstall">
  1577         <body><![CDATA[
  1578           var install = this._installStatus.mInstall;
  1579           if (!install)
  1580             return;
  1581           if (install.state != AddonManager.STATE_DOWNLOAD_FAILED &&
  1582               install.state != AddonManager.STATE_INSTALL_FAILED)
  1583             return;
  1584           install.install();
  1585         ]]></body>
  1586       </method>
  1588       <method name="showInDetailView">
  1589         <body><![CDATA[
  1590           gViewController.loadView("addons://detail/" +
  1591                                    encodeURIComponent(this.mAddon.id));
  1592         ]]></body>
  1593       </method>
  1595       <method name="onIncludeUpdateChanged">
  1596         <body><![CDATA[
  1597           var event = document.createEvent("Events");
  1598           event.initEvent("IncludeUpdateChanged", true, true);
  1599           this.dispatchEvent(event);
  1600         ]]></body>
  1601       </method>
  1603       <method name="onEnabling">
  1604         <body><![CDATA[
  1605           this._updateState();
  1606         ]]></body>
  1607       </method>
  1609       <method name="onEnabled">
  1610         <body><![CDATA[
  1611           this._updateState();
  1612         ]]></body>
  1613       </method>
  1615       <method name="onDisabling">
  1616         <body><![CDATA[
  1617           this._updateState();
  1618         ]]></body>
  1619       </method>
  1621       <method name="onDisabled">
  1622         <body><![CDATA[
  1623           this._updateState();
  1624         ]]></body>
  1625       </method>
  1627       <method name="onUninstalling">
  1628         <parameter name="aRestartRequired"/>
  1629         <body><![CDATA[
  1630           this._updateState();
  1631         ]]></body>
  1632       </method>
  1634       <method name="onOperationCancelled">
  1635         <body><![CDATA[
  1636           this._updateState();
  1637         ]]></body>
  1638       </method>
  1640       <method name="onPropertyChanged">
  1641         <parameter name="aProperties"/>
  1642         <body><![CDATA[
  1643           if (aProperties.indexOf("appDisabled") != -1 ||
  1644               aProperties.indexOf("userDisabled") != -1)
  1645             this._updateState();
  1646         ]]></body>
  1647       </method>
  1649       <method name="onNoUpdateAvailable">
  1650         <body><![CDATA[
  1651           this._showStatus("none");
  1652         ]]></body>
  1653       </method>
  1655       <method name="onCheckingUpdate">
  1656         <body><![CDATA[
  1657           this._showStatus("checking-update");
  1658         ]]></body>
  1659       </method>
  1661       <method name="onCompatibilityUpdateAvailable">
  1662         <body><![CDATA[
  1663           this._updateState();
  1664         ]]></body>
  1665       </method>
  1667       <method name="onExternalInstall">
  1668         <parameter name="aAddon"/>
  1669         <parameter name="aExistingAddon"/>
  1670         <parameter name="aNeedsRestart"/>
  1671         <body><![CDATA[
  1672           if (aExistingAddon.id != this.mAddon.id)
  1673             return;
  1675           // If the install completed without needing a restart then switch to
  1676           // using the new Addon
  1677           if (!aNeedsRestart)
  1678             this._initWithAddon(aAddon);
  1679           else
  1680             this._updateState();
  1681         ]]></body>
  1682       </method>
  1684       <method name="onNewInstall">
  1685         <parameter name="aInstall"/>
  1686         <body><![CDATA[
  1687           if (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_ENABLE)
  1688             return;
  1689           if (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
  1690               AddonManager.autoUpdateDefault)
  1691             return;
  1693           this.mManualUpdate = aInstall;
  1694           this._showStatus("update-available");
  1695           this._updateUpgradeInfo();
  1696         ]]></body>
  1697       </method>
  1699       <method name="onDownloadStarted">
  1700         <parameter name="aInstall"/>
  1701         <body><![CDATA[
  1702           this._updateState();
  1703           this._showStatus("progress");
  1704           this._installStatus.initWithInstall(aInstall);
  1705         ]]></body>
  1706       </method>
  1708       <method name="onInstallStarted">
  1709         <parameter name="aInstall"/>
  1710         <body><![CDATA[
  1711           this._updateState();
  1712           this._showStatus("progress");
  1713           this._installStatus.initWithInstall(aInstall);
  1714         ]]></body>
  1715       </method>
  1717       <method name="onInstallEnded">
  1718         <parameter name="aInstall"/>
  1719         <parameter name="aAddon"/>
  1720         <body><![CDATA[
  1721           // If the install completed without needing a restart then switch to
  1722           // using the new Addon
  1723           if (!(aAddon.pendingOperations & AddonManager.PENDING_INSTALL))
  1724             this._initWithAddon(aAddon);
  1725           else
  1726             this._updateState();
  1727         ]]></body>
  1728       </method>
  1730       <method name="onDownloadFailed">
  1731         <body><![CDATA[
  1732             this._updateState();
  1733         ]]></body>
  1734       </method>
  1736       <method name="onInstallFailed">
  1737         <body><![CDATA[
  1738             this._updateState();
  1739         ]]></body>
  1740       </method>
  1742       <method name="onInstallCancelled">
  1743         <body><![CDATA[
  1744             this._updateState();
  1745         ]]></body>
  1746       </method>
  1747     </implementation>
  1749     <handlers>
  1750       <handler event="click" button="0"><![CDATA[
  1751         switch (event.detail) {
  1752         case 1:
  1753           // Prevent double-click where the UI changes on the first click
  1754           this._lastClickTarget = event.originalTarget;
  1755           break;
  1756         case 2:
  1757           if (event.originalTarget.localName != 'button' &&
  1758               !event.originalTarget.classList.contains('text-link') &&
  1759               event.originalTarget == this._lastClickTarget) {
  1760             this.showInDetailView();
  1762           break;
  1764       ]]></handler>
  1765     </handlers>
  1766   </binding>
  1769   <!-- Addon - uninstalled - An uninstalled addon that can be re-installed. -->
  1770   <binding id="addon-uninstalled"
  1771            extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
  1772     <content>
  1773       <xul:hbox class="pending">
  1774         <xul:image class="pending-icon"/>
  1775         <xul:label anonid="notice" flex="1"/>
  1776         <xul:button anonid="restart-btn" class="button-link"
  1777                     label="&addon.restartNow.label;"
  1778                     command="cmd_restartApp"/>
  1779         <xul:button anonid="undo-btn" class="button-link"
  1780                     label="&addon.undoRemove.label;"
  1781                     tooltiptext="&addon.undoRemove.tooltip;"
  1782                     oncommand="document.getBindingParent(this).cancelUninstall();"/>
  1783         <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
  1784       </xul:hbox>
  1785     </content>
  1787     <implementation>
  1788       <constructor><![CDATA[
  1789         this._notice.textContent = gStrings.ext.formatStringFromName("uninstallNotice",
  1790                                                                      [this.mAddon.name],
  1791                                                                      1);
  1793         if (!this.isPending("uninstall"))
  1794           this._restartBtn.setAttribute("hidden", true);
  1796         gEventManager.registerAddonListener(this, this.mAddon.id);
  1797       ]]></constructor>
  1799       <destructor><![CDATA[
  1800         gEventManager.unregisterAddonListener(this, this.mAddon.id);
  1801       ]]></destructor>
  1803       <field name="_notice" readonly="true">
  1804         document.getAnonymousElementByAttribute(this, "anonid", "notice");
  1805       </field>
  1806       <field name="_restartBtn" readonly="true">
  1807         document.getAnonymousElementByAttribute(this, "anonid", "restart-btn");
  1808       </field>
  1810       <method name="cancelUninstall">
  1811         <body><![CDATA[
  1812           // This assumes that disabling does not require a restart when
  1813           // uninstalling doesn't. Things will still work if not, the add-on
  1814           // will just still be active until finally getting uninstalled.
  1816           if (this.isPending("uninstall"))
  1817             this.mAddon.cancelUninstall();
  1818           else if (this.getAttribute("wasDisabled") != "true")
  1819             this.mAddon.userDisabled = false;
  1821           this.removeAttribute("pending");
  1822         ]]></body>
  1823       </method>
  1825       <method name="onOperationCancelled">
  1826         <body><![CDATA[
  1827           if (!this.isPending("uninstall"))
  1828             this.removeAttribute("pending");
  1829         ]]></body>
  1830       </method>
  1832       <method name="onExternalInstall">
  1833         <parameter name="aAddon"/>
  1834         <parameter name="aExistingAddon"/>
  1835         <parameter name="aNeedsRestart"/>
  1836         <body><![CDATA[
  1837           if (aExistingAddon.id != this.mAddon.id)
  1838             return;
  1840           // Make sure any newly installed add-on has the correct disabled state
  1841           if (this.hasAttribute("wasDisabled"))
  1842             aAddon.userDisabled = this.getAttribute("wasDisabled") == "true";
  1844           // If the install completed without needing a restart then switch to
  1845           // using the new Addon
  1846           if (!aNeedsRestart)
  1847             this.mAddon = aAddon;
  1849           this.removeAttribute("pending");
  1850         ]]></body>
  1851       </method>
  1853       <method name="onInstallStarted">
  1854         <parameter name="aInstall"/>
  1855         <body><![CDATA[
  1856           // Make sure any newly installed add-on has the correct disabled state
  1857           if (this.hasAttribute("wasDisabled"))
  1858             aInstall.addon.userDisabled = this.getAttribute("wasDisabled") == "true";
  1859         ]]></body>
  1860       </method>
  1862       <method name="onInstallEnded">
  1863         <parameter name="aInstall"/>
  1864         <parameter name="aAddon"/>
  1865         <body><![CDATA[
  1866           // If the install completed without needing a restart then switch to
  1867           // using the new Addon
  1868           if (!(aAddon.pendingOperations & AddonManager.PENDING_INSTALL))
  1869             this.mAddon = aAddon;
  1871           this.removeAttribute("pending");
  1872         ]]></body>
  1873       </method>
  1874     </implementation>
  1875   </binding>
  1878   <!-- Addon - installing - an addon item that is currently being installed -->
  1879   <binding id="addon-installing"
  1880            extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
  1881     <content>
  1882       <xul:hbox anonid="warning-container" class="warning">
  1883         <xul:image class="warning-icon"/>
  1884         <xul:label anonid="warning" flex="1"/>
  1885         <xul:button anonid="warning-link" class="button-link"
  1886                    oncommand="document.getBindingParent(this).retryInstall();"/>
  1887         <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
  1888       </xul:hbox>
  1889       <xul:hbox class="content-container">
  1890         <xul:vbox class="icon-outer-container">
  1891           <xul:vbox class="icon-container">
  1892             <xul:image anonid="icon" class="icon"/>
  1893           </xul:vbox>
  1894         </xul:vbox>
  1895         <xul:vbox class="fade name-outer-container" flex="1">
  1896           <xul:hbox class="name-container">
  1897             <xul:label anonid="name" class="name" crop="end"/>
  1898             <xul:label anonid="version" class="version" hidden="true"/>
  1899           </xul:hbox>
  1900         </xul:vbox>
  1901         <xul:vbox class="install-status-container">
  1902           <xul:hbox anonid="install-status" class="install-status"/>
  1903         </xul:vbox>
  1904       </xul:hbox>
  1905     </content>
  1907     <implementation>
  1908       <constructor><![CDATA[
  1909         this._installStatus.mControl = this;
  1910         this._installStatus.mInstall = this.mInstall;
  1911         this.refreshInfo();
  1912       ]]></constructor>
  1914       <field name="_icon">
  1915         document.getAnonymousElementByAttribute(this, "anonid", "icon");
  1916       </field>
  1917       <field name="_name">
  1918         document.getAnonymousElementByAttribute(this, "anonid", "name");
  1919       </field>
  1920       <field name="_version">
  1921         document.getAnonymousElementByAttribute(this, "anonid", "version");
  1922       </field>
  1923       <field name="_warning">
  1924         document.getAnonymousElementByAttribute(this, "anonid", "warning");
  1925       </field>
  1926       <field name="_warningLink">
  1927         document.getAnonymousElementByAttribute(this, "anonid", "warning-link");
  1928       </field>
  1929       <field name="_installStatus">
  1930         document.getAnonymousElementByAttribute(this, "anonid",
  1931                                                 "install-status");
  1932       </field>
  1934       <method name="onInstallCompleted">
  1935         <body><![CDATA[
  1936           this.mAddon = this.mInstall.addon;
  1937           this.setAttribute("name", this.mAddon.name);
  1938           this.setAttribute("value", this.mAddon.id);
  1939           this.setAttribute("status", "installed");
  1940         ]]></body>
  1941       </method>
  1943       <method name="refreshInfo">
  1944         <body><![CDATA[
  1945           this.mAddon = this.mAddon || this.mInstall.addon;
  1946           if (this.mAddon) {
  1947             this._icon.src = this.mAddon.iconURL ||
  1948                              (this.mInstall ? this.mInstall.iconURL : "");
  1949             this._name.value = this.mAddon.name;
  1951             if (this.mAddon.version) {
  1952               this._version.value = this.mAddon.version;
  1953               this._version.hidden = false;
  1954             } else {
  1955               this._version.hidden = true;
  1958           } else {
  1959             this._icon.src = this.mInstall.iconURL;
  1960             // AddonInstall.name isn't always available - fallback to filename
  1961             if (this.mInstall.name) {
  1962               this._name.value = this.mInstall.name;
  1963             } else if (this.mInstall.sourceURI) {
  1964               var url = Components.classes["@mozilla.org/network/standard-url;1"]
  1965                                   .createInstance(Components.interfaces.nsIStandardURL);
  1966               url.init(url.URLTYPE_STANDARD, 80, this.mInstall.sourceURI.spec,
  1967                        null, null);
  1968               url.QueryInterface(Components.interfaces.nsIURL);
  1969               this._name.value = url.fileName;
  1972             if (this.mInstall.version) {
  1973               this._version.value = this.mInstall.version;
  1974               this._version.hidden = false;
  1975             } else {
  1976               this._version.hidden = true;
  1980           if (this.mInstall.state == AddonManager.STATE_DOWNLOAD_FAILED) {
  1981             this.setAttribute("notification", "warning");
  1982             this._warning.textContent = gStrings.ext.formatStringFromName(
  1983               "notification.downloadError",
  1984               [this._name.value], 1
  1985             );
  1986             this._warningLink.label = gStrings.ext.GetStringFromName("notification.downloadError.retry");
  1987             this._warningLink.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
  1988           } else if (this.mInstall.state == AddonManager.STATE_INSTALL_FAILED) {
  1989             this.setAttribute("notification", "warning");
  1990             this._warning.textContent = gStrings.ext.formatStringFromName(
  1991               "notification.installError",
  1992               [this._name.value], 1
  1993             );
  1994             this._warningLink.label = gStrings.ext.GetStringFromName("notification.installError.retry");
  1995             this._warningLink.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
  1996           } else {
  1997             this.removeAttribute("notification");
  1999         ]]></body>
  2000       </method>
  2002       <method name="retryInstall">
  2003         <body><![CDATA[
  2004           this.mInstall.install();
  2005         ]]></body>
  2006       </method>
  2007     </implementation>
  2008   </binding>
  2010   <binding id="detail-row">
  2011     <content>
  2012       <xul:label class="detail-row-label" xbl:inherits="value=label"/>
  2013       <xul:label class="detail-row-value" xbl:inherits="value"/>
  2014     </content>
  2016     <implementation>
  2017       <property name="value">
  2018         <getter><![CDATA[
  2019           return this.getAttribute("value");
  2020         ]]></getter>
  2021         <setter><![CDATA[
  2022           if (!val)
  2023             this.removeAttribute("value");
  2024           else
  2025             this.setAttribute("value", val);
  2026         ]]></setter>
  2027       </property>
  2028     </implementation>
  2029   </binding>
  2031 </bindings>

mercurial