From 241cb7999d052e59070c1f965d8e6e79519d4699 Mon Sep 17 00:00:00 2001 From: Tim van der Meij Date: Sun, 9 Mar 2014 23:29:34 +0100 Subject: [PATCH] Making extensions/chromium/chrome.tabs.executeScriptInFrame.js adhere to the style guide --- .../chrome.tabs.executeScriptInFrame.js | 354 ++++++++++-------- 1 file changed, 189 insertions(+), 165 deletions(-) diff --git a/extensions/chromium/chrome.tabs.executeScriptInFrame.js b/extensions/chromium/chrome.tabs.executeScriptInFrame.js index 5744e8d3a..c36c951c1 100644 --- a/extensions/chromium/chrome.tabs.executeScriptInFrame.js +++ b/extensions/chromium/chrome.tabs.executeScriptInFrame.js @@ -5,7 +5,7 @@ * * Implements the chrome.tabs.executeScriptInFrame API. * This API is similar to the chrome.tabs.executeScript method, except - * that it also recognizes the "frameId" property. + * that it also recognizes the "frameId" property. * This frameId can be obtained through the webNavigation or webRequest API. * * When an error occurs, chrome.runtime.lastError is set. @@ -18,32 +18,36 @@ * In addition, the following field must also be set in manifest.json: * "web_accessible_resources": ["getFrameId"] */ +/* globals chrome, console */ (function() { -/* jshint browser:true, maxlen:100 */ -/* globals chrome, console */ -'use strict'; -chrome.tabs.executeScriptInFrame = executeScript; + /* jshint browser:true, maxlen:100 */ + 'use strict'; -// This URL is used to communicate the frameId. The resource is never visited, so it should -// be a non-existent location. Do not use *, ", ' or line breaks in the file name. -var URL_WHAT_IS_MY_FRAME_ID = chrome.extension.getURL('getFrameId'); -// The callback will be called within ... ms: -// Don't set a too low value. -var MAXIMUM_RESPONSE_TIME_MS = 1000; + chrome.tabs.executeScriptInFrame = executeScript; -// Callbacks are stored here until they're invoked. -// Key = dummyUrl, value = callback function -var callbacks = {}; + // This URL is used to communicate the frameId. The resource is never + // visited, so it should be a non-existent location. Do not use *, ", ' + // or line breaks in the file name. + var URL_WHAT_IS_MY_FRAME_ID = chrome.extension.getURL('getFrameId'); + // The callback will be called within ... ms: + // Don't set a too low value. + var MAXIMUM_RESPONSE_TIME_MS = 1000; -chrome.webRequest.onBeforeRequest.addListener(function showFrameId(details) { + // Callbacks are stored here until they're invoked. + // Key = dummyUrl, value = callback function + var callbacks = {}; + + chrome.webRequest.onBeforeRequest.addListener(function showFrameId(details) { // Positive integer frameId >= 0 - // Since an image is used as a data transport, we add 1 to get a non-zero width. + // Since an image is used as a data transport, we add 1 to get a + // non-zero width. var frameId = details.frameId + 1; - // Assume that the frameId fits in three bytes - which is a very reasonable assumption. + // Assume that the frameId fits in three bytes - which is a very + // reasonable assumption. var width = String.fromCharCode(frameId & 0xFF, (frameId >> 8) & 0xFF); - // When frameId > 0xFFFF, use the height to convey the additional information. - // Again, add 1 to make sure that the height is non-zero. + // When frameId > 0xFFFF, use the height to convey the additional + // information. Again, add 1 to make sure that the height is non-zero. var height = String.fromCharCode((frameId >> 16) + 1, 0); // Convert data to base64 to avoid loss of bytes var image = 'data:image/gif;base64,' + btoa( @@ -76,184 +80,204 @@ chrome.webRequest.onBeforeRequest.addListener(function showFrameId(details) { // GIF trailer '\x3b' ); - return {redirectUrl: image}; -}, { + return {redirectUrl: image}; + }, { urls: [URL_WHAT_IS_MY_FRAME_ID + '*'], types: ['image'] -}, ['blocking']); + }, ['blocking']); -chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) { + chrome.runtime.onMessage.addListener(function(message, sender, + sendResponse) { if (message && message.executeScriptCallback) { - var callback = callbacks[message.identifier]; - if (callback) { - if (message.hello) { - clearTimeout(callback.timer); - return; - } - delete callbacks[message.identifier]; - // Result within an array to be consistent with the chrome.tabs.executeScript API. - callback([message.evalResult]); - } else { - console.warn('Callback not found for response in tab ' + sender.tab.id); + var callback = callbacks[message.identifier]; + if (callback) { + if (message.hello) { + clearTimeout(callback.timer); + return; } + delete callbacks[message.identifier]; + // Result within an array to be consistent with the + // chrome.tabs.executeScript API. + callback([message.evalResult]); + } else { + console.warn('Callback not found for response in tab ' + + sender.tab.id); + } } -}); + }); -/** - * Execute content script in a specific frame. - * - * @param tabId {integer} required - * @param details.frameId {integer} required - * @param details.code {string} Code or file is required (not both) - * @param details.file {string} Code or file is required (not both) - * @param details.runAt {optional string} One of "document_start", "document_end", "document_idle" - * @param callback {optional function(optional array of any result)} When an error occurs, result - * is not set. - */ -function executeScript(tabId, details, callback) { - console.assert(typeof details === 'object', 'details must be an object (argument 0)'); + /** + * Execute content script in a specific frame. + * + * @param tabId {integer} required + * @param details.frameId {integer} required + * @param details.code {string} Code or file is required (not both) + * @param details.file {string} Code or file is required (not both) + * @param details.runAt {optional string} One of "document_start", + * "document_end", "document_idle" + * @param callback {optional function(optional result array)} When an error + * occurs, result + * is not set. + */ + function executeScript(tabId, details, callback) { + console.assert(typeof details === 'object', + 'details must be an object (argument 0)'); var frameId = details.frameId; - console.assert(typeof tabId === 'number', 'details.tabId must be a number'); - console.assert(typeof frameId === 'number', 'details.frameId must be a number'); - var sourceType = 'code' in details ? 'code' : 'file'; + console.assert(typeof tabId === 'number', + 'details.tabId must be a number'); + console.assert(typeof frameId === 'number', + 'details.frameId must be a number'); + var sourceType = ('code' in details ? 'code' : 'file'); console.assert(sourceType in details, 'No source code or file specified'); var sourceValue = details[sourceType]; - console.assert(typeof sourceValue === 'string', 'details.' + sourceType + ' must be a string'); + console.assert(typeof sourceValue === 'string', + 'details.' + sourceType + ' must be a string'); var runAt = details.runAt; - if (!callback) callback = function() {/* no-op*/}; - console.assert(typeof callback === 'function', 'callback must be a function'); + if (!callback) { + callback = function() {/* no-op*/}; + } + console.assert(typeof callback === 'function', + 'callback must be a function'); if (frameId === 0) { - // No need for heavy lifting if we want to inject the script in the main frame - var injectDetails = { - allFrames: false, - runAt: runAt - }; - injectDetails[sourceType] = sourceValue; - chrome.tabs.executeScript(tabId, injectDetails, callback); - return; + // No need for heavy lifting if we want to inject the script + // in the main frame + var injectDetails = { + allFrames: false, + runAt: runAt + }; + injectDetails[sourceType] = sourceValue; + chrome.tabs.executeScript(tabId, injectDetails, callback); + return; } var identifier = Math.random().toString(36); if (sourceType === 'code') { - executeScriptInFrame(); + executeScriptInFrame(); } else { // sourceType === 'file' - (function() { - var x = new XMLHttpRequest(); - x.open('GET', chrome.extension.getURL(sourceValue), true); - x.onload = function() { - sourceValue = x.responseText; - executeScriptInFrame(); - }; - x.onerror = function executeScriptResourceFetchError() { - var message = 'Failed to load file: "' + sourceValue + '".'; - console.error('executeScript: ' + message); - chrome.runtime.lastError = chrome.extension.lastError = { message: message }; - try { - callback(); - } finally { - chrome.runtime.lastError = chrome.extension.lastError = undefined; - } - }; - x.send(); - })(); + (function() { + var x = new XMLHttpRequest(); + x.open('GET', chrome.extension.getURL(sourceValue), true); + x.onload = function() { + sourceValue = x.responseText; + executeScriptInFrame(); + }; + x.onerror = function executeScriptResourceFetchError() { + var message = 'Failed to load file: "' + sourceValue + '".'; + console.error('executeScript: ' + message); + chrome.runtime.lastError = chrome.extension.lastError = + { message: message }; + try { + callback(); + } finally { + chrome.runtime.lastError = chrome.extension.lastError = undefined; + } + }; + x.send(); + })(); } - function executeScriptInFrame() { - callbacks[identifier] = callback; - chrome.tabs.executeScript(tabId, { - code: '(' + DETECT_FRAME + ')(' + - 'window,' + - JSON.stringify(identifier) + ',' + - frameId + ',' + - JSON.stringify(sourceValue) + ')', - allFrames: true, - runAt: 'document_start' - }, function(results) { - if (results) { - callback.timer = setTimeout(executeScriptTimedOut, MAXIMUM_RESPONSE_TIME_MS); - } else { - // Failed :( - delete callbacks[identifier]; - callback(); - } - }); - } - function executeScriptTimedOut() { - var callback = callbacks[identifier]; - if (!callback) { - return; - } - delete callbacks[identifier]; - var message = 'Failed to execute script: Frame ' + frameId + ' not found in tab ' + tabId; - console.error('executeScript: ' + message); - chrome.runtime.lastError = chrome.extension.lastError = { message: message }; - try { - callback(); - } finally { - chrome.runtime.lastError = chrome.extension.lastError = undefined; + callbacks[identifier] = callback; + chrome.tabs.executeScript(tabId, { + code: '(' + DETECT_FRAME + ')(' + + 'window,' + + JSON.stringify(identifier) + ',' + + frameId + ',' + + JSON.stringify(sourceValue) + ')', + allFrames: true, + runAt: 'document_start' + }, function(results) { + if (results) { + callback.timer = setTimeout(executeScriptTimedOut, + MAXIMUM_RESPONSE_TIME_MS); + } else { + // Failed :( + delete callbacks[identifier]; + callback(); } + }); } -} -/** - * Code executed as a content script. - */ -var DETECT_FRAME = '' + function checkFrame(window, identifier, frameId, code) { + function executeScriptTimedOut() { + var callback = callbacks[identifier]; + if (!callback) { + return; + } + delete callbacks[identifier]; + var message = 'Failed to execute script: Frame ' + frameId + + ' not found in tab ' + tabId; + console.error('executeScript: ' + message); + chrome.runtime.lastError = chrome.extension.lastError = + { message: message }; + try { + callback(); + } finally { + chrome.runtime.lastError = chrome.extension.lastError = undefined; + } + } + } + + /** + * Code executed as a content script. + */ + var DETECT_FRAME = '' + function checkFrame(window, identifier, frameId, + code) { var i; if ('__executeScript_frameId__' in window) { - evalAsContentScript(); + evalAsContentScript(); } else { - // Do NOT use new Image(), because of http://crbug.com/245296 in Chrome 27-29 - i = window.document.createElement('img'); - i.onload = function() { - window.__executeScript_frameId__ = (this.naturalWidth - 1) + - (this.naturalHeight - 1 << 16); - evalAsContentScript(); - }; - // Trigger webRequest event to get frameId - // (append extra characters to bust the cache) - i.src = 'URL_WHAT_IS_MY_FRAME_ID?' + Math.random().toString(36).slice(-6); + // Do NOT use new Image() because of http://crbug.com/245296 + // in Chrome 27-29 + i = window.document.createElement('img'); + i.onload = function() { + window.__executeScript_frameId__ = (this.naturalWidth - 1) + + (this.naturalHeight - 1 << 16); + evalAsContentScript(); + }; + // Trigger webRequest event to get frameId + // (append extra characters to bust the cache) + i.src = 'URL_WHAT_IS_MY_FRAME_ID?' + + Math.random().toString(36).slice(-6); } for (i = 0 ; i < window.frames.length; ++i) { - try { - var frame = window.frames[i]; - var scheme = frame.location.protocol; - if (scheme !== 'https:' && scheme !== 'http:' && scheme !== 'file:') { - checkFrame(frame, identifier, frameId, code); - } - } catch (e) { - // blocked by same origin policy, so it's not a javascript: / about:blank - // URL. chrome.tabs.executeScript will run the script for the frame. + try { + var frame = window.frames[i]; + var scheme = frame.location.protocol; + if (scheme !== 'https:' && scheme !== 'http:' && scheme !== 'file:') { + checkFrame(frame, identifier, frameId, code); } + } catch (e) { + // blocked by same origin policy, so it's not a javascript:/about:blank + // URL. chrome.tabs.executeScript will run the script for the frame. + } } - function evalAsContentScript() { - if (window.__executeScript_frameId__ !== frameId) { - return; - } - // Send an early message to make sure that any blocking code - // in the evaluated code does not cause the time-out in the background page - // to be triggered - chrome.runtime.sendMessage({ - executeScriptCallback: true, - hello: true, - identifier: identifier - }); - var result = null; - try { - // jshint evil:true - result = window.eval(code); - } finally { - chrome.runtime.sendMessage({ - executeScriptCallback: true, - evalResult: result, - identifier: identifier - }); - } - } -}.toString().replace('URL_WHAT_IS_MY_FRAME_ID', URL_WHAT_IS_MY_FRAME_ID); + function evalAsContentScript() { + if (window.__executeScript_frameId__ !== frameId) { + return; + } + // Send an early message to make sure that any blocking code + // in the evaluated code does not cause the time-out in the background + // page to be triggered + chrome.runtime.sendMessage({ + executeScriptCallback: true, + hello: true, + identifier: identifier + }); + var result = null; + try { + // jshint evil:true + result = window.eval(code); + } finally { + chrome.runtime.sendMessage({ + executeScriptCallback: true, + evalResult: result, + identifier: identifier + }); + } + } + }.toString().replace('URL_WHAT_IS_MY_FRAME_ID', URL_WHAT_IS_MY_FRAME_ID); })();