1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/alerts/resources/content/alert.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,194 @@ 1.4 +// -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +Components.utils.import("resource://gre/modules/Services.jsm"); 1.11 + 1.12 +const Ci = Components.interfaces; 1.13 +const Cc = Components.classes; 1.14 + 1.15 +var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"] 1.16 + .getService(Ci.nsIWindowMediator); 1.17 + 1.18 +// Copied from nsILookAndFeel.h, see comments on eMetric_AlertNotificationOrigin 1.19 +const NS_ALERT_HORIZONTAL = 1; 1.20 +const NS_ALERT_LEFT = 2; 1.21 +const NS_ALERT_TOP = 4; 1.22 + 1.23 +const WINDOW_MARGIN = 10; 1.24 + 1.25 +var gOrigin = 0; // Default value: alert from bottom right. 1.26 +var gReplacedWindow = null; 1.27 +var gAlertListener = null; 1.28 +var gAlertTextClickable = false; 1.29 +var gAlertCookie = ""; 1.30 +var gIsReplaced = false; 1.31 + 1.32 +function prefillAlertInfo() { 1.33 + // unwrap all the args.... 1.34 + // arguments[0] --> the image src url 1.35 + // arguments[1] --> the alert title 1.36 + // arguments[2] --> the alert text 1.37 + // arguments[3] --> is the text clickable? 1.38 + // arguments[4] --> the alert cookie to be passed back to the listener 1.39 + // arguments[5] --> the alert origin reported by the look and feel 1.40 + // arguments[6] --> bidi 1.41 + // arguments[7] --> lang 1.42 + // arguments[8] --> replaced alert window (nsIDOMWindow) 1.43 + // arguments[9] --> an optional callback listener (nsIObserver) 1.44 + 1.45 + switch (window.arguments.length) { 1.46 + default: 1.47 + case 10: 1.48 + gAlertListener = window.arguments[9]; 1.49 + case 9: 1.50 + gReplacedWindow = window.arguments[8]; 1.51 + case 6: 1.52 + gOrigin = window.arguments[5]; 1.53 + case 5: 1.54 + gAlertCookie = window.arguments[4]; 1.55 + case 4: 1.56 + gAlertTextClickable = window.arguments[3]; 1.57 + if (gAlertTextClickable) { 1.58 + document.getElementById('alertNotification').setAttribute('clickable', true); 1.59 + document.getElementById('alertTextLabel').setAttribute('clickable', true); 1.60 + } 1.61 + case 3: 1.62 + document.getElementById('alertTextLabel').textContent = window.arguments[2]; 1.63 + case 2: 1.64 + document.getElementById('alertTitleLabel').setAttribute('value', window.arguments[1]); 1.65 + case 1: 1.66 + if (window.arguments[0]) { 1.67 + document.getElementById('alertImage').setAttribute('src', window.arguments[0]); 1.68 + } 1.69 + case 0: 1.70 + break; 1.71 + } 1.72 +} 1.73 + 1.74 +function onAlertLoad() { 1.75 + const ALERT_DURATION_IMMEDIATE = 4000; 1.76 + let alertTextBox = document.getElementById("alertTextBox"); 1.77 + let alertImageBox = document.getElementById("alertImageBox"); 1.78 + alertImageBox.style.minHeight = alertTextBox.scrollHeight + "px"; 1.79 + 1.80 + sizeToContent(); 1.81 + 1.82 + if (gReplacedWindow && !gReplacedWindow.closed) { 1.83 + moveWindowToReplace(gReplacedWindow); 1.84 + gReplacedWindow.gIsReplaced = true; 1.85 + gReplacedWindow.close(); 1.86 + } else { 1.87 + moveWindowToEnd(); 1.88 + } 1.89 + 1.90 + window.addEventListener("XULAlertClose", function() { window.close(); }); 1.91 + 1.92 + if (Services.prefs.getBoolPref("alerts.disableSlidingEffect")) { 1.93 + setTimeout(function() { window.close(); }, ALERT_DURATION_IMMEDIATE); 1.94 + return; 1.95 + } 1.96 + 1.97 + let alertBox = document.getElementById("alertBox"); 1.98 + alertBox.addEventListener("animationend", function hideAlert(event) { 1.99 + if (event.animationName == "alert-animation") { 1.100 + alertBox.removeEventListener("animationend", hideAlert, false); 1.101 + window.close(); 1.102 + } 1.103 + }, false); 1.104 + alertBox.setAttribute("animate", true); 1.105 + 1.106 + if (gAlertListener) { 1.107 + gAlertListener.observe(null, "alertshow", gAlertCookie); 1.108 + } 1.109 +} 1.110 + 1.111 +function moveWindowToReplace(aReplacedAlert) { 1.112 + let heightDelta = window.outerHeight - aReplacedAlert.outerHeight; 1.113 + 1.114 + // Move windows that come after the replaced alert if the height is different. 1.115 + if (heightDelta != 0) { 1.116 + let windows = windowMediator.getEnumerator('alert:alert'); 1.117 + while (windows.hasMoreElements()) { 1.118 + let alertWindow = windows.getNext(); 1.119 + // boolean to determine if the alert window is after the replaced alert. 1.120 + let alertIsAfter = gOrigin & NS_ALERT_TOP ? 1.121 + alertWindow.screenY > aReplacedAlert.screenY : 1.122 + aReplacedAlert.screenY > alertWindow.screenY; 1.123 + if (alertIsAfter) { 1.124 + // The new Y position of the window. 1.125 + let adjustedY = gOrigin & NS_ALERT_TOP ? 1.126 + alertWindow.screenY + heightDelta : 1.127 + alertWindow.screenY - heightDelta; 1.128 + alertWindow.moveTo(alertWindow.screenX, adjustedY); 1.129 + } 1.130 + } 1.131 + } 1.132 + 1.133 + let adjustedY = gOrigin & NS_ALERT_TOP ? aReplacedAlert.screenY : 1.134 + aReplacedAlert.screenY - heightDelta; 1.135 + window.moveTo(aReplacedAlert.screenX, adjustedY); 1.136 +} 1.137 + 1.138 +function moveWindowToEnd() { 1.139 + // Determine position 1.140 + let x = gOrigin & NS_ALERT_LEFT ? screen.availLeft : 1.141 + screen.availLeft + screen.availWidth - window.outerWidth; 1.142 + let y = gOrigin & NS_ALERT_TOP ? screen.availTop : 1.143 + screen.availTop + screen.availHeight - window.outerHeight; 1.144 + 1.145 + // Position the window at the end of all alerts. 1.146 + let windows = windowMediator.getEnumerator('alert:alert'); 1.147 + while (windows.hasMoreElements()) { 1.148 + let alertWindow = windows.getNext(); 1.149 + if (alertWindow != window) { 1.150 + if (gOrigin & NS_ALERT_TOP) { 1.151 + y = Math.max(y, alertWindow.screenY + alertWindow.outerHeight); 1.152 + } else { 1.153 + y = Math.min(y, alertWindow.screenY - window.outerHeight); 1.154 + } 1.155 + } 1.156 + } 1.157 + 1.158 + // Offset the alert by WINDOW_MARGIN pixels from the edge of the screen 1.159 + y += gOrigin & NS_ALERT_TOP ? WINDOW_MARGIN : -WINDOW_MARGIN; 1.160 + x += gOrigin & NS_ALERT_LEFT ? WINDOW_MARGIN : -WINDOW_MARGIN; 1.161 + 1.162 + window.moveTo(x, y); 1.163 +} 1.164 + 1.165 +function onAlertBeforeUnload() { 1.166 + if (!gIsReplaced) { 1.167 + // Move other alert windows to fill the gap left by closing alert. 1.168 + let heightDelta = window.outerHeight + WINDOW_MARGIN; 1.169 + let windows = windowMediator.getEnumerator('alert:alert'); 1.170 + while (windows.hasMoreElements()) { 1.171 + let alertWindow = windows.getNext(); 1.172 + if (alertWindow != window) { 1.173 + if (gOrigin & NS_ALERT_TOP) { 1.174 + if (alertWindow.screenY > window.screenY) { 1.175 + alertWindow.moveTo(alertWindow.screenX, alertWindow.screenY - heightDelta); 1.176 + } 1.177 + } else { 1.178 + if (window.screenY > alertWindow.screenY) { 1.179 + alertWindow.moveTo(alertWindow.screenX, alertWindow.screenY + heightDelta); 1.180 + } 1.181 + } 1.182 + } 1.183 + } 1.184 + } 1.185 + 1.186 + if (gAlertListener) { 1.187 + gAlertListener.observe(null, "alertfinished", gAlertCookie); 1.188 + } 1.189 +} 1.190 + 1.191 +function onAlertClick() { 1.192 + if (gAlertListener && gAlertTextClickable) { 1.193 + gAlertListener.observe(null, "alertclickcallback", gAlertCookie); 1.194 + } 1.195 + 1.196 + window.close(); 1.197 +}