From 032b3a6ac69a9f79292b73ef1eee6370b6735cda Mon Sep 17 00:00:00 2001 From: Brian Ford Date: Tue, 1 Apr 2014 14:26:03 -0700 Subject: [PATCH] WIP - I have no idea --- content-scripts/inject.js | 21 ++--- content-scripts/lib/niceNames.js | 121 +++++++++++++++----------- content-scripts/lib/niceNames.spec.js | 8 ++ package.json | 7 +- test/inject/injectSpec.js | 6 +- test/inject/mock/chromeExtension.js | 4 + 6 files changed, 101 insertions(+), 66 deletions(-) create mode 100644 content-scripts/lib/niceNames.spec.js diff --git a/content-scripts/inject.js b/content-scripts/inject.js index df6eb47..69d57fe 100644 --- a/content-scripts/inject.js +++ b/content-scripts/inject.js @@ -22,7 +22,7 @@ var instument = function instument (window) { if (!ngLoaded()) { // TODO: var name - var areWeThereYet = function (ev) { + function areWeThereYet (ev) { if (ev.srcElement.tagName === 'SCRIPT') { var oldOnload = ev.srcElement.onload; ev.srcElement.onload = function () { @@ -35,7 +35,7 @@ var instument = function instument (window) { } }; } - }; + } document.addEventListener('DOMNodeInserted', areWeThereYet); return; } @@ -51,6 +51,7 @@ var instument = function instument (window) { var throttle = require('./lib/throttle.js'); var summarizeObject = require('./lib/summarizeObject.js'); + var niceNames = require('./lib/niceNames.js'); // helper to extract dependencies from function arguments // not all versions of AngularJS expose annotate @@ -122,8 +123,7 @@ var instument = function instument (window) { deps: [] }; - var popover = null; - var instrumentedAppId = window.location.host + '~' + Math.random(); + var instrumentedAppId = window.location.host + '~' + Date.now() + '~' Math.random(); // Utils @@ -131,7 +131,7 @@ var instument = function instument (window) { var getScopeTree = function (id) { - var names = api.niceNames(); + var names = niceNames(); var traverse = function (sc) { var tree = { @@ -278,10 +278,9 @@ var instument = function instument (window) { return instrumentedAppId; }, - fireCustomEvent: fireCustomEvent, - - niceNames: require('./lib/niceNames.js'), - getModel: require('./lib/summarizeModel.js'), + fireCustomEvent : fireCustomEvent, + niceNames : niceNames, + getModel : summarizeObject, setSomeModel: function (id, path, value) { debug.scope[id].$apply(path + '=' + JSON.stringify(value)); @@ -314,9 +313,7 @@ var instument = function instument (window) { delete debug.modelWatchers[id][key]; } }); - }, - - enable: require('./lib/popover.js') + } }; var recordDependencies = function (providerName, dependencies) { diff --git a/content-scripts/lib/niceNames.js b/content-scripts/lib/niceNames.js index 1e0c1da..99186dd 100644 --- a/content-scripts/lib/niceNames.js +++ b/content-scripts/lib/niceNames.js @@ -3,56 +3,73 @@ module.exports = function niceNames () { var ngScopeElts = document.getElementsByClassName('ng-scope'); ngScopeElts = Array.prototype.slice.call(ngScopeElts); return ngScopeElts. - reduce(function (acc, elt) { - var $elt = angular.element(elt); - var scope = $elt.scope(); - - var name = {}; - - [ - 'ng-app', - 'ng-controller', - 'ng-repeat' - ]. - forEach(function (attr) { - var val = $elt.attr(attr), - className = $elt[0].className, - match, - lhs, - valueIdentifier, - keyIdentifier; - - if (val) { - name[attr] = val; - if (attr === 'ng-repeat') { - match = /(.+) in/.exec(val); - lhs = match[1]; - - match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/); - valueIdentifier = match[3] || match[1]; - keyIdentifier = match[2]; - - if (keyIdentifier) { - name.lhs = valueIdentifier + '["' + scope[keyIdentifier] + '"]' + summarizeObject(scope[valueIdentifier]); - } else { - name.lhs = valueIdentifier + summarizeObject(scope[valueIdentifier]); - } - - } - } else if (className.indexOf(attr) !== -1) { - match = (new RegExp(attr + ': ([a-zA-Z0-9]+);')).exec(className); - name[attr] = match[1]; - } - }); - - if (Object.keys(name).length === 0) { - name.tag = $elt[0].tagName.toLowerCase(); - name.classes = $elt[0].className. - replace(/(\W*ng-scope\W*)/, ' '). - split(' '). - filter(function (i) { return i; }); - } - acc[scope.$id] = name; - return acc; - }, {}); + reduce(accumulateElements, {}); + + function accumulateElements (acc, elt) { + acc[scope.$id] = nameElement(elt); + return acc; + } + }; + + +var interestingAttributes = { + 'ng-app': function (value) { + // body... + }, + 'ng-controller': function (value) { + // body... + }, + 'ng-repeat': function (value) { + match = /(.+) in/.exec(val); + lhs = match[1]; + + match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/); + valueIdentifier = match[3] || match[1]; + keyIdentifier = match[2]; + + if (keyIdentifier) { + name.lhs = valueIdentifier + '["' + scope[keyIdentifier] + '"]' + summarizeObject(scope[valueIdentifier]); + } else { + name.lhs = valueIdentifier + summarizeObject(scope[valueIdentifier]); + } + + } + } +} + + +function nameElement (element) { + var $elt = angular.element(elt), + scope = $elt.scope(), + name = {}; + + Object.keys(interestingAttributes).forEach(function (attributeName) { + + }) + + return Object.keys(name).length > 0 ? name : boringName($elt); +} + +function boringName ($elt) { + return { + tag: $elt[0].tagName.toLowerCase(), + name: $elt[0].className. + replace(/(\W*ng-scope\W*)/, ' '). + split(' '). + filter(function (i) { return i; }) + } +} + +function parseAttributeValue (attr) { + var val = $elt.attr(attr), + className; + + if (!val && className.indexOf(attr) !== -1) { + + className = $elt[0].className; + + match = (new RegExp(attr + ': ([a-zA-Z0-9]+);')).exec(className); + val = match[1]; + } +} diff --git a/content-scripts/lib/niceNames.spec.js b/content-scripts/lib/niceNames.spec.js new file mode 100644 index 0000000..b294b8e --- /dev/null +++ b/content-scripts/lib/niceNames.spec.js @@ -0,0 +1,8 @@ +// these tests run in node even though +// that's kind of a silly thing to do ¯\_(ツ)_/¯ + +var niceNames = require('./niceNames'); + +describe('niceNames', function() { + +}); diff --git a/package.json b/package.json index 0e00f8b..43e9e4c 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,11 @@ "grunt-release": "https://github.com/btford/grunt-release/archive/feat-tag-name.tar.gz", "marked": "~0.2.8", "grunt-zip": "~0.7.0", - "semver": "~1.1.4" + "semver": "~1.1.4", + "rewire": "~2.0.0", + "karma-phantomjs-launcher": "^0.1.3" + }, + "scripts": { + "test": "echo 'write them'" } } diff --git a/test/inject/injectSpec.js b/test/inject/injectSpec.js index d218a77..00fceae 100644 --- a/test/inject/injectSpec.js +++ b/test/inject/injectSpec.js @@ -1,7 +1,11 @@ describe('inject', function () { // inject/debug bootstraps asynchronously - beforeEach(function () {}); + beforeEach(function () { + waitsFor(function () { + return window.__ngDebug; + }, 'app to bootstrap', 100) + }); it('should expose a __ngDebug object to window', function () { expect(window.__ngDebug).not.toBeUndefined(); diff --git a/test/inject/mock/chromeExtension.js b/test/inject/mock/chromeExtension.js index 93747d8..f3fd312 100644 --- a/test/inject/mock/chromeExtension.js +++ b/test/inject/mock/chromeExtension.js @@ -1,5 +1,9 @@ // mocks window.chrome.extension +if (typeof chrome === 'undefined') { + window.chrome = {}; +} + chrome.extension = { sendMessage: dump };