Merge branch 'error-line'
This commit is contained in:
		
						commit
						044f24efb6
					
				
					 13 changed files with 226 additions and 130 deletions
				
			
		|  | @ -18,6 +18,6 @@ | |||
|     "sessions" | ||||
|   ], | ||||
|   "web_accessible_resources": [ | ||||
|     "build/command-line.html" | ||||
|     "build/console.html" | ||||
|   ] | ||||
| } | ||||
|  |  | |||
|  | @ -1,19 +0,0 @@ | |||
| import './command-line-frame.scss'; | ||||
| 
 | ||||
| export default class CommandLineFrame { | ||||
|   constructor(win, initial = '') { | ||||
|     let url = browser.runtime.getURL('build/command-line.html') + | ||||
|       '#' + encodeURIComponent(initial); | ||||
| 
 | ||||
|     let element = window.document.createElement('iframe'); | ||||
|     element.src = url; | ||||
|     element.className = 'vimvixen-command-line-frame'; | ||||
|     win.document.body.append(element); | ||||
| 
 | ||||
|     this.element = element; | ||||
|   } | ||||
| 
 | ||||
|   remove() { | ||||
|     this.element.remove(); | ||||
|   } | ||||
| } | ||||
|  | @ -1,18 +0,0 @@ | |||
| <!doctype html> | ||||
| <html> | ||||
|   <head> | ||||
|     <meta charset=utf-8 /> | ||||
|     <title>VimVixen command-line</title> | ||||
|     <script src='command-line.js'></script> | ||||
|   </head> | ||||
|   <body class='vimvixen-command-line'> | ||||
|     <div> | ||||
|       <p class='vimvixen-command-line-title'></p> | ||||
|       <div class='vimvixen-command-line-line'> | ||||
|         <i class='vimvixen-command-line-line-prompt'></i><input | ||||
|           id='vimvixen-command-line-line-input' | ||||
|           class='vimvixen-command-line-line-input'></input> | ||||
|       </div> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
|  | @ -1,64 +0,0 @@ | |||
| import './command-line.scss'; | ||||
| 
 | ||||
| const parent = window.parent; | ||||
| 
 | ||||
| // TODO consider object-oriented
 | ||||
| var prevValue = ""; | ||||
| 
 | ||||
