From b2eefffe4a84cd0a65d3aac68ec6f7d4838e39e6 Mon Sep 17 00:00:00 2001 From: Joshua Elson Date: Tue, 8 May 2012 16:53:08 -0600 Subject: [PATCH 1/3] Updates to support Chrome 19 --- README.md | 6 ++- README.md~ | 72 +++++++++++++++++++++++++++++ dist/firephp-0.5.0.crx | Bin 0 -> 6619 bytes src/html/dev_tools.html | 4 +- src/html/dev_tools.html~ | 6 +++ src/js/background.js | 17 +++++-- src/js/background.js~ | 48 +++++++++++++++++++ src/js/bootstrap.js | 10 ++-- src/js/bootstrap.js~ | 97 +++++++++++++++++++++++++++++++++++++++ src/js/bridge.js | 2 +- src/js/bridge.js~ | 58 +++++++++++++++++++++++ src/js/dev_tools.js | 6 +-- src/js/dev_tools.js~ | 8 ++++ src/js/logger.js | 3 +- src/js/logger.js~ | 63 +++++++++++++++++++++++++ src/manifest.json | 5 +- src/manifest.json~ | 43 +++++++++++++++++ 17 files changed, 432 insertions(+), 16 deletions(-) create mode 100644 README.md~ create mode 100644 dist/firephp-0.5.0.crx create mode 100644 src/html/dev_tools.html~ create mode 100644 src/js/background.js~ create mode 100644 src/js/bootstrap.js~ create mode 100644 src/js/bridge.js~ create mode 100644 src/js/dev_tools.js~ create mode 100644 src/js/logger.js~ create mode 100644 src/manifest.json~ diff --git a/README.md b/README.md index e93cc71..76de8a4 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ FirePHP-chrome is an extension for Google Chrome to allow the Chrome console to For more details of FirePHP: http://www.firephp.org/ +Revision History +-------------- +0.5.0: Updated to support Chrome 19 changes: manifest permissons, non-experimental dev components. + How to install -------------- This extension uses Chrome's "experimental extensions" so you'll need to enable these in your browser first: @@ -69,4 +73,4 @@ TODO: ---- - support more logging types (from here: http://reference.developercompanion.com/Tools/FirePHPCompanion/Run/Examples/) - remove test service and use developer comapnion examples -- autoupdating \ No newline at end of file +- autoupdating diff --git a/README.md~ b/README.md~ new file mode 100644 index 0000000..e93cc71 --- /dev/null +++ b/README.md~ @@ -0,0 +1,72 @@ + +FirePHP-chrome is an extension for Google Chrome to allow the Chrome console to display FirePHP messages. + +For more details of FirePHP: + http://www.firephp.org/ + +How to install +-------------- +This extension uses Chrome's "experimental extensions" so you'll need to enable these in your browser first: +1. Type "chrome://flags/" into Chrome's title bar +2. Find "Experimental Extension APIs" in the list +3. Click "Enable" +4. Restart Chrome + +There are 2 ways to install the extension. + +### Using CRX file: +1. Click on this link: + https://github.com/andrewn/firephp-chrome/raw/master/dist/firephp-0.3.0.crx +2. Chrome will warm you about extensions and apps, click "Continue" +3. Chrome will ask you if you want to "Install FirePHP-chrome", click "Install" + +### From source (if you want to develop the extension): +1. Download or clone the source +2. Open the extensions page via Window -> Extensions +3. Click on "Load unpacked extension" +4. Navigate to the "src/" directory and "Select" + +How to use +---------- +To use this extension, navigate to the page you want to inspect and: +1. Open the Developer Tools (Wrench -> Tools -> Developer Tools) +2. Click on the "Console" tab +3. Refresh the page + +You should now see any FirePHP messages sent from the server in the console output. + +Supported types +--------------- +WARN, LOG, INFO, ERROR, EXCEPTION are the currently supported types. + +How it works +------------ +A page with the Developer Tools panel open will have a FirePHP request header appended. + +The response headers are parsed in a background page, and sent through to a script running on the original page that outputs them to the console. + +Adding new types +---------------- +See the 'actionsToOutputMap' in src/js/bridge.js which is a map of action types "log", "info", "exception" to functions that format and output the info into the page. Add your type here and send me a pull request. + +Testing +------- +There's a ruby-based test service that sends headers for each of the supported types. If you add a new type, it would be good if you could change the service to output the correct headers too as this makes testing easier. + +Running the test service: + $ cd test-service + $ bundle install + $ bundle exec rackup + [2011-10-29 14:40:28] INFO WEBrick 1.3.1 + [2011-10-29 14:40:28] INFO ruby 1.8.7 (2010-01-10) [universal-darwin11.0] + [2011-10-29 14:40:28] INFO WEBrick::HTTPServer#start: pid=14191 port=9292 + +You can now visit the test server at http://localhost:9292/ + +It displays a list of the items being logged and viewing the console should show the same messages in the output. + +TODO: +---- +- support more logging types (from here: http://reference.developercompanion.com/Tools/FirePHPCompanion/Run/Examples/) +- remove test service and use developer comapnion examples +- autoupdating \ No newline at end of file diff --git a/dist/firephp-0.5.0.crx b/dist/firephp-0.5.0.crx new file mode 100644 index 0000000000000000000000000000000000000000..68925c47430ddb69f4b90bd9ee74f56166f231d4 GIT binary patch literal 6619 zcmbVQcRXC%w;x2W5uJ$0U?O@Xx)20m7`+8y^fnm1MzkP$?~&*RQKEB|sL^}xEzyZC zyyM>Yd%4%|{oWsMeP*3A=bZgrd!N16UT3YZggp;0ItT>%2M$yBUq*W@U)u|W&{i8+#X0ds5_zx|jlURuDNap?sMLbVVca4EW(o(;zvO!UuH_b>=GLa17@+^$1_Nkgf&8~7 z7g7;4WoRH!3Gkc{Xku+(V{T%Mbl|W+B5bUqp@=Cif`FYa14o+--yXW2>~Cc4H()^CelKzHTTGTa`MLC6Whx7@EZW|i z(9s&vLOineL)@H5GxKS+&)U2r2S559kUq79LLgjzSEMak`b6*{|JyxLy*IVqs8FAe zV+oGDE(cgh-Sx)-n}tmmBL8H*vV5?&!)O`!h#*O>~DG96>64@&$R-Z6Ir(85zlg z4ks)hc5>+|WpS8!6@{put2R6OhgL#~mZP1g&)rtkE=6?P7Zc$>9oWeyA$qZ6`1;|u z?C4&Mnjfg`oV&9hf_Jjegf4uA=) zu9<_i)xWvG$4yrcE#P4^px6HOXCp%cxTUE*!qLWvAJ8Y(?HJuOW;GhWR~-z3w>^b@g?kBY0Z zp}muvl9#z2-c$CcXC$?6csuNGI4tYTa;!Ws1Oq_t{A(yi#!mVU2!s{#|22{*Z3_LU z^mG+eyc+7yk)Vy{5D(yFHZh~!=v=gcK0FZEQnA<|5CPCRuv@GUrl!XBz+UiIn^T

