/services/sync/tps/extensions/mozmill/resource/modules/init.js

http://github.com/zpao/v8monkey · JavaScript · 212 lines · 106 code · 30 blank · 76 comment · 14 complexity · 3d71aacca4d0c339b41ec1e8ca02a14b MD5 · raw file

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is Mozilla Corporation Code.
  15. *
  16. * The Initial Developer of the Original Code is
  17. * Adam Christian.
  18. * Portions created by the Initial Developer are Copyright (C) 2008
  19. * the Initial Developer. All Rights Reserved.
  20. *
  21. * Contributor(s):
  22. * Adam Christian <adam.christian@gmail.com>
  23. * Mikeal Rogers <mikeal.rogers@gmail.com>
  24. * Henrik Skupin <hskupin@mozilla.com>
  25. *
  26. * Alternatively, the contents of this file may be used under the terms of
  27. * either the GNU General Public License Version 2 or later (the "GPL"), or
  28. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  29. * in which case the provisions of the GPL or the LGPL are applicable instead
  30. * of those above. If you wish to allow use of your version of this file only
  31. * under the terms of either the GPL or the LGPL, and not to allow others to
  32. * use your version of this file under the terms of the MPL, indicate your
  33. * decision by deleting the provisions above and replace them with the notice
  34. * and other provisions required by the GPL or the LGPL. If you do not delete
  35. * the provisions above, a recipient may use your version of this file under
  36. * the terms of any one of the MPL, the GPL or the LGPL.
  37. *
  38. * ***** END LICENSE BLOCK ***** */
  39. var frame = {}; Components.utils.import('resource://mozmill/modules/frame.js', frame);
  40. /**
  41. * Console listener which listens for error messages in the console and forwards
  42. * them to the Mozmill reporting system for output.
  43. */
  44. function ConsoleListener() {
  45. this.register();
  46. }
  47. ConsoleListener.prototype = {
  48. observe: function(aMessage) {
  49. var msg = aMessage.message;
  50. var re = /^\[.*Error:.*(chrome|resource):\/\/.*/i;
  51. if (msg.match(re)) {
  52. frame.events.fail(aMessage);
  53. }
  54. },
  55. QueryInterface: function (iid) {
  56. if (!iid.equals(Components.interfaces.nsIConsoleListener) && !iid.equals(Components.interfaces.nsISupports)) {
  57. throw Components.results.NS_ERROR_NO_INTERFACE;
  58. }
  59. return this;
  60. },
  61. register: function() {
  62. var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
  63. .getService(Components.interfaces.nsIConsoleService);
  64. aConsoleService.registerListener(this);
  65. },
  66. unregister: function() {
  67. var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"]
  68. .getService(Components.interfaces.nsIConsoleService);
  69. aConsoleService.unregisterListener(this);
  70. }
  71. }
  72. // start listening
  73. var consoleListener = new ConsoleListener();
  74. var EXPORTED_SYMBOLS = ["mozmill"];
  75. const Cc = Components.classes;
  76. const Ci = Components.interfaces;
  77. const Cu = Components.utils;
  78. var mozmill = Cu.import('resource://mozmill/modules/mozmill.js');
  79. // Observer for new top level windows
  80. var windowObserver = {
  81. observe: function(subject, topic, data) {
  82. attachEventListeners(subject);
  83. }
  84. };
  85. /**
  86. * Attach event listeners
  87. */
  88. function attachEventListeners(window) {
  89. // These are the event handlers
  90. function pageShowHandler(event) {
  91. var doc = event.originalTarget;
  92. var tab = window.gBrowser.getBrowserForDocument(doc);
  93. if (tab) {
  94. //log("*** Loaded tab: location=" + doc.location + ", baseURI=" + doc.baseURI + "\n");
  95. tab.mozmillDocumentLoaded = true;
  96. } else {
  97. //log("*** Loaded HTML location=" + doc.location + ", baseURI=" + doc.baseURI + "\n");
  98. doc.defaultView.mozmillDocumentLoaded = true;
  99. }
  100. // We need to add/remove the unload/pagehide event listeners to preserve caching.
  101. window.gBrowser.addEventListener("beforeunload", beforeUnloadHandler, true);
  102. window.gBrowser.addEventListener("pagehide", pageHideHandler, true);
  103. };
  104. var DOMContentLoadedHandler = function(event) {
  105. var errorRegex = /about:.+(error)|(blocked)\?/;
  106. if (errorRegex.exec(event.target.baseURI)) {
  107. // Wait about 1s to be sure the DOM is ready
  108. mozmill.utils.sleep(1000);
  109. var tab = window.gBrowser.getBrowserForDocument(event.target);
  110. if (tab)
  111. tab.mozmillDocumentLoaded = true;
  112. // We need to add/remove the unload event listener to preserve caching.
  113. window.gBrowser.addEventListener("beforeunload", beforeUnloadHandler, true);
  114. }
  115. };
  116. // beforeunload is still needed because pagehide doesn't fire before the page is unloaded.
  117. // still use pagehide for cases when beforeunload doesn't get fired
  118. function beforeUnloadHandler(event) {
  119. var doc = event.originalTarget;
  120. var tab = window.gBrowser.getBrowserForDocument(event.target);
  121. if (tab) {
  122. //log("*** Unload tab: location=" + doc.location + ", baseURI=" + doc.baseURI + "\n");
  123. tab.mozmillDocumentLoaded = false;
  124. } else {
  125. //log("*** Unload HTML location=" + doc.location + ", baseURI=" + doc.baseURI + "\n");
  126. doc.defaultView.mozmillDocumentLoaded = false;
  127. }
  128. window.gBrowser.removeEventListener("beforeunload", beforeUnloadHandler, true);
  129. };
  130. var pageHideHandler = function(event) {
  131. // If event.persisted is false, the beforeUnloadHandler should fire
  132. // and there is no need for this event handler.
  133. if (event.persisted) {
  134. var doc = event.originalTarget;
  135. var tab = window.gBrowser.getBrowserForDocument(event.target);
  136. if (tab) {
  137. //log("*** Unload tab: location=" + doc.location + ", baseURI=" + doc.baseURI + "\n");
  138. tab.mozmillDocumentLoaded = false;
  139. } else {
  140. //log("*** Unload HTML location=" + doc.location + ", baseURI=" + doc.baseURI + "\n");
  141. doc.defaultView.mozmillDocumentLoaded = false;
  142. }
  143. window.gBrowser.removeEventListener("beforeunload", beforeUnloadHandler, true);
  144. }
  145. };
  146. // Add the event handlers to the tabbedbrowser once its window has loaded
  147. window.addEventListener("load", function(event) {
  148. window.mozmillDocumentLoaded = true;
  149. if (window.gBrowser) {
  150. // Page is ready
  151. window.gBrowser.addEventListener("pageshow", pageShowHandler, true);
  152. // Note: Error pages will never fire a "load" event. For those we
  153. // have to wait for the "DOMContentLoaded" event. That's the final state.
  154. // Error pages will always have a baseURI starting with
  155. // "about:" followed by "error" or "blocked".
  156. window.gBrowser.addEventListener("DOMContentLoaded", DOMContentLoadedHandler, true);
  157. // Leave page (use caching)
  158. window.gBrowser.addEventListener("pagehide", pageHideHandler, true);
  159. }
  160. }, false);
  161. }
  162. /**
  163. * Initialize Mozmill
  164. */
  165. function initialize() {
  166. // Activate observer for new top level windows
  167. var observerService = Cc["@mozilla.org/observer-service;1"].
  168. getService(Ci.nsIObserverService);
  169. observerService.addObserver(windowObserver, "toplevel-window-ready", false);
  170. // Attach event listeners to all open windows
  171. var enumerator = Cc["@mozilla.org/appshell/window-mediator;1"].
  172. getService(Ci.nsIWindowMediator).getEnumerator("");
  173. while (enumerator.hasMoreElements()) {
  174. var win = enumerator.getNext();
  175. attachEventListeners(win);
  176. // For windows or dialogs already open we have to explicitly set the property
  177. // otherwise windows which load really quick never gets the property set and
  178. // we fail to create the controller
  179. win.mozmillDocumentLoaded = true;
  180. };
  181. }
  182. initialize();