| OLD | NEW |
| 1 // Copyright 2016 Google Inc. All rights reserved. | 1 // Copyright 2016 Google Inc. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Load the options, then register a keyboard listener. We capture the event | 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 | 6 // at the Window to let any handlers or listeners registered on the Document |
| 7 // have a chance to handle it first. | 7 // have a chance to handle it first. |
| 8 var options; | 8 var options; |
| 9 chrome.storage.sync.get({ | 9 chrome.storage.sync.get({ |
| 10 blacklist: [], | 10 blacklist: [], |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 e.metaKey || | 37 e.metaKey || |
| 38 window.history.length < 2) // Nowhere to go back or forward to anyway. | 38 window.history.length < 2) // Nowhere to go back or forward to anyway. |
| 39 return; | 39 return; |
| 40 | 40 |
| 41 // The blacklist overrides everything. | 41 // The blacklist overrides everything. |
| 42 var url = window.location.href; | 42 var url = window.location.href; |
| 43 if (options.blacklist.includes(url)) | 43 if (options.blacklist.includes(url)) |
| 44 return; | 44 return; |
| 45 | 45 |
| 46 // The whitelist overrides applet focus. | 46 // The whitelist overrides applet focus. |
| 47 // Listening on the Window means the event has no path (see | 47 // Before Chrome 55, listening on the Window means the event has no path, |
| 48 // http://crbug.com/645527), so we'll have to look at the focused (active) | 48 // instead pointing to the Window (see http://crbug.com/645527). In that |
| 49 // element. This means it will not work properly with shadow DOM. | 49 // case, we have to look at the focused (active) element. |
| 50 // TODO: Fix behavior with shadow DOM when the above bug is resolved. | 50 // TODO: Switch entirely to e.path once Chrome 55 is launched. |
| 51 if (!options.whitelist.includes(url) && | 51 var target = e.path[0]; |
| 52 disabledInApplet(document.activeElement)) | 52 if (target === window) |
| 53 target = document.activeElement; |
| 54 if (disabledInApplet(url, target)) |
| 53 return; | 55 return; |
| 54 if (isEditable(document.activeElement)) | 56 if (isEditable(target)) |
| 55 return; | 57 return; |
| 56 | 58 |
| 57 // Make sure this extension is still active. | 59 // Make sure this extension is still active. |
| 58 // sendMessage throws an internal error, not reported in lastError, if the | 60 // sendMessage throws an internal error, not reported in lastError, if the |
| 59 // other end no longer exists. So we use JS error-catching rather than | 61 // other end no longer exists. So we use JS error-catching rather than |
| 60 // extension errors. See http://crbug.com/650872 | 62 // extension errors. See http://crbug.com/650872 |
| 61 try { | 63 try { |
| 62 chrome.runtime.sendMessage('', function(response) { | 64 chrome.runtime.sendMessage('', function(response) { |
| 63 // Future-proofing in case sendMessage ever changes to setting lastError | 65 // Future-proofing in case sendMessage ever changes to setting lastError |
| 64 // instead of throwing a JS error. | 66 // instead of throwing a JS error. |
| 65 if (chrome.runtime.lastError) { | 67 if (chrome.runtime.lastError) { |
| 66 window.removeEventListener('keydown', handleBackspace); | 68 window.removeEventListener('keydown', handleBackspace); |
| 67 } else { | 69 } else { |
| 68 e.shiftKey ? window.history.forward(): window.history.back(); | 70 e.shiftKey ? window.history.forward(): window.history.back(); |
| 69 e.preventDefault(); | 71 e.preventDefault(); |
| 70 } | 72 } |
| 71 }); | 73 }); |
| 72 } catch(error) { | 74 } catch(error) { |
| 73 // If we have no connection to the background page, the extension has | 75 // If we have no connection to the background page, the extension has |
| 74 // been updated, disabled, or uninstalled. Remove our listener and do | 76 // been updated, disabled, or uninstalled. Remove our listener and do |
| 75 // nothing. | 77 // nothing. |
| 76 window.removeEventListener('keydown', handleBackspace); | 78 window.removeEventListener('keydown', handleBackspace); |
| 77 } | 79 } |
| 78 } | 80 } |
| 79 | 81 |
| 80 // Return true if the option to disable the extension in applets is enabled, | 82 // Return true if the option to disable the extension in applets is enabled, |
| 81 // and focus is in an embedded Flash or Java applet. | 83 // focus is in an embedded Flash or Java applet, and the current page is not |
| 82 function disabledInApplet(target) { | 84 // in the whitelist of pages for which that should not apply. |
| 83 if (!options.disableInApplets) | 85 function disabledInApplet(url, target) { |
| 86 if (!options.disableInApplets || options.whitelist.includes(url)) |
| 84 return false; | 87 return false; |
| 85 | 88 |
| 86 var nodeName = target.nodeName.toUpperCase(); | 89 var nodeName = target.nodeName.toUpperCase(); |
| 87 var nodeType = target.type || ''; | 90 var nodeType = target.type || ''; |
| 88 nodeType = nodeType.toLowerCase(); | 91 nodeType = nodeType.toLowerCase(); |
| 89 if ((nodeName === 'EMBED' || nodeName === 'OBJECT') && | 92 if ((nodeName === 'EMBED' || nodeName === 'OBJECT') && |
| 90 (nodeType === 'application/java' || | 93 (nodeType === 'application/java' || |
| 91 nodeType === 'application/pdf' || | 94 nodeType === 'application/pdf' || |
| 92 nodeType === 'application/x-chat' || | 95 nodeType === 'application/x-chat' || |
| 93 nodeType === 'application/x-google-chrome-pdf' || | 96 nodeType === 'application/x-google-chrome-pdf' || |
| 94 nodeType === 'application/x-shockwave-flash')) { | 97 nodeType === 'application/x-shockwave-flash')) { |
| 95 return true; | 98 return true; |
| 96 } | 99 } |
| 97 return false; | 100 return false; |
| 98 } | 101 } |
| OLD | NEW |