toolkit/mozapps/extensions/content/extensions.xml

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/mozapps/extensions/content/extensions.xml	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,2031 @@
     1.4 +<?xml version="1.0"?>
     1.5 +<!-- This Source Code Form is subject to the terms of the Mozilla Public
     1.6 +   - License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 +   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
     1.8 +
     1.9 +
    1.10 +<!DOCTYPE page [
    1.11 +<!ENTITY % extensionsDTD SYSTEM "chrome://mozapps/locale/extensions/extensions.dtd">
    1.12 +%extensionsDTD;
    1.13 +]>
    1.14 +
    1.15 +<bindings id="addonBindings"
    1.16 +          xmlns="http://www.mozilla.org/xbl"
    1.17 +          xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    1.18 +          xmlns:xbl="http://www.mozilla.org/xbl">
    1.19 +
    1.20 +
    1.21 +  <!-- Rating - displays current/average rating, allows setting user rating -->
    1.22 +  <binding id="rating">
    1.23 +    <content>
    1.24 +      <xul:image class="star"
    1.25 +                 onmouseover="document.getBindingParent(this)._hover(1);"
    1.26 +                 onclick="document.getBindingParent(this).userRating = 1;"/>
    1.27 +      <xul:image class="star"
    1.28 +                 onmouseover="document.getBindingParent(this)._hover(2);"
    1.29 +                 onclick="document.getBindingParent(this).userRating = 2;"/>
    1.30 +      <xul:image class="star"
    1.31 +                 onmouseover="document.getBindingParent(this)._hover(3);"
    1.32 +                 onclick="document.getBindingParent(this).userRating = 3;"/>
    1.33 +      <xul:image class="star"
    1.34 +                 onmouseover="document.getBindingParent(this)._hover(4);"
    1.35 +                 onclick="document.getBindingParent(this).userRating = 4;"/>
    1.36 +      <xul:image class="star"
    1.37 +                 onmouseover="document.getBindingParent(this)._hover(5);"
    1.38 +                 onclick="document.getBindingParent(this).userRating = 5;"/>
    1.39 +    </content>
    1.40 +
    1.41 +    <implementation>
    1.42 +      <constructor><![CDATA[
    1.43 +        this._updateStars();
    1.44 +      ]]></constructor>
    1.45 +
    1.46 +      <property name="stars" readonly="true">
    1.47 +        <getter><![CDATA[
    1.48 +          return document.getAnonymousNodes(this);
    1.49 +        ]]></getter>
    1.50 +      </property>
    1.51 +
    1.52 +      <property name="averageRating">
    1.53 +        <getter><![CDATA[
    1.54 +          if (this.hasAttribute("averagerating"))
    1.55 +            return this.getAttribute("averagerating");
    1.56 +          return -1;
    1.57 +        ]]></getter>
    1.58 +        <setter><![CDATA[
    1.59 +          this.setAttribute("averagerating", val);
    1.60 +          if (this.showRating == "average")
    1.61 +            this._updateStars();
    1.62 +        ]]></setter>
    1.63 +      </property>
    1.64 +
    1.65 +      <property name="userRating">
    1.66 +        <getter><![CDATA[
    1.67 +          if (this.hasAttribute("userrating"))
    1.68 +            return this.getAttribute("userrating");
    1.69 +          return -1;
    1.70 +        ]]></getter>
    1.71 +        <setter><![CDATA[
    1.72 +          if (this.showRating != "user")
    1.73 +            return;
    1.74 +          this.setAttribute("userrating", val);
    1.75 +          if (this.showRating == "user")
    1.76 +            this._updateStars();
    1.77 +        ]]></setter>
    1.78 +      </property>
    1.79 +
    1.80 +      <property name="showRating">
    1.81 +        <getter><![CDATA[
    1.82 +          if (this.hasAttribute("showrating"))
    1.83 +            return this.getAttribute("showrating");
    1.84 +          return "average";
    1.85 +        ]]></getter>
    1.86 +        <setter><![CDATA[
    1.87 +          if (val != "average" || val != "user")
    1.88 +            throw Components.Exception("Invalid value", Components.results.NS_ERROR_ILLEGAL_VALUE);
    1.89 +          this.setAttribute("showrating", val);
    1.90 +          this._updateStars();
    1.91 +        ]]></setter>
    1.92 +      </property>
    1.93 +
    1.94 +      <method name="_updateStars">
    1.95 +        <body><![CDATA[
    1.96 +          var stars = this.stars;
    1.97 +          var rating = this[this.showRating + "Rating"];
    1.98 +          // average ratings can be non-whole numbers, round them so they
    1.99 +          // match to their closest star
   1.100 +          rating = Math.round(rating);
   1.101 +          for (let i = 0; i < stars.length; i++)
   1.102 +            stars[i].setAttribute("on", rating > i);
   1.103 +        ]]></body>
   1.104 +      </method>
   1.105 +
   1.106 +      <method name="_hover">
   1.107 +        <parameter name="aScore"/>
   1.108 +        <body><![CDATA[
   1.109 +          if (this.showRating != "user")
   1.110 +            return;
   1.111 +          var stars = this.stars;
   1.112 +          for (let i = 0; i < stars.length; i++)
   1.113 +            stars[i].setAttribute("on", i <= (aScore -1));
   1.114 +        ]]></body>
   1.115 +      </method>
   1.116 +
   1.117 +    </implementation>
   1.118 +
   1.119 +    <handlers>
   1.120 +      <handler event="mouseout">
   1.121 +        this._updateStars();
   1.122 +      </handler>
   1.123 +    </handlers>
   1.124 +  </binding>
   1.125 +
   1.126 +  <!-- Download progress - shows graphical progress of download and any
   1.127 +       related status message. -->
   1.128 +  <binding id="download-progress">
   1.129 +    <content>
   1.130 +      <xul:stack flex="1">
   1.131 +        <xul:hbox flex="1">
   1.132 +          <xul:hbox class="start-cap"/>
   1.133 +          <xul:progressmeter anonid="progress" class="progress" flex="1"
   1.134 +                             min="0" max="100"/>
   1.135 +          <xul:hbox class="end-cap"/>
   1.136 +        </xul:hbox>
   1.137 +        <xul:hbox class="status-container">
   1.138 +          <xul:spacer flex="1"/>
   1.139 +          <xul:label anonid="status" class="status"/>
   1.140 +          <xul:spacer flex="1"/>
   1.141 +          <xul:button anonid="cancel-btn" class="cancel"
   1.142 +                      tooltiptext="&progress.cancel.tooltip;"
   1.143 +                      oncommand="document.getBindingParent(this).cancel();"/>
   1.144 +        </xul:hbox>
   1.145 +      </xul:stack>
   1.146 +    </content>
   1.147 +
   1.148 +    <implementation>
   1.149 +      <constructor><![CDATA[
   1.150 +        var progress = 0;
   1.151 +        if (this.hasAttribute("progress"))
   1.152 +          progress = parseInt(this.getAttribute("progress"));
   1.153 +        this.progress = progress;
   1.154 +      ]]></constructor>
   1.155 +
   1.156 +      <field name="_progress">
   1.157 +        document.getAnonymousElementByAttribute(this, "anonid", "progress");
   1.158 +      </field>
   1.159 +      <field name="_cancel">
   1.160 +        document.getAnonymousElementByAttribute(this, "anonid", "cancel-btn");
   1.161 +      </field>
   1.162 +      <field name="_status">
   1.163 +        document.getAnonymousElementByAttribute(this, "anonid", "status");
   1.164 +      </field>
   1.165 +
   1.166 +      <property name="progress">
   1.167 +        <getter><![CDATA[
   1.168 +          return this._progress.value;
   1.169 +        ]]></getter>
   1.170 +        <setter><![CDATA[
   1.171 +          this._progress.value = val;
   1.172 +          if (val == this._progress.max)
   1.173 +            this.setAttribute("complete", true);
   1.174 +          else
   1.175 +            this.removeAttribute("complete");
   1.176 +        ]]></setter>
   1.177 +      </property>
   1.178 +
   1.179 +      <property name="maxProgress">
   1.180 +        <getter><![CDATA[
   1.181 +          return this._progress.max;
   1.182 +        ]]></getter>
   1.183 +        <setter><![CDATA[
   1.184 +          if (val == -1) {
   1.185 +            this._progress.mode = "undetermined";
   1.186 +          } else {
   1.187 +            this._progress.mode = "determined";
   1.188 +            this._progress.max = val;
   1.189 +          }
   1.190 +          this.setAttribute("mode", this._progress.mode);
   1.191 +        ]]></setter>
   1.192 +      </property>
   1.193 +
   1.194 +      <property name="status">
   1.195 +        <getter><![CDATA[
   1.196 +          return this._status.value;
   1.197 +        ]]></getter>
   1.198 +        <setter><![CDATA[
   1.199 +          this._status.value = val;
   1.200 +        ]]></setter>
   1.201 +      </property>
   1.202 +
   1.203 +      <method name="cancel">
   1.204 +        <body><![CDATA[
   1.205 +          this.mInstall.cancel();
   1.206 +        ]]></body>
   1.207 +      </method>
   1.208 +    </implementation>
   1.209 +  </binding>
   1.210 +
   1.211 +
   1.212 +  <!-- Sorters - displays and controls the sort state of a list. -->
   1.213 +  <binding id="sorters">
   1.214 +    <content orient="horizontal">
   1.215 +      <xul:button anonid="name-btn" class="sorter"
   1.216 +                  label="&sort.name.label;" tooltiptext="&sort.name.tooltip;"
   1.217 +                  oncommand="this.parentNode._handleChange('name');"/>
   1.218 +      <xul:button anonid="date-btn" class="sorter"
   1.219 +                  label="&sort.dateUpdated.label;"
   1.220 +                  tooltiptext="&sort.dateUpdated.tooltip;"
   1.221 +                  oncommand="this.parentNode._handleChange('updateDate');"/>
   1.222 +      <xul:button anonid="price-btn" class="sorter" hidden="true"
   1.223 +                  label="&sort.price.label;"
   1.224 +                  tooltiptext="&sort.price.tooltip;"
   1.225 +                  oncommand="this.parentNode._handleChange('purchaseAmount');"/>
   1.226 +      <xul:button anonid="relevance-btn" class="sorter" hidden="true"
   1.227 +                  label="&sort.relevance.label;"
   1.228 +                  tooltiptext="&sort.relevance.tooltip;"
   1.229 +                  oncommand="this.parentNode._handleChange('relevancescore');"/>
   1.230 +    </content>
   1.231 +
   1.232 +    <implementation>
   1.233 +      <constructor><![CDATA[
   1.234 +        if (!this.hasAttribute("sortby"))
   1.235 +          this.setAttribute("sortby", "name");
   1.236 +
   1.237 +        if (this.getAttribute("showrelevance") == "true")
   1.238 +          this._btnRelevance.hidden = false;
   1.239 +
   1.240 +        if (this.getAttribute("showprice") == "true")
   1.241 +          this._btnPrice.hidden = false;
   1.242 +
   1.243 +        this._refreshState();
   1.244 +      ]]></constructor>
   1.245 +
   1.246 +      <field name="handler">null</field>
   1.247 +      <field name="_btnName">
   1.248 +        document.getAnonymousElementByAttribute(this, "anonid", "name-btn");
   1.249 +      </field>
   1.250 +      <field name="_btnDate">
   1.251 +        document.getAnonymousElementByAttribute(this, "anonid", "date-btn");
   1.252 +      </field>
   1.253 +      <field name="_btnPrice">
   1.254 +        document.getAnonymousElementByAttribute(this, "anonid", "price-btn");
   1.255 +      </field>
   1.256 +      <field name="_btnRelevance">
   1.257 +        document.getAnonymousElementByAttribute(this, "anonid", "relevance-btn");
   1.258 +      </field>
   1.259 +
   1.260 +      <property name="sortBy">
   1.261 +        <getter><![CDATA[
   1.262 +          return this.getAttribute("sortby");
   1.263 +        ]]></getter>
   1.264 +        <setter><![CDATA[
   1.265 +          if (val != this.sortBy) {
   1.266 +            this.setAttribute("sortBy", val);
   1.267 +            this._refreshState();
   1.268 +          }
   1.269 +        ]]></setter>
   1.270 +      </property>
   1.271 +
   1.272 +      <property name="ascending">
   1.273 +        <getter><![CDATA[
   1.274 +          return (this.getAttribute("ascending") == "true");
   1.275 +        ]]></getter>
   1.276 +        <setter><![CDATA[
   1.277 +          val = !!val;
   1.278 +          if (val != this.ascending) {
   1.279 +            this.setAttribute("ascending", val);
   1.280 +            this._refreshState();
   1.281 +          }
   1.282 +        ]]></setter>
   1.283 +      </property>
   1.284 +
   1.285 +      <property name="showrelevance">
   1.286 +        <getter><![CDATA[
   1.287 +          return (this.getAttribute("showrelevance") == "true");
   1.288 +        ]]></getter>
   1.289 +        <setter><![CDATA[
   1.290 +          val = !!val;
   1.291 +          this.setAttribute("showrelevance", val);
   1.292 +          this._btnRelevance.hidden = !val;
   1.293 +        ]]></setter>
   1.294 +      </property>
   1.295 +
   1.296 +      <property name="showprice">
   1.297 +        <getter><![CDATA[
   1.298 +          return (this.getAttribute("showprice") == "true");
   1.299 +        ]]></getter>
   1.300 +        <setter><![CDATA[
   1.301 +          val = !!val;
   1.302 +          this.setAttribute("showprice", val);
   1.303 +          this._btnPrice.hidden = !val;
   1.304 +        ]]></setter>
   1.305 +      </property>
   1.306 +
   1.307 +      <method name="setSort">
   1.308 +        <parameter name="aSort"/>
   1.309 +        <parameter name="aAscending"/>
   1.310 +        <body><![CDATA[
   1.311 +          var sortChanged = false;
   1.312 +          if (aSort != this.sortBy) {
   1.313 +            this.setAttribute("sortby", aSort);
   1.314 +            sortChanged = true;
   1.315 +          }
   1.316 +
   1.317 +          aAscending = !!aAscending;
   1.318 +          if (this.ascending != aAscending) {
   1.319 +            this.setAttribute("ascending", aAscending);
   1.320 +            sortChanged = true;
   1.321 +          }
   1.322 +
   1.323 +          if (sortChanged)
   1.324 +            this._refreshState();
   1.325 +        ]]></body>
   1.326 +      </method>
   1.327 +
   1.328 +      <method name="_handleChange">
   1.329 +        <parameter name="aSort"/>
   1.330 +        <body><![CDATA[
   1.331 +          const ASCENDING_SORT_FIELDS = ["name", "purchaseAmount"];
   1.332 +
   1.333 +          // Toggle ascending if sort by is not changing, otherwise
   1.334 +          // name sorting defaults to ascending, others to descending
   1.335 +          if (aSort == this.sortBy)
   1.336 +            this.ascending = !this.ascending;
   1.337 +          else
   1.338 +            this.setSort(aSort, ASCENDING_SORT_FIELDS.indexOf(aSort) >= 0);
   1.339 +        ]]></body>
   1.340 +      </method>
   1.341 +
   1.342 +      <method name="_refreshState">
   1.343 +        <body><![CDATA[
   1.344 +          var sortBy = this.sortBy;
   1.345 +          var checkState = this.ascending ? 2 : 1;
   1.346 +
   1.347 +          if (sortBy == "name") {
   1.348 +            this._btnName.checkState = checkState;
   1.349 +            this._btnName.checked = true;
   1.350 +          } else {
   1.351 +            this._btnName.checkState = 0;
   1.352 +            this._btnName.checked = false;
   1.353 +          }
   1.354 +
   1.355 +          if (sortBy == "updateDate") {
   1.356 +            this._btnDate.checkState = checkState;
   1.357 +            this._btnDate.checked = true;
   1.358 +          } else {
   1.359 +            this._btnDate.checkState = 0;
   1.360 +            this._btnDate.checked = false;
   1.361 +          }
   1.362 +
   1.363 +          if (sortBy == "purchaseAmount") {
   1.364 +            this._btnPrice.checkState = checkState;
   1.365 +            this._btnPrice.checked = true;
   1.366 +          } else {
   1.367 +            this._btnPrice.checkState = 0;
   1.368 +            this._btnPrice.checked = false;
   1.369 +          }
   1.370 +
   1.371 +          if (sortBy == "relevancescore") {
   1.372 +            this._btnRelevance.checkState = checkState;
   1.373 +            this._btnRelevance.checked = true;
   1.374 +          } else {
   1.375 +            this._btnRelevance.checkState = 0;
   1.376 +            this._btnRelevance.checked = false;
   1.377 +          }
   1.378 +
   1.379 +          if (this.handler && "onSortChanged" in this.handler)
   1.380 +            this.handler.onSortChanged(sortBy, this.ascending);
   1.381 +        ]]></body>
   1.382 +      </method>
   1.383 +    </implementation>
   1.384 +  </binding>
   1.385 +
   1.386 +
   1.387 +  <!-- Categories list - displays the list of categories on the left pane. -->
   1.388 +  <binding id="categories-list"
   1.389 +           extends="chrome://global/content/bindings/richlistbox.xml#richlistbox">
   1.390 +    <implementation>
   1.391 +      <!-- This needs to be overridden to allow the fancy animation while not
   1.392 +           allowing that item to be selected when hiding.  -->
   1.393 +      <method name="_canUserSelect">
   1.394 +        <parameter name="aItem"/>
   1.395 +        <body>
   1.396 +        <![CDATA[
   1.397 +          if (aItem.hasAttribute("disabled") &&
   1.398 +              aItem.getAttribute("disabled") == "true")
   1.399 +            return false;
   1.400 +          var style = document.defaultView.getComputedStyle(aItem, "");
   1.401 +          return style.display != "none" && style.visibility == "visible";
   1.402 +        ]]>
   1.403 +        </body>
   1.404 +      </method>
   1.405 +    </implementation>
   1.406 +  </binding>
   1.407 +
   1.408 +
   1.409 +  <!-- Category item - an item in the category list. -->
   1.410 +  <binding id="category"
   1.411 +           extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
   1.412 +    <content align="center">
   1.413 +      <xul:image anonid="icon" class="category-icon"/>
   1.414 +      <xul:label anonid="name" class="category-name" flex="1" xbl:inherits="value=name"/>
   1.415 +      <xul:label anonid="badge" class="category-badge" xbl:inherits="value=count"/>
   1.416 +    </content>
   1.417 +
   1.418 +    <implementation>
   1.419 +      <constructor><![CDATA[
   1.420 +        if (!this.hasAttribute("count"))
   1.421 +          this.setAttribute("count", 0);
   1.422 +      ]]></constructor>
   1.423 +
   1.424 +      <property name="badgeCount">
   1.425 +        <getter><![CDATA[
   1.426 +          return this.getAttribute("count");
   1.427 +        ]]></getter>
   1.428 +        <setter><![CDATA[
   1.429 +          if (this.getAttribute("count") == val)
   1.430 +            return;
   1.431 +
   1.432 +          this.setAttribute("count", val);
   1.433 +          var event = document.createEvent("Events");
   1.434 +          event.initEvent("CategoryBadgeUpdated", true, true);
   1.435 +          this.dispatchEvent(event);
   1.436 +        ]]></setter>
   1.437 +      </property>
   1.438 +    </implementation>
   1.439 +  </binding>
   1.440 +
   1.441 +
   1.442 +  <!-- Creator link - Name of a user/developer, providing a link if relevant. -->
   1.443 +  <binding id="creator-link">
   1.444 +    <content>
   1.445 +      <xul:label anonid="label" value="&addon.createdBy.label;"/>
   1.446 +      <xul:label anonid="creator-link" class="creator-link text-link"/>
   1.447 +      <xul:label anonid="creator-name" class="creator-name"/>
   1.448 +    </content>
   1.449 +
   1.450 +    <implementation>
   1.451 +      <constructor><![CDATA[
   1.452 +        if (this.hasAttribute("nameonly") &&
   1.453 +            this.getAttribute("nameonly") == "true") {
   1.454 +          this._label.hidden = true;
   1.455 +        }
   1.456 +      ]]></constructor>
   1.457 +
   1.458 +      <field name="_label">
   1.459 +        document.getAnonymousElementByAttribute(this, "anonid", "label");
   1.460 +      </field>
   1.461 +      <field name="_creatorLink">
   1.462 +        document.getAnonymousElementByAttribute(this, "anonid", "creator-link");
   1.463 +      </field>
   1.464 +      <field name="_creatorName">
   1.465 +        document.getAnonymousElementByAttribute(this, "anonid", "creator-name");
   1.466 +      </field>
   1.467 +
   1.468 +      <method name="setCreator">
   1.469 +        <parameter name="aCreator"/>
   1.470 +        <parameter name="aHomepageURL"/>
   1.471 +        <body><![CDATA[
   1.472 +          if (!aCreator) {
   1.473 +            this.collapsed = true;
   1.474 +            return;
   1.475 +          }
   1.476 +          this.collapsed = false;
   1.477 +          var url = aCreator.url || aHomepageURL;
   1.478 +          var showLink = !!url;
   1.479 +          if (showLink) {
   1.480 +            this._creatorLink.value = aCreator.name;
   1.481 +            this._creatorLink.href = url;
   1.482 +          } else {
   1.483 +            this._creatorName.value = aCreator.name;
   1.484 +          }
   1.485 +          this._creatorLink.hidden = !showLink;
   1.486 +          this._creatorName.hidden = showLink;
   1.487 +        ]]></body>
   1.488 +      </method>
   1.489 +    </implementation>
   1.490 +  </binding>
   1.491 +
   1.492 +
   1.493 +  <!-- Install status - Displays the status of an install/upgrade. -->
   1.494 +  <binding id="install-status">
   1.495 +    <content>
   1.496 +      <xul:label anonid="message"/>
   1.497 +      <xul:progressmeter anonid="progress" class="download-progress"/>
   1.498 +      <xul:button anonid="purchase-remote-btn" hidden="true"
   1.499 +                  class="addon-control"
   1.500 +                  oncommand="document.getBindingParent(this).purchaseRemote();"/>
   1.501 +      <xul:button anonid="install-remote-btn" hidden="true"
   1.502 +                  class="addon-control install" label="&addon.install.label;"
   1.503 +                  tooltiptext="&addon.install.tooltip;"
   1.504 +                  oncommand="document.getBindingParent(this).installRemote();"/>
   1.505 +    </content>
   1.506 +
   1.507 +    <implementation>
   1.508 +      <constructor><![CDATA[
   1.509 +        if (this.mInstall)
   1.510 +          this.initWithInstall(this.mInstall);
   1.511 +        else if (this.mControl.mAddon.install)
   1.512 +          this.initWithInstall(this.mControl.mAddon.install);
   1.513 +        else
   1.514 +          this.refreshState();
   1.515 +      ]]></constructor>
   1.516 +
   1.517 +      <destructor><![CDATA[
   1.518 +        if (this.mInstall)
   1.519 +          this.mInstall.removeListener(this);
   1.520 +      ]]></destructor>
   1.521 +
   1.522 +      <field name="_message">
   1.523 +        document.getAnonymousElementByAttribute(this, "anonid", "message");
   1.524 +      </field>
   1.525 +      <field name="_progress">
   1.526 +        document.getAnonymousElementByAttribute(this, "anonid", "progress");
   1.527 +      </field>
   1.528 +      <field name="_purchaseRemote">
   1.529 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.530 +                                                "purchase-remote-btn");
   1.531 +      </field>
   1.532 +      <field name="_installRemote">
   1.533 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.534 +                                                "install-remote-btn");
   1.535 +      </field>
   1.536 +      <field name="_restartNeeded">
   1.537 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.538 +                                                "restart-needed");
   1.539 +      </field>
   1.540 +      <field name="_undo">
   1.541 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.542 +                                                "undo-btn");
   1.543 +      </field>
   1.544 +
   1.545 +      <method name="initWithInstall">
   1.546 +        <parameter name="aInstall"/>
   1.547 +        <body><![CDATA[
   1.548 +          if (this.mInstall) {
   1.549 +            this.mInstall.removeListener(this);
   1.550 +            this.mInstall = null;
   1.551 +          }
   1.552 +          this.mInstall = aInstall;
   1.553 +          this._progress.mInstall = aInstall;
   1.554 +          this.refreshState();
   1.555 +          this.mInstall.addListener(this);
   1.556 +        ]]></body>
   1.557 +      </method>
   1.558 +
   1.559 +      <method name="refreshState">
   1.560 +        <body><![CDATA[
   1.561 +          var showInstallRemote = false;
   1.562 +          var showPurchase = false;
   1.563 +
   1.564 +          if (this.mInstall) {
   1.565 +
   1.566 +            switch (this.mInstall.state) {
   1.567 +              case AddonManager.STATE_AVAILABLE:
   1.568 +                if (this.mControl.getAttribute("remote") != "true")
   1.569 +                  break;
   1.570 +
   1.571 +                this._progress.hidden = true;
   1.572 +                showInstallRemote = true;
   1.573 +                break;
   1.574 +              case AddonManager.STATE_DOWNLOADING:
   1.575 +                this.showMessage("installDownloading");
   1.576 +                break;
   1.577 +              case AddonManager.STATE_CHECKING:
   1.578 +                this.showMessage("installVerifying");
   1.579 +                break;
   1.580 +              case AddonManager.STATE_DOWNLOADED:
   1.581 +                this.showMessage("installDownloaded");
   1.582 +                break;
   1.583 +              case AddonManager.STATE_DOWNLOAD_FAILED:
   1.584 +                // XXXunf expose what error occured (bug 553487)
   1.585 +                this.showMessage("installDownloadFailed", true);
   1.586 +                break;
   1.587 +              case AddonManager.STATE_INSTALLING:
   1.588 +                this.showMessage("installInstalling");
   1.589 +                break;
   1.590 +              case AddonManager.STATE_INSTALL_FAILED:
   1.591 +                // XXXunf expose what error occured (bug 553487)
   1.592 +                this.showMessage("installFailed", true);
   1.593 +                break;
   1.594 +              case AddonManager.STATE_CANCELLED:
   1.595 +                this.showMessage("installCancelled", true);
   1.596 +                break;
   1.597 +            }
   1.598 +
   1.599 +          } else if (this.mControl.mAddon.purchaseURL) {
   1.600 +            this._progress.hidden = true;
   1.601 +            showPurchase = true;
   1.602 +            this._purchaseRemote.label =
   1.603 +              gStrings.ext.formatStringFromName("addon.purchase.label",
   1.604 +                [this.mControl.mAddon.purchaseDisplayAmount], 1);
   1.605 +            this._purchaseRemote.tooltiptext =
   1.606 +              gStrings.ext.GetStringFromName("addon.purchase.tooltip");
   1.607 +          }
   1.608 +
   1.609 +          this._purchaseRemote.hidden = !showPurchase;
   1.610 +          this._installRemote.hidden = !showInstallRemote;
   1.611 +
   1.612 +          if ("refreshInfo" in this.mControl)
   1.613 +            this.mControl.refreshInfo();
   1.614 +        ]]></body>
   1.615 +      </method>
   1.616 +
   1.617 +      <method name="showMessage">
   1.618 +        <parameter name="aMsgId"/>
   1.619 +        <parameter name="aHideProgress"/>
   1.620 +        <body><![CDATA[
   1.621 +          this._message.setAttribute("hidden", !aHideProgress);
   1.622 +          this._progress.setAttribute("hidden", !!aHideProgress);
   1.623 +
   1.624 +          var msg = gStrings.ext.GetStringFromName(aMsgId);
   1.625 +          if (aHideProgress)
   1.626 +            this._message.value = msg;
   1.627 +          else
   1.628 +            this._progress.status = msg;
   1.629 +        ]]></body>
   1.630 +      </method>
   1.631 +
   1.632 +      <method name="purchaseRemote">
   1.633 +        <body><![CDATA[
   1.634 +          openURL(this.mControl.mAddon.purchaseURL);
   1.635 +        ]]></body>
   1.636 +      </method>
   1.637 +
   1.638 +      <method name="installRemote">
   1.639 +        <body><![CDATA[
   1.640 +          if (this.mControl.getAttribute("remote") != "true")
   1.641 +            return;
   1.642 +
   1.643 +          if (this.mControl.mAddon.eula) {
   1.644 +            var data = {
   1.645 +              addon: this.mControl.mAddon,
   1.646 +              accepted: false
   1.647 +            };
   1.648 +            window.openDialog("chrome://mozapps/content/extensions/eula.xul", "_blank",
   1.649 +                              "chrome,dialog,modal,centerscreen,resizable=no", data);
   1.650 +            if (!data.accepted)
   1.651 +              return;
   1.652 +          }
   1.653 +
   1.654 +          delete this.mControl.mAddon;
   1.655 +          this.mControl.mInstall = this.mInstall;
   1.656 +          this.mControl.setAttribute("status", "installing");
   1.657 +          this.mInstall.install();
   1.658 +        ]]></body>
   1.659 +      </method>
   1.660 +
   1.661 +      <method name="undoAction">
   1.662 +        <body><![CDATA[
   1.663 +          if (!this.mAddon)
   1.664 +            return;
   1.665 +          var pending = this.mAddon.pendingOperations;
   1.666 +          if (pending & AddonManager.PENDING_ENABLE)
   1.667 +            this.mAddon.userDisabled = true;
   1.668 +          else if (pending & AddonManager.PENDING_DISABLE)
   1.669 +            this.mAddon.userDisabled = false;
   1.670 +          this.refreshState();
   1.671 +        ]]></body>
   1.672 +      </method>
   1.673 +
   1.674 +      <method name="onDownloadStarted">
   1.675 +        <body><![CDATA[
   1.676 +          this.refreshState();
   1.677 +        ]]></body>
   1.678 +      </method>
   1.679 +
   1.680 +      <method name="onDownloadEnded">
   1.681 +        <body><![CDATA[
   1.682 +          this.refreshState();
   1.683 +        ]]></body>
   1.684 +      </method>
   1.685 +
   1.686 +      <method name="onDownloadFailed">
   1.687 +        <body><![CDATA[
   1.688 +          this.refreshState();
   1.689 +        ]]></body>
   1.690 +      </method>
   1.691 +
   1.692 +      <method name="onDownloadProgress">
   1.693 +        <body><![CDATA[
   1.694 +          this._progress.maxProgress = this.mInstall.maxProgress;
   1.695 +          this._progress.progress = this.mInstall.progress;
   1.696 +        ]]></body>
   1.697 +      </method>
   1.698 +
   1.699 +      <method name="onInstallStarted">
   1.700 +        <body><![CDATA[
   1.701 +          this._progress.progress = 0;
   1.702 +          this.refreshState();
   1.703 +        ]]></body>
   1.704 +      </method>
   1.705 +
   1.706 +      <method name="onInstallEnded">
   1.707 +        <body><![CDATA[
   1.708 +          this.refreshState();
   1.709 +          if ("onInstallCompleted" in this.mControl)
   1.710 +            this.mControl.onInstallCompleted();
   1.711 +        ]]></body>
   1.712 +      </method>
   1.713 +
   1.714 +      <method name="onInstallFailed">
   1.715 +        <body><![CDATA[
   1.716 +          this.refreshState();
   1.717 +        ]]></body>
   1.718 +      </method>
   1.719 +    </implementation>
   1.720 +  </binding>
   1.721 +
   1.722 +
   1.723 +  <!-- Addon - base - parent binding of any item representing an addon. -->
   1.724 +  <binding id="addon-base"
   1.725 +           extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
   1.726 +    <implementation>
   1.727 +      <method name="hasPermission">
   1.728 +        <parameter name="aPerm"/>
   1.729 +        <body><![CDATA[
   1.730 +          var perm = AddonManager["PERM_CAN_" + aPerm.toUpperCase()];
   1.731 +          return !!(this.mAddon.permissions & perm);
   1.732 +        ]]></body>
   1.733 +      </method>
   1.734 +
   1.735 +      <method name="opRequiresRestart">
   1.736 +        <parameter name="aOperation"/>
   1.737 +        <body><![CDATA[
   1.738 +          var operation = AddonManager["OP_NEEDS_RESTART_" + aOperation.toUpperCase()];
   1.739 +          return !!(this.mAddon.operationsRequiringRestart & operation);
   1.740 +        ]]></body>
   1.741 +      </method>
   1.742 +
   1.743 +      <method name="isPending">
   1.744 +        <parameter name="aAction"/>
   1.745 +        <body><![CDATA[
   1.746 +          var action = AddonManager["PENDING_" + aAction.toUpperCase()];
   1.747 +          return !!(this.mAddon.pendingOperations & action);
   1.748 +        ]]></body>
   1.749 +      </method>
   1.750 +
   1.751 +      <method name="onUninstalled">
   1.752 +        <body><![CDATA[
   1.753 +          this.parentNode.removeChild(this);
   1.754 +        ]]></body>
   1.755 +      </method>
   1.756 +    </implementation>
   1.757 +  </binding>
   1.758 +
   1.759 +
   1.760 +  <!-- Addon - generic - A normal addon item, or an update to one -->
   1.761 +  <binding id="addon-generic"
   1.762 +           extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
   1.763 +    <content>
   1.764 +      <xul:hbox anonid="warning-container"
   1.765 +                class="warning">
   1.766 +        <xul:image class="warning-icon"/>
   1.767 +        <xul:label anonid="warning" flex="1"/>
   1.768 +        <xul:label anonid="warning-link" class="text-link"/>
   1.769 +        <xul:button anonid="warning-btn" class="button-link"/>
   1.770 +        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
   1.771 +      </xul:hbox>
   1.772 +      <xul:hbox anonid="error-container"
   1.773 +                class="error">
   1.774 +        <xul:image class="error-icon"/>
   1.775 +        <xul:label anonid="error" flex="1"/>
   1.776 +        <xul:label anonid="error-link" class="text-link"/>
   1.777 +        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
   1.778 +      </xul:hbox>
   1.779 +      <xul:hbox anonid="pending-container"
   1.780 +                class="pending">
   1.781 +        <xul:image class="pending-icon"/>
   1.782 +        <xul:label anonid="pending" flex="1"/>
   1.783 +        <xul:button anonid="restart-btn" class="button-link"
   1.784 +                    label="&addon.restartNow.label;"
   1.785 +                    oncommand="document.getBindingParent(this).restart();"/>
   1.786 +        <xul:button anonid="undo-btn" class="button-link"
   1.787 +                    label="&addon.undoAction.label;"
   1.788 +                    tooltipText="&addon.undoAction.tooltip;"
   1.789 +                    oncommand="document.getBindingParent(this).undo();"/>
   1.790 +        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
   1.791 +      </xul:hbox>
   1.792 +
   1.793 +      <xul:hbox class="content-container">
   1.794 +        <xul:vbox class="icon-container">
   1.795 +          <xul:image anonid="icon" class="icon"/>
   1.796 +        </xul:vbox>
   1.797 +        <xul:vbox class="content-inner-container" flex="1">
   1.798 +          <xul:hbox class="basicinfo-container">
   1.799 +              <xul:hbox class="name-container">
   1.800 +                <xul:label anonid="name" class="name" crop="end" flex="1"
   1.801 +                           xbl:inherits="value=name,tooltiptext=name"/>
   1.802 +                <xul:label anonid="version" class="version"/>
   1.803 +                <xul:label class="disabled-postfix" value="&addon.disabled.postfix;"/>
   1.804 +                <xul:label class="update-postfix" value="&addon.update.postfix;"/>
   1.805 +                <xul:spacer flex="5000"/> <!-- Necessary to make the name crop -->
   1.806 +              </xul:hbox>
   1.807 +            <xul:label anonid="date-updated" class="date-updated"
   1.808 +                       unknown="&addon.unknownDate;"/>
   1.809 +          </xul:hbox>
   1.810 +          <xul:hbox class="experiment-container">
   1.811 +            <svg width="6" height="6" viewBox="0 0 6 6" version="1.1"
   1.812 +                 xmlns="http://www.w3.org/2000/svg"
   1.813 +                 class="experiment-bullet-container">
   1.814 +              <circle cx="3" cy="3" r="3" class="experiment-bullet"/>
   1.815 +            </svg>
   1.816 +            <xul:label anonid="experiment-state" class="experiment-state"/>
   1.817 +            <xul:label anonid="experiment-time" class="experiment-time"/>
   1.818 +          </xul:hbox>
   1.819 +
   1.820 +          <xul:hbox class="advancedinfo-container" flex="1">
   1.821 +            <xul:vbox class="description-outer-container" flex="1">
   1.822 +              <xul:hbox class="description-container">
   1.823 +                <xul:label anonid="description" class="description" crop="end" flex="1"/>
   1.824 +                <xul:button anonid="details-btn" class="details button-link"
   1.825 +                            label="&addon.details.label;"
   1.826 +                            tooltiptext="&addon.details.tooltip;"
   1.827 +                            oncommand="document.getBindingParent(this).showInDetailView();"/>
   1.828 +                <xul:spacer flex="5000"/> <!-- Necessary to make the description crop -->
   1.829 +              </xul:hbox>
   1.830 +              <xul:vbox anonid="relnotes-container" class="relnotes-container">
   1.831 +                <xul:label class="relnotes-header" value="&addon.releaseNotes.label;"/>
   1.832 +                <xul:label anonid="relnotes-loading" value="&addon.loadingReleaseNotes.label;"/>
   1.833 +                <xul:label anonid="relnotes-error" hidden="true"
   1.834 +                           value="&addon.errorLoadingReleaseNotes.label;"/>
   1.835 +                <xul:vbox anonid="relnotes" class="relnotes"/>
   1.836 +              </xul:vbox>
   1.837 +              <xul:hbox class="relnotes-toggle-container">
   1.838 +                <xul:button anonid="relnotes-toggle-btn" class="relnotes-toggle"
   1.839 +                            hidden="true" label="&cmd.showReleaseNotes.label;"
   1.840 +                            tooltiptext="&cmd.showReleaseNotes.tooltip;"
   1.841 +                            showlabel="&cmd.showReleaseNotes.label;"
   1.842 +                            showtooltip="&cmd.showReleaseNotes.tooltip;"
   1.843 +                            hidelabel="&cmd.hideReleaseNotes.label;"
   1.844 +                            hidetooltip="&cmd.hideReleaseNotes.tooltip;"
   1.845 +                            oncommand="document.getBindingParent(this).toggleReleaseNotes();"/>
   1.846 +              </xul:hbox>
   1.847 +            </xul:vbox>
   1.848 +            <xul:vbox class="status-control-wrapper">
   1.849 +              <xul:hbox class="status-container">
   1.850 +                <xul:hbox anonid="checking-update" hidden="true">
   1.851 +                  <xul:image class="spinner"/>
   1.852 +                  <xul:label value="&addon.checkingForUpdates.label;"/>
   1.853 +                </xul:hbox>
   1.854 +                <xul:vbox anonid="update-available" class="update-available"
   1.855 +                          hidden="true">
   1.856 +                  <xul:checkbox anonid="include-update" class="include-update"
   1.857 +                                label="&addon.includeUpdate.label;" checked="true"
   1.858 +                                oncommand="document.getBindingParent(this).onIncludeUpdateChanged();"/>
   1.859 +                  <xul:hbox class="update-info-container">
   1.860 +                    <xul:label class="update-available-notice"
   1.861 +                               value="&addon.updateAvailable.label;"/>
   1.862 +                    <xul:button anonid="update-btn" class="addon-control update"
   1.863 +                                label="&addon.updateNow.label;"
   1.864 +                                tooltiptext="&addon.updateNow.tooltip;"
   1.865 +                                oncommand="document.getBindingParent(this).upgrade();"/>
   1.866 +                  </xul:hbox>
   1.867 +                </xul:vbox>
   1.868 +                <xul:hbox anonid="install-status" class="install-status"
   1.869 +                          hidden="true"/>
   1.870 +              </xul:hbox>
   1.871 +              <xul:hbox anonid="control-container" class="control-container">
   1.872 +                <xul:button anonid="preferences-btn"
   1.873 +                            class="addon-control preferences"
   1.874 +#ifdef XP_WIN
   1.875 +                            label="&cmd.showPreferencesWin.label;"
   1.876 +                            tooltiptext="&cmd.showPreferencesWin.tooltip;"
   1.877 +#else
   1.878 +                            label="&cmd.showPreferencesUnix.label;"
   1.879 +                            tooltiptext="&cmd.showPreferencesUnix.tooltip;"
   1.880 +#endif
   1.881 +                            oncommand="document.getBindingParent(this).showPreferences();"/>
   1.882 +                            <!-- label="&cmd.debugAddon.label;" -->
   1.883 +                <xul:button anonid="debug-btn" class="addon-control debug"
   1.884 +                            label="&cmd.debugAddon.label;"
   1.885 +                            oncommand="document.getBindingParent(this).debug();"/>
   1.886 +
   1.887 +                <xul:button anonid="enable-btn"  class="addon-control enable"
   1.888 +                            label="&cmd.enableAddon.label;"
   1.889 +                            oncommand="document.getBindingParent(this).userDisabled = false;"/>
   1.890 +                <xul:button anonid="disable-btn" class="addon-control disable"
   1.891 +                            label="&cmd.disableAddon.label;"
   1.892 +                            oncommand="document.getBindingParent(this).userDisabled = true;"/>
   1.893 +                <xul:button anonid="remove-btn" class="addon-control remove"
   1.894 +                            label="&cmd.uninstallAddon.label;"
   1.895 +                            oncommand="document.getBindingParent(this).uninstall();"/>
   1.896 +                <xul:menulist anonid="state-menulist"
   1.897 +                              class="addon-control state"
   1.898 +                              tooltiptext="&cmd.stateMenu.tooltip;">
   1.899 +                  <xul:menupopup>
   1.900 +                    <xul:menuitem anonid="ask-to-activate-menuitem"
   1.901 +                                  class="addon-control"
   1.902 +                                  label="&cmd.askToActivate.label;"
   1.903 +                                  tooltiptext="&cmd.askToActivate.tooltip;"
   1.904 +                                  oncommand="document.getBindingParent(this).userDisabled = AddonManager.STATE_ASK_TO_ACTIVATE;"/>
   1.905 +                    <xul:menuitem anonid="always-activate-menuitem"
   1.906 +                                  class="addon-control"
   1.907 +                                  label="&cmd.alwaysActivate.label;"
   1.908 +                                  tooltiptext="&cmd.alwaysActivate.tooltip;"
   1.909 +                                  oncommand="document.getBindingParent(this).userDisabled = false;"/>
   1.910 +                    <xul:menuitem anonid="never-activate-menuitem"
   1.911 +                                  class="addon-control"
   1.912 +                                  label="&cmd.neverActivate.label;"
   1.913 +                                  tooltiptext="&cmd.neverActivate.tooltip;"
   1.914 +                                  oncommand="document.getBindingParent(this).userDisabled = true;"/>
   1.915 +                  </xul:menupopup>
   1.916 +                </xul:menulist>
   1.917 +              </xul:hbox>
   1.918 +            </xul:vbox>
   1.919 +          </xul:hbox>
   1.920 +        </xul:vbox>
   1.921 +      </xul:hbox>
   1.922 +    </content>
   1.923 +
   1.924 +    <implementation>
   1.925 +      <constructor><![CDATA[
   1.926 +        this._installStatus.mControl = this;
   1.927 +
   1.928 +        this.setAttribute("contextmenu", "addonitem-popup");
   1.929 +
   1.930 +        this._showStatus("none");
   1.931 +
   1.932 +        this._initWithAddon(this.mAddon);
   1.933 +
   1.934 +        gEventManager.registerAddonListener(this, this.mAddon.id);
   1.935 +      ]]></constructor>
   1.936 +
   1.937 +      <destructor><![CDATA[
   1.938 +        gEventManager.unregisterAddonListener(this, this.mAddon.id);
   1.939 +      ]]></destructor>
   1.940 +
   1.941 +      <field name="_warningContainer">
   1.942 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.943 +                                                "warning-container");
   1.944 +      </field>
   1.945 +      <field name="_warning">
   1.946 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.947 +                                                "warning");
   1.948 +      </field>
   1.949 +      <field name="_warningLink">
   1.950 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.951 +                                                "warning-link");
   1.952 +      </field>
   1.953 +      <field name="_warningBtn">
   1.954 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.955 +                                                "warning-btn");
   1.956 +      </field>
   1.957 +      <field name="_errorContainer">
   1.958 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.959 +                                                "error-container");
   1.960 +      </field>
   1.961 +      <field name="_error">
   1.962 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.963 +                                                "error");
   1.964 +      </field>
   1.965 +      <field name="_errorLink">
   1.966 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.967 +                                                "error-link");
   1.968 +      </field>
   1.969 +      <field name="_pendingContainer">
   1.970 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.971 +                                                "pending-container");
   1.972 +      </field>
   1.973 +      <field name="_pending">
   1.974 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.975 +                                                "pending");
   1.976 +      </field>
   1.977 +      <field name="_infoContainer">
   1.978 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.979 +                                                "info-container");
   1.980 +      </field>
   1.981 +      <field name="_info">
   1.982 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.983 +                                                "info");
   1.984 +      </field>
   1.985 +      <field name="_version">
   1.986 +        document.getAnonymousElementByAttribute(this, "anonid", "version");
   1.987 +      </field>
   1.988 +      <field name="_experimentState">
   1.989 +        document.getAnonymousElementByAttribute(this, "anonid", "experiment-state");
   1.990 +      </field>
   1.991 +      <field name="_experimentTime">
   1.992 +        document.getAnonymousElementByAttribute(this, "anonid", "experiment-time");
   1.993 +      </field>
   1.994 +      <field name="_icon">
   1.995 +        document.getAnonymousElementByAttribute(this, "anonid", "icon");
   1.996 +      </field>
   1.997 +      <field name="_dateUpdated">
   1.998 +        document.getAnonymousElementByAttribute(this, "anonid",
   1.999 +                                                "date-updated");
  1.1000 +      </field>
  1.1001 +      <field name="_description">
  1.1002 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1003 +                                                "description");
  1.1004 +      </field>
  1.1005 +      <field name="_stateMenulist">
  1.1006 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1007 +                                                "state-menulist");
  1.1008 +      </field>
  1.1009 +      <field name="_askToActivateMenuitem">
  1.1010 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1011 +                                                "ask-to-activate-menuitem");
  1.1012 +      </field>
  1.1013 +      <field name="_alwaysActivateMenuitem">
  1.1014 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1015 +                                                "always-activate-menuitem");
  1.1016 +      </field>
  1.1017 +      <field name="_neverActivateMenuitem">
  1.1018 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1019 +                                                "never-activate-menuitem");
  1.1020 +      </field>
  1.1021 +      <field name="_preferencesBtn">
  1.1022 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1023 +                                                "preferences-btn");
  1.1024 +      </field>
  1.1025 +      <field name="_enableBtn">
  1.1026 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1027 +                                                "enable-btn");
  1.1028 +      </field>
  1.1029 +      <field name="_debugBtn">
  1.1030 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1031 +                                                "debug-btn");
  1.1032 +      </field>
  1.1033 +      <field name="_disableBtn">
  1.1034 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1035 +                                                "disable-btn");
  1.1036 +      </field>
  1.1037 +      <field name="_removeBtn">
  1.1038 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1039 +                                                "remove-btn");
  1.1040 +      </field>
  1.1041 +      <field name="_updateBtn">
  1.1042 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1043 +                                                "update-btn");
  1.1044 +      </field>
  1.1045 +      <field name="_controlContainer">
  1.1046 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1047 +                                                "control-container");
  1.1048 +      </field>
  1.1049 +      <field name="_installStatus">
  1.1050 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1051 +                                                "install-status");
  1.1052 +      </field>
  1.1053 +      <field name="_checkingUpdate">
  1.1054 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1055 +                                                "checking-update");
  1.1056 +      </field>
  1.1057 +      <field name="_updateAvailable">
  1.1058 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1059 +                                                "update-available");
  1.1060 +      </field>
  1.1061 +      <field name="_includeUpdate">
  1.1062 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1063 +                                                "include-update");
  1.1064 +      </field>
  1.1065 +      <field name="_relNotesLoaded">false</field>
  1.1066 +      <field name="_relNotesToggle">
  1.1067 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1068 +                                                "relnotes-toggle-btn");
  1.1069 +      </field>
  1.1070 +      <field name="_relNotesLoading">
  1.1071 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1072 +                                                "relnotes-loading");
  1.1073 +      </field>
  1.1074 +      <field name="_relNotesError">
  1.1075 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1076 +                                                "relnotes-error");
  1.1077 +      </field>
  1.1078 +      <field name="_relNotesContainer">
  1.1079 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1080 +                                                "relnotes-container");
  1.1081 +      </field>
  1.1082 +      <field name="_relNotes">
  1.1083 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1084 +                                                "relnotes");
  1.1085 +      </field>
  1.1086 +
  1.1087 +      <property name="userDisabled">
  1.1088 +        <getter><![CDATA[
  1.1089 +          return this.mAddon.userDisabled;
  1.1090 +        ]]></getter>
  1.1091 +        <setter><![CDATA[
  1.1092 +          this.mAddon.userDisabled = val;
  1.1093 +        ]]></setter>
  1.1094 +      </property>
  1.1095 +
  1.1096 +      <property name="includeUpdate">
  1.1097 +        <getter><![CDATA[
  1.1098 +          return this._includeUpdate.checked && !!this.mManualUpdate;
  1.1099 +        ]]></getter>
  1.1100 +        <setter><![CDATA[
  1.1101 +          //XXXunf Eventually, we'll want to persist this for individual
  1.1102 +          //       updates - see bug 594619.
  1.1103 +          this._includeUpdate.checked = !!val;
  1.1104 +        ]]></setter>
  1.1105 +      </property>
  1.1106 +
  1.1107 +      <method name="_initWithAddon">
  1.1108 +        <parameter name="aAddon"/>
  1.1109 +        <body><![CDATA[
  1.1110 +          this.mAddon = aAddon;
  1.1111 +
  1.1112 +          this._installStatus.mAddon = this.mAddon;
  1.1113 +          this._updateDates();
  1.1114 +          this._updateState();
  1.1115 +
  1.1116 +          this.setAttribute("name", aAddon.name);
  1.1117 +
  1.1118 +          var iconURL = this.mAddon.iconURL;
  1.1119 +          if (iconURL)
  1.1120 +            this._icon.src = iconURL;
  1.1121 +          else
  1.1122 +            this._icon.src = "";
  1.1123 +
  1.1124 +          if (shouldShowVersionNumber(this.mAddon))
  1.1125 +            this._version.value = this.mAddon.version;
  1.1126 +          else
  1.1127 +            this._version.hidden = true;
  1.1128 +
  1.1129 +          if (this.mAddon.description)
  1.1130 +            this._description.value = this.mAddon.description;
  1.1131 +          else
  1.1132 +            this._description.hidden = true;
  1.1133 +
  1.1134 +          if (!("applyBackgroundUpdates" in this.mAddon) ||
  1.1135 +              (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DISABLE ||
  1.1136 +               (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
  1.1137 +                !AddonManager.autoUpdateDefault))) {
  1.1138 +            var self = this;
  1.1139 +            AddonManager.getAllInstalls(function(aInstallsList) {
  1.1140 +              // This can return after the binding has been destroyed,
  1.1141 +              // so try to detect that and return early
  1.1142 +              if (!("onNewInstall" in self))
  1.1143 +                return;
  1.1144 +              for (let install of aInstallsList) {
  1.1145 +                if (install.existingAddon &&
  1.1146 +                    install.existingAddon.id == self.mAddon.id &&
  1.1147 +                    install.state == AddonManager.STATE_AVAILABLE) {
  1.1148 +                  self.onNewInstall(install);
  1.1149 +                  self.onIncludeUpdateChanged();
  1.1150 +                }
  1.1151 +              }
  1.1152 +            });
  1.1153 +          }
  1.1154 +        ]]></body>
  1.1155 +      </method>
  1.1156 +
  1.1157 +      <method name="_showStatus">
  1.1158 +        <parameter name="aType"/>
  1.1159 +        <body><![CDATA[
  1.1160 +          this._controlContainer.hidden = aType != "none" &&
  1.1161 +                                          !(aType == "update-available" && !this.hasAttribute("upgrade"));
  1.1162 +
  1.1163 +          this._installStatus.hidden = aType != "progress";
  1.1164 +          if (aType == "progress")
  1.1165 +            this._installStatus.refreshState();
  1.1166 +          this._checkingUpdate.hidden = aType != "checking-update";
  1.1167 +          this._updateAvailable.hidden = aType != "update-available";
  1.1168 +          this._relNotesToggle.hidden = !(this.mManualUpdate ?
  1.1169 +                                          this.mManualUpdate.releaseNotesURI :
  1.1170 +                                          this.mAddon.releaseNotesURI);
  1.1171 +        ]]></body>
  1.1172 +      </method>
  1.1173 +
  1.1174 +      <method name="_updateDates">
  1.1175 +        <body><![CDATA[
  1.1176 +          function formatDate(aDate) {
  1.1177 +            return Cc["@mozilla.org/intl/scriptabledateformat;1"]
  1.1178 +                     .getService(Ci.nsIScriptableDateFormat)
  1.1179 +                     .FormatDate("",
  1.1180 +                                 Ci.nsIScriptableDateFormat.dateFormatLong,
  1.1181 +                                 aDate.getFullYear(),
  1.1182 +                                 aDate.getMonth() + 1,
  1.1183 +                                 aDate.getDate()
  1.1184 +                                 );
  1.1185 +          }
  1.1186 +
  1.1187 +          if (this.mAddon.updateDate)
  1.1188 +            this._dateUpdated.value = formatDate(this.mAddon.updateDate);
  1.1189 +          else
  1.1190 +            this._dateUpdated.value = this._dateUpdated.getAttribute("unknown");
  1.1191 +        ]]></body>
  1.1192 +      </method>
  1.1193 +
  1.1194 +      <method name="_updateState">
  1.1195 +        <body><![CDATA[
  1.1196 +          if (this.parentNode.selectedItem == this)
  1.1197 +            gViewController.updateCommands();
  1.1198 +
  1.1199 +          var pending = this.mAddon.pendingOperations;
  1.1200 +          if (pending != AddonManager.PENDING_NONE) {
  1.1201 +            this.removeAttribute("notification");
  1.1202 +
  1.1203 +            var pending = null;
  1.1204 +            const PENDING_OPERATIONS = ["enable", "disable", "install",
  1.1205 +                                        "uninstall", "upgrade"];
  1.1206 +            for (let op of PENDING_OPERATIONS) {
  1.1207 +              if (this.isPending(op))
  1.1208 +                pending = op;
  1.1209 +            }
  1.1210 +
  1.1211 +            this.setAttribute("pending", pending);
  1.1212 +            this._pending.textContent = gStrings.ext.formatStringFromName(
  1.1213 +              "notification." + pending,
  1.1214 +              [this.mAddon.name, gStrings.brandShortName], 2
  1.1215 +            );
  1.1216 +          } else {
  1.1217 +            this.removeAttribute("pending");
  1.1218 +
  1.1219 +            var isUpgrade = this.hasAttribute("upgrade");
  1.1220 +            var install = this._installStatus.mInstall;
  1.1221 +
  1.1222 +            if (install && install.state == AddonManager.STATE_DOWNLOAD_FAILED) {
  1.1223 +              this.setAttribute("notification", "warning");
  1.1224 +              this._warning.textContent = gStrings.ext.formatStringFromName(
  1.1225 +                "notification.downloadError",
  1.1226 +                [this.mAddon.name], 1
  1.1227 +              );
  1.1228 +              this._warningBtn.label = gStrings.ext.GetStringFromName("notification.downloadError.retry");
  1.1229 +              this._warningBtn.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
  1.1230 +              this._warningBtn.setAttribute("oncommand", "document.getBindingParent(this).retryInstall();");
  1.1231 +              this._warningBtn.hidden = false;
  1.1232 +              this._warningLink.hidden = true;
  1.1233 +            } else if (install && install.state == AddonManager.STATE_INSTALL_FAILED) {
  1.1234 +              this.setAttribute("notification", "warning");
  1.1235 +              this._warning.textContent = gStrings.ext.formatStringFromName(
  1.1236 +                "notification.installError",
  1.1237 +                [this.mAddon.name], 1
  1.1238 +              );
  1.1239 +              this._warningBtn.label = gStrings.ext.GetStringFromName("notification.installError.retry");
  1.1240 +              this._warningBtn.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
  1.1241 +              this._warningBtn.setAttribute("oncommand", "document.getBindingParent(this).retryInstall();");
  1.1242 +              this._warningBtn.hidden = false;
  1.1243 +              this._warningLink.hidden = true;
  1.1244 +            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED) {
  1.1245 +              this.setAttribute("notification", "error");
  1.1246 +              this._error.textContent = gStrings.ext.formatStringFromName(
  1.1247 +                "notification.blocked",
  1.1248 +                [this.mAddon.name], 1
  1.1249 +              );
  1.1250 +              this._errorLink.value = gStrings.ext.GetStringFromName("notification.blocked.link");
  1.1251 +              this._errorLink.href = this.mAddon.blocklistURL;
  1.1252 +              this._errorLink.hidden = false;
  1.1253 +            } else if ((!isUpgrade && !this.mAddon.isCompatible) && (AddonManager.checkCompatibility
  1.1254 +            || (this.mAddon.blocklistState != Ci.nsIBlocklistService.STATE_SOFTBLOCKED))) {
  1.1255 +              this.setAttribute("notification", "warning");
  1.1256 +              this._warning.textContent = gStrings.ext.formatStringFromName(
  1.1257 +                "notification.incompatible",
  1.1258 +                [this.mAddon.name, gStrings.brandShortName, gStrings.appVersion], 3
  1.1259 +              );
  1.1260 +              this._warningLink.hidden = true;
  1.1261 +              this._warningBtn.hidden = true;
  1.1262 +            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED) {
  1.1263 +              this.setAttribute("notification", "warning");
  1.1264 +              this._warning.textContent = gStrings.ext.formatStringFromName(
  1.1265 +                "notification.softblocked",
  1.1266 +                [this.mAddon.name], 1
  1.1267 +              );
  1.1268 +              this._warningLink.value = gStrings.ext.GetStringFromName("notification.softblocked.link");
  1.1269 +              this._warningLink.href = this.mAddon.blocklistURL;
  1.1270 +              this._warningLink.hidden = false;
  1.1271 +              this._warningBtn.hidden = true;
  1.1272 +            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
  1.1273 +              this.setAttribute("notification", "warning");
  1.1274 +              this._warning.textContent = gStrings.ext.formatStringFromName(
  1.1275 +                "notification.outdated",
  1.1276 +                [this.mAddon.name], 1
  1.1277 +              );
  1.1278 +              this._warningLink.value = gStrings.ext.GetStringFromName("notification.outdated.link");
  1.1279 +              this._warningLink.href = Services.urlFormatter.formatURLPref("plugins.update.url");
  1.1280 +              this._warningLink.hidden = false;
  1.1281 +              this._warningBtn.hidden = true;
  1.1282 +            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE) {
  1.1283 +              this.setAttribute("notification", "error");
  1.1284 +              this._error.textContent = gStrings.ext.formatStringFromName(
  1.1285 +                "notification.vulnerableUpdatable",
  1.1286 +                [this.mAddon.name], 1
  1.1287 +              );
  1.1288 +              this._errorLink.value = gStrings.ext.GetStringFromName("notification.vulnerableUpdatable.link");
  1.1289 +              this._errorLink.href = this.mAddon.blocklistURL;
  1.1290 +              this._errorLink.hidden = false;
  1.1291 +            } else if (!isUpgrade && this.mAddon.blocklistState == Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) {
  1.1292 +              this.setAttribute("notification", "error");
  1.1293 +              this._error.textContent = gStrings.ext.formatStringFromName(
  1.1294 +                "notification.vulnerableNoUpdate",
  1.1295 +                [this.mAddon.name], 1
  1.1296 +              );
  1.1297 +              this._errorLink.value = gStrings.ext.GetStringFromName("notification.vulnerableNoUpdate.link");
  1.1298 +              this._errorLink.href = this.mAddon.blocklistURL;
  1.1299 +              this._errorLink.hidden = false;
  1.1300 +            } else {
  1.1301 +              this.removeAttribute("notification");
  1.1302 +            }
  1.1303 +          }
  1.1304 +
  1.1305 +          this._preferencesBtn.hidden = (!this.mAddon.optionsURL) ||
  1.1306 +                                        this.mAddon.optionsType == AddonManager.OPTIONS_TYPE_INLINE_INFO;
  1.1307 +
  1.1308 +          let addonType = AddonManager.addonTypes[this.mAddon.type];
  1.1309 +          if (addonType.flags & AddonManager.TYPE_SUPPORTS_ASK_TO_ACTIVATE &&
  1.1310 +              (this.hasPermission("ask_to_activate") ||
  1.1311 +               this.hasPermission("enable") ||
  1.1312 +               this.hasPermission("disable"))) {
  1.1313 +            this._enableBtn.disabled = true;
  1.1314 +            this._disableBtn.disabled = true;
  1.1315 +            this._askToActivateMenuitem.disabled = !this.hasPermission("ask_to_activate");
  1.1316 +            this._alwaysActivateMenuitem.disabled = !this.hasPermission("enable");
  1.1317 +            this._neverActivateMenuitem.disabled = !this.hasPermission("disable");
  1.1318 +            if (this.mAddon.userDisabled === true) {
  1.1319 +              this._stateMenulist.selectedItem = this._neverActivateMenuitem;
  1.1320 +            } else if (this.mAddon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) {
  1.1321 +              this._stateMenulist.selectedItem = this._askToActivateMenuitem;
  1.1322 +            } else {
  1.1323 +              this._stateMenulist.selectedItem = this._alwaysActivateMenuitem;
  1.1324 +            }
  1.1325 +            this._stateMenulist.selectedItem.disabled = false;
  1.1326 +            this._stateMenulist.disabled = false;
  1.1327 +          } else {
  1.1328 +            this._stateMenulist.disabled = true;
  1.1329 +            if (this.hasPermission("enable")) {
  1.1330 +              this._enableBtn.hidden = false;
  1.1331 +              let tooltip = gViewController.commands["cmd_enableItem"]
  1.1332 +                                           .getTooltip(this.mAddon);
  1.1333 +              this._enableBtn.setAttribute("tooltiptext", tooltip);
  1.1334 +            } else {
  1.1335 +              this._enableBtn.hidden = true;
  1.1336 +            }
  1.1337 +
  1.1338 +            if (this.hasPermission("disable")) {
  1.1339 +              this._disableBtn.hidden = false;
  1.1340 +              let tooltip = gViewController.commands["cmd_disableItem"]
  1.1341 +                                           .getTooltip(this.mAddon);
  1.1342 +              this._disableBtn.setAttribute("tooltiptext", tooltip);
  1.1343 +            } else {
  1.1344 +              this._disableBtn.hidden = true;
  1.1345 +            }
  1.1346 +          }
  1.1347 +
  1.1348 +          if (this.hasPermission("uninstall")) {
  1.1349 +            this._removeBtn.hidden = false;
  1.1350 +            let tooltip = gViewController.commands["cmd_uninstallItem"]
  1.1351 +                                         .getTooltip(this.mAddon);
  1.1352 +            this._removeBtn.setAttribute("tooltiptext", tooltip);
  1.1353 +          } else {
  1.1354 +            this._removeBtn.hidden = true;
  1.1355 +          }
  1.1356 +
  1.1357 +          this.setAttribute("active", this.mAddon.isActive);
  1.1358 +
  1.1359 +          var showProgress = this.mAddon.purchaseURL || (this.mAddon.install &&
  1.1360 +                             this.mAddon.install.state != AddonManager.STATE_INSTALLED);
  1.1361 +          this._showStatus(showProgress ? "progress" : "none");
  1.1362 +
  1.1363 +          let debuggable = this.mAddon.isDebuggable &&
  1.1364 +                           Services.prefs.getBoolPref('devtools.chrome.enabled') &&
  1.1365 +                           Services.prefs.getBoolPref('devtools.debugger.remote-enabled');
  1.1366 +
  1.1367 +          this._debugBtn.disabled = this._debugBtn.hidden = !debuggable
  1.1368 +
  1.1369 +          if (this.mAddon.type == "experiment") {
  1.1370 +            this.removeAttribute("notification");
  1.1371 +            let prefix = "experiment.";
  1.1372 +            let active = this.mAddon.isActive;
  1.1373 +
  1.1374 +            if (!showProgress) {
  1.1375 +              let stateKey = prefix + "state." + (active ? "active" : "complete");
  1.1376 +              this._experimentState.value = gStrings.ext.GetStringFromName(stateKey);
  1.1377 +
  1.1378 +              let now = Date.now();
  1.1379 +              let end = this.endDate;
  1.1380 +              let days = Math.abs(end - now) / (24 * 60 * 60 * 1000);
  1.1381 +
  1.1382 +              let timeKey = prefix + "time.";
  1.1383 +              let timeMessage;
  1.1384 +
  1.1385 +              if (days < 1) {
  1.1386 +                timeKey += (active ? "endsToday" : "endedToday");
  1.1387 +                timeMessage = gStrings.ext.GetStringFromName(timeKey);
  1.1388 +              } else {
  1.1389 +                timeKey += (active ? "daysRemaining" : "daysPassed");
  1.1390 +                days = Math.round(days);
  1.1391 +                let timeString = gStrings.ext.GetStringFromName(timeKey);
  1.1392 +                timeMessage = PluralForm.get(days, timeString)
  1.1393 +                                        .replace("#1", days);
  1.1394 +              }
  1.1395 +
  1.1396 +              this._experimentTime.value = timeMessage;
  1.1397 +            }
  1.1398 +          }
  1.1399 +        ]]></body>
  1.1400 +      </method>
  1.1401 +
  1.1402 +      <method name="_updateUpgradeInfo">
  1.1403 +        <body><![CDATA[
  1.1404 +          // Only update the version string if we're displaying the upgrade info
  1.1405 +          if (this.hasAttribute("upgrade") && shouldShowVersionNumber(this.mAddon))
  1.1406 +            this._version.value = this.mManualUpdate.version;
  1.1407 +        ]]></body>
  1.1408 +      </method>
  1.1409 +
  1.1410 +      <method name="_fetchReleaseNotes">
  1.1411 +        <parameter name="aURI"/>
  1.1412 +        <body><![CDATA[
  1.1413 +          var self = this;
  1.1414 +          if (!aURI || this._relNotesLoaded) {
  1.1415 +            sendToggleEvent();
  1.1416 +            return;
  1.1417 +          }
  1.1418 +
  1.1419 +          var relNotesData = null, transformData = null;
  1.1420 +
  1.1421 +          this._relNotesLoaded = true;
  1.1422 +          this._relNotesLoading.hidden = false;
  1.1423 +          this._relNotesError.hidden = true;
  1.1424 +
  1.1425 +          function sendToggleEvent() {
  1.1426 +            var event = document.createEvent("Events");
  1.1427 +            event.initEvent("RelNotesToggle", true, true);
  1.1428 +            self.dispatchEvent(event);
  1.1429 +          }
  1.1430 +
  1.1431 +          function showRelNotes() {
  1.1432 +            if (!relNotesData || !transformData)
  1.1433 +              return;
  1.1434 +
  1.1435 +            self._relNotesLoading.hidden = true;
  1.1436 +
  1.1437 +            var processor = Components.classes["@mozilla.org/document-transformer;1?type=xslt"]
  1.1438 +                                      .createInstance(Components.interfaces.nsIXSLTProcessor);
  1.1439 +            processor.flags |= Components.interfaces.nsIXSLTProcessorPrivate.DISABLE_ALL_LOADS;
  1.1440 +
  1.1441 +            processor.importStylesheet(transformData);
  1.1442 +            var fragment = processor.transformToFragment(relNotesData, document);
  1.1443 +            self._relNotes.appendChild(fragment);
  1.1444 +            if (self.hasAttribute("show-relnotes")) {
  1.1445 +              var container = self._relNotesContainer;
  1.1446 +              container.style.height = container.scrollHeight + "px";
  1.1447 +            }
  1.1448 +            sendToggleEvent();
  1.1449 +          }
  1.1450 +
  1.1451 +          function handleError() {
  1.1452 +            dataReq.abort();
  1.1453 +            styleReq.abort();
  1.1454 +            self._relNotesLoading.hidden = true;
  1.1455 +            self._relNotesError.hidden = false;
  1.1456 +            self._relNotesLoaded = false; // allow loading to be re-tried
  1.1457 +            sendToggleEvent();
  1.1458 +          }
  1.1459 +
  1.1460 +          function handleResponse(aEvent) {
  1.1461 +            var req = aEvent.target;
  1.1462 +            var ct = req.getResponseHeader("content-type");
  1.1463 +            if ((!ct || ct.indexOf("text/html") < 0) &&
  1.1464 +                req.responseXML &&
  1.1465 +                req.responseXML.documentElement.namespaceURI != XMLURI_PARSE_ERROR) {
  1.1466 +              if (req == dataReq)
  1.1467 +                relNotesData = req.responseXML;
  1.1468 +              else
  1.1469 +                transformData = req.responseXML;
  1.1470 +              showRelNotes();
  1.1471 +            } else {
  1.1472 +              handleError();
  1.1473 +            }
  1.1474 +          }
  1.1475 +
  1.1476 +          var dataReq = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
  1.1477 +                              .createInstance(Components.interfaces.nsIXMLHttpRequest);
  1.1478 +          dataReq.open("GET", aURI.spec, true);
  1.1479 +          dataReq.addEventListener("load", handleResponse, false);
  1.1480 +          dataReq.addEventListener("error", handleError, false);
  1.1481 +          dataReq.send(null);
  1.1482 +
  1.1483 +          var styleReq = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
  1.1484 +                              .createInstance(Components.interfaces.nsIXMLHttpRequest);
  1.1485 +          styleReq.open("GET", UPDATES_RELEASENOTES_TRANSFORMFILE, true);
  1.1486 +          styleReq.addEventListener("load", handleResponse, false);
  1.1487 +          styleReq.addEventListener("error", handleError, false);
  1.1488 +          styleReq.send(null);
  1.1489 +        ]]></body>
  1.1490 +      </method>
  1.1491 +
  1.1492 +      <method name="toggleReleaseNotes">
  1.1493 +        <body><![CDATA[
  1.1494 +          if (this.hasAttribute("show-relnotes")) {
  1.1495 +            this._relNotesContainer.style.height = "0px";
  1.1496 +            this.removeAttribute("show-relnotes");
  1.1497 +            this._relNotesToggle.setAttribute(
  1.1498 +              "label",
  1.1499 +              this._relNotesToggle.getAttribute("showlabel")
  1.1500 +            );
  1.1501 +            this._relNotesToggle.setAttribute(
  1.1502 +              "tooltiptext",
  1.1503 +              this._relNotesToggle.getAttribute("showtooltip")
  1.1504 +            );
  1.1505 +            var event = document.createEvent("Events");
  1.1506 +            event.initEvent("RelNotesToggle", true, true);
  1.1507 +            this.dispatchEvent(event);
  1.1508 +          } else {
  1.1509 +            this._relNotesContainer.style.height = this._relNotesContainer.scrollHeight +
  1.1510 +                                                   "px";
  1.1511 +            this.setAttribute("show-relnotes", true);
  1.1512 +            this._relNotesToggle.setAttribute(
  1.1513 +              "label",
  1.1514 +              this._relNotesToggle.getAttribute("hidelabel")
  1.1515 +            );
  1.1516 +            this._relNotesToggle.setAttribute(
  1.1517 +              "tooltiptext",
  1.1518 +              this._relNotesToggle.getAttribute("hidetooltip")
  1.1519 +            );
  1.1520 +            var uri = this.mManualUpdate ?
  1.1521 +                      this.mManualUpdate.releaseNotesURI :
  1.1522 +                      this.mAddon.releaseNotesURI;
  1.1523 +            this._fetchReleaseNotes(uri);
  1.1524 +          }
  1.1525 +        ]]></body>
  1.1526 +      </method>
  1.1527 +
  1.1528 +      <method name="restart">
  1.1529 +        <body><![CDATA[
  1.1530 +          gViewController.commands["cmd_restartApp"].doCommand();
  1.1531 +        ]]></body>
  1.1532 +      </method>
  1.1533 +
  1.1534 +      <method name="undo">
  1.1535 +        <body><![CDATA[
  1.1536 +          gViewController.commands["cmd_cancelOperation"].doCommand(this.mAddon);
  1.1537 +        ]]></body>
  1.1538 +      </method>
  1.1539 +
  1.1540 +      <method name="uninstall">
  1.1541 +        <body><![CDATA[
  1.1542 +          // If uninstalling does not require a restart then just disable it
  1.1543 +          // and show the undo UI.
  1.1544 +          if (!this.opRequiresRestart("uninstall")) {
  1.1545 +            this.setAttribute("wasDisabled", this.mAddon.userDisabled);
  1.1546 +
  1.1547 +            // We must set userDisabled to true first, this will call
  1.1548 +            // _updateState which will clear any pending attribute set.
  1.1549 +            this.mAddon.userDisabled = true;
  1.1550 +
  1.1551 +            // This won't update any other add-on manager views (bug 582002)
  1.1552 +            this.setAttribute("pending", "uninstall");
  1.1553 +          } else {
  1.1554 +            this.mAddon.uninstall();
  1.1555 +          }
  1.1556 +        ]]></body>
  1.1557 +      </method>
  1.1558 +
  1.1559 +      <method name="debug">
  1.1560 +        <body><![CDATA[
  1.1561 +          gViewController.doCommand("cmd_debugItem", this.mAddon);
  1.1562 +        ]]></body>
  1.1563 +      </method>
  1.1564 +
  1.1565 +      <method name="showPreferences">
  1.1566 +        <body><![CDATA[
  1.1567 +          gViewController.doCommand("cmd_showItemPreferences", this.mAddon);
  1.1568 +        ]]></body>
  1.1569 +      </method>
  1.1570 +
  1.1571 +      <method name="upgrade">
  1.1572 +        <body><![CDATA[
  1.1573 +          var install = this.mManualUpdate;
  1.1574 +          delete this.mManualUpdate;
  1.1575 +          install.install();
  1.1576 +        ]]></body>
  1.1577 +      </method>
  1.1578 +
  1.1579 +      <method name="retryInstall">
  1.1580 +        <body><![CDATA[
  1.1581 +          var install = this._installStatus.mInstall;
  1.1582 +          if (!install)
  1.1583 +            return;
  1.1584 +          if (install.state != AddonManager.STATE_DOWNLOAD_FAILED &&
  1.1585 +              install.state != AddonManager.STATE_INSTALL_FAILED)
  1.1586 +            return;
  1.1587 +          install.install();
  1.1588 +        ]]></body>
  1.1589 +      </method>
  1.1590 +
  1.1591 +      <method name="showInDetailView">
  1.1592 +        <body><![CDATA[
  1.1593 +          gViewController.loadView("addons://detail/" +
  1.1594 +                                   encodeURIComponent(this.mAddon.id));
  1.1595 +        ]]></body>
  1.1596 +      </method>
  1.1597 +
  1.1598 +      <method name="onIncludeUpdateChanged">
  1.1599 +        <body><![CDATA[
  1.1600 +          var event = document.createEvent("Events");
  1.1601 +          event.initEvent("IncludeUpdateChanged", true, true);
  1.1602 +          this.dispatchEvent(event);
  1.1603 +        ]]></body>
  1.1604 +      </method>
  1.1605 +
  1.1606 +      <method name="onEnabling">
  1.1607 +        <body><![CDATA[
  1.1608 +          this._updateState();
  1.1609 +        ]]></body>
  1.1610 +      </method>
  1.1611 +
  1.1612 +      <method name="onEnabled">
  1.1613 +        <body><![CDATA[
  1.1614 +          this._updateState();
  1.1615 +        ]]></body>
  1.1616 +      </method>
  1.1617 +
  1.1618 +      <method name="onDisabling">
  1.1619 +        <body><![CDATA[
  1.1620 +          this._updateState();
  1.1621 +        ]]></body>
  1.1622 +      </method>
  1.1623 +
  1.1624 +      <method name="onDisabled">
  1.1625 +        <body><![CDATA[
  1.1626 +          this._updateState();
  1.1627 +        ]]></body>
  1.1628 +      </method>
  1.1629 +
  1.1630 +      <method name="onUninstalling">
  1.1631 +        <parameter name="aRestartRequired"/>
  1.1632 +        <body><![CDATA[
  1.1633 +          this._updateState();
  1.1634 +        ]]></body>
  1.1635 +      </method>
  1.1636 +
  1.1637 +      <method name="onOperationCancelled">
  1.1638 +        <body><![CDATA[
  1.1639 +          this._updateState();
  1.1640 +        ]]></body>
  1.1641 +      </method>
  1.1642 +
  1.1643 +      <method name="onPropertyChanged">
  1.1644 +        <parameter name="aProperties"/>
  1.1645 +        <body><![CDATA[
  1.1646 +          if (aProperties.indexOf("appDisabled") != -1 ||
  1.1647 +              aProperties.indexOf("userDisabled") != -1)
  1.1648 +            this._updateState();
  1.1649 +        ]]></body>
  1.1650 +      </method>
  1.1651 +
  1.1652 +      <method name="onNoUpdateAvailable">
  1.1653 +        <body><![CDATA[
  1.1654 +          this._showStatus("none");
  1.1655 +        ]]></body>
  1.1656 +      </method>
  1.1657 +
  1.1658 +      <method name="onCheckingUpdate">
  1.1659 +        <body><![CDATA[
  1.1660 +          this._showStatus("checking-update");
  1.1661 +        ]]></body>
  1.1662 +      </method>
  1.1663 +
  1.1664 +      <method name="onCompatibilityUpdateAvailable">
  1.1665 +        <body><![CDATA[
  1.1666 +          this._updateState();
  1.1667 +        ]]></body>
  1.1668 +      </method>
  1.1669 +
  1.1670 +      <method name="onExternalInstall">
  1.1671 +        <parameter name="aAddon"/>
  1.1672 +        <parameter name="aExistingAddon"/>
  1.1673 +        <parameter name="aNeedsRestart"/>
  1.1674 +        <body><![CDATA[
  1.1675 +          if (aExistingAddon.id != this.mAddon.id)
  1.1676 +            return;
  1.1677 +
  1.1678 +          // If the install completed without needing a restart then switch to
  1.1679 +          // using the new Addon
  1.1680 +          if (!aNeedsRestart)
  1.1681 +            this._initWithAddon(aAddon);
  1.1682 +          else
  1.1683 +            this._updateState();
  1.1684 +        ]]></body>
  1.1685 +      </method>
  1.1686 +
  1.1687 +      <method name="onNewInstall">
  1.1688 +        <parameter name="aInstall"/>
  1.1689 +        <body><![CDATA[
  1.1690 +          if (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_ENABLE)
  1.1691 +            return;
  1.1692 +          if (this.mAddon.applyBackgroundUpdates == AddonManager.AUTOUPDATE_DEFAULT &&
  1.1693 +              AddonManager.autoUpdateDefault)
  1.1694 +            return;
  1.1695 +
  1.1696 +          this.mManualUpdate = aInstall;
  1.1697 +          this._showStatus("update-available");
  1.1698 +          this._updateUpgradeInfo();
  1.1699 +        ]]></body>
  1.1700 +      </method>
  1.1701 +
  1.1702 +      <method name="onDownloadStarted">
  1.1703 +        <parameter name="aInstall"/>
  1.1704 +        <body><![CDATA[
  1.1705 +          this._updateState();
  1.1706 +          this._showStatus("progress");
  1.1707 +          this._installStatus.initWithInstall(aInstall);
  1.1708 +        ]]></body>
  1.1709 +      </method>
  1.1710 +
  1.1711 +      <method name="onInstallStarted">
  1.1712 +        <parameter name="aInstall"/>
  1.1713 +        <body><![CDATA[
  1.1714 +          this._updateState();
  1.1715 +          this._showStatus("progress");
  1.1716 +          this._installStatus.initWithInstall(aInstall);
  1.1717 +        ]]></body>
  1.1718 +      </method>
  1.1719 +
  1.1720 +      <method name="onInstallEnded">
  1.1721 +        <parameter name="aInstall"/>
  1.1722 +        <parameter name="aAddon"/>
  1.1723 +        <body><![CDATA[
  1.1724 +          // If the install completed without needing a restart then switch to
  1.1725 +          // using the new Addon
  1.1726 +          if (!(aAddon.pendingOperations & AddonManager.PENDING_INSTALL))
  1.1727 +            this._initWithAddon(aAddon);
  1.1728 +          else
  1.1729 +            this._updateState();
  1.1730 +        ]]></body>
  1.1731 +      </method>
  1.1732 +
  1.1733 +      <method name="onDownloadFailed">
  1.1734 +        <body><![CDATA[
  1.1735 +            this._updateState();
  1.1736 +        ]]></body>
  1.1737 +      </method>
  1.1738 +
  1.1739 +      <method name="onInstallFailed">
  1.1740 +        <body><![CDATA[
  1.1741 +            this._updateState();
  1.1742 +        ]]></body>
  1.1743 +      </method>
  1.1744 +
  1.1745 +      <method name="onInstallCancelled">
  1.1746 +        <body><![CDATA[
  1.1747 +            this._updateState();
  1.1748 +        ]]></body>
  1.1749 +      </method>
  1.1750 +    </implementation>
  1.1751 +
  1.1752 +    <handlers>
  1.1753 +      <handler event="click" button="0"><![CDATA[
  1.1754 +        switch (event.detail) {
  1.1755 +        case 1:
  1.1756 +          // Prevent double-click where the UI changes on the first click
  1.1757 +          this._lastClickTarget = event.originalTarget;
  1.1758 +          break;
  1.1759 +        case 2:
  1.1760 +          if (event.originalTarget.localName != 'button' &&
  1.1761 +              !event.originalTarget.classList.contains('text-link') &&
  1.1762 +              event.originalTarget == this._lastClickTarget) {
  1.1763 +            this.showInDetailView();
  1.1764 +          }
  1.1765 +          break;
  1.1766 +        }
  1.1767 +      ]]></handler>
  1.1768 +    </handlers>
  1.1769 +  </binding>
  1.1770 +
  1.1771 +
  1.1772 +  <!-- Addon - uninstalled - An uninstalled addon that can be re-installed. -->
  1.1773 +  <binding id="addon-uninstalled"
  1.1774 +           extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
  1.1775 +    <content>
  1.1776 +      <xul:hbox class="pending">
  1.1777 +        <xul:image class="pending-icon"/>
  1.1778 +        <xul:label anonid="notice" flex="1"/>
  1.1779 +        <xul:button anonid="restart-btn" class="button-link"
  1.1780 +                    label="&addon.restartNow.label;"
  1.1781 +                    command="cmd_restartApp"/>
  1.1782 +        <xul:button anonid="undo-btn" class="button-link"
  1.1783 +                    label="&addon.undoRemove.label;"
  1.1784 +                    tooltiptext="&addon.undoRemove.tooltip;"
  1.1785 +                    oncommand="document.getBindingParent(this).cancelUninstall();"/>
  1.1786 +        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
  1.1787 +      </xul:hbox>
  1.1788 +    </content>
  1.1789 +
  1.1790 +    <implementation>
  1.1791 +      <constructor><![CDATA[
  1.1792 +        this._notice.textContent = gStrings.ext.formatStringFromName("uninstallNotice",
  1.1793 +                                                                     [this.mAddon.name],
  1.1794 +                                                                     1);
  1.1795 +
  1.1796 +        if (!this.isPending("uninstall"))
  1.1797 +          this._restartBtn.setAttribute("hidden", true);
  1.1798 +
  1.1799 +        gEventManager.registerAddonListener(this, this.mAddon.id);
  1.1800 +      ]]></constructor>
  1.1801 +
  1.1802 +      <destructor><![CDATA[
  1.1803 +        gEventManager.unregisterAddonListener(this, this.mAddon.id);
  1.1804 +      ]]></destructor>
  1.1805 +
  1.1806 +      <field name="_notice" readonly="true">
  1.1807 +        document.getAnonymousElementByAttribute(this, "anonid", "notice");
  1.1808 +      </field>
  1.1809 +      <field name="_restartBtn" readonly="true">
  1.1810 +        document.getAnonymousElementByAttribute(this, "anonid", "restart-btn");
  1.1811 +      </field>
  1.1812 +
  1.1813 +      <method name="cancelUninstall">
  1.1814 +        <body><![CDATA[
  1.1815 +          // This assumes that disabling does not require a restart when
  1.1816 +          // uninstalling doesn't. Things will still work if not, the add-on
  1.1817 +          // will just still be active until finally getting uninstalled.
  1.1818 +
  1.1819 +          if (this.isPending("uninstall"))
  1.1820 +            this.mAddon.cancelUninstall();
  1.1821 +          else if (this.getAttribute("wasDisabled") != "true")
  1.1822 +            this.mAddon.userDisabled = false;
  1.1823 +
  1.1824 +          this.removeAttribute("pending");
  1.1825 +        ]]></body>
  1.1826 +      </method>
  1.1827 +
  1.1828 +      <method name="onOperationCancelled">
  1.1829 +        <body><![CDATA[
  1.1830 +          if (!this.isPending("uninstall"))
  1.1831 +            this.removeAttribute("pending");
  1.1832 +        ]]></body>
  1.1833 +      </method>
  1.1834 +
  1.1835 +      <method name="onExternalInstall">
  1.1836 +        <parameter name="aAddon"/>
  1.1837 +        <parameter name="aExistingAddon"/>
  1.1838 +        <parameter name="aNeedsRestart"/>
  1.1839 +        <body><![CDATA[
  1.1840 +          if (aExistingAddon.id != this.mAddon.id)
  1.1841 +            return;
  1.1842 +
  1.1843 +          // Make sure any newly installed add-on has the correct disabled state
  1.1844 +          if (this.hasAttribute("wasDisabled"))
  1.1845 +            aAddon.userDisabled = this.getAttribute("wasDisabled") == "true";
  1.1846 +
  1.1847 +          // If the install completed without needing a restart then switch to
  1.1848 +          // using the new Addon
  1.1849 +          if (!aNeedsRestart)
  1.1850 +            this.mAddon = aAddon;
  1.1851 +
  1.1852 +          this.removeAttribute("pending");
  1.1853 +        ]]></body>
  1.1854 +      </method>
  1.1855 +
  1.1856 +      <method name="onInstallStarted">
  1.1857 +        <parameter name="aInstall"/>
  1.1858 +        <body><![CDATA[
  1.1859 +          // Make sure any newly installed add-on has the correct disabled state
  1.1860 +          if (this.hasAttribute("wasDisabled"))
  1.1861 +            aInstall.addon.userDisabled = this.getAttribute("wasDisabled") == "true";
  1.1862 +        ]]></body>
  1.1863 +      </method>
  1.1864 +
  1.1865 +      <method name="onInstallEnded">
  1.1866 +        <parameter name="aInstall"/>
  1.1867 +        <parameter name="aAddon"/>
  1.1868 +        <body><![CDATA[
  1.1869 +          // If the install completed without needing a restart then switch to
  1.1870 +          // using the new Addon
  1.1871 +          if (!(aAddon.pendingOperations & AddonManager.PENDING_INSTALL))
  1.1872 +            this.mAddon = aAddon;
  1.1873 +
  1.1874 +          this.removeAttribute("pending");
  1.1875 +        ]]></body>
  1.1876 +      </method>
  1.1877 +    </implementation>
  1.1878 +  </binding>
  1.1879 +
  1.1880 +
  1.1881 +  <!-- Addon - installing - an addon item that is currently being installed -->
  1.1882 +  <binding id="addon-installing"
  1.1883 +           extends="chrome://mozapps/content/extensions/extensions.xml#addon-base">
  1.1884 +    <content>
  1.1885 +      <xul:hbox anonid="warning-container" class="warning">
  1.1886 +        <xul:image class="warning-icon"/>
  1.1887 +        <xul:label anonid="warning" flex="1"/>
  1.1888 +        <xul:button anonid="warning-link" class="button-link"
  1.1889 +                   oncommand="document.getBindingParent(this).retryInstall();"/>
  1.1890 +        <xul:spacer flex="5000"/> <!-- Necessary to allow the message to wrap -->
  1.1891 +      </xul:hbox>
  1.1892 +      <xul:hbox class="content-container">
  1.1893 +        <xul:vbox class="icon-outer-container">
  1.1894 +          <xul:vbox class="icon-container">
  1.1895 +            <xul:image anonid="icon" class="icon"/>
  1.1896 +          </xul:vbox>
  1.1897 +        </xul:vbox>
  1.1898 +        <xul:vbox class="fade name-outer-container" flex="1">
  1.1899 +          <xul:hbox class="name-container">
  1.1900 +            <xul:label anonid="name" class="name" crop="end"/>
  1.1901 +            <xul:label anonid="version" class="version" hidden="true"/>
  1.1902 +          </xul:hbox>
  1.1903 +        </xul:vbox>
  1.1904 +        <xul:vbox class="install-status-container">
  1.1905 +          <xul:hbox anonid="install-status" class="install-status"/>
  1.1906 +        </xul:vbox>
  1.1907 +      </xul:hbox>
  1.1908 +    </content>
  1.1909 +
  1.1910 +    <implementation>
  1.1911 +      <constructor><![CDATA[
  1.1912 +        this._installStatus.mControl = this;
  1.1913 +        this._installStatus.mInstall = this.mInstall;
  1.1914 +        this.refreshInfo();
  1.1915 +      ]]></constructor>
  1.1916 +
  1.1917 +      <field name="_icon">
  1.1918 +        document.getAnonymousElementByAttribute(this, "anonid", "icon");
  1.1919 +      </field>
  1.1920 +      <field name="_name">
  1.1921 +        document.getAnonymousElementByAttribute(this, "anonid", "name");
  1.1922 +      </field>
  1.1923 +      <field name="_version">
  1.1924 +        document.getAnonymousElementByAttribute(this, "anonid", "version");
  1.1925 +      </field>
  1.1926 +      <field name="_warning">
  1.1927 +        document.getAnonymousElementByAttribute(this, "anonid", "warning");
  1.1928 +      </field>
  1.1929 +      <field name="_warningLink">
  1.1930 +        document.getAnonymousElementByAttribute(this, "anonid", "warning-link");
  1.1931 +      </field>
  1.1932 +      <field name="_installStatus">
  1.1933 +        document.getAnonymousElementByAttribute(this, "anonid",
  1.1934 +                                                "install-status");
  1.1935 +      </field>
  1.1936 +
  1.1937 +      <method name="onInstallCompleted">
  1.1938 +        <body><![CDATA[
  1.1939 +          this.mAddon = this.mInstall.addon;
  1.1940 +          this.setAttribute("name", this.mAddon.name);
  1.1941 +          this.setAttribute("value", this.mAddon.id);
  1.1942 +          this.setAttribute("status", "installed");
  1.1943 +        ]]></body>
  1.1944 +      </method>
  1.1945 +
  1.1946 +      <method name="refreshInfo">
  1.1947 +        <body><![CDATA[
  1.1948 +          this.mAddon = this.mAddon || this.mInstall.addon;
  1.1949 +          if (this.mAddon) {
  1.1950 +            this._icon.src = this.mAddon.iconURL ||
  1.1951 +                             (this.mInstall ? this.mInstall.iconURL : "");
  1.1952 +            this._name.value = this.mAddon.name;
  1.1953 +
  1.1954 +            if (this.mAddon.version) {
  1.1955 +              this._version.value = this.mAddon.version;
  1.1956 +              this._version.hidden = false;
  1.1957 +            } else {
  1.1958 +              this._version.hidden = true;
  1.1959 +            }
  1.1960 +
  1.1961 +          } else {
  1.1962 +            this._icon.src = this.mInstall.iconURL;
  1.1963 +            // AddonInstall.name isn't always available - fallback to filename
  1.1964 +            if (this.mInstall.name) {
  1.1965 +              this._name.value = this.mInstall.name;
  1.1966 +            } else if (this.mInstall.sourceURI) {
  1.1967 +              var url = Components.classes["@mozilla.org/network/standard-url;1"]
  1.1968 +                                  .createInstance(Components.interfaces.nsIStandardURL);
  1.1969 +              url.init(url.URLTYPE_STANDARD, 80, this.mInstall.sourceURI.spec,
  1.1970 +                       null, null);
  1.1971 +              url.QueryInterface(Components.interfaces.nsIURL);
  1.1972 +              this._name.value = url.fileName;
  1.1973 +            }
  1.1974 +
  1.1975 +            if (this.mInstall.version) {
  1.1976 +              this._version.value = this.mInstall.version;
  1.1977 +              this._version.hidden = false;
  1.1978 +            } else {
  1.1979 +              this._version.hidden = true;
  1.1980 +            }
  1.1981 +          }
  1.1982 +
  1.1983 +          if (this.mInstall.state == AddonManager.STATE_DOWNLOAD_FAILED) {
  1.1984 +            this.setAttribute("notification", "warning");
  1.1985 +            this._warning.textContent = gStrings.ext.formatStringFromName(
  1.1986 +              "notification.downloadError",
  1.1987 +              [this._name.value], 1
  1.1988 +            );
  1.1989 +            this._warningLink.label = gStrings.ext.GetStringFromName("notification.downloadError.retry");
  1.1990 +            this._warningLink.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
  1.1991 +          } else if (this.mInstall.state == AddonManager.STATE_INSTALL_FAILED) {
  1.1992 +            this.setAttribute("notification", "warning");
  1.1993 +            this._warning.textContent = gStrings.ext.formatStringFromName(
  1.1994 +              "notification.installError",
  1.1995 +              [this._name.value], 1
  1.1996 +            );
  1.1997 +            this._warningLink.label = gStrings.ext.GetStringFromName("notification.installError.retry");
  1.1998 +            this._warningLink.tooltipText = gStrings.ext.GetStringFromName("notification.downloadError.retry.tooltip");
  1.1999 +          } else {
  1.2000 +            this.removeAttribute("notification");
  1.2001 +          }
  1.2002 +        ]]></body>
  1.2003 +      </method>
  1.2004 +
  1.2005 +      <method name="retryInstall">
  1.2006 +        <body><![CDATA[
  1.2007 +          this.mInstall.install();
  1.2008 +        ]]></body>
  1.2009 +      </method>
  1.2010 +    </implementation>
  1.2011 +  </binding>
  1.2012 +
  1.2013 +  <binding id="detail-row">
  1.2014 +    <content>
  1.2015 +      <xul:label class="detail-row-label" xbl:inherits="value=label"/>
  1.2016 +      <xul:label class="detail-row-value" xbl:inherits="value"/>
  1.2017 +    </content>
  1.2018 +
  1.2019 +    <implementation>
  1.2020 +      <property name="value">
  1.2021 +        <getter><![CDATA[
  1.2022 +          return this.getAttribute("value");
  1.2023 +        ]]></getter>
  1.2024 +        <setter><![CDATA[
  1.2025 +          if (!val)
  1.2026 +            this.removeAttribute("value");
  1.2027 +          else
  1.2028 +            this.setAttribute("value", val);
  1.2029 +        ]]></setter>
  1.2030 +      </property>
  1.2031 +    </implementation>
  1.2032 +  </binding>
  1.2033 +
  1.2034 +</bindings>

mercurial