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.

161 lines
4.4 KiB

10 years ago
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. // For non background pages
  17. /* global self */
  18. /******************************************************************************/
  19. (function() {
  20. 'use strict';
  21. /******************************************************************************/
  22. self.vAPI = self.vAPI || {};
  23. var chrome = self.chrome;
  24. var vAPI = self.vAPI;
  25. // https://github.com/gorhill/uBlock/issues/456
  26. // Already injected?
  27. if ( vAPI.vapiClientInjected ) {
  28. return;
  29. }
  30. vAPI.vapiClientInjected = true;
  31. vAPI.chrome = true;
  32. /******************************************************************************/
  33. var messagingConnector = function(response) {
  34. if ( !response ) {
  35. return;
  36. }
  37. var channels = vAPI.messaging.channels;
  38. var channel, listener;
  39. if ( response.broadcast === true && !response.portName ) {
  40. for ( channel in channels ) {
  41. if ( channels.hasOwnProperty(channel) === false ) {
  42. continue;
  43. }
  44. listener = channels[channel].listener;
  45. if ( typeof listener === 'function' ) {
  46. listener(response.msg);
  47. }
  48. }
  49. return;
  50. }
  51. if ( response.requestId ) {
  52. listener = vAPI.messaging.listeners[response.requestId];
  53. delete vAPI.messaging.listeners[response.requestId];
  54. delete response.requestId;
  55. }
  56. if ( !listener ) {
  57. channel = channels[response.portName];
  58. listener = channel && channel.listener;
  59. }
  60. if ( typeof listener === 'function' ) {
  61. listener(response.msg);
  62. }
  63. };
  64. /******************************************************************************/
  65. var uniqueId = function() {
  66. return Math.random().toString(36).slice(2);
  67. };
  68. /******************************************************************************/
  69. vAPI.messaging = {
  70. port: null,
  71. channels: {},
  72. listeners: {},
  73. requestId: 1,
  74. connectorId: uniqueId(),
  75. setup: function() {
  76. this.port = chrome.runtime.connect({name: this.connectorId});
  77. this.port.onMessage.addListener(messagingConnector);
  78. },
  79. close: function() {
  80. if ( this.port === null ) {
  81. return;
  82. }
  83. this.port.disconnect();
  84. this.port.onMessage.removeListener(messagingConnector);
  85. this.port = null;
  86. this.channels = {};
  87. this.listeners = {};
  88. },
  89. channel: function(channelName, callback) {
  90. if ( !channelName ) {
  91. return;
  92. }
  93. this.channels[channelName] = {
  94. portName: channelName,
  95. listener: typeof callback === 'function' ? callback : null,
  96. send: function(message, callback) {
  97. if ( vAPI.messaging.port === null ) {
  98. vAPI.messaging.setup();
  99. }
  100. message = {
  101. portName: this.portName,
  102. msg: message
  103. };
  104. if ( callback ) {
  105. message.requestId = vAPI.messaging.requestId++;
  106. vAPI.messaging.listeners[message.requestId] = callback;
  107. }
  108. vAPI.messaging.port.postMessage(message);
  109. },
  110. close: function() {
  111. delete vAPI.messaging.channels[this.portName];
  112. }
  113. };
  114. return this.channels[channelName];
  115. }
  116. };
  117. /******************************************************************************/
  118. vAPI.canExecuteContentScript = function() {
  119. return true;
  120. };
  121. /******************************************************************************/
  122. })();
  123. /******************************************************************************/