@@ -40,6 +40,7 @@ var logger = self.logger;
4040var messager = logger . messager ;
4141
4242var inspectedTabId = '' ;
43+ var inspectedURL = '' ;
4344var inspectedHostname = '' ;
4445var pollTimer = null ;
4546var fingerprint = null ;
@@ -282,7 +283,48 @@ var nidFromNode = function(node) {
282283
283284var startDialog = ( function ( ) {
284285 var dialog = uDom . nodeFromId ( 'cosmeticFilteringDialog' ) ;
285- var candidateFilters = [ ] ;
286+ var textarea = dialog . querySelector ( 'textarea' ) ;
287+ var hideSelectors = [ ] ;
288+ var unhideSelectors = [ ] ;
289+ var inputTimer = null ;
290+
291+ var onInputChanged = ( function ( ) {
292+ var parse = function ( ) {
293+ inputTimer = null ;
294+ hideSelectors = [ ] ;
295+ unhideSelectors = [ ] ;
296+
297+ var line , matches ;
298+ var re = / ^ ( [ ^ # ] * ) ( # @ ? # ) ( .+ ) $ / ;
299+ var lines = textarea . value . split ( / \s * \n \s * / ) ;
300+ for ( var i = 0 ; i < lines . length ; i ++ ) {
301+ line = lines [ i ] . trim ( ) ;
302+ if ( line === '' || line . charAt ( 0 ) === '!' ) {
303+ continue ;
304+ }
305+ matches = re . exec ( line ) ;
306+ if ( matches === null || matches . length !== 4 ) {
307+ continue ;
308+ }
309+ if ( inspectedHostname . lastIndexOf ( matches [ 1 ] ) === - 1 ) {
310+ continue ;
311+ }
312+ if ( matches [ 2 ] === '##' ) {
313+ hideSelectors . push ( matches [ 3 ] ) ;
314+ } else {
315+ unhideSelectors . push ( matches [ 3 ] ) ;
316+ }
317+ }
318+
319+ showCommitted ( ) ;
320+ } ;
321+
322+ return function parseAsync ( ) {
323+ if ( inputTimer === null ) {
324+ inputTimer = vAPI . setTimeout ( parse , 743 ) ;
325+ }
326+ } ;
327+ } ) ( ) ;
286328
287329 var onClick = function ( ev ) {
288330 var target = ev . target ;
@@ -292,45 +334,94 @@ var startDialog = (function() {
292334 return stop ( ) ;
293335 }
294336 ev . stopPropagation ( ) ;
337+
338+ if ( target . id === 'createCosmeticFilters' ) {
339+ messager . send ( { what : 'createUserFilter' , filters : textarea . value } ) ;
340+ // Force a reload for the new cosmetic filter(s) to take effect
341+ messager . send ( { what : 'reloadTab' , tabId : inspectedTabId } ) ;
342+ return stop ( ) ;
343+ }
295344 } ;
296345
297- var stop = function ( ) {
298- dialog . removeEventListener ( 'click' , onClick , true ) ;
299- document . body . removeChild ( dialog ) ;
346+ var onCooked = function ( entries ) {
347+ if ( Array . isArray ( entries ) === false ) {
348+ return ;
349+ }
350+ hideSelectors = entries ;
351+ var taValue = [ ] , i , node ;
352+ var d = new Date ( ) ;
353+ taValue . push ( '! ' + d . toLocaleString ( ) + ' ' + inspectedURL ) ;
354+ for ( i = 0 ; i < entries . length ; i ++ ) {
355+ taValue . push ( inspectedHostname + '##' + entries [ i ] ) ;
356+ }
357+ var nodes = domTree . querySelectorAll ( 'code.filter.off' ) ;
358+ for ( i = 0 ; i < nodes . length ; i ++ ) {
359+ node = nodes [ i ] ;
360+ unhideSelectors . push ( node . textContent ) ;
361+ taValue . push ( inspectedHostname + '#@#' + node . textContent ) ;
362+ }
363+ textarea . value = taValue . join ( '\n' ) ;
364+ document . body . appendChild ( dialog ) ;
365+ dialog . addEventListener ( 'click' , onClick , true ) ;
366+ showCommitted ( ) ;
367+ } ;
368+
369+ var showCommitted = function ( ) {
370+ messager . sendTo (
371+ {
372+ what : 'showCommitted' ,
373+ hide : hideSelectors . join ( ',\n' ) ,
374+ unhide : unhideSelectors . join ( ',\n' )
375+ } ,
376+ inspectedTabId ,
377+ 'dom-inspector.js'
378+ ) ;
379+ } ;
380+
381+ var showInteractive = function ( ) {
382+ messager . sendTo (
383+ {
384+ what : 'showInteractive' ,
385+ hide : hideSelectors . join ( ',\n' ) ,
386+ unhide : unhideSelectors . join ( ',\n' )
387+ } ,
388+ inspectedTabId ,
389+ 'dom-inspector.js'
390+ ) ;
300391 } ;
301392
302393 var start = function ( ) {
303- // Collect all selectors which are currently toggled
304- var node , filters = [ ] ;
394+ textarea . addEventListener ( 'input' , onInputChanged ) ;
395+ var node , entries = [ ] ;
305396 var nodes = domTree . querySelectorAll ( 'code.off' ) ;
306397 for ( var i = 0 ; i < nodes . length ; i ++ ) {
307398 node = nodes [ i ] ;
308- if ( node . classList . contains ( 'filter' ) ) {
309- filters . push ( {
310- prefix : '#@#' ,
311- nid : '' ,
312- selector : node . textContent
313- } ) ;
314- } else {
315- filters . push ( {
316- prefix : '##' ,
399+ if ( node . classList . contains ( 'filter' ) === false ) {
400+ entries . push ( {
317401 nid : nidFromNode ( node ) ,
318- selector : node . textContent
402+ selector : selectorFromNode ( node )
319403 } ) ;
320404 }
321405 }
406+ messager . sendTo (
407+ { what : 'cookFilters' , entries : entries } ,
408+ inspectedTabId ,
409+ 'dom-inspector.js' ,
410+ onCooked
411+ ) ;
412+ } ;
322413
323- // TODO: Send filters through dom-inspector.js for further processing.
324-
325- candidateFilters = filters ;
326- var taValue = [ ] , filter ;
327- for ( i = 0 ; i < filters . length ; i ++ ) {
328- filter = filters [ i ] ;
329- taValue . push ( inspectedHostname + filter . prefix + filter . selector ) ;
414+ var stop = function ( ) {
415+ if ( inputTimer !== null ) {
416+ clearTimeout ( inputTimer ) ;
417+ inputTimer = null ;
330418 }
331- dialog . querySelector ( 'textarea' ) . value = taValue . join ( '\n' ) ;
332- document . body . appendChild ( dialog ) ;
333- dialog . addEventListener ( 'click' , onClick , true ) ;
419+ showInteractive ( ) ;
420+ hideSelectors = [ ] ;
421+ unhideSelectors = [ ] ;
422+ textarea . removeEventListener ( 'input' , onInputChanged ) ;
423+ dialog . removeEventListener ( 'click' , onClick , true ) ;
424+ document . body . removeChild ( dialog ) ;
334425 } ;
335426
336427 return start ;
@@ -404,7 +495,10 @@ var onMouseOver = (function() {
404495 if ( inspectedTabId === '' ) {
405496 return ;
406497 }
407-
498+ // Convenience: skip real-time highlighting if shift key is pressed.
499+ if ( ev . shiftKey ) {
500+ return ;
501+ }
408502 // Find closest `li`
409503 var target = ev . target ;
410504 while ( target !== null ) {
@@ -447,6 +541,7 @@ var fetchDOMAsync = (function() {
447541 case 'full' :
448542 renderDOMFull ( response ) ;
449543 fingerprint = response . fingerprint ;
544+ inspectedURL = response . url ;
450545 inspectedHostname = response . hostname ;
451546 break ;
452547
0 commit comments