^j_IVF;V$>UUgL|>_s{L7<;5acejQGKJ5Fp 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 - + - \ No newline at end of file + diff --git a/src/html/dev_tools.html~ b/src/html/dev_tools.html~ new file mode 100644 index 0000000..d1264b7 --- /dev/null +++ b/src/html/dev_tools.html~ @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/js/background.js b/src/js/background.js index c3f18b9..f13b27d 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -1,20 +1,27 @@ var logger = new Logger(); +console.log("Firing up FirePHP Debugger"); + // Add the X-FirePHP-Version header to all requests var filter, extraInfoSpec = ["blocking", "requestHeaders"]; -chrome.experimental.webRequest.onBeforeSendHeaders.addListener( + + +chrome.webRequest.onBeforeSendHeaders.addListener( function(details) { var headers = details.requestHeaders; + + console.warn("Inserting X-FirePHP header"); + headers.push({ name : "X-FirePHP-Version", - value : "0.6" + value : "0.6.1" }); return { requestHeaders: headers } }, - /* RequestFilter */ filter, + {urls: [""]}, /* array of string */ extraInfoSpec ); @@ -37,4 +44,6 @@ chrome.extension.onRequest.addListener( ); } } -); \ No newline at end of file +); + +console.log("Completed BG Page Load"); diff --git a/src/js/background.js~ b/src/js/background.js~ new file mode 100644 index 0000000..80e50b3 --- /dev/null +++ b/src/js/background.js~ @@ -0,0 +1,48 @@ +var logger = new Logger(); + +console.log("Firing up FirePHP Debugger"); + +// Add the X-FirePHP-Version header to all requests +var filter, + extraInfoSpec = ["blocking", "requestHeaders"]; + + +chrome.webRequest.onBeforeSendHeaders.addListener( + function(details) { + var headers = details.requestHeaders; + + console.warn("Inserting X-FirePHP header"); + + headers.push({ + name : "X-FirePHP-Version", + value : "0.6.1" + }); + return { + requestHeaders: headers + } + }, + {urls: [""]}, + /* array of string */ extraInfoSpec +); + + +// The dev panel sends us interesting requests +// via dev_tools.js +chrome.extension.onRequest.addListener( + function(request, sender, sendResponse) { + var headersMap = {}; + request.headers.forEach(function (item) { + console.log(item.value); + headersMap[item.name] = item.value; + }); + + var items = logger.log(headersMap); + + if (items.length) { + chrome.tabs.sendRequest( + request.tabId, + items + ); + } + } +); diff --git a/src/js/bootstrap.js b/src/js/bootstrap.js index 8636395..b1e88d0 100644 --- a/src/js/bootstrap.js +++ b/src/js/bootstrap.js @@ -12,6 +12,7 @@ var Bootstrap = (function (){ type: STABLE, ns : chrome }; + } else if (chrome.experimental && chrome.experimental.webRequest) { ns = { type: EXPERIMENTAL, @@ -28,6 +29,9 @@ var Bootstrap = (function (){ //, tabId: tabId }, extraInfoSpec = ["statusLine", "responseHeaders"]; + + console.log ("using namespace: " + ns); + if ( apiNs ) { apiNs.ns.webRequest.onCompleted.addListener( function(details) { @@ -78,14 +82,14 @@ var Bootstrap = (function (){ }); */ - chrome.experimental.devtools.resources.getHAR(function(result) { + chrome.devtools.network.getHAR(function(result) { var entries = result.entries; if (!entries.length) { Console.warn("ChromeFirePHP suggests that you reload the page to track" + " FirePHP messages for all the resources"); } - chrome.experimental.devtools.resources.onFinished.addListener( + chrome.devtools.network.onRequestFinished.addListener( function () { chrome.experimental.devtools.log("test"); } ); }); @@ -93,4 +97,4 @@ var Bootstrap = (function (){ } }; -})(); \ No newline at end of file +})(); diff --git a/src/js/bootstrap.js~ b/src/js/bootstrap.js~ new file mode 100644 index 0000000..77a3d45 --- /dev/null +++ b/src/js/bootstrap.js~ @@ -0,0 +1,97 @@ +var Bootstrap = (function (){ + + var STABLE = 'STABLE', + EXPERIMENTAL = 'EXPERIMENTAL'; + + var viewer = new Logger(); + + function getApiNs() { + var ns; + if (chrome.webRequest) { + ns = { + type: STABLE, + ns : chrome + }; + + } else if (chrome.experimental && chrome.experimental.webRequest) { + ns = { + type: EXPERIMENTAL, + ns : chrome.experimental + }; + } + return ns; + } + + function registerListeners(tabId) { + var apiNs = getApiNs(), + filter = { + types: ["main_frame" /*, "sub_frame", "xmlhttprequest", "other", "stylesheet", "script", "image", "object" */] + //, tabId: tabId + }, + extraInfoSpec = ["statusLine", "responseHeaders"]; + if ( apiNs ) { + apiNs.ns.webRequest.onCompleted.addListener( + function(details) { + console.log("webRequest.onCompleted", tabId, details); + var headers = {}; + details.responseHeaders.forEach(function (item) { + headers[item.name] = item.value; + }); + console.log("headers", headers); + var consoleMessages = viewer.log(headers); + + console.log("about to send tab %o the following consoleMessages %o", tabId, consoleMessages); + + chrome.tabs.sendRequest( + tabId, + consoleMessages + /* responseCallback - not used */ + ); + }, + filter, + extraInfoSpec + ); + // function ( evt ) { + // Get tab for this event and initialise + // controller + // chrome.tabs.get( evt.tabId, function(tab) { + // console.log('Creating new controller for ', evt.url, tab); + // new Controller( evt.url, tab ); + // }); + // } + } else { + console.error('webRequest API doesn\'t exist. Exiting'); + } + console.log('webRequest API is ', apiNs.type); + }; + + return { + init: function () { + //registerListeners(); + /* + chrome.contextMenus.create({ + "title": "Activate FirePHP", + "contexts":["all"], + "onclick": function (info, tab) { + console.log("Activate FirePHP for tab ", tab.id); + registerListeners(tab.id); + } + }); + */ + + chrome.devtools.network.getHAR(function(result) { + var entries = result.entries; + if (!entries.length) { + Console.warn("ChromeFirePHP suggests that you reload the page to track" + + " FirePHP messages for all the resources"); + } + + chrome.devtools.network.onRequestFinished.addListener( + function () { chrome.experimental.devtools.log("test"); } + ); + }); + + } + }; + +})(); diff --git a/src/js/bridge.js b/src/js/bridge.js index 94012ce..1793d91 100644 --- a/src/js/bridge.js +++ b/src/js/bridge.js @@ -65,4 +65,4 @@ } ); -})(); \ No newline at end of file +})(); diff --git a/src/js/bridge.js~ b/src/js/bridge.js~ new file mode 100644 index 0000000..df20232 --- /dev/null +++ b/src/js/bridge.js~ @@ -0,0 +1,58 @@ +(function(){ + + var dirObject = function(o) { + for (key in o) { + if (o.hasOwnProperty(key)) { + console.log(key + ':', o[key]); + } + } + }; + + var dirStacktrace = function(stacktrace) { + console.group('Stack trace'); + stacktrace.forEach(function (trace, idx) { + console.groupCollapsed(idx + '. ' + shortPath(trace.file) + '(' + trace.line + '): ' + trace.class + trace.type + trace.function + '(' + joinArguments(trace.args) + ')'); + dirObject(trace); + console.groupEnd(); + }); + console.groupEnd(); + }; + + var shortPath = function (path) { + return path.split('/').splice(-3).join('/'); + }; + + var joinArguments = function (args) { + var result = []; + args.forEach(function (arg) { + if (typeof arg === 'object') { + result.push(arg.__className); + } else { + result.push(arg); + } + }); + return result.join(', '); + }; + + /* + Map action types to specific outputs + */ + var actionsToOutputMap = { + 'exception' : function (type, body) { + console.error("Exception '" + body.Class + "' with message '" + body.Message + "' in " + shortPath(body.File) + ':' + body.Line); + dirStacktrace(body.Trace); + }, + 'default' : function (type, body) { + if (console[type]) { console[type]( body ); } + } + } + + var outputForAction = function (action, body) { + if (actionsToOutputMap[action]) { + actionsToOutputMap[action]( action, body ); + } else { + actionsToOutputMap['default']( action, body ); + } + }; + +})(); diff --git a/src/js/dev_tools.js b/src/js/dev_tools.js index 2f3073b..620c705 100644 --- a/src/js/dev_tools.js +++ b/src/js/dev_tools.js @@ -1,8 +1,8 @@ -chrome.experimental.devtools.resources.onFinished.addListener(function(resources) { - var tabId = chrome.experimental.devtools.inspectedWindow.tabId, +chrome.devtools.network.onRequestFinished.addListener(function(resources) { + var tabId = chrome.devtools.inspectedWindow.tabId, headers = resources.response.headers; chrome.extension.sendRequest({ tabId : tabId , headers : headers }); -}); \ No newline at end of file +}); diff --git a/src/js/dev_tools.js~ b/src/js/dev_tools.js~ new file mode 100644 index 0000000..4cb26ba --- /dev/null +++ b/src/js/dev_tools.js~ @@ -0,0 +1,8 @@ +chrome.devtools.network.onFinished.addListener(function(resources) { + var tabId = chrome.devtools.inspectedWindow.tabId, + headers = resources.response.headers; + chrome.extension.sendRequest({ + tabId : tabId + , headers : headers + }); +}); diff --git a/src/js/logger.js b/src/js/logger.js index b09ccc4..a699908 100644 --- a/src/js/logger.js +++ b/src/js/logger.js @@ -29,6 +29,7 @@ var Logger = (function(){ log: function ( headers ) { var logMessages = []; for ( item in headers ) { + console.log("header" + item); var logKey = item.match(this.logging[0]); if (logKey) { var commandParts = headers[item].match( this.commandMessage ), @@ -48,7 +49,7 @@ var Logger = (function(){ }); } } else { - //console.warn('not logging info', item); + console.warn('not logging info', item); } } diff --git a/src/js/logger.js~ b/src/js/logger.js~ new file mode 100644 index 0000000..5a51dae --- /dev/null +++ b/src/js/logger.js~ @@ -0,0 +1,63 @@ +/* + Understands WildFire logging headers + +*/ +var Logger = (function(){ + function Logger(){}; + Logger.prototype = { + + wfToChromeMap: { + "LOG" : "log", + "INFO": "info", + "WARN": "warn", + "ERROR": "error", + "EXCEPTION": "exception" + }, + + meta: [ + /X-Wf-Protocol-[\d]*/, + /X-Wf-[\d]*-Plugin-[\d]*/, + /X-Wf-[\d]*-Structure-[\d]*/ + ], + + logging: [ + /X-Wf-[\d]*-[\d]*-[\d]*-([\d]*)/ + ], + + commandMessage: /(\d*) *\| *(\[.*\])\ *| */, + + log: function ( headers ) { + var logMessages = []; + for ( item in headers ) { + chrome.extension.getBackgroundPage().console.log("header" + item); + var logKey = item.match(this.logging[0]); + if (logKey) { + var commandParts = headers[item].match( this.commandMessage ), + size = commandParts[1], + msg = JSON.parse( commandParts[2] ), + meta = msg[0], + body = msg[1], + idx = parseInt(logKey[1], 10); + + if ( meta["Type"] in this.wfToChromeMap ) { + var action = this.wfToChromeMap[meta["Type"]]; + logMessages.push({ + 'idx': idx, + 'meta': meta, + 'body': body, + 'action': action + }); + } + } else { + console.warn('not logging info', item); + } + } + + logMessages.sort(function (a, b) { return a.idx - b.idx; }); + + return logMessages; + } + + }; + return Logger; +})(); diff --git a/src/manifest.json b/src/manifest.json index ba1ecaa..213173b 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,11 +1,14 @@ { "name": "FirePHP-chrome", - "version": "0.3.0", + "version": "0.5.0", "description": "FirePHP-chrome is an extension for Google Chrome to allow the Chrome console to display FirePHP messages.", "permissions": [ + "background", "experimental", "tabs", + "webRequest", + "webRequestBlocking", //"history", /* Request permissions for all sites */ "http://*/*", diff --git a/src/manifest.json~ b/src/manifest.json~ new file mode 100644 index 0000000..0686f20 --- /dev/null +++ b/src/manifest.json~ @@ -0,0 +1,43 @@ +{ + "name": "FirePHP-chrome", + "version": "0.5.0", + + "description": "FirePHP-chrome is an extension for Google Chrome to allow the Chrome console to display FirePHP messages.", + "permissions": [ + "background", + "tabs", + "webRequest", + "webRequestBlocking", + //"history", + /* Request permissions for all sites */ + "http://*/*", + "https://*/*" + ], + + /* + The background listens for page + load events, parses the wildfire + headers and passes to a content script + in the loaded page. + */ + "background_page": "html/background.html", + "devtools_page": "html/dev_tools.html", + + /* + The content script ouputs to the + page's console. + */ + "content_scripts": [{ + "matches" : [ + "http://*/*", + "https://*/*" + ], + "js" : [ + "js/bridge.js" + ], + "run_at" : "document_start", + "all_frames" : false + }] + +} + From c4a61f4fad368feae6b6f67185b25659cf89de1d Mon Sep 17 00:00:00 2001 From: Joshua Elson Date: Tue, 8 May 2012 16:54:12 -0600 Subject: [PATCH 2/3] Updates to support Chrome 19 --- README.md~ | 72 -------------------------------- src/js/background.js~ | 48 --------------------- src/js/bootstrap.js~ | 97 ------------------------------------------- src/js/dev_tools.js~ | 8 ---- 4 files changed, 225 deletions(-) delete mode 100644 README.md~ delete mode 100644 src/js/background.js~ delete mode 100644 src/js/bootstrap.js~ delete mode 100644 src/js/dev_tools.js~ diff --git a/README.md~ b/README.md~ deleted file mode 100644 index e93cc71..0000000 --- a/README.md~ +++ /dev/null @@ -1,72 +0,0 @@ - -FirePHP-chrome is an extension for Google Chrome to allow the Chrome console to display FirePHP messages. - -For more details of FirePHP: - http://www.firephp.org/ - -How to install --------------- -This extension uses Chrome's "experimental extensions" so you'll need to enable these in your browser first: -1. Type "chrome://flags/" into Chrome's title bar -2. Find "Experimental Extension APIs" in the list -3. Click "Enable" -4. Restart Chrome - -There are 2 ways to install the extension. - -### Using CRX file: -1. Click on this link: - https://github.com/andrewn/firephp-chrome/raw/master/dist/firephp-0.3.0.crx -2. Chrome will warm you about extensions and apps, click "Continue" -3. Chrome will ask you if you want to "Install FirePHP-chrome", click "Install" - -### From source (if you want to develop the extension): -1. Download or clone the source -2. Open the extensions page via Window -> Extensions -3. Click on "Load unpacked extension" -4. Navigate to the "src/" directory and "Select" - -How to use ----------- -To use this extension, navigate to the page you want to inspect and: -1. Open the Developer Tools (Wrench -> Tools -> Developer Tools) -2. Click on the "Console" tab -3. Refresh the page - -You should now see any FirePHP messages sent from the server in the console output. - -Supported types ---------------- -WARN, LOG, INFO, ERROR, EXCEPTION are the currently supported types. - -How it works ------------- -A page with the Developer Tools panel open will have a FirePHP request header appended. - -The response headers are parsed in a background page, and sent through to a script running on the original page that outputs them to the console. - -Adding new types ----------------- -See the 'actionsToOutputMap' in src/js/bridge.js which is a map of action types "log", "info", "exception" to functions that format and output the info into the page. Add your type here and send me a pull request. - -Testing -------- -There's a ruby-based test service that sends headers for each of the supported types. If you add a new type, it would be good if you could change the service to output the correct headers too as this makes testing easier. - -Running the test service: - $ cd test-service - $ bundle install - $ bundle exec rackup - [2011-10-29 14:40:28] INFO WEBrick 1.3.1 - [2011-10-29 14:40:28] INFO ruby 1.8.7 (2010-01-10) [universal-darwin11.0] - [2011-10-29 14:40:28] INFO WEBrick::HTTPServer#start: pid=14191 port=9292 - -You can now visit the test server at http://localhost:9292/ - -It displays a list of the items being logged and viewing the console should show the same messages in the output. - -TODO: ----- -- support more logging types (from here: http://reference.developercompanion.com/Tools/FirePHPCompanion/Run/Examples/) -- remove test service and use developer comapnion examples -- autoupdating \ No newline at end of file diff --git a/src/js/background.js~ b/src/js/background.js~ deleted file mode 100644 index 80e50b3..0000000 --- a/src/js/background.js~ +++ /dev/null @@ -1,48 +0,0 @@ -var logger = new Logger(); - -console.log("Firing up FirePHP Debugger"); - -// Add the X-FirePHP-Version header to all requests -var filter, - extraInfoSpec = ["blocking", "requestHeaders"]; - - -chrome.webRequest.onBeforeSendHeaders.addListener( - function(details) { - var headers = details.requestHeaders; - - console.warn("Inserting X-FirePHP header"); - - headers.push({ - name : "X-FirePHP-Version", - value : "0.6.1" - }); - return { - requestHeaders: headers - } - }, - {urls: [""]}, - /* array of string */ extraInfoSpec -); - - -// The dev panel sends us interesting requests -// via dev_tools.js -chrome.extension.onRequest.addListener( - function(request, sender, sendResponse) { - var headersMap = {}; - request.headers.forEach(function (item) { - console.log(item.value); - headersMap[item.name] = item.value; - }); - - var items = logger.log(headersMap); - - if (items.length) { - chrome.tabs.sendRequest( - request.tabId, - items - ); - } - } -); diff --git a/src/js/bootstrap.js~ b/src/js/bootstrap.js~ deleted file mode 100644 index 77a3d45..0000000 --- a/src/js/bootstrap.js~ +++ /dev/null @@ -1,97 +0,0 @@ -var Bootstrap = (function (){ - - var STABLE = 'STABLE', - EXPERIMENTAL = 'EXPERIMENTAL'; - - var viewer = new Logger(); - - function getApiNs() { - var ns; - if (chrome.webRequest) { - ns = { - type: STABLE, - ns : chrome - }; - - } else if (chrome.experimental && chrome.experimental.webRequest) { - ns = { - type: EXPERIMENTAL, - ns : chrome.experimental - }; - } - return ns; - } - - function registerListeners(tabId) { - var apiNs = getApiNs(), - filter = { - types: ["main_frame" /*, "sub_frame", "xmlhttprequest", "other", "stylesheet", "script", "image", "object" */] - //, tabId: tabId - }, - extraInfoSpec = ["statusLine", "responseHeaders"]; - if ( apiNs ) { - apiNs.ns.webRequest.onCompleted.addListener( - function(details) { - console.log("webRequest.onCompleted", tabId, details); - var headers = {}; - details.responseHeaders.forEach(function (item) { - headers[item.name] = item.value; - }); - console.log("headers", headers); - var consoleMessages = viewer.log(headers); - - console.log("about to send tab %o the following consoleMessages %o", tabId, consoleMessages); - - chrome.tabs.sendRequest( - tabId, - consoleMessages - /* responseCallback - not used */ - ); - }, - filter, - extraInfoSpec - ); - // function ( evt ) { - // Get tab for this event and initialise - // controller - // chrome.tabs.get( evt.tabId, function(tab) { - // console.log('Creating new controller for ', evt.url, tab); - // new Controller( evt.url, tab ); - // }); - // } - } else { - console.error('webRequest API doesn\'t exist. Exiting'); - } - console.log('webRequest API is ', apiNs.type); - }; - - return { - init: function () { - //registerListeners(); - /* - chrome.contextMenus.create({ - "title": "Activate FirePHP", - "contexts":["all"], - "onclick": function (info, tab) { - console.log("Activate FirePHP for tab ", tab.id); - registerListeners(tab.id); - } - }); - */ - - chrome.devtools.network.getHAR(function(result) { - var entries = result.entries; - if (!entries.length) { - Console.warn("ChromeFirePHP suggests that you reload the page to track" + - " FirePHP messages for all the resources"); - } - - chrome.devtools.network.onRequestFinished.addListener( - function () { chrome.experimental.devtools.log("test"); } - ); - }); - - } - }; - -})(); diff --git a/src/js/dev_tools.js~ b/src/js/dev_tools.js~ deleted file mode 100644 index 4cb26ba..0000000 --- a/src/js/dev_tools.js~ +++ /dev/null @@ -1,8 +0,0 @@ -chrome.devtools.network.onFinished.addListener(function(resources) { - var tabId = chrome.devtools.inspectedWindow.tabId, - headers = resources.response.headers; - chrome.extension.sendRequest({ - tabId : tabId - , headers : headers - }); -}); From a9d43e8aa6d85d1de98d759c70499fb894d67914 Mon Sep 17 00:00:00 2001 From: Joshua Elson Date: Tue, 8 May 2012 16:55:48 -0600 Subject: [PATCH 3/3] Clean up cache --- src/html/dev_tools.html~ | 6 ---- src/js/bridge.js~ | 58 ------------------------------------ src/js/logger.js~ | 63 ---------------------------------------- src/manifest.json~ | 43 --------------------------- 4 files changed, 170 deletions(-) delete mode 100644 src/html/dev_tools.html~ delete mode 100644 src/js/bridge.js~ delete mode 100644 src/js/logger.js~ delete mode 100644 src/manifest.json~ diff --git a/src/html/dev_tools.html~ b/src/html/dev_tools.html~ deleted file mode 100644 index d1264b7..0000000 --- a/src/html/dev_tools.html~ +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/js/bridge.js~ b/src/js/bridge.js~ deleted file mode 100644 index df20232..0000000 --- a/src/js/bridge.js~ +++ /dev/null @@ -1,58 +0,0 @@ -(function(){ - - var dirObject = function(o) { - for (key in o) { - if (o.hasOwnProperty(key)) { - console.log(key + ':', o[key]); - } - } - }; - - var dirStacktrace = function(stacktrace) { - console.group('Stack trace'); - stacktrace.forEach(function (trace, idx) { - console.groupCollapsed(idx + '. ' + shortPath(trace.file) + '(' + trace.line + '): ' + trace.class + trace.type + trace.function + '(' + joinArguments(trace.args) + ')'); - dirObject(trace); - console.groupEnd(); - }); - console.groupEnd(); - }; - - var shortPath = function (path) { - return path.split('/').splice(-3).join('/'); - }; - - var joinArguments = function (args) { - var result = []; - args.forEach(function (arg) { - if (typeof arg === 'object') { - result.push(arg.__className); - } else { - result.push(arg); - } - }); - return result.join(', '); - }; - - /* - Map action types to specific outputs - */ - var actionsToOutputMap = { - 'exception' : function (type, body) { - console.error("Exception '" + body.Class + "' with message '" + body.Message + "' in " + shortPath(body.File) + ':' + body.Line); - dirStacktrace(body.Trace); - }, - 'default' : function (type, body) { - if (console[type]) { console[type]( body ); } - } - } - - var outputForAction = function (action, body) { - if (actionsToOutputMap[action]) { - actionsToOutputMap[action]( action, body ); - } else { - actionsToOutputMap['default']( action, body ); - } - }; - -})(); diff --git a/src/js/logger.js~ b/src/js/logger.js~ deleted file mode 100644 index 5a51dae..0000000 --- a/src/js/logger.js~ +++ /dev/null @@ -1,63 +0,0 @@ -/* - Understands WildFire logging headers - -*/ -var Logger = (function(){ - function Logger(){}; - Logger.prototype = { - - wfToChromeMap: { - "LOG" : "log", - "INFO": "info", - "WARN": "warn", - "ERROR": "error", - "EXCEPTION": "exception" - }, - - meta: [ - /X-Wf-Protocol-[\d]*/, - /X-Wf-[\d]*-Plugin-[\d]*/, - /X-Wf-[\d]*-Structure-[\d]*/ - ], - - logging: [ - /X-Wf-[\d]*-[\d]*-[\d]*-([\d]*)/ - ], - - commandMessage: /(\d*) *\| *(\[.*\])\ *| */, - - log: function ( headers ) { - var logMessages = []; - for ( item in headers ) { - chrome.extension.getBackgroundPage().console.log("header" + item); - var logKey = item.match(this.logging[0]); - if (logKey) { - var commandParts = headers[item].match( this.commandMessage ), - size = commandParts[1], - msg = JSON.parse( commandParts[2] ), - meta = msg[0], - body = msg[1], - idx = parseInt(logKey[1], 10); - - if ( meta["Type"] in this.wfToChromeMap ) { - var action = this.wfToChromeMap[meta["Type"]]; - logMessages.push({ - 'idx': idx, - 'meta': meta, - 'body': body, - 'action': action - }); - } - } else { - console.warn('not logging info', item); - } - } - - logMessages.sort(function (a, b) { return a.idx - b.idx; }); - - return logMessages; - } - - }; - return Logger; -})(); diff --git a/src/manifest.json~ b/src/manifest.json~ deleted file mode 100644 index 0686f20..0000000 --- a/src/manifest.json~ +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "FirePHP-chrome", - "version": "0.5.0", - - "description": "FirePHP-chrome is an extension for Google Chrome to allow the Chrome console to display FirePHP messages.", - "permissions": [ - "background", - "tabs", - "webRequest", - "webRequestBlocking", - //"history", - /* Request permissions for all sites */ - "http://*/*", - "https://*/*" - ], - - /* - The background listens for page - load events, parses the wildfire - headers and passes to a content script - in the loaded page. - */ - "background_page": "html/background.html", - "devtools_page": "html/dev_tools.html", - - /* - The content script ouputs to the - page's console. - */ - "content_scripts": [{ - "matches" : [ - "http://*/*", - "https://*/*" - ], - "js" : [ - "js/bridge.js" - ], - "run_at" : "document_start", - "all_frames" : false - }] - -} -