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.

97 lines
2.5 KiB

  1. /* globals Services, sendAsyncMessage, addMessageListener, removeMessageListener, content */
  2. (function() {
  3. 'use strict';
  4. let appName = 'ublock';
  5. let contentBaseURI = 'chrome://' + appName + '/content/js/';
  6. let listeners = {};
  7. let _addMessageListener = function(id, fn) {
  8. _removeMessageListener(id);
  9. listeners[id] = function(msg) {
  10. fn(msg.data);
  11. };
  12. addMessageListener(id, listeners[id]);
  13. };
  14. let _removeMessageListener = function(id) {
  15. if (listeners[id]) {
  16. removeMessageListener(id, listeners[id]);
  17. }
  18. delete listeners[id];
  19. };
  20. addMessageListener('µBlock:broadcast', function(msg) {
  21. for (let id in listeners) {
  22. listeners[id](msg);
  23. }
  24. });
  25. let initContext = function(win, sandbox) {
  26. if (sandbox) {
  27. win = Components.utils.Sandbox([win], {
  28. sandboxPrototype: win,
  29. wantComponents: false,
  30. wantXHRConstructor: false
  31. });
  32. }
  33. win.sendAsyncMessage = sendAsyncMessage;
  34. win.addMessageListener = _addMessageListener;
  35. win.removeMessageListener = _removeMessageListener;
  36. return win;
  37. };
  38. let observer = {
  39. observe: function(win) {
  40. if (!win || win.top !== content) {
  41. return;
  42. }
  43. if (!(win.document instanceof win.HTMLDocument
  44. && (/^https?:$/.test(win.location.protocol)))) {
  45. return;
  46. }
  47. let lss = Services.scriptloader.loadSubScript;
  48. win = initContext(win, true);
  49. lss(contentBaseURI + 'vapi-client.js', win);
  50. lss(contentBaseURI + 'contentscript-start.js', win);
  51. if (win.document.readyState === 'loading') {
  52. let docReady = function(e) {
  53. this.removeEventListener(e.type, docReady, true);
  54. lss(contentBaseURI + 'contentscript-end.js', win);
  55. };
  56. win.document.addEventListener('DOMContentLoaded', docReady, true);
  57. }
  58. else {
  59. lss(contentBaseURI + 'contentscript-end.js', win);
  60. }
  61. }
  62. };
  63. Services.obs.addObserver(observer, 'content-document-global-created', false);
  64. let DOMReady = function(e) {
  65. let win = e.target.defaultView;
  66. // inject the message handlers for the options page
  67. if (win.location.protocol === 'chrome:' && win.location.host === appName) {
  68. initContext(win);
  69. }
  70. };
  71. addEventListener('DOMContentLoaded', DOMReady, true);
  72. addEventListener('unload', function() {
  73. Services.obs.removeObserver(observer, 'content-document-global-created');
  74. observer = listeners = null;
  75. }, false);
  76. })();