import { remote } from 'electron' ; import * as path from 'path' ; Polymer ( { is : 'builtin-search' , properties : { displayed : { type : Boolean , value : false , } , searching : { type : Boolean , value : false , } , activeIdx : { type : Number , value : 0 , } , webviewLoaded : { type : Boolean , value : false , } , onMount : Object , onUnmount : Object , } , focusOnInput ( ) { this . webview . focus ( ) ; this . webview . send ( 'builtin-search:focus' ) ; } , _prepareWebView ( ) { this . webview = document . createElement ( 'webview' ) as WebViewElement ; this . webview . style . width = '300px' ; this . webview . style . height = '80px' ; this . webview . style . outline = 'none' ; this . webview . setAttribute ( 'nodeintegration' , 'on' ) ; this . webview . setAttribute ( 'autosize' , 'on' ) ; this . webview . src = 'file://' + path . join ( __dirname , 'search-input.html' ) ; this . webview . addEventListener ( 'ipc-message' , ( e ) => { const channel = e . channel as string ; switch ( channel ) { case 'builtin-search:query' : { const text = ( e . args [ 0 ] || '' ) as string ; this . search ( text ) ; break ; } case 'builtin-search:close' : { this . dismiss ( ) ; break ; } default : break ; } } ) ; this . webview . addEventListener ( 'dom-ready' , ( ) => { this . webview . addEventListener ( 'blur' , ( _ ) => { this . focusOnInput ( ) ; } ) ; } ) ; document . querySelector ( '.input-workaround' ) . appendChild ( this . webview ) ; } , ready ( ) { this . button = document . querySelector ( '.builtin-search-button' ) ; this . button . addEventListener ( 'click' , ( ) => { this . search ( this . input . value ) ; } ) ; this . body = document . querySelector ( '.builtin-search-body' ) ; this . body . classList . add ( 'animated' ) ; if ( this . displayed ) { this . body . style . display = 'block' ; } this . matches = document . querySelector ( '.builtin-search-matches' ) ; remote . getCurrentWebContents ( ) . on ( 'found-in-page' , ( _ , result ) => { if ( this . requestId !== result . requestId ) { return ; } if ( result . activeMatchOrdinal ) { this . activeIdx = result . activeMatchOrdinal ; } if ( result . finalUpdate && result . matches ) { this . setResult ( this . activeIdx , result . matches ) ; } } ) ; this . up_button = document . querySelector ( '.builtin-search-up' ) ; this . up_button . addEventListener ( 'click' , ( ) => this . searchNext ( this . query , false ) ) ; this . down_button = document . querySelector ( '.builtin-search-down' ) ; this . down_button . addEventListener ( 'click' , ( ) => this . searchNext ( this . query , true ) ) ; this . close_button = document . querySelector ( '.builtin-search-close' ) ; this . close_button . addEventListener ( 'click' , ( ) => this . dismiss ( ) ) ; } , toggle ( ) { if ( this . displayed ) { this . dismiss ( ) ; } else { this . show ( ) ; } if ( this . displayed ) { this . focusOnInput ( ) ; } } , show ( ) { if ( this . displayed ) { return ; } if ( ! this . webviewLoaded ) { this . _prepareWebView ( ) ; this . webviewLoaded = true ; } this . body . classList . remove ( 'slideOutUp' ) ; this . body . classList . add ( 'slideInDown' ) ; this . body . style . display = 'block' ; this . displayed = true ; if ( this . onMount ) { this . onMount ( ) ; } } , dismiss ( ) { if ( ! this . displayed ) { return ; } const removeNode = ( ) => { this . body . style . display = 'none' ; this . body . removeEventListener ( 'animationend' , removeNode ) ; this . displayed = false ; } ; this . body . addEventListener ( 'animationend' , removeNode ) ; this . body . classList . remove ( 'slideInDown' ) ; this . body . classList . add ( 'slideOutUp' ) ; if ( this . searching ) { this . stopSearch ( ) ; } if ( this . onUnmount ) { this . onUnmount ( ) ; } } , search ( word ) { if ( word === '' ) { this . dismiss ( ) ; return ; } if ( ! this . searching || this . query !== word ) { this . requestId = remote . getCurrentWebContents ( ) . findInPage ( word ) ; this . searching = true ; this . query = word ; this . focusOnInput ( ) ; return ; } this . searchNext ( word , true ) ; } , searchNext ( text , forward ) { if ( text === '' ) { return ; } const options = { forward , findNext : true , } ; this . requestId = remote . getCurrentWebContents ( ) . findInPage ( text , options ) ; this . focusOnInput ( ) ; } , stopSearch ( ) { if ( ! this . searching ) { return ; } this . setResult ( 0 , 0 ) ; remote . getCurrentWebContents ( ) . stopFindInPage ( 'clearSelection' ) ; this . searching = false ; this . query = '' ; this . requestId = undefined ; this . activeIdx = 0 ; } , setResult ( no , all ) { this . matches . innerText = `${ no }/${ all }` ; } , } ) ;