Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Listen for shift-backspace or unmodified backspace and navigate if not in | 1 // Copyright 2016 Google Inc. All rights reserved. |
| 2 // an editable field. We capture the event at the Window to let any handlers | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // or listeners registered on the Document have a chance to handle it first. | 3 // found in the LICENSE file. |
| 4 window.addEventListener('keydown', function(e) { | 4 |
| 5 // Load the options, then register a keyboard listener. We capture the event | |
| 6 // at the Window to let any handlers or listeners registered on the Document | |
| 7 // have a chance to handle it first. | |
| 8 var options; | |
| 9 chrome.storage.sync.get({ | |
| 10 blacklist: [], | |
| 11 disableInApplets: true, | |
| 12 whitelist: [] | |
| 13 }, function(items) { | |
| 14 options = items; | |
| 15 window.addEventListener('keydown', function(e) { | |
| 16 handleBackspace(e); | |
| 17 }); | |
| 18 }); | |
| 19 | |
| 20 // Update the local options when they're changed externally. | |
| 21 chrome.storage.onChanged.addListener(function(changes, area) { | |
| 22 if (area === 'sync') { | |
| 23 if (changes.blacklist) | |
| 24 options.blacklist = changes.blacklist.newValue; | |
| 25 if (changes.disableInApplets) | |
| 26 options.disableInApplets = changes.disableInApplets.newValue; | |
| 27 if (changes.whitelist) | |
| 28 options.whitelist = changes.whitelist.newValue; | |
| 29 } | |
| 30 }); | |
| 31 | |
| 32 // Check for shift-backspace or unmodified backspace and navigate if | |
| 33 // applicable. | |
| 34 function handleBackspace(e) { | |
| 35 if (e.defaultPrevented || | |
| 36 e.key !== 'Backspace' || | |
| 37 e.altKey || | |
| 38 e.ctrlKey || | |
| 39 e.metaKey) | |
| 40 return; | |
| 41 | |
| 42 // The blacklist overrides everything. | |
| 43 var url = window.location.href; | |
| 44 if (options.blacklist.includes(url)) | |
| 45 return; | |
| 46 | |
| 47 // The whitelist overrides applet focus. | |
| 5 // Listening on the Window means the event has no path (see | 48 // Listening on the Window means the event has no path (see |
| 6 // http://crbug.com/645527), so we'll have to look at the focused (active) | 49 // http://crbug.com/645527), so we'll have to look at the focused (active) |
| 7 // element. This means it will not work properly with shadow DOM. | 50 // element. This means it will not work properly with shadow DOM. |
| 8 // TODO: Fix behavior with shadow DOM when the above bug is resolved. | 51 // TODO: Fix behavior with shadow DOM when the above bug is resolved. |
| 9 if (e.key === 'Backspace' && | 52 if (!options.whitelist.includes(url) && |
| 10 !e.defaultPrevented && | 53 disabledInApplet(document.activeElement)) |
| 11 !e.altKey && | 54 return; |
| 12 !e.ctrlKey && | 55 if (isEditable(document.activeElement)) |
| 13 !e.metaKey && | 56 return; |
| 14 !isEditable(document.activeElement)) { | 57 |
| 15 e.shiftKey ? window.history.forward(): window.history.back(); | 58 e.shiftKey ? window.history.forward(): window.history.back(); |
| 16 e.preventDefault(); | 59 e.preventDefault(); |
| 60 } | |
| 61 | |
| 62 // Return true if the option to diable the extension in applets is enabled, and | |
|
ojan
2016/09/15 19:07:15
typo: diable
| |
| 63 // focus is in an embedded Flash or Java applet. | |
| 64 function disabledInApplet(target) { | |
| 65 if (!options.disableInApplets) | |
| 66 return false; | |
| 67 | |
| 68 var nodeName = target.nodeName.toUpperCase(); | |
| 69 var nodeType = target.type || ''; | |
| 70 nodeType = nodeType.toLowerCase(); | |
| 71 if ((nodeName === 'EMBED' || nodeName === 'OBJECT') && | |
| 72 (nodeType === 'application/x-shockwave-flash' || | |
| 73 nodeType === 'application/java')) { | |
| 74 return true; | |
| 17 } | 75 } |
| 18 }); | 76 return false; |
| 77 } | |
| OLD | NEW |