vapi-common.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*******************************************************************************
  2. ηMatrix - a browser extension to black/white list requests.
  3. Copyright (C) 2014-2019 The uMatrix/uBlock Origin authors
  4. Copyright (C) 2019 Alessio Vanni
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see {http://www.gnu.org/licenses/}.
  15. Home: https://gitlab.com/vannilla/ematrix
  16. uMatrix Home: https://github.com/gorhill/uMatrix
  17. */
  18. /* global sendAsyncMessage */
  19. // For background page or non-background pages
  20. 'use strict';
  21. /******************************************************************************/
  22. (function(self) {
  23. /******************************************************************************/
  24. const {Services} = Components.utils.import(
  25. 'resource://gre/modules/Services.jsm',
  26. null
  27. );
  28. // https://bugs.chromium.org/p/project-zero/issues/detail?id=1225&desc=6#c10
  29. if ( self.vAPI === undefined || self.vAPI.eMatrix !== true ) {
  30. self.vAPI = { eMatrix: true };
  31. }
  32. var vAPI = self.vAPI;
  33. /******************************************************************************/
  34. vAPI.setTimeout = vAPI.setTimeout || function(callback, delay, extra) {
  35. return setTimeout(function(a) { callback(a); }, delay, extra);
  36. };
  37. /******************************************************************************/
  38. // http://www.w3.org/International/questions/qa-scripts#directions
  39. var setScriptDirection = function(language) {
  40. document.body.setAttribute(
  41. 'dir',
  42. ['ar', 'he', 'fa', 'ps', 'ur'].indexOf(language) !== -1 ? 'rtl' : 'ltr'
  43. );
  44. };
  45. /******************************************************************************/
  46. vAPI.download = function(details) {
  47. if ( !details.url ) {
  48. return;
  49. }
  50. var a = document.createElement('a');
  51. a.href = details.url;
  52. a.setAttribute('download', details.filename || '');
  53. a.dispatchEvent(new MouseEvent('click'));
  54. };
  55. /******************************************************************************/
  56. vAPI.insertHTML = (function() {
  57. const parser = Components.classes['@mozilla.org/parserutils;1']
  58. .getService(Components.interfaces.nsIParserUtils);
  59. // https://github.com/gorhill/uBlock/issues/845
  60. // Apparently dashboard pages execute with `about:blank` principal.
  61. return function(node, html) {
  62. while ( node.firstChild ) {
  63. node.removeChild(node.firstChild);
  64. }
  65. node.appendChild(parser.parseFragment(
  66. html,
  67. parser.SanitizerAllowStyle,
  68. false,
  69. Services.io.newURI('about:blank', null, null),
  70. document.documentElement
  71. ));
  72. };
  73. })();
  74. /******************************************************************************/
  75. vAPI.getURL = function(path) {
  76. return 'chrome://' + location.host + '/content/' + path.replace(/^\/+/, '');
  77. };
  78. /******************************************************************************/
  79. vAPI.i18n = (function() {
  80. var stringBundle = Services.strings.createBundle(
  81. 'chrome://' + location.host + '/locale/messages.properties'
  82. );
  83. return function(s) {
  84. try {
  85. return stringBundle.GetStringFromName(s);
  86. } catch (ex) {
  87. return '';
  88. }
  89. };
  90. })();
  91. setScriptDirection(navigator.language);
  92. /******************************************************************************/
  93. vAPI.closePopup = function() {
  94. sendAsyncMessage(location.host + ':closePopup');
  95. };
  96. /******************************************************************************/
  97. // A localStorage-like object which should be accessible from the
  98. // background page or auxiliary pages.
  99. // This storage is optional, but it is nice to have, for a more polished user
  100. // experience.
  101. vAPI.localStorage = {
  102. pbName: '',
  103. pb: null,
  104. str: Components.classes['@mozilla.org/supports-string;1']
  105. .createInstance(Components.interfaces.nsISupportsString),
  106. init: function(pbName) {
  107. this.pbName = pbName;
  108. this.pb = Services.prefs.getBranch(pbName);
  109. },
  110. getItem: function(key) {
  111. try {
  112. return this.pb.getComplexValue(
  113. key,
  114. Components.interfaces.nsISupportsString
  115. ).data;
  116. } catch (ex) {
  117. return null;
  118. }
  119. },
  120. setItem: function(key, value) {
  121. this.str.data = value;
  122. this.pb.setComplexValue(
  123. key,
  124. Components.interfaces.nsISupportsString,
  125. this.str
  126. );
  127. },
  128. getBool: function(key) {
  129. try {
  130. return this.pb.getBoolPref(key);
  131. } catch (ex) {
  132. return null;
  133. }
  134. },
  135. setBool: function(key, value) {
  136. this.pb.setBoolPref(key, value);
  137. },
  138. setDefaultBool: function(key, defaultValue) {
  139. Services.prefs.getDefaultBranch(this.pbName).setBoolPref(key, defaultValue);
  140. },
  141. removeItem: function(key) {
  142. this.pb.clearUserPref(key);
  143. },
  144. clear: function() {
  145. this.pb.deleteBranch('');
  146. }
  147. };
  148. vAPI.localStorage.init('extensions.' + location.host + '.');
  149. /******************************************************************************/
  150. })(this);
  151. /******************************************************************************/