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.

192 lines
5.3 KiB

10 years ago
10 years ago
10 years ago
10 years ago
  1. /*******************************************************************************
  2. µBlock - a 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 addMessageListener, removeMessageListener, sendAsyncMessage */
  17. // For non background pages
  18. /******************************************************************************/
  19. (function(self) {
  20. 'use strict';
  21. /******************************************************************************/
  22. self.vAPI = self.vAPI || {};
  23. vAPI.firefox = true;
  24. /******************************************************************************/
  25. var messagingConnector = function(response) {
  26. if ( !response ) {
  27. return;
  28. }
  29. var channels = vAPI.messaging.channels;
  30. var channel, listener;
  31. if ( response.broadcast === true && !response.channelName ) {
  32. for ( channel in channels ) {
  33. if ( channels.hasOwnProperty(channel) === false ) {
  34. continue;
  35. }
  36. listener = channels[channel].listener;
  37. if ( typeof listener === 'function' ) {
  38. listener(response.msg);
  39. }
  40. }
  41. return;
  42. }
  43. if ( response.requestId ) {
  44. listener = vAPI.messaging.listeners[response.requestId];
  45. delete vAPI.messaging.listeners[response.requestId];
  46. delete response.requestId;
  47. }
  48. if ( !listener ) {
  49. channel = channels[response.channelName];
  50. listener = channel && channel.listener;
  51. }
  52. if ( typeof listener === 'function' ) {
  53. listener(response.msg);
  54. }
  55. };
  56. /******************************************************************************/
  57. vAPI.messaging = {
  58. channels: {},
  59. listeners: {},
  60. requestId: 1,
  61. setup: function() {
  62. this.connector = function(msg) {
  63. messagingConnector(JSON.parse(msg));
  64. };
  65. addMessageListener(this.connector);
  66. this.channels['vAPI'] = {};
  67. this.channels['vAPI'].listener = function(msg) {
  68. if ( msg.cmd === 'injectScript' ) {
  69. var details = msg.details;
  70. if ( !details.allFrames && window !== window.top ) {
  71. return;
  72. }
  73. self.injectScript(details.file || details.code, !details.file);
  74. }
  75. };
  76. },
  77. close: function() {
  78. if ( !this.connector ) {
  79. return;
  80. }
  81. removeMessageListener();
  82. this.connector = null;
  83. this.channels = {};
  84. this.listeners = {};
  85. },
  86. channel: function(channelName, callback) {
  87. if ( !channelName ) {
  88. return;
  89. }
  90. this.channels[channelName] = {
  91. channelName: channelName,
  92. listener: typeof callback === 'function' ? callback : null,
  93. send: function(message, callback) {
  94. if ( !vAPI.messaging.connector ) {
  95. vAPI.messaging.setup();
  96. }
  97. message = {
  98. channelName: self._sandboxId_ + '|' + this.channelName,
  99. msg: message
  100. };
  101. if ( callback ) {
  102. message.requestId = vAPI.messaging.requestId++;
  103. vAPI.messaging.listeners[message.requestId] = callback;
  104. }
  105. sendAsyncMessage('ublock:background', message);
  106. },
  107. close: function() {
  108. delete vAPI.messaging.channels[this.channelName];
  109. }
  110. };
  111. return this.channels[channelName];
  112. }
  113. };
  114. /******************************************************************************/
  115. var toggleListener = function({type, persisted}) {
  116. if ( !vAPI.messaging.connector ) {
  117. return;
  118. }
  119. if ( type === 'pagehide' ) {
  120. removeMessageListener();
  121. return;
  122. }
  123. if ( persisted ) {
  124. addMessageListener(vAPI.messaging.connector);
  125. }
  126. };
  127. window.addEventListener('pagehide', toggleListener, true);
  128. window.addEventListener('pageshow', toggleListener, true);
  129. /******************************************************************************/
  130. vAPI.canExecuteContentScript = function() {
  131. return true;
  132. };
  133. /******************************************************************************/
  134. vAPI.getUrlNormalizer = function() {
  135. return {
  136. get href() {
  137. return this._url || '';
  138. },
  139. set href(url) {
  140. this._url = _urlNormalizer_(url, document.baseURI);
  141. }
  142. };
  143. };
  144. /******************************************************************************/
  145. })(this);
  146. /******************************************************************************/