@@ -41,6 +41,7 @@ let filteredLoggerEntryVoidedCount = 0;
41
41
let popupLoggerBox ;
42
42
let popupLoggerTooltips ;
43
43
let activeTabId = 0 ;
44
+ let filterAuthorMode = false ;
44
45
let selectedTabId = 0 ;
45
46
let netInspectorPaused = false ;
46
47
@@ -64,7 +65,7 @@ const tabIdFromAttribute = function(elem) {
64
65
65
66
// Current design allows for only one modal DOM-based dialog at any given time.
66
67
//
67
- const modalDialog = ( function ( ) {
68
+ const modalDialog = ( ( ) => {
68
69
const overlay = uDom . nodeFromId ( 'modalOverlay' ) ;
69
70
const container = overlay . querySelector (
70
71
':scope > div > div:nth-of-type(1)'
@@ -949,6 +950,8 @@ const onLogBufferRead = function(response) {
949
950
allTabIdsToken = response . tabIdsToken ;
950
951
}
951
952
953
+ filterAuthorMode = response . filterAuthorMode === true ;
954
+
952
955
if ( activeTabIdChanged ) {
953
956
pageSelectorFromURLHash ( ) ;
954
957
}
@@ -1085,7 +1088,7 @@ const reloadTab = function(ev) {
1085
1088
/******************************************************************************/
1086
1089
/******************************************************************************/
1087
1090
1088
- ( function ( ) {
1091
+ ( ( ) => {
1089
1092
const reRFC3986 = / ^ ( [ ^ : \/ ? # ] + : ) ? ( \/ \/ [ ^ \/ ? # ] * ) ? ( [ ^ ? # ] * ) ( \? [ ^ # ] * ) ? ( # .* ) ? / ;
1090
1093
const reSchemeOnly = / ^ [ \w - ] + : $ / ;
1091
1094
const staticFilterTypes = {
@@ -1203,24 +1206,35 @@ const reloadTab = function(ev) {
1203
1206
) ;
1204
1207
} ;
1205
1208
1206
- const onClick = function ( ev ) {
1209
+ const onClick = async function ( ev ) {
1207
1210
const target = ev . target ;
1208
1211
const tcl = target . classList ;
1209
1212
1210
1213
// Select a mode
1211
1214
if ( tcl . contains ( 'header' ) ) {
1212
- dialog . setAttribute ( 'data-pane' , target . getAttribute ( 'data-pane' ) ) ;
1213
1215
ev . stopPropagation ( ) ;
1216
+ dialog . setAttribute ( 'data-pane' , target . getAttribute ( 'data-pane' ) ) ;
1214
1217
return ;
1215
1218
}
1216
1219
1220
+ // Toggle temporary exception filter
1221
+ if ( tcl . contains ( 'exceptor' ) ) {
1222
+ ev . stopPropagation ( ) ;
1223
+ const status = await messaging . send ( 'loggerUI' , {
1224
+ what : 'toggleTemporaryException' ,
1225
+ filter : filterFromTargetRow ( ) ,
1226
+ } ) ;
1227
+ const row = target . closest ( 'div' ) ;
1228
+ row . classList . toggle ( 'exceptored' , status ) ;
1229
+ return ;
1230
+ }
1231
+
1217
1232
// Create static filter
1218
1233
if ( target . id === 'createStaticFilter' ) {
1234
+ ev . stopPropagation ( ) ;
1219
1235
const value = staticFilterNode ( ) . value ;
1220
1236
// Avoid duplicates
1221
- if ( createdStaticFilters . hasOwnProperty ( value ) ) {
1222
- return ;
1223
- }
1237
+ if ( createdStaticFilters . hasOwnProperty ( value ) ) { return ; }
1224
1238
createdStaticFilters [ value ] = true ;
1225
1239
if ( value !== '' ) {
1226
1240
messaging . send ( 'loggerUI' , {
@@ -1232,109 +1246,103 @@ const reloadTab = function(ev) {
1232
1246
} ) ;
1233
1247
}
1234
1248
updateWidgets ( ) ;
1235
- ev . stopPropagation ( ) ;
1236
1249
return ;
1237
1250
}
1238
1251
1239
1252
// Save url filtering rule(s)
1240
1253
if ( target . id === 'saveRules' ) {
1241
- messaging . send ( 'loggerUI' , {
1254
+ ev . stopPropagation ( ) ;
1255
+ await messaging . send ( 'loggerUI' , {
1242
1256
what : 'saveURLFilteringRules' ,
1243
1257
context : selectValue ( 'select.dynamic.origin' ) ,
1244
1258
urls : targetURLs ,
1245
1259
type : uglyTypeFromSelector ( 'dynamic' ) ,
1246
- } ) . then ( ( ) => {
1247
- colorize ( ) ;
1248
1260
} ) ;
1249
- ev . stopPropagation ( ) ;
1261
+ colorize ( ) ;
1250
1262
return ;
1251
1263
}
1252
1264
1253
1265
const persist = ! ! ev . ctrlKey || ! ! ev . metaKey ;
1254
1266
1255
1267
// Remove url filtering rule
1256
1268
if ( tcl . contains ( 'action' ) ) {
1257
- messaging . send ( 'loggerUI' , {
1269
+ ev . stopPropagation ( ) ;
1270
+ await messaging . send ( 'loggerUI' , {
1258
1271
what : 'setURLFilteringRule' ,
1259
1272
context : selectValue ( 'select.dynamic.origin' ) ,
1260
1273
url : target . getAttribute ( 'data-url' ) ,
1261
1274
type : uglyTypeFromSelector ( 'dynamic' ) ,
1262
1275
action : 0 ,
1263
1276
persist : persist ,
1264
- } ) . then ( ( ) => {
1265
- colorize ( ) ;
1266
1277
} ) ;
1267
- ev . stopPropagation ( ) ;
1278
+ colorize ( ) ;
1268
1279
return ;
1269
1280
}
1270
1281
1271
1282
// add "allow" url filtering rule
1272
1283
if ( tcl . contains ( 'allow' ) ) {
1273
- messaging . send ( 'loggerUI' , {
1284
+ ev . stopPropagation ( ) ;
1285
+ await messaging . send ( 'loggerUI' , {
1274
1286
what : 'setURLFilteringRule' ,
1275
1287
context : selectValue ( 'select.dynamic.origin' ) ,
1276
1288
url : target . parentNode . getAttribute ( 'data-url' ) ,
1277
1289
type : uglyTypeFromSelector ( 'dynamic' ) ,
1278
1290
action : 2 ,
1279
1291
persist : persist ,
1280
- } ) . then ( ( ) => {
1281
- colorize ( ) ;
1282
1292
} ) ;
1283
- ev . stopPropagation ( ) ;
1293
+ colorize ( ) ;
1284
1294
return ;
1285
1295
}
1286
1296
1287
1297
// add "block" url filtering rule
1288
1298
if ( tcl . contains ( 'noop' ) ) {
1289
- messaging . send ( 'loggerUI' , {
1299
+ ev . stopPropagation ( ) ;
1300
+ await messaging . send ( 'loggerUI' , {
1290
1301
what : 'setURLFilteringRule' ,
1291
1302
context : selectValue ( 'select.dynamic.origin' ) ,
1292
1303
url : target . parentNode . getAttribute ( 'data-url' ) ,
1293
1304
type : uglyTypeFromSelector ( 'dynamic' ) ,
1294
1305
action : 3 ,
1295
1306
persist : persist ,
1296
- } ) . then ( ( ) => {
1297
- colorize ( ) ;
1298
1307
} ) ;
1299
- ev . stopPropagation ( ) ;
1308
+ colorize ( ) ;
1300
1309
return ;
1301
1310
}
1302
1311
1303
1312
// add "block" url filtering rule
1304
1313
if ( tcl . contains ( 'block' ) ) {
1305
- messaging . send ( 'loggerUI' , {
1314
+ ev . stopPropagation ( ) ;
1315
+ await messaging . send ( 'loggerUI' , {
1306
1316
what : 'setURLFilteringRule' ,
1307
1317
context : selectValue ( 'select.dynamic.origin' ) ,
1308
1318
url : target . parentNode . getAttribute ( 'data-url' ) ,
1309
1319
type : uglyTypeFromSelector ( 'dynamic' ) ,
1310
1320
action : 1 ,
1311
1321
persist : persist ,
1312
- } ) . then ( ( ) => {
1313
- colorize ( ) ;
1314
1322
} ) ;
1315
- ev . stopPropagation ( ) ;
1323
+ colorize ( ) ;
1316
1324
return ;
1317
1325
}
1318
1326
1319
1327
// Force a reload of the tab
1320
1328
if ( tcl . contains ( 'reload' ) ) {
1329
+ ev . stopPropagation ( ) ;
1321
1330
messaging . send ( 'loggerUI' , {
1322
1331
what : 'reloadTab' ,
1323
1332
tabId : targetTabId ,
1324
1333
} ) ;
1325
- ev . stopPropagation ( ) ;
1326
1334
return ;
1327
1335
}
1328
1336
1329
1337
// Hightlight corresponding element in target web page
1330
1338
if ( tcl . contains ( 'picker' ) ) {
1339
+ ev . stopPropagation ( ) ;
1331
1340
messaging . send ( 'loggerUI' , {
1332
1341
what : 'launchElementPicker' ,
1333
1342
tabId : targetTabId ,
1334
1343
targetURL : 'img\t' + targetURLs [ 0 ] ,
1335
1344
select : true ,
1336
1345
} ) ;
1337
- ev . stopPropagation ( ) ;
1338
1346
return ;
1339
1347
}
1340
1348
} ;
@@ -1426,6 +1434,37 @@ const reloadTab = function(ev) {
1426
1434
return urls ;
1427
1435
} ;
1428
1436
1437
+ const filterFromTargetRow = function ( ) {
1438
+ return targetRow . children [ 1 ] . textContent ;
1439
+ } ;
1440
+
1441
+ const toSummaryPaneFilterNode = async function ( receiver , filter ) {
1442
+ receiver . children [ 1 ] . textContent = filter ;
1443
+ if ( filterAuthorMode !== true ) { return ; }
1444
+ const match = / # @ ? # / . exec ( filter ) ;
1445
+ if ( match === null ) { return ; }
1446
+ const fragment = document . createDocumentFragment ( ) ;
1447
+ fragment . appendChild ( document . createTextNode ( match [ 0 ] ) ) ;
1448
+ const selector = filter . slice ( match . index + match [ 0 ] . length ) ;
1449
+ const span = document . createElement ( 'span' ) ;
1450
+ span . className = 'filter' ;
1451
+ span . textContent = selector ;
1452
+ fragment . appendChild ( span ) ;
1453
+ let isTemporaryException = false ;
1454
+ if ( match [ 0 ] === '#@#' ) {
1455
+ isTemporaryException = await messaging . send ( 'loggerUI' , {
1456
+ what : 'hasTemporaryException' ,
1457
+ filter,
1458
+ } ) ;
1459
+ receiver . classList . toggle ( 'exceptored' , isTemporaryException ) ;
1460
+ }
1461
+ if ( match [ 0 ] === '##' || isTemporaryException ) {
1462
+ receiver . children [ 2 ] . style . visibility = '' ;
1463
+ }
1464
+ receiver . children [ 1 ] . textContent = '' ;
1465
+ receiver . children [ 1 ] . appendChild ( fragment ) ;
1466
+ } ;
1467
+
1429
1468
const fillSummaryPaneFilterList = async function ( rows ) {
1430
1469
const rawFilter = targetRow . children [ 1 ] . textContent ;
1431
1470
const compiledFilter = targetRow . getAttribute ( 'data-filter' ) ;
@@ -1468,7 +1507,7 @@ const reloadTab = function(ev) {
1468
1507
bestMatchFilter !== '' &&
1469
1508
Array . isArray ( response [ bestMatchFilter ] )
1470
1509
) {
1471
- rows [ 0 ] . children [ 1 ] . textContent = bestMatchFilter ;
1510
+ toSummaryPaneFilterNode ( rows [ 0 ] , bestMatchFilter ) ;
1472
1511
rows [ 1 ] . children [ 1 ] . appendChild ( nodeFromFilter (
1473
1512
bestMatchFilter ,
1474
1513
response [ bestMatchFilter ]
@@ -1499,7 +1538,7 @@ const reloadTab = function(ev) {
1499
1538
} ) ;
1500
1539
handleResponse ( response ) ;
1501
1540
}
1502
- } ;
1541
+ } ;
1503
1542
1504
1543
const fillSummaryPane = function ( ) {
1505
1544
const rows = dialog . querySelectorAll ( '.pane.details > div' ) ;
@@ -1508,12 +1547,12 @@ const reloadTab = function(ev) {
1508
1547
const trch = tr . children ;
1509
1548
let text ;
1510
1549
// Filter and context
1511
- text = trch [ 1 ] . textContent ;
1550
+ text = filterFromTargetRow ( ) ;
1512
1551
if (
1513
1552
( text !== '' ) &&
1514
1553
( trcl . contains ( 'cosmeticRealm' ) || trcl . contains ( 'networkRealm' ) )
1515
1554
) {
1516
- rows [ 0 ] . children [ 1 ] . textContent = text ;
1555
+ toSummaryPaneFilterNode ( rows [ 0 ] , text ) ;
1517
1556
} else {
1518
1557
rows [ 0 ] . style . display = 'none' ;
1519
1558
}
@@ -1753,7 +1792,7 @@ const reloadTab = function(ev) {
1753
1792
fillSummaryPane ( ) ;
1754
1793
fillDynamicPane ( ) ;
1755
1794
fillStaticPane ( ) ;
1756
- dialog . addEventListener ( 'click' , onClick , true ) ;
1795
+ dialog . addEventListener ( 'click' , ev => { onClick ( ev ) ; } , true ) ;
1757
1796
dialog . addEventListener ( 'change' , onSelectChange , true ) ;
1758
1797
dialog . addEventListener ( 'input' , onInputChange , true ) ;
1759
1798
modalDialog . show ( ) ;
0 commit comments