vapi-browser.js 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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-2022 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. 'use strict';
  19. /******************************************************************************/
  20. (function () {
  21. vAPI.browser = {};
  22. vAPI.browser.getTabBrowser = function (win) {
  23. return win && win.gBrowser || null;
  24. };
  25. vAPI.browser.getOwnerWindow = function (target) {
  26. if (target.ownerDocument) {
  27. return target.ownerDocument.defaultView;
  28. }
  29. return null;
  30. };
  31. vAPI.browser.settings = {
  32. // For now, only booleans.
  33. originalValues: {},
  34. rememberOriginalValue: function (path, setting) {
  35. let key = path + '.' + setting;
  36. if (this.originalValues.hasOwnProperty(key)) {
  37. return;
  38. }
  39. let hasUserValue;
  40. let branch = Services.prefs.getBranch(path + '.');
  41. try {
  42. hasUserValue = branch.prefHasUserValue(setting);
  43. } catch (ex) {
  44. // Ignore
  45. }
  46. if (hasUserValue !== undefined) {
  47. this.originalValues[key] = hasUserValue
  48. ? this.getValue(path, setting)
  49. : undefined;
  50. }
  51. },
  52. clear: function (path, setting) {
  53. let key = path + '.' + setting;
  54. // Value was not overriden -- nothing to restore
  55. if (this.originalValues.hasOwnProperty(key) === false) {
  56. return;
  57. }
  58. let value = this.originalValues[key];
  59. // https://github.com/gorhill/uBlock/issues/292#issuecomment-109621979
  60. // Forget the value immediately, it may change outside of
  61. // uBlock control.
  62. delete this.originalValues[key];
  63. // Original value was a default one
  64. if (value === undefined) {
  65. try {
  66. Services.prefs.getBranch(path + '.').clearUserPref(setting);
  67. } catch (ex) {
  68. // Ignore
  69. }
  70. return;
  71. }
  72. // Reset to original value
  73. this.setValue(path, setting, value);
  74. },
  75. getValue: function (path, setting) {
  76. let branch = Services.prefs.getBranch(path + '.');
  77. try {
  78. switch (branch.getPrefType(setting)) {
  79. case branch.PREF_INT:
  80. return branch.getIntPref(setting);
  81. case branch.PREF_BOOL:
  82. return branch.getBoolPref(setting);
  83. default:
  84. // not supported
  85. return;
  86. }
  87. } catch (e) {
  88. // Ignore
  89. }
  90. },
  91. setValue: function (path, setting, value) {
  92. let branch = Services.prefs.getBranch(path + '.');
  93. try {
  94. switch (typeof value) {
  95. case 'number':
  96. return branch.setIntPref(setting, value);
  97. case 'boolean':
  98. return branch.setBoolPref(setting, value);
  99. default:
  100. // not supported
  101. return;
  102. }
  103. } catch (e) {
  104. // Ignore
  105. }
  106. },
  107. setSetting: function (setting, value) {
  108. switch (setting) {
  109. case 'prefetching':
  110. this.rememberOriginalValue('network', 'prefetch-next');
  111. // https://bugzilla.mozilla.org/show_bug.cgi?id=814169
  112. // Sigh.
  113. // eMatrix: doesn't seem the case for Pale
  114. // Moon/Basilisk, but let's keep this anyway
  115. this.rememberOriginalValue('network.http', 'speculative-parallel-limit');
  116. // https://github.com/gorhill/uBlock/issues/292
  117. // "true" means "do not disable", i.e. leave entry alone
  118. if (value) {
  119. this.clear('network', 'prefetch-next');
  120. this.clear('network.http', 'speculative-parallel-limit');
  121. } else {
  122. this.setValue('network', 'prefetch-next', false);
  123. this.setValue('network.http',
  124. 'speculative-parallel-limit', 0);
  125. }
  126. break;
  127. case 'hyperlinkAuditing':
  128. this.rememberOriginalValue('browser', 'send_pings');
  129. this.rememberOriginalValue('beacon', 'enabled');
  130. // https://github.com/gorhill/uBlock/issues/292
  131. // "true" means "do not disable", i.e. leave entry alone
  132. if (value) {
  133. this.clear('browser', 'send_pings');
  134. this.clear('beacon', 'enabled');
  135. } else {
  136. this.setValue('browser', 'send_pings', false);
  137. this.setValue('beacon', 'enabled', false);
  138. }
  139. break;
  140. case 'webrtcIPAddress':
  141. let prefName;
  142. let prefVal;
  143. // https://github.com/gorhill/uBlock/issues/894
  144. // Do not disable completely WebRTC if it can be avoided. FF42+
  145. // has a `media.peerconnection.ice.default_address_only` pref which
  146. // purpose is to prevent local IP address leakage.
  147. if (this.getValue('media.peerconnection',
  148. 'ice.default_address_only') !== undefined) {
  149. prefName = 'ice.default_address_only';
  150. prefVal = true;
  151. } else {
  152. prefName = 'enabled';
  153. prefVal = false;
  154. }
  155. this.rememberOriginalValue('media.peerconnection', prefName);
  156. if (value) {
  157. this.clear('media.peerconnection', prefName);
  158. } else {
  159. this.setValue('media.peerconnection', prefName, prefVal);
  160. }
  161. break;
  162. default:
  163. break;
  164. }
  165. },
  166. set: function (details) {
  167. for (let setting in details) {
  168. if (details.hasOwnProperty(setting) === false) {
  169. continue;
  170. }
  171. this.setSetting(setting, !!details[setting]);
  172. }
  173. },
  174. restoreAll: function () {
  175. let pos;
  176. for (let key in this.originalValues) {
  177. if (this.originalValues.hasOwnProperty(key) === false) {
  178. continue;
  179. }
  180. pos = key.lastIndexOf('.');
  181. this.clear(key.slice(0, pos), key.slice(pos + 1));
  182. }
  183. },
  184. };
  185. vAPI.addCleanUpTask(vAPI.browser.settings
  186. .restoreAll.bind(vAPI.browser.settings));
  187. vAPI.browser.data = {};
  188. vAPI.browser.data.clearCache = function (callback) {
  189. // PURGE_DISK_DATA_ONLY:1
  190. // PURGE_DISK_ALL:2
  191. // PURGE_EVERYTHING:3
  192. // However I verified that no argument does clear the cache data.
  193. // There is no cache2 for older versions of Firefox.
  194. if (Services.cache2) {
  195. Services.cache2.clear();
  196. } else if (Services.cache) {
  197. Services.cache.evictEntries(Services.cache.STORE_ON_DISK);
  198. }
  199. if (typeof callback === 'function') {
  200. callback();
  201. }
  202. };
  203. vAPI.browser.data.clearOrigin = function(/* domain */) {
  204. // TODO
  205. // eMatrix: is this actually needed? I don't really know what
  206. // it's supposed to do anyway.
  207. };
  208. })();