toolkit/content/widgets/notification.xml

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

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

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

     1 <?xml version="1.0"?>
     2 <!-- This Source Code Form is subject to the terms of the Mozilla Public
     3    - License, v. 2.0. If a copy of the MPL was not distributed with this
     4    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
     7 <!DOCTYPE bindings [
     8 <!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd">
     9 %notificationDTD;
    10 ]>
    12 <bindings id="notificationBindings"
    13           xmlns="http://www.mozilla.org/xbl"
    14           xmlns:xbl="http://www.mozilla.org/xbl"
    15           xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    17   <binding id="notificationbox">
    18     <content>
    19       <xul:stack xbl:inherits="hidden=notificationshidden"
    20                  class="notificationbox-stack">
    21         <xul:spacer/>
    22         <children includes="notification"/>
    23       </xul:stack>
    24       <children/>
    25     </content>
    27     <implementation>
    28       <field name="PRIORITY_INFO_LOW" readonly="true">1</field>
    29       <field name="PRIORITY_INFO_MEDIUM" readonly="true">2</field>
    30       <field name="PRIORITY_INFO_HIGH" readonly="true">3</field>
    31       <field name="PRIORITY_WARNING_LOW" readonly="true">4</field>
    32       <field name="PRIORITY_WARNING_MEDIUM" readonly="true">5</field>
    33       <field name="PRIORITY_WARNING_HIGH" readonly="true">6</field>
    34       <field name="PRIORITY_CRITICAL_LOW" readonly="true">7</field>
    35       <field name="PRIORITY_CRITICAL_MEDIUM" readonly="true">8</field>
    36       <field name="PRIORITY_CRITICAL_HIGH" readonly="true">9</field>
    37       <field name="PRIORITY_CRITICAL_BLOCK" readonly="true">10</field>
    39       <field name="currentNotification">null</field>
    41       <field name="_closedNotification">null</field>
    42       <field name="_blockingCanvas">null</field>
    43       <field name="_animating">false</field>
    45       <property name="notificationsHidden"
    46                 onget="return this.getAttribute('notificationshidden') == 'true';">
    47         <setter>
    48           if (val)
    49             this.setAttribute('notificationshidden', true);
    50           else this.removeAttribute('notificationshidden');
    51           return val;
    52         </setter>
    53       </property>
    55       <property name="allNotifications" readonly="true">
    56         <getter>
    57         <![CDATA[
    58           var closedNotification = this._closedNotification;
    59           var notifications = this.getElementsByTagName('notification');
    60           return Array.filter(notifications, function(n) n != closedNotification);
    61         ]]>
    62         </getter>
    63       </property>
    65       <method name="getNotificationWithValue">
    66         <parameter name="aValue"/>
    67         <body>
    68           <![CDATA[
    69             var notifications = this.allNotifications;
    70             for (var n = notifications.length - 1; n >= 0; n--) {
    71               if (aValue == notifications[n].getAttribute("value"))
    72                 return notifications[n];
    73             }
    74             return null;
    75           ]]>
    76         </body>
    77       </method>
    79       <method name="appendNotification">
    80         <parameter name="aLabel"/>
    81         <parameter name="aValue"/>
    82         <parameter name="aImage"/>
    83         <parameter name="aPriority"/>
    84         <parameter name="aButtons"/>
    85         <parameter name="aEventCallback"/>
    86         <body>
    87           <![CDATA[
    88             if (aPriority < this.PRIORITY_INFO_LOW ||
    89                 aPriority > this.PRIORITY_CRITICAL_BLOCK)
    90               throw "Invalid notification priority " + aPriority;
    92             // check for where the notification should be inserted according to
    93             // priority. If two are equal, the existing one appears on top.
    94             var notifications = this.allNotifications;
    95             var insertPos = null;
    96             for (var n = notifications.length - 1; n >= 0; n--) {
    97               if (notifications[n].priority < aPriority)
    98                 break;
    99               insertPos = notifications[n];
   100             }
   102             const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
   103             var newitem = document.createElementNS(XULNS, "notification");
   104             newitem.setAttribute("label", aLabel);
   105             newitem.setAttribute("value", aValue);
   106             if (aImage)
   107               newitem.setAttribute("image", aImage);
   108             newitem.eventCallback = aEventCallback;
   110             if (aButtons) {
   111               // The notification-button-default class is added to the button
   112               // with isDefault set to true. If there is no such button, it is
   113               // added to the first button (unless that button has isDefault
   114               // set to false). There cannot be multiple default buttons.
   115               var defaultElem;
   117               for (var b = 0; b < aButtons.length; b++) {
   118                 var button = aButtons[b];
   119                 var buttonElem = document.createElementNS(XULNS, "button");
   120                 buttonElem.setAttribute("label", button.label);
   121                 buttonElem.setAttribute("accesskey", button.accessKey);
   122                 buttonElem.classList.add("notification-button");
   124                 if (button.isDefault ||
   125                     b == 0 && !("isDefault" in button))
   126                   defaultElem = buttonElem;
   128                 newitem.appendChild(buttonElem);
   129                 buttonElem.buttonInfo = button;
   130               }
   132               if (defaultElem)
   133                 defaultElem.classList.add("notification-button-default");
   134             }
   136             newitem.setAttribute("priority", aPriority);
   137             if (aPriority >= this.PRIORITY_CRITICAL_LOW)
   138               newitem.setAttribute("type", "critical");
   139             else if (aPriority <= this.PRIORITY_INFO_HIGH)
   140               newitem.setAttribute("type", "info");
   141             else
   142               newitem.setAttribute("type", "warning");
   144             if (!insertPos) {
   145               newitem.style.position = "fixed";
   146               newitem.style.top = "100%";
   147               newitem.style.marginTop = "-15px";
   148               newitem.style.opacity = "0";
   149             }
   150             this.insertBefore(newitem, insertPos);
   151             if (!insertPos)
   152               this._showNotification(newitem, true);
   154             // Fire event for accessibility APIs
   155             var event = document.createEvent("Events");
   156             event.initEvent("AlertActive", true, true);
   157             newitem.dispatchEvent(event);
   159             return newitem;
   160           ]]>
   161         </body>
   162       </method>
   164       <method name="removeNotification">
   165         <parameter name="aItem"/>
   166         <parameter name="aSkipAnimation"/>
   167         <body>
   168           <![CDATA[
   169             if (aItem == this.currentNotification)
   170               this.removeCurrentNotification(aSkipAnimation);
   171             else if (aItem != this._closedNotification)
   172               this._removeNotificationElement(aItem);
   173             return aItem;
   174           ]]>
   175         </body>
   176       </method>
   178       <method name="_removeNotificationElement">
   179         <parameter name="aChild"/>
   180         <body>
   181           <![CDATA[
   182             if (aChild.eventCallback)
   183               aChild.eventCallback("removed");
   184             this.removeChild(aChild);
   186             // make sure focus doesn't get lost (workaround for bug 570835)
   187             let fm = Components.classes["@mozilla.org/focus-manager;1"]
   188                                .getService(Components.interfaces.nsIFocusManager);
   189             if (!fm.getFocusedElementForWindow(window, false, {}))
   190               fm.moveFocus(window, this, fm.MOVEFOCUS_FORWARD, 0);
   191           ]]>
   192         </body>
   193       </method>
   195       <method name="removeCurrentNotification">
   196         <parameter name="aSkipAnimation"/>
   197         <body>
   198           <![CDATA[
   199             this._showNotification(this.currentNotification, false, aSkipAnimation);
   200           ]]>
   201         </body>
   202       </method>
   204       <method name="removeAllNotifications">
   205         <parameter name="aImmediate"/>
   206         <body>
   207           <![CDATA[
   208             var notifications = this.allNotifications;
   209             for (var n = notifications.length - 1; n >= 0; n--) {
   210               if (aImmediate)
   211                 this._removeNotificationElement(notifications[n]);
   212               else
   213                 this.removeNotification(notifications[n]);
   214             }
   215             this.currentNotification = null;
   217             // Must clear up any currently animating notification
   218             if (aImmediate)
   219               this._finishAnimation();
   220           ]]>
   221         </body>
   222       </method>
   224       <method name="removeTransientNotifications">
   225         <body>
   226           <![CDATA[
   227             var notifications = this.allNotifications;
   228             for (var n = notifications.length - 1; n >= 0; n--) {
   229               var notification = notifications[n];
   230               if (notification.persistence)
   231                 notification.persistence--;
   232               else if (Date.now() > notification.timeout)
   233                 this.removeNotification(notification);
   234             }
   235           ]]>
   236         </body>
   237       </method>
   239       <method name="_showNotification">
   240         <parameter name="aNotification"/>
   241         <parameter name="aSlideIn"/>
   242         <parameter name="aSkipAnimation"/>
   243         <body>
   244           <![CDATA[
   245             this._finishAnimation();
   247             var height = aNotification.boxObject.height;
   248             var skipAnimation = aSkipAnimation || (height == 0);
   250             if (aSlideIn) {
   251               this.currentNotification = aNotification;
   252               aNotification.style.removeProperty("position");
   253               aNotification.style.removeProperty("top");
   254               aNotification.style.removeProperty("margin-top");
   255               aNotification.style.removeProperty("opacity");
   257               if (skipAnimation) {
   258                 this._setBlockingState(this.currentNotification);
   259                 return;
   260               }
   261             }
   262             else {
   263               this._closedNotification = aNotification;
   264               var notifications = this.allNotifications;
   265               var idx = notifications.length - 1;
   266               this.currentNotification = (idx >= 0) ? notifications[idx] : null;
   268               if (skipAnimation) {
   269                 this._removeNotificationElement(this._closedNotification);
   270                 this._closedNotification = null;
   271                 this._setBlockingState(this.currentNotification);
   272                 return;
   273               }
   275               aNotification.style.marginTop = -height + "px";
   276               aNotification.style.opacity = 0;
   277             }
   279             this._animating = true;
   280           ]]>
   281         </body>
   282       </method>
   284       <method name="_finishAnimation">
   285         <body><![CDATA[
   286           if (this._animating) {
   287             this._animating = false;
   288             if (this._closedNotification) {
   289               this._removeNotificationElement(this._closedNotification);
   290               this._closedNotification = null;
   291             }
   292             this._setBlockingState(this.currentNotification);
   293           }
   294         ]]></body>
   295       </method>
   297       <method name="_setBlockingState">
   298         <parameter name="aNotification"/>
   299         <body>
   300           <![CDATA[
   301             var isblock = aNotification &&
   302                           aNotification.priority == this.PRIORITY_CRITICAL_BLOCK;
   303             var canvas = this._blockingCanvas;
   304             if (isblock) {
   305               if (!canvas)
   306                 canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
   307               const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
   308               var content = this.firstChild;
   309               if (!content ||
   310                    content.namespaceURI != XULNS ||
   311                    content.localName != "browser")
   312                 return;
   314               var width = content.boxObject.width;
   315               var height = content.boxObject.height;
   316               content.collapsed = true;
   318               canvas.setAttribute("width", width);
   319               canvas.setAttribute("height", height);
   320               canvas.setAttribute("flex", "1");
   322               this.appendChild(canvas);
   323               this._blockingCanvas = canvas;
   325               var bgcolor = "white";
   326               try {
   327                 var prefService = Components.classes["@mozilla.org/preferences-service;1"].
   328                                     getService(Components.interfaces.nsIPrefBranch);
   329                 bgcolor = prefService.getCharPref("browser.display.background_color");
   331                 var win = content.contentWindow;
   332                 var context = canvas.getContext("2d");
   333                 context.globalAlpha = 0.5;
   334                 context.drawWindow(win, win.scrollX, win.scrollY,
   335                                    width, height, bgcolor);
   336               }
   337               catch(ex) { };
   338             }
   339             else if (canvas) {
   340               canvas.parentNode.removeChild(canvas);
   341               this._blockingCanvas = null;
   342               var content = this.firstChild;
   343               if (content)
   344                 content.collapsed = false;
   345             }
   346           ]]>
   347         </body>
   348       </method>
   350     </implementation>
   352     <handlers>
   353       <handler event="transitionend"><![CDATA[
   354         if (event.target.localName == "notification" &&
   355             event.propertyName == "margin-top")
   356           this._finishAnimation();
   357       ]]></handler>
   358     </handlers>
   360   </binding>
   362   <binding id="notification" role="xul:alert">
   363     <content>
   364       <xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type">
   365         <xul:hbox anonid="details" align="center" flex="1"
   366                   oncommand="this.parentNode.parentNode._doButtonCommand(event);">
   367           <xul:image anonid="messageImage" class="messageImage" xbl:inherits="src=image,type,value"/>
   368           <xul:description anonid="messageText" class="messageText" flex="1" xbl:inherits="xbl:text=label"/>
   369           <xul:spacer flex="1"/>
   370           <children/>
   371         </xul:hbox>
   372         <xul:toolbarbutton ondblclick="event.stopPropagation();"
   373                            class="messageCloseButton close-icon tabbable"
   374                            xbl:inherits="hidden=hideclose"
   375                            tooltiptext="&closeNotification.tooltip;"
   376                            oncommand="document.getBindingParent(this).close();"/>
   377       </xul:hbox>
   378     </content>
   379     <resources>
   380       <stylesheet src="chrome://global/skin/notification.css"/>
   381     </resources>
   382     <implementation>
   383       <property name="label" onset="this.setAttribute('label', val); return val;"
   384                              onget="return this.getAttribute('label');"/>
   385       <property name="value" onset="this.setAttribute('value', val); return val;"
   386                              onget="return this.getAttribute('value');"/>
   387       <property name="image" onset="this.setAttribute('image', val); return val;"
   388                              onget="return this.getAttribute('image');"/>
   389       <property name="type" onset="this.setAttribute('type', val); return val;"
   390                             onget="return this.getAttribute('type');"/>
   391       <property name="priority" onget="return parseInt(this.getAttribute('priority')) || 0;"
   392                                 onset="this.setAttribute('priority', val); return val;"/>
   393       <property name="persistence" onget="return parseInt(this.getAttribute('persistence')) || 0;"
   394                                    onset="this.setAttribute('persistence', val); return val;"/>
   395       <field name="timeout">0</field>
   397       <property name="control" readonly="true">
   398         <getter>
   399           <![CDATA[
   400             var parent = this.parentNode;
   401             while (parent) {
   402               if (parent.localName == "notificationbox")
   403                 return parent;
   404               parent = parent.parentNode;
   405             }
   406             return null;
   407           ]]>
   408         </getter>
   409       </property>
   411       <method name="close">
   412         <body>
   413           <![CDATA[
   414             var control = this.control;
   415             if (control)
   416               control.removeNotification(this);
   417             else
   418               this.hidden = true;
   419           ]]>
   420         </body>
   421       </method>
   423       <method name="_doButtonCommand">
   424         <parameter name="aEvent"/>
   425         <body>
   426           <![CDATA[
   427             if (!("buttonInfo" in aEvent.target))
   428               return;
   430             var button = aEvent.target.buttonInfo;
   431             if (button.popup) {
   432               document.getElementById(button.popup).
   433                 openPopup(aEvent.originalTarget, "after_start", 0, 0, false, false, aEvent);
   434               aEvent.stopPropagation();
   435             }
   436             else {
   437               var callback = button.callback;
   438               if (callback) {
   439                 var result = callback(this, button);
   440                 if (!result)
   441                   this.close();
   442                 aEvent.stopPropagation();
   443               }
   444             }
   445           ]]>
   446         </body>
   447       </method>
   448     </implementation>
   449   </binding>
   451   <binding id="popup-notification">
   452     <content align="start">
   453       <xul:image class="popup-notification-icon"
   454                  xbl:inherits="popupid,src=icon"/>
   455       <xul:vbox flex="1">
   456         <xul:description class="popup-notification-description"
   457                          xbl:inherits="xbl:text=label"/>
   458         <children includes="popupnotificationcontent"/>
   459         <xul:label class="text-link popup-notification-learnmore-link"
   460                xbl:inherits="href=learnmoreurl">&learnMore;</xul:label>
   461         <xul:spacer flex="1"/>
   462         <xul:hbox class="popup-notification-button-container"
   463                   pack="end" align="center">
   464           <xul:button anonid="button"
   465                       class="popup-notification-menubutton"
   466                       type="menu-button"
   467                       xbl:inherits="oncommand=buttoncommand,label=buttonlabel,accesskey=buttonaccesskey">
   468             <xul:menupopup anonid="menupopup"
   469                            xbl:inherits="oncommand=menucommand">
   470               <children/>
   471               <xul:menuitem class="menuitem-iconic popup-notification-closeitem"
   472                             label="&closeNotificationItem.label;"
   473                             xbl:inherits="oncommand=closeitemcommand,hidden=hidenotnow"/>
   474             </xul:menupopup>
   475           </xul:button>
   476         </xul:hbox>
   477       </xul:vbox>
   478       <xul:vbox pack="start">
   479         <xul:toolbarbutton anonid="closebutton"
   480                            class="messageCloseButton close-icon popup-notification-closebutton tabbable"
   481                            xbl:inherits="oncommand=closebuttoncommand"
   482                            tooltiptext="&closeNotification.tooltip;"/>
   483       </xul:vbox>
   484     </content>
   485     <resources>
   486       <stylesheet src="chrome://global/skin/notification.css"/>
   487     </resources>
   488     <implementation>
   489       <field name="closebutton" readonly="true">
   490         document.getAnonymousElementByAttribute(this, "anonid", "closebutton");
   491       </field>
   492       <field name="button" readonly="true">
   493         document.getAnonymousElementByAttribute(this, "anonid", "button");
   494       </field>
   495       <field name="menupopup" readonly="true">
   496         document.getAnonymousElementByAttribute(this, "anonid", "menupopup");
   497       </field>
   498     </implementation>
   499   </binding>
   500 </bindings>

mercurial