| const blurData = () => { | ||||
|   return JSON.stringify({ | ||||
|     type: 'vimvixen.commandline.blur' | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| const keydownData = (input) => { | ||||
|   return JSON.stringify({ | ||||
|     type: 'vimvixen.commandline.enter', | ||||
|     value: input.value | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| const keyupData = (input) => { | ||||
|   return JSON.stringify({ | ||||
|     type: 'vimvixen.commandline.change', | ||||
|     value: input.value | ||||
|   }); | ||||
| }; | ||||
| 
 | ||||
| const handleBlur = () => { | ||||
|   parent.postMessage(blurData(), '*'); | ||||
| }; | ||||
| 
 | ||||
| const handleKeydown = (e) => { | ||||
|   switch(e.keyCode) { | ||||
|   case KeyboardEvent.DOM_VK_ESCAPE: | ||||
|     parent.postMessage(blurData(), '*'); | ||||
|     break; | ||||
|   case KeyboardEvent.DOM_VK_RETURN: | ||||
|     parent.postMessage(keydownData(e.target), '*'); | ||||
|     break; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const handleKeyup = (e) => { | ||||
|   if (e.target.value === prevValue) { | ||||
|     return; | ||||
|   } | ||||
|   parent.postMessage(keyupData(e.target), '*'); | ||||
|   prevValue = e.target.value; | ||||
| }; | ||||
| 
 | ||||
| window.addEventListener('load', () => { | ||||
|   let hash = window.location.hash; | ||||
|   let initial = ''; | ||||
|   if (hash.length > 0) { | ||||
|     initial = decodeURIComponent(hash.substring(1)); | ||||
|   } | ||||
| 
 | ||||
|   let input = window.document.querySelector('#vimvixen-command-line-line-input'); | ||||
|   input.addEventListener('blur', handleBlur); | ||||
|   input.addEventListener('keydown', handleKeydown); | ||||
|   input.addEventListener('keyup', handleKeyup); | ||||
|   input.value = initial; | ||||
|   input.focus(); | ||||
| }); | ||||
							
								
								
									
										44
									
								
								src/console/console-frame.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/console/console-frame.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| import './console-frame.scss'; | ||||
| import * as messages from '../shared/messages'; | ||||
| 
 | ||||
| export default class ConsoleFrame { | ||||
|   constructor(win) { | ||||
|     let element = window.document.createElement('iframe'); | ||||
|     element.src = browser.runtime.getURL('build/console.html'); | ||||
|     element.className = 'vimvixen-console-frame'; | ||||
|     win.document.body.append(element); | ||||
| 
 | ||||
|     this.element = element; | ||||
| 
 | ||||
|     this.hide(); | ||||
|   } | ||||
| 
 | ||||
|   showCommand(text) { | ||||
|     this.showFrame(); | ||||
| 
 | ||||
|     let message = { | ||||
|       type: 'vimvixen.console.show.command', | ||||
|       text: text | ||||
|     }; | ||||
|     messages.send(this.element.contentWindow, message); | ||||
|   } | ||||
| 
 | ||||
|   showError(text) { | ||||
|     this.showFrame(); | ||||
| 
 | ||||
|     let message = { | ||||
|       type: 'vimvixen.console.show.error', | ||||
|       text: text | ||||
|     }; | ||||
|     messages.send(this.element.contentWindow, message); | ||||
|   } | ||||
| 
 | ||||
|   showFrame() { | ||||
|     this.element.style.display = 'block'; | ||||
|   } | ||||
| 
 | ||||
|   hide() { | ||||
|     this.element.style.display = 'none'; | ||||
|     this.element.blur(); | ||||
|   } | ||||
| } | ||||
|  | @ -1,4 +1,4 @@ | |||
| .vimvixen-command-line-frame { | ||||
| .vimvixen-console-frame { | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
|   bottom: 0; | ||||
|  | @ -8,4 +8,5 @@ | |||
|   position: fixed; | ||||
|   z-index: 10000; | ||||
|   border: none; | ||||
|   pointer-events:none; | ||||
| } | ||||
							
								
								
									
										20
									
								
								src/console/console.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/console/console.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| <!doctype html> | ||||
| <html> | ||||
|   <head> | ||||
|     <meta charset=utf-8 /> | ||||
|     <title>VimVixen console</title> | ||||
|     <script src='console.js'></script> | ||||
|   </head> | ||||
|   <body class='vimvixen-console'> | ||||
|     <p id='vimvixen-console-error' | ||||
|        class='vimvixen-console-error'></p> | ||||
|     <div id='vimvixen-console-command'> | ||||
|       <p class='vimvixen-console-title'></p> | ||||
|       <div class='vimvixen-console-command'> | ||||
|         <i class='vimvixen-console-command-prompt'></i><input | ||||
|           id='vimvixen-console-command-input' | ||||
|           class='vimvixen-console-command-input'></input> | ||||
|       </div> | ||||
|     </div> | ||||
|   </body> | ||||
| </html> | ||||
							
								
								
									
										89
									
								
								src/console/console.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/console/console.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,89 @@ | |||
| import './console.scss'; | ||||
| import * as messages from '../shared/messages'; | ||||
| 
 | ||||
| const parent = window.parent; | ||||
| 
 | ||||
| // TODO consider object-oriented
 | ||||
| var prevValue = ""; | ||||
| 
 | ||||
| const blurMessage = () => { | ||||
|   return { | ||||
|     type: 'vimvixen.commandline.blur' | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const keydownMessage = (input) => { | ||||
|   return { | ||||
|     type: 'vimvixen.commandline.enter', | ||||
|     value: input.value | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const keyupMessage = (input) => { | ||||
|   return { | ||||
|     type: 'vimvixen.commandline.change', | ||||
|     value: input.value | ||||
|   }; | ||||
| }; | ||||
| 
 | ||||
| const handleBlur = () => { | ||||
|   messages.send(parent, blurMessage()); | ||||
| }; | ||||
| 
 | ||||
| const handleKeydown = (e) => { | ||||
|   switch(e.keyCode) { | ||||
|   case KeyboardEvent.DOM_VK_ESCAPE: | ||||
|     messages.send(parent, blurMessage()); | ||||
|     break; | ||||
|   case KeyboardEvent.DOM_VK_RETURN: | ||||
|     messages.send(parent, keydownMessage(e.target)); | ||||
|     break; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| const handleKeyup = (e) => { | ||||
|   if (e.target.value === prevValue) { | ||||
|     return; | ||||
|   } | ||||
|   messages.send(parent, keyupMessage(e.target)); | ||||
|   prevValue = e.target.value; | ||||
| }; | ||||
| 
 | ||||
| window.addEventListener('load', () => { | ||||
|   let input = window.document.querySelector('#vimvixen-console-command-input'); | ||||
|   input.addEventListener('blur', handleBlur); | ||||
|   input.addEventListener('keydown', handleKeydown); | ||||
|   input.addEventListener('keyup', handleKeyup); | ||||
| }); | ||||
| 
 | ||||
| const showCommand = (text) => { | ||||
|   let input = window.document.querySelector('#vimvixen-console-command-input'); | ||||
|   input.value = text; | ||||
|   input.focus(); | ||||
| 
 | ||||
|   let command = window.document.querySelector('#vimvixen-console-command'); | ||||
|   command.style.display = 'block'; | ||||
| 
 | ||||
|   let error = window.document.querySelector('#vimvixen-console-error'); | ||||
|   error.style.display = 'none'; | ||||
| } | ||||
| 
 | ||||
| const showError = (text) => { | ||||
|   let error = window.document.querySelector('#vimvixen-console-error'); | ||||
|   error.textContent = text; | ||||
|   error.style.display = 'block'; | ||||
| 
 | ||||
|   let command = window.document.querySelector('#vimvixen-console-command'); | ||||
|   command.style.display = 'none'; | ||||
| } | ||||
| 
 | ||||
| messages.receive(window, (message) => { | ||||
|   switch (message.type) { | ||||
|   case 'vimvixen.console.show.command': | ||||
|     showCommand(message.text); | ||||
|     break; | ||||
|   case 'vimvixen.console.show.error': | ||||
|     showError(message.text); | ||||
|     break; | ||||
|   } | ||||
| }); | ||||
|  | @ -10,16 +10,25 @@ body { | |||
|   right: 0; | ||||
| } | ||||
| 
 | ||||
| .vimvixen-command-line { | ||||
| .vimvixen-console { | ||||
|   border-top: 1px solid gray; | ||||
|   bottom: 0; | ||||
|   margin: 0; | ||||
|   padding: 0; | ||||
| 
 | ||||
|   @mixin input-style { | ||||
|   @mixin consoole-font { | ||||
|     font-style: normal; | ||||
|     font-family: monospace; | ||||
|     font-size: 12px; | ||||
|     line-height: 16px; | ||||
|   } | ||||
| 
 | ||||
|   &-error { | ||||
|     background-color: red; | ||||
|     font-weight: bold; | ||||
|     color: white; | ||||
| 
 | ||||
|     @include consoole-font; | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -29,24 +38,24 @@ body { | |||
|     margin: 0; | ||||
|     padding: 0; | ||||
| 
 | ||||
|     @include input-style; | ||||
|     @include consoole-font; | ||||
|   } | ||||
| 
 | ||||
|   &-line { | ||||
|   &-command { | ||||
|     background-color: white; | ||||
|     display: flex; | ||||
| 
 | ||||
|     &-prompt:before { | ||||
|       content: ':'; | ||||
| 
 | ||||
|       @include input-style; | ||||
|       @include consoole-font; | ||||
|     } | ||||
| 
 | ||||
|     &-input { | ||||
|       border: none; | ||||
|       flex-grow: 1; | ||||
| 
 | ||||
|       @include input-style; | ||||
|       @include consoole-font; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | @ -1,10 +1,11 @@ | |||
| import * as scrolls from './scrolls'; | ||||
| import * as histories from './histories'; | ||||
| import * as actions from '../shared/actions'; | ||||
| import CommandLineFrame from '../command-line/command-line-frame'; | ||||
| import * as messages from '../shared/messages'; | ||||
| import ConsoleFrame from '../console/console-frame'; | ||||
| import Follow from './follow'; | ||||
| 
 | ||||
| let cmd = null; | ||||
| let vvConsole = new ConsoleFrame(window); | ||||
| 
 | ||||
| const invokeEvent = (action) => { | ||||
|   if (typeof action === 'undefined' || action === null) { | ||||
|  | @ -13,14 +14,14 @@ const invokeEvent = (action) => { | |||
| 
 | ||||
|   switch (action[0]) { | ||||
|   case actions.CMD_OPEN: | ||||
|     cmd = new CommandLineFrame(window); | ||||
|     vvConsole.showCommand(''); | ||||
|     break; | ||||
|   case actions.CMD_TABS_OPEN: | ||||
|     if (action[1] || false) { | ||||
|       // alter url
 | ||||
|       cmd = new CommandLineFrame(window, 'open ' + window.location.href); | ||||
|       vvConsole.showCommand('open ' + window.location.href); | ||||
|     } else { | ||||
|       cmd = new CommandLineFrame(window, 'open '); | ||||
|       vvConsole.showCommand('open '); | ||||
|     } | ||||
|     break; | ||||
|   case actions.SCROLL_LINES: | ||||
|  | @ -71,21 +72,10 @@ window.addEventListener("keypress", (e) => { | |||
|       }); | ||||
| }); | ||||
| 
 | ||||
| window.addEventListener('message', (e) => { | ||||
|   let message; | ||||
|   try { | ||||
|     message = JSON.parse(e.data); | ||||
|   } catch (e) { | ||||
|     // ignore message posted by author of web page
 | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
| messages.receive(window, (message) => { | ||||
|   switch (message.type) { | ||||
|   case 'vimvixen.commandline.blur': | ||||
|     if (cmd) { | ||||
|       cmd.remove(); | ||||
|       cmd = null; | ||||
|     } | ||||
|     vvConsole.hide(); | ||||
|     break; | ||||
|   case 'vimvixen.commandline.enter': | ||||
|     browser.runtime.sendMessage({ | ||||
|  |  | |||
							
								
								
									
										19
									
								
								src/shared/messages.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/shared/messages.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| const receive = (win, callback) => { | ||||
|   win.addEventListener('message', (e) => { | ||||
|     let message; | ||||
|     try { | ||||
|       message = JSON.parse(e.data); | ||||
|     } catch (e) { | ||||
|       // ignore message posted by author of web page
 | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     callback(message); | ||||
|   }) | ||||
| } | ||||
| 
 | ||||
| const send = (win, message) => { | ||||
|   win.postMessage(JSON.stringify(message), '*'); | ||||
| } | ||||
| 
 | ||||
| export { receive, send }; | ||||
							
								
								
									
										25
									
								
								test/shared/messages.test.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								test/shared/messages.test.js
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | |||
| import { expect } from "chai"; | ||||
| import * as messages from '../../src/shared/messages'; | ||||
| 
 | ||||
| describe('messages', () => { | ||||
|   describe('#receive', () => { | ||||
|     it('received a message', (done) => { | ||||
|       messages.receive(window, (message) => { | ||||
|         expect(message).to.deep.equal({ type: 'vimvixen.test' }); | ||||
|         done(); | ||||
|       }); | ||||
|       window.postMessage(JSON.stringify({ type: 'vimvixen.test' }), '*'); | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   describe('#send', () => { | ||||
|     it('sends a message', (done) => { | ||||
|       window.addEventListener('message', (e) => { | ||||
|         let json = JSON.parse(e.data); | ||||
|         expect(json).to.deep.equal({ type: 'vimvixen.test' }); | ||||
|         done(); | ||||
|       }); | ||||
|       messages.send(window, { type: 'vimvixen.test' }); | ||||
|     }); | ||||
|   }); | ||||
| }); | ||||
|  | @ -8,7 +8,7 @@ module.exports = { | |||
|   entry: { | ||||
|     index: path.join(src, 'content'), | ||||
|     background: path.join(src, 'background'), | ||||
|     'command-line': path.join(src, 'command-line', 'command-line.js') | ||||
|     console: path.join(src, 'console', 'console.js') | ||||
|   }, | ||||
| 
 | ||||
|   output: { | ||||
|  | @ -43,8 +43,8 @@ module.exports = { | |||
| 
 | ||||
|   plugins: [ | ||||
|     new HtmlWebpackPlugin({ | ||||
|       template: path.join(src, 'command-line', 'command-line.html'), | ||||
|       filename: path.join(dist, 'command-line.html'), | ||||
|       template: path.join(src, 'console', 'console.html'), | ||||
|       filename: path.join(dist, 'console.html'), | ||||
|       inject: false | ||||
|     }) | ||||
|   ] | ||||
|  |  | |||
		Reference in a new issue