Status4Evar.jsm 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. "use strict";
  5. const EXPORTED_SYMBOLS = ["Status4Evar"];
  6. const CC = Components.classes;
  7. const CI = Components.interfaces;
  8. const CU = Components.utils;
  9. const s4e_service = CC["@caligonstudios.com/status4evar;1"].getService(CI.nsIStatus4Evar);
  10. CU.import("resource://gre/modules/Services.jsm");
  11. CU.import("resource://gre/modules/XPCOMUtils.jsm");
  12. CU.import("resource://gre/modules/AddonManager.jsm");
  13. CU.import("resource:///modules/statusbar/Status.jsm");
  14. CU.import("resource:///modules/statusbar/Progress.jsm");
  15. CU.import("resource:///modules/statusbar/Downloads.jsm");
  16. CU.import("resource:///modules/statusbar/Toolbars.jsm");
  17. function Status4Evar(window, gBrowser, toolbox)
  18. {
  19. this._window = window;
  20. this._toolbox = toolbox;
  21. this.getters = new S4EWindowGetters(this._window);
  22. this.toolbars = new S4EToolbars(this._window, gBrowser, this._toolbox, s4e_service, this.getters);
  23. this.statusService = new S4EStatusService(this._window, s4e_service, this.getters);
  24. this.progressMeter = new S4EProgressService(gBrowser, s4e_service, this.getters, this.statusService);
  25. this.downloadStatus = new S4EDownloadService(this._window, gBrowser, s4e_service, this.getters);
  26. this.sizeModeService = new SizeModeService(this._window, gBrowser, this);
  27. this._window.addEventListener("unload", this, false);
  28. }
  29. Status4Evar.prototype =
  30. {
  31. _window: null,
  32. _toolbox: null,
  33. getters: null,
  34. toolbars: null,
  35. statusService: null,
  36. progressMeter: null,
  37. downloadStatus: null,
  38. sizeModeService: null,
  39. setup: function()
  40. {
  41. this._toolbox.addEventListener("beforecustomization", this, false);
  42. this._toolbox.addEventListener("aftercustomization", this, false);
  43. this.toolbars.setup();
  44. this.updateWindow();
  45. // OMFG HAX! If a page is already loading, fake a network start event
  46. if(this._window.XULBrowserWindow._busyUI)
  47. {
  48. let nsIWPL = CI.nsIWebProgressListener;
  49. this.progressMeter.onStateChange(0, null, nsIWPL.STATE_START | nsIWPL.STATE_IS_NETWORK, 0);
  50. }
  51. },
  52. destroy: function()
  53. {
  54. this._window.removeEventListener("unload", this, false);
  55. this._toolbox.removeEventListener("aftercustomization", this, false);
  56. this._toolbox.removeEventListener("beforecustomization", this, false);
  57. this.getters.destroy();
  58. this.statusService.destroy();
  59. this.downloadStatus.destroy();
  60. this.progressMeter.destroy();
  61. this.toolbars.destroy();
  62. this.sizeModeService.destroy();
  63. ["_window", "_toolbox", "getters", "statusService", "downloadStatus",
  64. "progressMeter", "toolbars", "sizeModeService"].forEach(function(prop)
  65. {
  66. delete this[prop];
  67. }, this);
  68. },
  69. handleEvent: function(aEvent)
  70. {
  71. switch(aEvent.type)
  72. {
  73. case "unload":
  74. this.destroy();
  75. break;
  76. case "beforecustomization":
  77. this.beforeCustomization();
  78. break;
  79. case "aftercustomization":
  80. this.updateWindow();
  81. break;
  82. }
  83. },
  84. beforeCustomization: function()
  85. {
  86. this.toolbars.updateSplitters(false);
  87. this.toolbars.updateWindowGripper(false);
  88. this.statusService.setNoUpdate(true);
  89. let status_label = this.getters.statusWidgetLabel;
  90. if(status_label)
  91. {
  92. status_label.value = this.getters.strings.getString("statusText");
  93. }
  94. this.downloadStatus.customizing(true);
  95. },
  96. updateWindow: function()
  97. {
  98. this.statusService.setNoUpdate(false);
  99. this.getters.resetGetters();
  100. this.statusService.buildTextOrder();
  101. this.statusService.buildBinding();
  102. this.downloadStatus.init();
  103. this.downloadStatus.customizing(false);
  104. this.toolbars.updateSplitters(true);
  105. s4e_service.updateWindow(this._window);
  106. // This also handles the following:
  107. // * buildTextOrder()
  108. // * updateStatusField(true)
  109. // * updateWindowGripper(true)
  110. },
  111. launchOptions: function(currentWindow)
  112. {
  113. let optionsURL = "chrome://browser/content/statusbar/prefs.xul";
  114. let windows = Services.wm.getEnumerator(null);
  115. while (windows.hasMoreElements())
  116. {
  117. let win = windows.getNext();
  118. if (win.document.documentURI == optionsURL)
  119. {
  120. win.focus();
  121. return;
  122. }
  123. }
  124. let features = "chrome,titlebar,toolbar,centerscreen";
  125. try
  126. {
  127. let instantApply = Services.prefs.getBoolPref("browser.preferences.instantApply");
  128. features += instantApply ? ",dialog=no" : ",modal";
  129. }
  130. catch(e)
  131. {
  132. features += ",modal";
  133. }
  134. currentWindow.openDialog(optionsURL, "", features);
  135. }
  136. };
  137. function S4EWindowGetters(window)
  138. {
  139. this._window = window;
  140. }
  141. S4EWindowGetters.prototype =
  142. {
  143. _window: null,
  144. _getterMap:
  145. [
  146. ["addonbar", "addon-bar"],
  147. ["addonbarCloseButton", "addonbar-closebutton"],
  148. ["browserBottomBox", "browser-bottombox"],
  149. ["downloadButton", "status4evar-download-button"],
  150. ["downloadButtonTooltip", "status4evar-download-tooltip"],
  151. ["downloadButtonProgress", "status4evar-download-progress-bar"],
  152. ["downloadButtonLabel", "status4evar-download-label"],
  153. ["downloadButtonAnchor", "status4evar-download-anchor"],
  154. ["downloadNotifyAnchor", "status4evar-download-notification-anchor"],
  155. ["statusBar", "status4evar-status-bar"],
  156. ["statusWidget", "status4evar-status-widget"],
  157. ["statusWidgetLabel", "status4evar-status-text"],
  158. ["strings", "bundle_status4evar"],
  159. ["throbberProgress", "status4evar-throbber-widget"],
  160. ["toolbarProgress", "status4evar-progress-bar"]
  161. ],
  162. resetGetters: function()
  163. {
  164. let document = this._window.document;
  165. this._getterMap.forEach(function(getter)
  166. {
  167. let [prop, id] = getter;
  168. delete this[prop];
  169. this.__defineGetter__(prop, function()
  170. {
  171. delete this[prop];
  172. return this[prop] = document.getElementById(id);
  173. });
  174. }, this);
  175. delete this.statusOverlay;
  176. this.__defineGetter__("statusOverlay", function()
  177. {
  178. let so = this._window.XULBrowserWindow.statusTextField;
  179. if(!so)
  180. {
  181. return null;
  182. }
  183. delete this.statusOverlay;
  184. return this.statusOverlay = so;
  185. });
  186. },
  187. destroy: function()
  188. {
  189. this._getterMap.forEach(function(getter)
  190. {
  191. let [prop, id] = getter;
  192. delete this[prop];
  193. }, this);
  194. ["statusOverlay", "statusOverlay", "_window"].forEach(function(prop)
  195. {
  196. delete this[prop];
  197. }, this);
  198. }
  199. };
  200. function SizeModeService(window, gBrowser, s4e)
  201. {
  202. this._window = window;
  203. this._gBrowser = gBrowser;
  204. this._s4e = s4e;
  205. this._mm = this._window.messageManager;
  206. this.lastFullScreen = this._window.fullScreen;
  207. this.lastwindowState = this._window.windowState;
  208. if(s4e_service.advancedStatusDetectFullScreen)
  209. {
  210. this._mm.addMessageListener("status4evar@caligonstudios.com:video-detect-answer", this)
  211. this._mm.loadFrameScript("resource:///modules/statusbar/content-thunk.js", true);
  212. }
  213. this._window.addEventListener("sizemodechange", this, false);
  214. }
  215. SizeModeService.prototype =
  216. {
  217. _window: null,
  218. _gBrowser: null,
  219. _s4e: null,
  220. _mm: null,
  221. lastFullScreen: null,
  222. lastwindowState: null,
  223. destroy: function()
  224. {
  225. this._window.removeEventListener("sizemodechange", this, false);
  226. if(s4e_service.advancedStatusDetectFullScreen)
  227. {
  228. this._mm.removeDelayedFrameScript("resource:///modules/statusbar/content-thunk.js");
  229. this._mm.removeMessageListener("status4evar@caligonstudios.com:video-detect-answer", this);
  230. }
  231. ["_window", "_gBrowser", "_s4e", "_mm"].forEach(function(prop)
  232. {
  233. delete this[prop];
  234. }, this);
  235. },
  236. handleEvent: function(e)
  237. {
  238. if(this._window.fullScreen != this.lastFullScreen && s4e_service.advancedStatusDetectFullScreen)
  239. {
  240. this.lastFullScreen = this._window.fullScreen;
  241. if(this.lastFullScreen && s4e_service.advancedStatusDetectVideo)
  242. {
  243. this._gBrowser.selectedBrowser.messageManager.sendAsyncMessage("status4evar@caligonstudios.com:video-detect");
  244. }
  245. else
  246. {
  247. this._s4e.statusService.setFullScreenState(this.lastFullScreen, false);
  248. }
  249. }
  250. if(this._window.windowState != this.lastwindowState)
  251. {
  252. this.lastwindowState = this._window.windowState;
  253. this._s4e.toolbars.updateWindowGripper(true);
  254. }
  255. },
  256. receiveMessage: function(message)
  257. {
  258. if(message.name == "status4evar@caligonstudios.com:video-detect-answer")
  259. {
  260. this._s4e.statusService.setFullScreenState(this.lastFullScreen, message.data.isVideo);
  261. }
  262. },
  263. QueryInterface: XPCOMUtils.generateQI([ CI.nsIDOMEventListener, CI.nsIMessageListener ])
  264. };