toolkit/mozapps/extensions/content/extensions.xml

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial