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.

165 lines
4.7 KiB

  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() {
  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. return;
  85. }
  86. removeMessageListener(this.connectorId, this.connector);
  87. this.connector = null;
  88. this.channels = {};
  89. this.listeners = {};
  90. },
  91. channel: function(channelName, callback) {
  92. if ( !channelName ) {
  93. return;
  94. }
  95. this.channels[channelName] = {
  96. portName: channelName,
  97. listener: typeof callback === 'function' ? callback : null,
  98. send: function(message, callback) {
  99. if ( !vAPI.messaging.connector ) {
  100. vAPI.messaging.setup();
  101. }
  102. message = {
  103. portName: vAPI.messaging.connectorId + '|' + this.portName,
  104. msg: message
  105. };
  106. if ( callback ) {
  107. message.requestId = vAPI.messaging.requestId++;
  108. vAPI.messaging.listeners[message.requestId] = callback;
  109. }
  110. sendAsyncMessage('ublock:background', message);
  111. },
  112. close: function() {
  113. delete vAPI.messaging.channels[this.portName];
  114. }
  115. };
  116. return this.channels[channelName];
  117. }
  118. };
  119. /******************************************************************************/
  120. vAPI.canExecuteContentScript = function() {
  121. return true;
  122. };
  123. /******************************************************************************/
  124. })();
  125. /******************************************************************************/