@browserless.io/browserless 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +55 -36
  3. package/build/config.d.ts +2 -2
  4. package/build/config.js +3 -3
  5. package/build/data/classes.json +1 -1
  6. package/build/data/selectors.json +1 -1
  7. package/build/http.d.ts +1 -0
  8. package/build/http.js +1 -0
  9. package/build/routes/chrome/http/content.post.body.json +8 -8
  10. package/build/routes/chrome/http/pdf.post.body.json +8 -8
  11. package/build/routes/chrome/http/scrape.post.body.json +8 -8
  12. package/build/routes/chrome/http/screenshot.post.body.json +9 -9
  13. package/build/routes/chromium/http/content.post.body.json +8 -8
  14. package/build/routes/chromium/http/pdf.post.body.json +8 -8
  15. package/build/routes/chromium/http/scrape.post.body.json +8 -8
  16. package/build/routes/chromium/http/screenshot.post.body.json +9 -9
  17. package/build/routes/management/http/active.get.d.ts +16 -0
  18. package/build/routes/management/http/active.get.js +17 -0
  19. package/build/routes/management/tests/management.spec.js +7 -0
  20. package/build/server.js +1 -1
  21. package/build/types.d.ts +6 -4
  22. package/build/types.js +1 -0
  23. package/build/utils.d.ts +1 -1
  24. package/docker/base/Dockerfile +1 -1
  25. package/extensions/ublock/1p-filters.html +4 -3
  26. package/extensions/ublock/3p-filters.html +3 -3
  27. package/extensions/ublock/_locales/ar/messages.json +16 -4
  28. package/extensions/ublock/_locales/az/messages.json +16 -4
  29. package/extensions/ublock/_locales/be/messages.json +19 -7
  30. package/extensions/ublock/_locales/bg/messages.json +16 -4
  31. package/extensions/ublock/_locales/bn/messages.json +33 -21
  32. package/extensions/ublock/_locales/br_FR/messages.json +33 -21
  33. package/extensions/ublock/_locales/bs/messages.json +16 -4
  34. package/extensions/ublock/_locales/ca/messages.json +16 -4
  35. package/extensions/ublock/_locales/cs/messages.json +16 -4
  36. package/extensions/ublock/_locales/cv/messages.json +16 -4
  37. package/extensions/ublock/_locales/cy/messages.json +16 -4
  38. package/extensions/ublock/_locales/da/messages.json +21 -9
  39. package/extensions/ublock/_locales/de/messages.json +17 -5
  40. package/extensions/ublock/_locales/el/messages.json +16 -4
  41. package/extensions/ublock/_locales/en/messages.json +16 -4
  42. package/extensions/ublock/_locales/en_GB/messages.json +16 -4
  43. package/extensions/ublock/_locales/eo/messages.json +17 -5
  44. package/extensions/ublock/_locales/es/messages.json +16 -4
  45. package/extensions/ublock/_locales/et/messages.json +16 -4
  46. package/extensions/ublock/_locales/eu/messages.json +16 -4
  47. package/extensions/ublock/_locales/fa/messages.json +24 -12
  48. package/extensions/ublock/_locales/fi/messages.json +16 -4
  49. package/extensions/ublock/_locales/fil/messages.json +16 -4
  50. package/extensions/ublock/_locales/fr/messages.json +16 -4
  51. package/extensions/ublock/_locales/fy/messages.json +16 -4
  52. package/extensions/ublock/_locales/gl/messages.json +16 -4
  53. package/extensions/ublock/_locales/gu/messages.json +16 -4
  54. package/extensions/ublock/_locales/he/messages.json +25 -13
  55. package/extensions/ublock/_locales/hi/messages.json +31 -19
  56. package/extensions/ublock/_locales/hr/messages.json +16 -4
  57. package/extensions/ublock/_locales/hu/messages.json +16 -4
  58. package/extensions/ublock/_locales/hy/messages.json +17 -5
  59. package/extensions/ublock/_locales/id/messages.json +16 -4
  60. package/extensions/ublock/_locales/it/messages.json +17 -5
  61. package/extensions/ublock/_locales/ja/messages.json +16 -4
  62. package/extensions/ublock/_locales/ka/messages.json +16 -4
  63. package/extensions/ublock/_locales/kk/messages.json +16 -4
  64. package/extensions/ublock/_locales/kn/messages.json +74 -62
  65. package/extensions/ublock/_locales/ko/messages.json +16 -4
  66. package/extensions/ublock/_locales/lt/messages.json +23 -11
  67. package/extensions/ublock/_locales/lv/messages.json +16 -4
  68. package/extensions/ublock/_locales/mk/messages.json +16 -4
  69. package/extensions/ublock/_locales/ml/messages.json +19 -7
  70. package/extensions/ublock/_locales/mr/messages.json +16 -4
  71. package/extensions/ublock/_locales/ms/messages.json +16 -4
  72. package/extensions/ublock/_locales/nb/messages.json +16 -4
  73. package/extensions/ublock/_locales/nl/messages.json +16 -4
  74. package/extensions/ublock/_locales/no/messages.json +16 -4
  75. package/extensions/ublock/_locales/oc/messages.json +16 -4
  76. package/extensions/ublock/_locales/pa/messages.json +16 -4
  77. package/extensions/ublock/_locales/pl/messages.json +17 -5
  78. package/extensions/ublock/_locales/pt_BR/messages.json +16 -4
  79. package/extensions/ublock/_locales/pt_PT/messages.json +16 -4
  80. package/extensions/ublock/_locales/ro/messages.json +17 -5
  81. package/extensions/ublock/_locales/ru/messages.json +16 -4
  82. package/extensions/ublock/_locales/si/messages.json +16 -4
  83. package/extensions/ublock/_locales/sk/messages.json +16 -4
  84. package/extensions/ublock/_locales/sl/messages.json +16 -4
  85. package/extensions/ublock/_locales/so/messages.json +16 -4
  86. package/extensions/ublock/_locales/sq/messages.json +16 -4
  87. package/extensions/ublock/_locales/sr/messages.json +16 -4
  88. package/extensions/ublock/_locales/sv/messages.json +20 -8
  89. package/extensions/ublock/_locales/sw/messages.json +16 -4
  90. package/extensions/ublock/_locales/ta/messages.json +16 -4
  91. package/extensions/ublock/_locales/te/messages.json +16 -4
  92. package/extensions/ublock/_locales/th/messages.json +42 -30
  93. package/extensions/ublock/_locales/tr/messages.json +19 -7
  94. package/extensions/ublock/_locales/uk/messages.json +16 -4
  95. package/extensions/ublock/_locales/ur/messages.json +16 -4
  96. package/extensions/ublock/_locales/vi/messages.json +16 -4
  97. package/extensions/ublock/_locales/zh_CN/messages.json +16 -4
  98. package/extensions/ublock/_locales/zh_TW/messages.json +42 -30
  99. package/extensions/ublock/assets/assets.json +95 -78
  100. package/extensions/ublock/assets/resources/scriptlets.js +70 -24
  101. package/extensions/ublock/assets/thirdparties/easylist/easylist.txt +6258 -3453
  102. package/extensions/ublock/assets/thirdparties/easylist/easyprivacy.txt +277 -40
  103. package/extensions/ublock/assets/thirdparties/pgl.yoyo.org/as/serverlist +8 -32
  104. package/extensions/ublock/assets/thirdparties/publicsuffix.org/list/effective_tld_names.dat +107 -12
  105. package/extensions/ublock/assets/thirdparties/urlhaus-filter/urlhaus-filter-online.txt +1160 -954
  106. package/extensions/ublock/assets/ublock/badlists.txt +1 -2
  107. package/extensions/ublock/assets/ublock/badware.min.txt +395 -270
  108. package/extensions/ublock/assets/ublock/filters.min.txt +1176 -1238
  109. package/extensions/ublock/assets/ublock/privacy.min.txt +32 -31
  110. package/extensions/ublock/assets/ublock/quick-fixes.min.txt +120 -110
  111. package/extensions/ublock/assets/ublock/unbreak.min.txt +75 -36
  112. package/extensions/ublock/css/1p-filters.css +2 -1
  113. package/extensions/ublock/css/3p-filters.css +1 -16
  114. package/extensions/ublock/css/advanced-settings.css +1 -0
  115. package/extensions/ublock/css/asset-viewer.css +1 -0
  116. package/extensions/ublock/css/code-viewer.css +1 -0
  117. package/extensions/ublock/css/codemirror.css +37 -10
  118. package/extensions/ublock/css/common.css +36 -2
  119. package/extensions/ublock/css/dashboard.css +9 -3
  120. package/extensions/ublock/css/devtools.css +1 -0
  121. package/extensions/ublock/css/document-blocked.css +3 -3
  122. package/extensions/ublock/css/dom-inspector.css +1 -0
  123. package/extensions/ublock/css/dyna-rules.css +1 -0
  124. package/extensions/ublock/css/epicker-ui.css +76 -66
  125. package/extensions/ublock/css/fa-icons.css +1 -0
  126. package/extensions/ublock/css/logger-ui.css +2 -0
  127. package/extensions/ublock/css/popup-fenix.css +1 -0
  128. package/extensions/ublock/css/whitelist.css +1 -0
  129. package/extensions/ublock/dashboard.html +20 -13
  130. package/extensions/ublock/devtools.html +2 -0
  131. package/extensions/ublock/dyna-rules.html +2 -2
  132. package/extensions/ublock/img/flags-of-the-world/np.png +0 -0
  133. package/extensions/ublock/img/fontawesome/fontawesome-defs.svg +1 -0
  134. package/extensions/ublock/js/1p-filters.js +72 -23
  135. package/extensions/ublock/js/3p-filters.js +71 -25
  136. package/extensions/ublock/js/asset-viewer.js +1 -0
  137. package/extensions/ublock/js/assets.js +83 -89
  138. package/extensions/ublock/js/background.js +20 -27
  139. package/extensions/ublock/js/base64-custom.js +1 -102
  140. package/extensions/ublock/js/benchmarks.js +36 -21
  141. package/extensions/ublock/js/biditrie.js +8 -23
  142. package/extensions/ublock/js/broadcast.js +2 -4
  143. package/extensions/ublock/js/cachestorage.js +594 -396
  144. package/extensions/ublock/js/codemirror/search.js +49 -37
  145. package/extensions/ublock/js/codemirror/ubo-static-filtering.js +233 -215
  146. package/extensions/ublock/js/contentscript-extra.js +31 -1
  147. package/extensions/ublock/js/cosmetic-filtering.js +35 -33
  148. package/extensions/ublock/js/dashboard.js +11 -7
  149. package/extensions/ublock/js/devtools.js +22 -0
  150. package/extensions/ublock/js/dom.js +2 -2
  151. package/extensions/ublock/js/dyna-rules.js +17 -16
  152. package/extensions/ublock/js/epicker-ui.js +41 -16
  153. package/extensions/ublock/js/fa-icons.js +1 -0
  154. package/extensions/ublock/js/hntrie.js +10 -25
  155. package/extensions/ublock/js/i18n.js +15 -15
  156. package/extensions/ublock/js/logger-ui.js +9 -6
  157. package/extensions/ublock/js/messaging.js +51 -26
  158. package/extensions/ublock/js/pagestore.js +21 -23
  159. package/extensions/ublock/js/popup-fenix.js +35 -22
  160. package/extensions/ublock/js/redirect-engine.js +15 -30
  161. package/extensions/ublock/js/reverselookup.js +1 -1
  162. package/extensions/ublock/js/s14e-serializer.js +1405 -0
  163. package/extensions/ublock/js/scriptlet-filtering-core.js +1 -1
  164. package/extensions/ublock/js/scriptlets/epicker.js +27 -18
  165. package/extensions/ublock/js/settings.js +32 -21
  166. package/extensions/ublock/js/start.js +121 -62
  167. package/extensions/ublock/js/static-ext-filtering-db.js +6 -6
  168. package/extensions/ublock/js/static-ext-filtering.js +17 -28
  169. package/extensions/ublock/js/static-filtering-parser.js +26 -4
  170. package/extensions/ublock/js/static-net-filtering.js +69 -168
  171. package/extensions/ublock/js/storage.js +178 -155
  172. package/extensions/ublock/js/traffic.js +11 -7
  173. package/extensions/ublock/js/vapi-background.js +49 -62
  174. package/extensions/ublock/js/vapi-client.js +13 -16
  175. package/extensions/ublock/js/webext.js +10 -2
  176. package/extensions/ublock/js/whitelist.js +27 -25
  177. package/extensions/ublock/lib/publicsuffixlist/publicsuffixlist.js +3 -7
  178. package/extensions/ublock/manifest.json +2 -1
  179. package/extensions/ublock/web_accessible_resources/epicker-ui.html +5 -8
  180. package/extensions/ublock/whitelist.html +3 -4
  181. package/package.json +12 -12
  182. package/src/config.ts +3 -4
  183. package/src/http.ts +1 -0
  184. package/src/routes/management/http/active.get.ts +30 -0
  185. package/src/routes/management/tests/management.spec.ts +13 -0
  186. package/src/server.ts +1 -1
  187. package/src/types.ts +2 -1
  188. package/static/docs/swagger.json +57 -11
  189. package/static/docs/swagger.min.json +56 -10
  190. package/static/function/client.js +4155 -3350
  191. package/extensions/ublock/_locales/ku/messages.json +0 -1294
