import * as key from 'keymaster' ; class PluginState { state : any ; constructor ( state ) { for ( let key in state ) { this [ key ] = state [ key ] ; } } getFullState ( ) { return this ; } set ( obj ) { for ( let key in obj ) { this [ key ] = obj [ key ] ; } } } export class Plugin { pluginName : string ; urlRegex : any ; shortcuts : any [ ] ; pluginState : any ; constructor ( pluginName , urlRegex , shortcuts , state ) { this . pluginName = pluginName ; this . urlRegex = urlRegex ; this . shortcuts = shortcuts ; this . pluginState = new PluginState ( state ) ; this . init ( ) ; } init ( ) { chrome . runtime . onMessage . addListener ( ( request , sender , sendResponse ) => { if ( request . handshake ) { sendResponse ( { handshake : true } ) ; } else if ( request . loadShortcuts ) { key . filter = ( event ) => true ; for ( let s of this . shortcuts ) { key ( s . keys . join ( ', ' ) , ( event , handler ) => { s . action ( event , this . pluginState ) ; chrome . runtime . sendMessage ( { logEvent : true , eventCategory : 'shortcut-triggered' , eventAction : this . pluginName , eventLabel : s . keys . join ( ', ' ) } ) ; } ) ; } } } ) ; } getShortcutsMDS ( ) { return this . shortcuts . filter ( ( s ) => { return s . showInPanel ; } ) . map ( ( s ) => { let shortcut = JSON . parse ( JSON . stringify ( s ) ) ; delete shortcut . showInPanel ; shortcut . keys = s . keys . map ( key => { return { default : [ key ] } ; } ) ; return shortcut ; } ) ; } getFileName ( ) { return this . pluginName . replace ( ' ' , '-' ) . toLowerCase ( ) ; } } export class PluginBuilder { pluginName : string ; urlRegex : any ; shortcuts : any ; state : any ; constructor ( ) { this . shortcuts = { } ; this . state = { } ; } registerShortcut ( name , keys , action , options ? ) { if ( ! name ) { throw 'Must include a name.' ; } if ( typeof keys === 'string' ) { keys = [ keys ] ; } let config = { keys : keys , action : action , showInPanel : true } ; if ( options && ! options . showInPanel ) { config . showInPanel = false ; } this . validateConfig ( config ) ; this . shortcuts [ name ] = config ; } setPluginName ( pluginName ) { this . pluginName = pluginName ; } setUrlRegex ( urlRegex ) { this . urlRegex = urlRegex ; } validateConfig ( config ) { if ( config . keys . constructor !== Array ) { throw 'Invalid or missing keys' ; } if ( typeof config [ 'action' ] !== 'function' ) { throw 'Invalid or missing action' ; } return true ; } setInitialState ( state ) { this . state = state ; } build ( ) { if ( ! this . pluginName ) { throw 'Plugin name is missing' ; } if ( ! this . urlRegex ) { throw 'URL regex is missing' ; } let shortcuts = [ ] ; for ( let name in this . shortcuts ) { shortcuts . push ( { name : name , keys : this . shortcuts [ name ] . keys , action : this . shortcuts [ name ] . action , showInPanel : this . shortcuts [ name ] . showInPanel } ) ; } return new Plugin ( this . pluginName , this . urlRegex , shortcuts , this . state ) ; } }