|
|
|
|
|
|
|
|
|
// tabId -> devtool port
|
|
|
|
|
var inspectedTabs = {};
|
|
|
|
|
|
|
|
|
|
// tabId -> buffered data
|
|
|
|
|
var data = {};
|
|
|
|
|
|
|
|
|
|
function bufferOrForward(message, sender) {
|
|
|
|
|
var tabId = sender.tab.id,
|
|
|
|
|
devToolsPort = inspectedTabs[tabId];
|
|
|
|
|
|
|
|
|
|
if (!data[tabId] || message === 'refresh') {
|
|
|
|
|
resetState(tabId);
|
|
|
|
|
|
|
|
|
|
// TODO: this is kind of a hack-y spot to put this
|
|
|
|
|
showPageAction(tabId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO: not sure how I feel about special-casing `refresh`
|
|
|
|
|
if (message !== 'refresh') {
|
|
|
|
|
message = JSON.parse(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bufferData(tabId, message);
|
|
|
|
|
if (devToolsPort) {
|
|
|
|
|
devToolsPort.postMessage(message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function resetState(tabId) {
|
|
|
|
|
data[tabId] = {
|
|
|
|
|
hints: [],
|
|
|
|
|
scopes: {}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function bufferData(tabId, message) {
|
|
|
|
|
var tabData = data[tabId],
|
|
|
|
|
scope;
|
|
|
|
|
|
|
|
|
|
if (message.message) {
|
|
|
|
|
return tabData.hints.push(message);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (message.event) {
|
|
|
|
|
if (message.event === 'scope:new') {
|
|
|
|
|
tabData.scopes[message.child] = {
|
|
|
|
|
parent: message.parent,
|
|
|
|
|
children: [],
|
|
|
|
|
models: {}
|
|
|
|
|
};
|
|
|
|
|
if (tabData.scopes[message.parent]) {
|
|
|
|
|
tabData.scopes[message.parent].children.push(message.child);
|
|
|
|
|
}
|
|
|
|
|
} else if (message.id && (scope = tabData.scopes[message.id])) {
|
|
|
|
|
if (message.event === 'scope:destroy') {
|
|
|
|
|
if (scope.parent) {
|
|
|
|
|
scope.parent.children.splice(scope.parent.children.indexOf(child), 1);
|
|
|
|
|
}
|
|
|
|
|
delete scopes[message.id];
|
|
|
|
|
} else if (message.event === 'model:change') {
|
|
|
|
|
scope.models[message.path] = (typeof message.value === 'undefined') ?
|
|
|
|
|
undefined : JSON.parse(message.value);
|
|
|
|
|
} else if (message.event === 'scope:link') {
|
|
|
|
|
scope.descriptor = message.descriptor;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// context script –> background
|
|
|
|
|
chrome.runtime.onMessage.addListener(bufferOrForward);
|
|
|
|
|
|
|
|
|
|
chrome.runtime.onConnect.addListener(function(devToolsPort) {
|
|
|
|
|
|
|
|
|
|
devToolsPort.onMessage.addListener(registerInspectedTabId);
|
|
|
|
|
|
|
|
|
|
function registerInspectedTabId(inspectedTabId) {
|
|
|
|
|
inspectedTabs[inspectedTabId] = devToolsPort;
|
|
|
|
|
|
|
|
|
|
if (!data[inspectedTabId]) {
|
|
|
|
|
resetState(inspectedTabId);
|
|
|
|
|
}
|
|
|
|
|
devToolsPort.postMessage({
|
|
|
|
|
event: 'hydrate',
|
|
|
|
|
data: data[inspectedTabId]
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
devToolsPort.onDisconnect.addListener(function () {
|
|
|
|
|
delete inspectedTabs[inspectedTabId];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//devToolsPort.onMessage.removeListener(registerInspectedTabId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
chrome.tabs.onRemoved.addListener(function (tabId) {
|
|
|
|
|
if (data[tabId]) {
|
|
|
|
|
delete data[tabId];
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function showPageAction(tabId) {
|
|
|
|
|
chrome.pageAction.show(tabId);
|
|
|
|
|
chrome.pageAction.setTitle({
|
|
|
|
|
tabId: tabId,
|
|
|
|
|
title: 'Batarang Active'
|
|
|
|
|
});
|
|
|
|
|
}
|