@@ -200,7 +200,7 @@ export class ScriptletFilteringEngine {
200
200
  }
201
201
 
202
202
  fromSelfie(selfie) {
203
- if ( selfie instanceof Object === false ) { return false; }
203
+ if ( typeof selfie !== 'object' || selfie === null ) { return false; }
204
204
  if ( selfie.version !== VERSION ) { return false; }
205
205
  this.scriptletDB.fromSelfie(selfie);
206
206
  return true;
@@ -619,6 +619,21 @@ const filterToDOMInterface = (( ) => {
619
619
  const reCaret = '(?:[^%.0-9a-z_-]|$)';
620
620
  const rePseudoElements = /:(?::?after|:?before|:[a-z-]+)$/;
621
621
 
622
+ const matchElemToRegex = (elem, re) => {
623
+ const srcProp = netFilter1stSources[elem.localName];
624
+ let src = elem[srcProp];
625
+ if ( src instanceof SVGAnimatedString ) {
626
+ src = src.baseVal;
627
+ }
628
+ if ( typeof src === 'string' && /^https?:\/\//.test(src) ) {
629
+ if ( re.test(src) ) { return srcProp; }
630
+ }
631
+ src = elem.currentSrc;
632
+ if ( typeof src === 'string' && /^https?:\/\//.test(src) ) {
633
+ if ( re.test(src) ) { return srcProp; }
634
+ }
635
+ };
636
+
622
637
  // Net filters: we need to lookup manually -- translating into a foolproof
623
638
  // CSS selector is just not possible.
624
639
  //
@@ -672,28 +687,21 @@ const filterToDOMInterface = (( ) => {
672
687
  // Lookup by tag names.
673
688
  // https://github.com/uBlockOrigin/uBlock-issues/issues/2260
674
689
  // Maybe get to the actual URL indirectly.
690
+ //
691
+ // https://github.com/uBlockOrigin/uBlock-issues/issues/3142
692
+ // Don't try to match against non-network URIs.
675
693
  const elems = document.querySelectorAll(
676
694
  Object.keys(netFilter1stSources).join()
677
695
  );
678
696
  for ( const elem of elems ) {
679
- const srcProp = netFilter1stSources[elem.localName];
680
- let src = elem[srcProp];
681
- if ( src instanceof SVGAnimatedString ) {
682
- src = src.baseVal;
683
- }
684
- if (
685
- typeof src === 'string' &&
686
- reFilter.test(src) ||
687
- typeof elem.currentSrc === 'string' &&
688
- reFilter.test(elem.currentSrc)
689
- ) {
690
- out.push({
691
- elem,
692
- src: srcProp,
693
- opt: filterTypes[elem.localName],
694
- style: vAPI.hideStyle,
695
- });
696
- }
697
+ const srcProp = matchElemToRegex(elem, reFilter);
698
+ if ( srcProp === undefined ) { continue; }
699
+ out.push({
700
+ elem,
701
+ src: srcProp,
702
+ opt: filterTypes[elem.localName],
703
+ style: vAPI.hideStyle,
704
+ });
697
705
  }
698
706
 
699
707
  // Find matching background image in current set of candidate elements.
@@ -1247,6 +1255,7 @@ const pickerCSSStyle = [
1247
1255
  'display: block',
1248
1256
  'filter: none',
1249
1257
  'height: 100vh',
1258
+ ' height: 100svh',
1250
1259
  'left: 0',
1251
1260
  'margin: 0',
1252
1261
  'max-height: none',
@@ -27,7 +27,7 @@ import { setAccentColor, setTheme } from './theme.js';
27
27
 
28
28
  /******************************************************************************/
29
29
 
30
- const handleImportFilePicker = function() {
30
+ function handleImportFilePicker() {
31
31
  const file = this.files[0];
32
32
  if ( file === undefined || file.name === '' ) { return; }
33
33
 
@@ -88,22 +88,22 @@ const handleImportFilePicker = function() {
88
88
  };
89
89
 
90
90
  fr.readAsText(file);
91
- };
91
+ }
92
92
 
93
93
  /******************************************************************************/
94
94
 
95
- const startImportFilePicker = function() {
95
+ function startImportFilePicker() {
96
96
  const input = qs$('#restoreFilePicker');
97
97
  // Reset to empty string, this will ensure an change event is properly
98
98
  // triggered if the user pick a file, even if it is the same as the last
99
99
  // one picked.
100
100
  input.value = '';
101
101
  input.click();
102
- };
102
+ }
103
103
 
104
104
  /******************************************************************************/
105
105
 
106
- const exportToFile = async function() {
106
+ async function exportToFile() {
107
107
  const response = await vAPI.messaging.send('dashboard', {
108
108
  what: 'backupUserData',
109
109
  });
@@ -119,11 +119,11 @@ const exportToFile = async function() {
119
119
  'filename': response.localData.lastBackupFile
120
120
  });
121
121
  onLocalDataReceived(response.localData);
122
- };
122
+ }
123
123
 
124
124
  /******************************************************************************/
125
125
 
126
- const onLocalDataReceived = function(details) {
126
+ function onLocalDataReceived(details) {
127
127
  let v, unit;
128
128
  if ( typeof details.storageUsed === 'number' ) {
129
129
  v = details.storageUsed;
@@ -187,32 +187,32 @@ const onLocalDataReceived = function(details) {
187
187
  dom.attr('[data-setting-name="hyperlinkAuditingDisabled"]', 'disabled', '');
188
188
  dom.attr('[data-setting-name="webrtcIPAddressHidden"]', 'disabled', '');
189
189
  }
190
- };
190
+ }
191
191
 
192
192
  /******************************************************************************/
193
193
 
194
- const resetUserData = function() {
194
+ function resetUserData() {
195
195
  const msg = i18n$('aboutResetDataConfirm');
196
196
  const proceed = window.confirm(msg);
197
197
  if ( proceed !== true ) { return; }
198
198
  vAPI.messaging.send('dashboard', {
199
199
  what: 'resetUserData',
200
200
  });
201
- };
201
+ }
202
202
 
203
203
  /******************************************************************************/
204
204
 
205
- const synchronizeDOM = function() {
205
+ function synchronizeDOM() {
206
206
  dom.cl.toggle(
207
207
  dom.body,
208
208
  'advancedUser',
209
209
  qs$('[data-setting-name="advancedUserEnabled"]').checked === true
210
210
  );
211
- };
211
+ }
212
212
 
213
213
  /******************************************************************************/
214
214
 
215
- const changeUserSettings = function(name, value) {
215
+ function changeUserSettings(name, value) {
216
216
  vAPI.messaging.send('dashboard', {
217
217
  what: 'userSettings',
218
218
  name,
@@ -235,11 +235,11 @@ const changeUserSettings = function(name, value) {
235
235
  default:
236
236
  break;
237
237
  }
238
- };
238
+ }
239
239
 
240
240
  /******************************************************************************/
241
241
 
242
- const onValueChanged = function(ev) {
242
+ function onValueChanged(ev) {
243
243
  const input = ev.target;
244
244
  const name = dom.attr(input, 'data-setting-name');
245
245
  let value = input.value;
@@ -256,14 +256,20 @@ const onValueChanged = function(ev) {
256
256
  }
257
257
 
258
258
  changeUserSettings(name, value);
259
- };
259
+ }
260
260
 
261
261
  /******************************************************************************/
262
262
 
263
263
  // TODO: use data-* to declare simple settings
264
264
 
265
- const onUserSettingsReceived = function(details) {
265
+ function onUserSettingsReceived(details) {
266
266
  const checkboxes = qsa$('[data-setting-type="bool"]');
267
+ const onchange = ev => {
268
+ const checkbox = ev.target;
269
+ const name = checkbox.dataset.settingName || '';
270
+ changeUserSettings(name, checkbox.checked);
271
+ synchronizeDOM();
272
+ };
267
273
  for ( const checkbox of checkboxes ) {
268
274
  const name = dom.attr(checkbox, 'data-setting-name') || '';
269
275
  if ( details[name] === undefined ) {
@@ -272,10 +278,7 @@ const onUserSettingsReceived = function(details) {
272
278
  continue;
273
279
  }
274
280
  checkbox.checked = details[name] === true;
275
- dom.on(checkbox, 'change', ( ) => {
276
- changeUserSettings(name, checkbox.checked);
277
- synchronizeDOM();
278
- });
281
+ dom.on(checkbox, 'change', onchange);
279
282
  }
280
283
 
281
284
  if ( details.canLeakLocalIPAddresses === true ) {
@@ -295,6 +298,14 @@ const onUserSettingsReceived = function(details) {
295
298
  dom.on('#restoreFilePicker', 'change', handleImportFilePicker);
296
299
 
297
300
  synchronizeDOM();
301
+ }
302
+
303
+ /******************************************************************************/
304
+
305
+ self.wikilink = 'https://github.com/gorhill/uBlock/wiki/Dashboard:-Settings';
306
+
307
+ self.hasUnsavedData = function() {
308
+ return false;
298
309
  };
299
310
 
300
311
  /******************************************************************************/
@@ -63,6 +63,11 @@ import {
63
63
 
64
64
  /******************************************************************************/
65
65
 
66
+ let lastVersionInt = 0;
67
+ let thisVersionInt = 0;
68
+
69
+ /******************************************************************************/
70
+
66
71
  vAPI.app.onShutdown = ( ) => {
67
72
  staticFilteringReverseLookup.shutdown();
68
73
  io.updateStop();
@@ -76,6 +81,10 @@ vAPI.app.onShutdown = ( ) => {
76
81
  permanentSwitches.reset();
77
82
  };
78
83
 
84
+ vAPI.alarms.onAlarm.addListener(alarm => {
85
+ µb.alarmQueue.push(alarm.name);
86
+ });
87
+
79
88
  /******************************************************************************/
80
89
 
81
90
  // This is called only once, when everything has been loaded in memory after
@@ -139,22 +148,29 @@ const initializeTabs = async ( ) => {
139
148
  // https://www.reddit.com/r/uBlockOrigin/comments/s7c9go/
140
149
  // Abort suspending network requests when uBO is merely being installed.
141
150
 
142
- const onVersionReady = lastVersion => {
143
- if ( lastVersion === vAPI.app.version ) { return; }
151
+ const onVersionReady = async lastVersion => {
152
+ lastVersionInt = vAPI.app.intFromVersion(lastVersion);
153
+ thisVersionInt = vAPI.app.intFromVersion(vAPI.app.version);
154
+ if ( thisVersionInt === lastVersionInt ) { return; }
144
155
 
145
156
  vAPI.storage.set({
146
157
  version: vAPI.app.version,
147
158
  versionUpdateTime: Date.now(),
148
159
  });
149
160
 
150
- const lastVersionInt = vAPI.app.intFromVersion(lastVersion);
151
-
152
161
  // Special case: first installation
153
162
  if ( lastVersionInt === 0 ) {
154
163
  vAPI.net.unsuspend({ all: true, discard: true });
155
164
  return;
156
165
  }
157
166
 
167
+ // Remove cache items with obsolete names
168
+ if ( lastVersionInt < vAPI.app.intFromVersion('1.56.1b5') ) {
169
+ io.remove(`compiled/${µb.pslAssetKey}`);
170
+ io.remove('compiled/redirectEngine/resources');
171
+ io.remove('selfie/main');
172
+ }
173
+
158
174
  // Since built-in resources may have changed since last version, we
159
175
  // force a reload of all resources.
160
176
  redirectEngine.invalidateResourcesSelfie(io);
@@ -162,11 +178,6 @@ const onVersionReady = lastVersion => {
162
178
 
163
179
  /******************************************************************************/
164
180
 
165
- // https://github.com/chrisaljoudi/uBlock/issues/226
166
- // Whitelist in memory.
167
- // Whitelist parser needs PSL to be ready.
168
- // gorhill 2014-12-15: not anymore
169
- //
170
181
  // https://github.com/uBlockOrigin/uBlock-issues/issues/1433
171
182
  // Allow admins to add their own trusted-site directives.
172
183
 
@@ -174,16 +185,38 @@ const onNetWhitelistReady = (netWhitelistRaw, adminExtra) => {
174
185
  if ( typeof netWhitelistRaw === 'string' ) {
175
186
  netWhitelistRaw = netWhitelistRaw.split('\n');
176
187
  }
188
+
189
+ // Remove now obsolete built-in trusted directives
190
+ if ( lastVersionInt !== thisVersionInt ) {
191
+ if ( lastVersionInt < vAPI.app.intFromVersion('1.56.1b12') ) {
192
+ const obsolete = [
193
+ 'about-scheme',
194
+ 'chrome-scheme',
195
+ 'edge-scheme',
196
+ 'opera-scheme',
197
+ 'vivaldi-scheme',
198
+ 'wyciwyg-scheme',
199
+ ];
200
+ for ( const directive of obsolete ) {
201
+ const i = netWhitelistRaw.findIndex(s =>
202
+ s === directive || s === `# ${directive}`
203
+ );
204
+ if ( i === -1 ) { continue; }
205
+ netWhitelistRaw.splice(i, 1);
206
+ }
207
+ }
208
+ }
209
+
177
210
  // Append admin-controlled trusted-site directives
178
- if (
179
- adminExtra instanceof Object &&
180
- Array.isArray(adminExtra.trustedSiteDirectives)
181
- ) {
182
- for ( const directive of adminExtra.trustedSiteDirectives ) {
183
- µb.netWhitelistDefault.push(directive);
184
- netWhitelistRaw.push(directive);
211
+ if ( adminExtra instanceof Object ) {
212
+ if ( Array.isArray(adminExtra.trustedSiteDirectives) ) {
213
+ for ( const directive of adminExtra.trustedSiteDirectives ) {
214
+ µb.netWhitelistDefault.push(directive);
215
+ netWhitelistRaw.push(directive);
216
+ }
185
217
  }
186
218
  }
219
+
187
220
  µb.netWhitelist = µb.whitelistFromArray(netWhitelistRaw);
188
221
  µb.netWhitelistModifyTime = Date.now();
189
222
  };
@@ -221,8 +254,7 @@ const onUserSettingsReady = fetched => {
221
254
  fetched.importedLists.length === 0 &&
222
255
  fetched.externalLists !== ''
223
256
  ) {
224
- fetched.importedLists =
225
- fetched.externalLists.trim().split(/[\n\r]+/);
257
+ fetched.importedLists = fetched.externalLists.trim().split(/[\n\r]+/);
226
258
  }
227
259
 
228
260
  fromFetch(µb.userSettings, fetched);
@@ -252,19 +284,19 @@ const onUserSettingsReady = fetched => {
252
284
  // Wait for removal of invalid cached data to be completed.
253
285
 
254
286
  const onCacheSettingsReady = async (fetched = {}) => {
287
+ let selfieIsInvalid = false;
255
288
  if ( fetched.compiledMagic !== µb.systemSettings.compiledMagic ) {
256
289
  µb.compiledFormatChanged = true;
257
- µb.selfieIsInvalid = true;
290
+ selfieIsInvalid = true;
258
291
  ubolog(`Serialized format of static filter lists changed`);
259
292
  }
260
293
  if ( fetched.selfieMagic !== µb.systemSettings.selfieMagic ) {
261
- µb.selfieIsInvalid = true;
294
+ selfieIsInvalid = true;
262
295
  ubolog(`Serialized format of selfie changed`);
263
296
  }
264
- if ( µb.selfieIsInvalid ) {
265
- µb.selfieManager.destroy();
266
- cacheStorage.set(µb.systemSettings);
267
- }
297
+ if ( selfieIsInvalid === false ) { return; }
298
+ µb.selfieManager.destroy({ janitor: true });
299
+ cacheStorage.set(µb.systemSettings);
268
300
  };
269
301
 
270
302
  /******************************************************************************/
@@ -303,12 +335,6 @@ const onHiddenSettingsReady = async ( ) => {
303
335
  ubolog(`WASM modules ready ${Date.now()-vAPI.T0} ms after launch`);
304
336
  });
305
337
  }
306
-
307
- // Maybe override default cache storage
308
- µb.supportStats.cacheBackend = await cacheStorage.select(
309
- µb.hiddenSettings.cacheStorageAPI
310
- );
311
- ubolog(`Backend storage for cache will be ${µb.supportStats.cacheBackend}`);
312
338
  };
313
339
 
314
340
  /******************************************************************************/
@@ -322,7 +348,6 @@ const onFirstFetchReady = (fetched, adminExtra) => {
322
348
  }
323
349
 
324
350
  // Order is important -- do not change:
325
- fromFetch(µb.localSettings, fetched);
326
351
  fromFetch(µb.restoreBackupSettings, fetched);
327
352
 
328
353
  permanentFirewall.fromString(fetched.dynamicFilteringString);
@@ -333,7 +358,6 @@ const onFirstFetchReady = (fetched, adminExtra) => {
333
358
  sessionSwitches.assign(permanentSwitches);
334
359
 
335
360
  onNetWhitelistReady(fetched.netWhitelist, adminExtra);
336
- onVersionReady(fetched.version);
337
361
  };
338
362
 
339
363
  /******************************************************************************/
@@ -358,14 +382,9 @@ const createDefaultProps = ( ) => {
358
382
  'dynamicFilteringString': µb.dynamicFilteringDefault.join('\n'),
359
383
  'urlFilteringString': '',
360
384
  'hostnameSwitchesString': µb.hostnameSwitchesDefault.join('\n'),
361
- 'lastRestoreFile': '',
362
- 'lastRestoreTime': 0,
363
- 'lastBackupFile': '',
364
- 'lastBackupTime': 0,
365
385
  'netWhitelist': µb.netWhitelistDefault,
366
386
  'version': '0.0.0.0'
367
387
  };
368
- toFetch(µb.localSettings, fetchableProps);
369
388
  toFetch(µb.restoreBackupSettings, fetchableProps);
370
389
  return fetchableProps;
371
390
  };
@@ -389,23 +408,25 @@ try {
389
408
  const adminExtra = await vAPI.adminStorage.get('toAdd');
390
409
  ubolog(`Extra admin settings ready ${Date.now()-vAPI.T0} ms after launch`);
391
410
 
392
- // https://github.com/uBlockOrigin/uBlock-issues/issues/1365
393
- // Wait for onCacheSettingsReady() to be fully ready.
394
- const [ , , lastVersion ] = await Promise.all([
411
+ // Maybe override default cache storage
412
+ µb.supportStats.cacheBackend = await cacheStorage.select(
413
+ µb.hiddenSettings.cacheStorageAPI
414
+ );
415
+ ubolog(`Backend storage for cache will be ${µb.supportStats.cacheBackend}`);
416
+
417
+ await vAPI.storage.get(createDefaultProps()).then(async fetched => {
418
+ ubolog(`Version ready ${Date.now()-vAPI.T0} ms after launch`);
419
+ await onVersionReady(fetched.version);
420
+ return fetched;
421
+ }).then(fetched => {
422
+ ubolog(`First fetch ready ${Date.now()-vAPI.T0} ms after launch`);
423
+ onFirstFetchReady(fetched, adminExtra);
424
+ });
425
+
426
+ await Promise.all([
395
427
  µb.loadSelectedFilterLists().then(( ) => {
396
428
  ubolog(`List selection ready ${Date.now()-vAPI.T0} ms after launch`);
397
429
  }),
398
- cacheStorage.get(
399
- { compiledMagic: 0, selfieMagic: 0 }
400
- ).then(fetched => {
401
- ubolog(`Cache magic numbers ready ${Date.now()-vAPI.T0} ms after launch`);
402
- onCacheSettingsReady(fetched);
403
- }),
404
- vAPI.storage.get(createDefaultProps()).then(fetched => {
405
- ubolog(`First fetch ready ${Date.now()-vAPI.T0} ms after launch`);
406
- onFirstFetchReady(fetched, adminExtra);
407
- return fetched.version;
408
- }),
409
430
  µb.loadUserSettings().then(fetched => {
410
431
  ubolog(`User settings ready ${Date.now()-vAPI.T0} ms after launch`);
411
432
  onUserSettingsReady(fetched);
@@ -413,10 +434,15 @@ try {
413
434
  µb.loadPublicSuffixList().then(( ) => {
414
435
  ubolog(`PSL ready ${Date.now()-vAPI.T0} ms after launch`);
415
436
  }),
437
+ cacheStorage.get({ compiledMagic: 0, selfieMagic: 0 }).then(bin => {
438
+ ubolog(`Cache magic numbers ready ${Date.now()-vAPI.T0} ms after launch`);
439
+ onCacheSettingsReady(bin);
440
+ }),
441
+ µb.loadLocalSettings(),
416
442
  ]);
417
443
 
418
444
  // https://github.com/uBlockOrigin/uBlock-issues/issues/1547
419
- if ( lastVersion === '0.0.0.0' && vAPI.webextFlavor.soup.has('chromium') ) {
445
+ if ( lastVersionInt === 0 && vAPI.webextFlavor.soup.has('chromium') ) {
420
446
  vAPI.app.restart();
421
447
  return;
422
448
  }
@@ -434,7 +460,7 @@ let selfieIsValid = false;
434
460
  try {
435
461
  selfieIsValid = await µb.selfieManager.load();
436
462
  if ( selfieIsValid === true ) {
437
- ubolog(`Selfie ready ${Date.now()-vAPI.T0} ms after launch`);
463
+ ubolog(`Loaded filtering engine from selfie ${Date.now()-vAPI.T0} ms after launch`);
438
464
  }
439
465
  } catch (ex) {
440
466
  console.trace(ex);
@@ -471,15 +497,6 @@ webRequest.start();
471
497
  // as possible ensure minimal memory usage baseline.
472
498
  lz4Codec.relinquish();
473
499
 
474
- // https://github.com/chrisaljoudi/uBlock/issues/184
475
- // Check for updates not too far in the future.
476
- io.addObserver(µb.assetObserver.bind(µb));
477
- µb.scheduleAssetUpdater({
478
- updateDelay: µb.userSettings.autoUpdate
479
- ? µb.hiddenSettings.autoUpdateDelayAfterLaunch * 1000
480
- : 0
481
- });
482
-
483
500
  // Force an update of the context menu according to the currently
484
501
  // active tab.
485
502
  contextMenu.update();
@@ -504,5 +521,47 @@ ubolog(`All ready ${µb.supportStats.allReadyAfter} after launch`);
504
521
 
505
522
  µb.isReadyResolve();
506
523
 
524
+
525
+ // https://github.com/chrisaljoudi/uBlock/issues/184
526
+ // Check for updates not too far in the future.
527
+ io.addObserver(µb.assetObserver.bind(µb));
528
+ if ( µb.userSettings.autoUpdate ) {
529
+ let needEmergencyUpdate = false;
530
+ const entries = await io.getUpdateAges({
531
+ filters: µb.selectedFilterLists,
532
+ internal: [ '*' ],
533
+ });
534
+ for ( const entry of entries ) {
535
+ if ( entry.ageNormalized < 2 ) { continue; }
536
+ needEmergencyUpdate = true;
537
+ break;
538
+ }
539
+ const updateDelay = needEmergencyUpdate
540
+ ? 2000
541
+ : µb.hiddenSettings.autoUpdateDelayAfterLaunch * 1000;
542
+ µb.scheduleAssetUpdater({
543
+ auto: true,
544
+ updateDelay,
545
+ fetchDelay: needEmergencyUpdate ? 1000 : undefined
546
+ });
547
+ }
548
+
549
+ // Process alarm queue
550
+ while ( µb.alarmQueue.length !== 0 ) {
551
+ const what = µb.alarmQueue.shift();
552
+ ubolog(`Processing alarm event from suspended state: '${what}'`);
553
+ switch ( what ) {
554
+ case 'assetUpdater':
555
+ µb.scheduleAssetUpdater({ auto: true, updateDelay: 2000, fetchDelay : 1000 });
556
+ break;
557
+ case 'createSelfie':
558
+ µb.selfieManager.create();
559
+ break;
560
+ case 'saveLocalSettings':
561
+ µb.saveLocalSettings();
562
+ break;
563
+ }
564
+ }
565
+
507
566
  // <<<<< end of async/await scope
508
567
  })();
@@ -141,8 +141,8 @@ const StaticExtFilteringHostnameDB = class {
141
141
  toSelfie() {
142
142
  return {
143
143
  version: this.version,
144
- hostnameToSlotIdMap: Array.from(this.hostnameToSlotIdMap),
145
- regexToSlotIdMap: Array.from(this.regexToSlotIdMap),
144
+ hostnameToSlotIdMap: this.hostnameToSlotIdMap,
145
+ regexToSlotIdMap: this.regexToSlotIdMap,
146
146
  hostnameSlots: this.hostnameSlots,
147
147
  strSlots: this.strSlots,
148
148
  size: this.size
@@ -150,11 +150,11 @@ const StaticExtFilteringHostnameDB = class {
150
150
  }
151
151
 
152
152
  fromSelfie(selfie) {
153
- if ( selfie === undefined ) { return; }
154
- this.hostnameToSlotIdMap = new Map(selfie.hostnameToSlotIdMap);
153
+ if ( typeof selfie !== 'object' || selfie === null ) { return; }
154
+ this.hostnameToSlotIdMap = selfie.hostnameToSlotIdMap;
155
155
  // Regex-based lookup available in uBO 1.47.0 and above
156
- if ( Array.isArray(selfie.regexToSlotIdMap) ) {
157
- this.regexToSlotIdMap = new Map(selfie.regexToSlotIdMap);
156
+ if ( selfie.regexToSlotIdMap ) {
157
+ this.regexToSlotIdMap = selfie.regexToSlotIdMap;
158
158
  }
159
159
  this.hostnameSlots = selfie.hostnameSlots;
160
160
  this.strSlots = selfie.strSlots;
@@ -26,9 +26,8 @@
26
26
  import cosmeticFilteringEngine from './cosmetic-filtering.js';
27
27
  import htmlFilteringEngine from './html-filtering.js';
28
28
  import httpheaderFilteringEngine from './httpheader-filtering.js';
29
- import io from './assets.js';
30
- import logger from './logger.js';
31
29
  import scriptletFilteringEngine from './scriptlet-filtering.js';
30
+ import logger from './logger.js';
32
31
 
33
32
  /*******************************************************************************
34
33
 
@@ -147,34 +146,24 @@ staticExtFilteringEngine.fromCompiledContent = function(reader, options) {
147
146
  htmlFilteringEngine.fromCompiledContent(reader, options);
148
147
  };
149
148
 
150
- staticExtFilteringEngine.toSelfie = function(path) {
151
- return io.put(
152
- `${path}/main`,
153
- JSON.stringify({
154
- cosmetic: cosmeticFilteringEngine.toSelfie(),
155
- scriptlets: scriptletFilteringEngine.toSelfie(),
156
- httpHeaders: httpheaderFilteringEngine.toSelfie(),
157
- html: htmlFilteringEngine.toSelfie(),
158
- })
159
- );
149
+ staticExtFilteringEngine.toSelfie = function() {
150
+ return {
151
+ cosmetic: cosmeticFilteringEngine.toSelfie(),
152
+ scriptlets: scriptletFilteringEngine.toSelfie(),
153
+ httpHeaders: httpheaderFilteringEngine.toSelfie(),
154
+ html: htmlFilteringEngine.toSelfie(),
155
+ };
160
156
  };
161
157
 
162
- staticExtFilteringEngine.fromSelfie = function(path) {
163
- return io.get(`${path}/main`).then(details => {
164
- let selfie;
165
- try {
166
- selfie = JSON.parse(details.content);
167
- } catch (ex) {
168
- }
169
- if ( selfie instanceof Object === false ) { return false; }
170
- cosmeticFilteringEngine.fromSelfie(selfie.cosmetic);
171
- httpheaderFilteringEngine.fromSelfie(selfie.httpHeaders);
172
- htmlFilteringEngine.fromSelfie(selfie.html);
173
- if ( scriptletFilteringEngine.fromSelfie(selfie.scriptlets) === false ) {
174
- return false;
175
- }
176
- return true;
177
- });
158
+ staticExtFilteringEngine.fromSelfie = async function(selfie) {
159
+ if ( typeof selfie !== 'object' || selfie === null ) { return false; }
160
+ cosmeticFilteringEngine.fromSelfie(selfie.cosmetic);
161
+ httpheaderFilteringEngine.fromSelfie(selfie.httpHeaders);
162
+ htmlFilteringEngine.fromSelfie(selfie.html);
163
+ if ( scriptletFilteringEngine.fromSelfie(selfie.scriptlets) === false ) {
164
+ return false;
165
+ }
166
+ return true;
178
167
  };
179
168
 
180
169
  /******************************************************************************/