You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
5.4 KiB

  1. /*******************************************************************************
  2. µBlock - a Chromium browser extension to block requests.
  3. Copyright (C) 2014 The µBlock authors
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see {http://www.gnu.org/licenses/}.
  14. Home: https://github.com/gorhill/uBlock
  15. */
  16. /* global Services */
  17. // For background page
  18. /******************************************************************************/
  19. (function() {
  20. 'use strict';
  21. /******************************************************************************/
  22. const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
  23. Cu['import']('resource://gre/modules/Services.jsm');
  24. /******************************************************************************/
  25. self.vAPI = self.vAPI || {};
  26. vAPI.firefox = true;
  27. /******************************************************************************/
  28. vAPI.messaging = {
  29. gmm: Cc['@mozilla.org/globalmessagemanager;1'].getService(Ci.nsIMessageListenerManager),
  30. frameScript: 'chrome://ublock/content/frameScript.js',
  31. listeners: {},
  32. defaultHandler: null,
  33. NOOPFUNC: function(){},
  34. UNHANDLED: 'vAPI.messaging.notHandled'
  35. };
  36. /******************************************************************************/
  37. vAPI.messaging.gmm.loadFrameScript(vAPI.messaging.frameScript, true);
  38. /******************************************************************************/
  39. vAPI.messaging.listen = function(listenerName, callback) {
  40. this.listeners[listenerName] = callback;
  41. };
  42. /******************************************************************************/
  43. vAPI.messaging.onMessage = function(request) {
  44. var messageManager = request.target.messageManager;
  45. var listenerId = request.data.portName.split('|');
  46. var portName = listenerId[1];
  47. listenerId = listenerId[0];
  48. var callback = vAPI.messaging.NOOPFUNC;
  49. if ( request.data.requestId !== undefined ) {
  50. callback = function(response) {
  51. messageManager.sendAsyncMessage(
  52. listenerId,
  53. JSON.stringify({
  54. requestId: request.data.requestId,
  55. portName: portName,
  56. msg: response !== undefined ? response : null
  57. })
  58. );
  59. };
  60. }
  61. // TODO:
  62. var sender = {
  63. tab: {
  64. id: 0
  65. }
  66. };
  67. // Specific handler
  68. var r = vAPI.messaging.UNHANDLED;
  69. var listener = vAPI.messaging.listeners[portName];
  70. if ( typeof listener === 'function' ) {
  71. r = listener(request.data.msg, sender, callback);
  72. }
  73. if ( r !== vAPI.messaging.UNHANDLED ) {
  74. return;
  75. }
  76. // Default handler
  77. r = vAPI.messaging.defaultHandler(request.data.msg, sender, callback);
  78. if ( r !== vAPI.messaging.UNHANDLED ) {
  79. return;
  80. }
  81. console.error('µBlock> messaging > unknown request: %o', request.data);
  82. // Unhandled:
  83. // Need to callback anyways in case caller expected an answer, or
  84. // else there is a memory leak on caller's side
  85. callback();
  86. };
  87. /******************************************************************************/
  88. vAPI.messaging.setup = function(defaultHandler) {
  89. // Already setup?
  90. if ( this.defaultHandler !== null ) {
  91. return;
  92. }
  93. if ( typeof defaultHandler !== 'function' ) {
  94. defaultHandler = function(){ return vAPI.messaging.UNHANDLED; };
  95. }
  96. this.defaultHandler = defaultHandler;
  97. this.gmm.addMessageListener(vAPI.app.name + ':background', this.onMessage);
  98. };
  99. /******************************************************************************/
  100. vAPI.messaging.broadcast = function(msg) {
  101. this.gmm.broadcastAsyncMessage(vAPI.app.name + ':broadcast', msg);
  102. };
  103. /******************************************************************************/
  104. vAPI.lastError = function() {
  105. return null;
  106. };
  107. /******************************************************************************/
  108. // clean up when the extension is disabled
  109. window.addEventListener('unload', function() {
  110. vAPI.messaging.gmm.removeMessageListener(
  111. app.name + ':background',
  112. vAPI.messaging.postMessage
  113. );
  114. vAPI.messaging.gmm.removeDelayedFrameScript(vAPI.messaging.frameScript);
  115. // close extension tabs
  116. var enumerator = Services.wm.getEnumerator('navigator:browser');
  117. var host = 'ublock';
  118. var gBrowser, tabs, i, extURI;
  119. while (enumerator.hasMoreElements()) {
  120. gBrowser = enumerator.getNext().gBrowser;
  121. tabs = gBrowser.tabs;
  122. i = tabs.length;
  123. while (i--) {
  124. extURI = tabs[i].linkedBrowser.currentURI;
  125. if (extURI.scheme === 'chrome' && extURI.host === host) {
  126. gBrowser.removeTab(tabs[i]);
  127. }
  128. }
  129. }
  130. });
  131. /******************************************************************************/
  132. })();
  133. /******************************************************************************/