message passing nonsense

test-unit-sauce
Brian Ford 11 years ago
parent 49a130c53b
commit 04d7a1bbd1

@ -1,6 +1,6 @@
// notify of page refreshes // notify of page refreshes
chrome.extension.onConnect.addListener(function(port) { chrome.extension.onConnect.addListener(function (port) {
port.onMessage.addListener(function (msg) { port.onMessage.addListener(function (msg) {
if (msg.action === 'register') { if (msg.action === 'register') {
var respond = function (tabId, changeInfo, tab) { var respond = function (tabId, changeInfo, tab) {
@ -16,4 +16,11 @@ chrome.extension.onConnect.addListener(function(port) {
}); });
} }
}); });
chrome.extension.onMessage.addListener(function (msg) {
if (msg.action === 'modelChange') {
port.postMessage(msg);
}
});
}); });

@ -27,41 +27,8 @@ angular.module('panelApp').controller('ModelCtrl', function ModelCtrl($scope, ap
$scope.enableInspector = appModel.enableInspector; $scope.enableInspector = appModel.enableInspector;
appContext.watchModelChange(function (msg) {
$scope.$on('poll', function () { console.log(msg);
// get the list of root scopes
appModel.getRootScopes(function (rootScopes) {
$scope.$apply(function () {
$scope.roots = rootScopes;
if ($scope.roots.length === 0) {
$scope.selectedRoot = null;
} else if (!$scope.selectedRoot) {
$scope.selectedRoot = $scope.roots[0];
}
if ($scope.selectedRoot && !$scope.selectedScope) {
$scope.selectedScope = $scope.selectedRoot;
}
});
});
// get scope tree
if ($scope.selectedRoot) {
appModel.getScopeTree($scope.selectedRoot, function (tree) {
$scope.$apply(function () {
$scope.tree = tree;
});
});
}
// get models on the selected scope
if ($scope.selectedScope) {
appModel.getModel($scope.selectedScope, function (model) {
$scope.$apply(function () {
$scope.model = model;
});
});
}
}); });

@ -1,64 +1,20 @@
angular.module('panelApp').directive('batJsonTree', function($compile) { angular.module('panelApp').directive('batJsonTree', function($compile, appModel) {
return { return {
restrict: 'E', restrict: 'E',
terminal: true, terminal: true,
scope: { scope: {
val: '=' scopeId: '='
//edit: '=',
}, },
link: function (scope, element, attrs) { link: function (scope, element, attrs) {
// this is more complicated then it should be
// see: https://github.com/angular/angular.js/issues/898
var buildDom = function (object) { var watching = [];
var html = '';
var prop;
if (object === undefined) {
html += '<i>undefined</i>';
} else if (object === null) {
html += '<i>null</i>';
} else if (object instanceof Array) {
var i;
html += '<div class="scope-branch">[ ';
if (object.length > 0) {
html += buildDom(object[0]);
for (i = 1; i < object.length; i++) {
html += ', ' + buildDom(object[i]);
}
}
html += ' ]</div>';
} else if (object instanceof Object) {
html += ' { ';
for (prop in object) {
if (object.hasOwnProperty(prop)) {
html += '<div class="scope-branch">' + prop + ': ' + buildDom(object[prop]) + '</div>';
}
}
html += ' } ';
} else {
html += '<span>' + object.toString() + '</span>';
}
return html;
};
var isEmpty = function (object) { console.log(element);
var prop;
for (prop in object) {
if (object.hasOwnProperty(prop)) {
return false;
}
}
return true;
};
scope.$watch('val', function (newVal, oldVal) { var scopeId = '003';
if (newVal === null) {
element.html('<div class="alert alert-info">Select a scope to view its models.</div>'); appModel.getModel(scopeId, [], function (obj) {
} else if (isEmpty(newVal)) { console.log(obj);
element.html('<pre>{ This scope has no models }</pre>');
} else {
element.html('<pre>' + buildDom(newVal) + '</pre>');
}
}); });
} }
}; };

@ -57,6 +57,24 @@ var inject = function () {
performance.now = performance.webkitNow; performance.now = performance.webkitNow;
} }
// Send notifications from app context to devtools context
// =======================================================
var eventProxyElement = document.createElement('div');
eventProxyElement.id = '__ngDebugElement';
eventProxyElement.style.display = 'none';
document.body.appendChild(eventProxyElement);
var customEvent = document.createEvent('Event');
customEvent.initEvent('myCustomEvent', true, true);
function fireCustomEvent (data) {
eventProxyElement.innerText = data;
eventProxyElement.dispatchEvent(customEvent);
}
// Based on cycle.js // Based on cycle.js
// https://github.com/douglascrockford/JSON-js/blob/master/cycle.js // https://github.com/douglascrockford/JSON-js/blob/master/cycle.js
@ -269,6 +287,8 @@ var inject = function () {
return ids; return ids;
}, },
fireCustomEvent: fireCustomEvent,
// returns null or cached scope // returns null or cached scope
getModel: function (id) { getModel: function (id) {
if (debug.scopeDirty[id]) { if (debug.scopeDirty[id]) {
@ -277,6 +297,75 @@ var inject = function () {
} }
}, },
getSomeModel: function (id, path) {
path = path || [];
var dest = debug.scopes[id],
segment;
if (!dest) {
console.log('no scope');
return;
}
while (path.length > 0) {
segment = path.shift();
dest = dest[segment];
if (!dest) {
console.log('no dest');
return;
}
}
if (dest instanceof Array) {
return {
'~array-length': dest.length
};
} else if (typeof dest === 'object') {
return Object.
keys(dest).
filter(function (key) {
return key[0] !== '$' || key[1] !== '$';
}).
reduce(function (obj, prop) {
obj[prop] = dest[prop] instanceof Array ?
{ '~array-length': dest[prop].length } :
typeof dest[prop] === 'object' ?
{ '~object': true } :
dest[prop];
return obj;
}, {});
} else {
return dest;
}
},
setSomeModel: function (id, path, value) {
path = path || [];
var dest = debug.scopes[id],
segment;
if (!dest) {
return;
}
while (path.length > 1) {
segment = path.shift();
dest = dest[segment];
if (!dest) {
return;
}
}
if (dest[path[0]]) {
debug.scopes[id].$apply(function batarangEditModel () {
dest[path[0]] = value;
});
}
},
getScopeTree: function (id) { getScopeTree: function (id) {
if (debug.scopeTreeDirty[id] === false) { if (debug.scopeTreeDirty[id] === false) {
return; return;
@ -889,6 +978,20 @@ var inject = function () {
return script; return script;
}())); }()));
var eventProxyElement = document.getElementById('__ngDebugElement');
if (eventProxyElement) {
eventProxyElement.addEventListener('myCustomEvent', function() {
var eventData = eventProxyElement.innerText;
chrome.extension.sendMessage({
action: 'modelChange',
value: eventData
});
});
document.removeEventListener('DOMContentLoaded', inject);
}
}; };
// only inject if cookie is set // only inject if cookie is set

@ -1,6 +1,8 @@
// Service for running code in the context of the application being debugged // Service for running code in the context of the application being debugged
angular.module('panelApp').factory('appContext', function (chromeExtension) { angular.module('panelApp').factory('appContext', function (chromeExtension) {
var port = chrome.extension.connect();
// Public API // Public API
// ========== // ==========
return { return {
@ -82,18 +84,23 @@ angular.module('panelApp').factory('appContext', function (chromeExtension) {
// TODO: move to chromeExtension? // TODO: move to chromeExtension?
watchRefresh: function (cb) { watchRefresh: function (cb) {
var port = chrome.extension.connect();
port.postMessage({ port.postMessage({
action: 'register', action: 'register',
inspectedTabId: chrome.devtools.inspectedWindow.tabId inspectedTabId: chrome.devtools.inspectedWindow.tabId
}); });
port.onMessage.addListener(function(msg) { port.onMessage.addListener(function (msg) {
if (msg === 'refresh') { if (msg === 'refresh') {
cb(); cb();
} }
}); });
port.onDisconnect.addListener(function (a) { },
console.log(a);
// TODO: move to chromeExtension?
watchModelChange: function (cb) {
port.onMessage.addListener(function (msg) {
if (msg.action === 'modelChange') {
cb(msg);
}
}); });
} }

@ -28,19 +28,29 @@ angular.module('panelApp').factory('appModel', function (chromeExtension, appCon
}); });
}, },
// only runs callback if model has changed since last call getModel: function (id, path, callback) {
getModel: function (id, callback) {
if (!id) { if (!id) {
return; return;
} }
chromeExtension.eval(function (window, args) { chromeExtension.eval(function (window, args) {
return window.__ngDebug.getModel(args.id); return window.__ngDebug.getSomeModel(args.id, args.path);
}, {id: id}, function (tree) { }, {
if (tree) { id: id,
_scopeCache[id] = tree; path: path
} }, callback);
callback(_scopeCache[id]); },
});
setModel: function (id, path, value, callback) {
if (!id) {
return;
}
chromeExtension.eval(function (window, args) {
return window.__ngDebug.setSomeModel(args.id, args.path, args.value);
}, {
id: id,
path: path,
value: value
}, callback);
}, },
getScopeTree: function (id, callback) { getScopeTree: function (id, callback) {