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.

99 lines
2.6 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(appName + ':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. let readyState = win.document.readyState;
  52. if (readyState === "interactive" || readyState === "complete") {
  53. lss(contentBaseURI + 'contentscript-end.js', win);
  54. }
  55. else {
  56. let docReady = function(e) {
  57. this.removeEventListener(e.type, docReady, true);
  58. lss(contentBaseURI + 'contentscript-end.js', win);
  59. };
  60. win.document.addEventListener('DOMContentLoaded', docReady, true);
  61. }
  62. }
  63. };
  64. Services.obs.addObserver(observer, 'content-document-global-created', false);
  65. let DOMReady = function(e) {
  66. let win = e.target.defaultView;
  67. // inject the message handlers for the options page
  68. if (win.location.protocol === 'chrome:' && win.location.host === appName) {
  69. initContext(win);
  70. }
  71. };
  72. addEventListener('DOMContentLoaded', DOMReady, true);
  73. addEventListener('unload', function() {
  74. Services.obs.removeObserver(observer, 'content-document-global-created');
  75. observer = listeners = null;
  76. }, false);
  77. })();