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.

163 lines
4.7 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 addMessageListener, removeMessageListener, sendAsyncMessage */
  17. // For non background pages
  18. /******************************************************************************/
  19. (function() {
  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.portName ) {
  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.portName];
  50. listener = channel && channel.listener;
  51. }
  52. if ( typeof listener === 'function' ) {
  53. listener(response.msg);
  54. }
  55. };
  56. /******************************************************************************/
  57. var uniqueId = function() {
  58. return Math.random().toString(36).slice(2);
  59. };
  60. /******************************************************************************/
  61. vAPI.messaging = {
  62. channels: {},
  63. listeners: {},
  64. requestId: 1,
  65. connectorId: uniqueId(),
  66. setup: function() {
  67. this.connector = function(msg) {
  68. messagingConnector(JSON.parse(msg));
  69. };
  70. addMessageListener(this.connectorId, this.connector);
  71. this.channels['vAPI'] = {};
  72. this.channels['vAPI'].listener = function(msg) {
  73. if (msg.cmd === 'injectScript') {
  74. var details = msg.details;
  75. if (!details.allFrames && window !== window.top) {
  76. return;
  77. }
  78. self.injectScript(details.file || details.code, !details.file);
  79. }
  80. };
  81. },
  82. close: function() {
  83. if (this.connector) {
  84. removeMessageListener(this.connectorId, this.connector);
  85. this.connector = null;
  86. this.channels = {};
  87. this.listeners = {};
  88. }
  89. },
  90. channel: function(channelName, callback) {
  91. if ( !channelName ) {
  92. return;
  93. }
  94. this.channels[channelName] = {
  95. portName: channelName,
  96. listener: typeof callback === 'function' ? callback : null,
  97. send: function(message, callback) {
  98. if ( !vAPI.messaging.connector ) {
  99. vAPI.messaging.setup();
  100. }
  101. message = {
  102. portName: vAPI.messaging.connectorId + '|' + this.portName,
  103. msg: message
  104. };
  105. if ( callback ) {
  106. message.requestId = vAPI.messaging.requestId++;
  107. vAPI.messaging.listeners[message.requestId] = callback;
  108. }
  109. sendAsyncMessage('ublock:background', message);
  110. },
  111. close: function() {
  112. delete vAPI.messaging.channels[this.portName];
  113. }
  114. };
  115. return this.channels[channelName];
  116. }
  117. };
  118. /******************************************************************************/
  119. vAPI.canExecuteContentScript = function() {
  120. return true;
  121. };
  122. /******************************************************************************/
  123. })();
  124. /******************************************************************************/