forked from googlearchive/polymer-devtools-extension
-
Notifications
You must be signed in to change notification settings - Fork 0
/
background.js
142 lines (134 loc) · 4.64 KB
/
background.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Responsible for channeling messages from devtools pane and content scripts
// Here is where the associations between them are made across tabs.
(function() {
var tabIdToPortMap = {};
var portIdToTabIdMap = {};
var portIdToPortMap = {};
var isFreshPage = {};
var isPolymerPage = {};
// To assign port IDs to ports because ports aren't hashable
var lastPortId = 0;
// A panel just tried to connect to the extension background
chrome.runtime.onConnect.addListener(function(port) {
var portId;
function onMessage(message, sender, sendResponse) {
switch (message.name) {
case 'panel-init':
portId = ++lastPortId;
tabIdToPortMap[message.tabId] = port;
portIdToTabIdMap[portId] = message.tabId;
portIdToPortMap[portId] = port;
chrome.tabs.executeScript(message.tabId, {
file: 'contentScript.js'
});
break;
case 'fresh-page':
// Tab's location had changed and the page confirmed that it was a refresh.
// Start the content script.
chrome.tabs.executeScript(message.tabId, {
file: 'contentScript.js'
});
// Mark it so.
isFreshPage[message.tabId] = true;
isPolymerPage[message.tabId] = message.isPolymerPage;
break;
}
}
// We expect a `panel-init` message from it soon after the connection.
port.onMessage.addListener(onMessage);
// When a panel closes
port.onDisconnect.addListener(function() {
// Find the tab
tabId = portIdToTabIdMap[portId];
// Delete all associations
delete portIdToTabIdMap[portId];
delete portIdToPortMap[portId];
delete tabIdToPortMap[tabId];
delete isFreshPage[tabId];
delete isPolymerPage[tabId];
// Send a message to the content script do necessary clean-up
chrome.tabs.sendMessage(tabId, {
name: 'clean-up'
});
});
});
// All the communcation
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
var port = tabIdToPortMap[sender.tab.id];
if (!port) {
return;
}
switch (message.name) {
case 'object-changed':
// When an object changes
port.postMessage({
name: 'object-changed',
changeList: message.changeList
});
break;
case 'dom-mutation':
// When a DOM mutation occurs
port.postMessage({
name: 'dom-mutation',
changeList: message.changeList
});
break;
case 'inspected-element-changed':
// When element selection changes in the inspector
port.postMessage({
name: 'inspected-element-changed',
key: message.key
});
break;
case 'polymer-ready':
// If `polymer-ready` happens after chrome.tabs detects page reload.
port.postMessage({
name: 'refresh'
});
break;
}
});
// When a page navigation is initiated.
// Sequence of events that happen:
// 1. Background-page to panel => 'check-page-refresh'
// Possibly (if page is fresh):
// 2. panel to Background-page => 'fresh-page'
// 3. Background-page to panel => 'refresh'
// Possibly (if `polymer-ready` happened after content script was loaded):
// 4. content-script to background-page => 'polymer-ready'
// 5. background-page to panel => 'refresh'
chrome.webNavigation.onCommitted.addListener(function(details) {
if (details.frameId !== 0) {
// If it is not the top-frame, we just ignore it.
return;
}
var tabId = details.tabId;
if (tabId in tabIdToPortMap) {
// If extension was open in this tab, send a message to check if this was
// an actual page reload. Further action is based on the response to this.
var port = tabIdToPortMap[tabId];
isFreshPage[tabId] = false;
isPolymerPage[tabId] = false;
port.postMessage({
name: 'check-page-fresh'
});
}
});
// When a page navigation is completed.
chrome.webNavigation.onCompleted.addListener(function(details) {
if (details.frameId !== 0) {
// If it is not the top-frame, we just ignore it.
return;
}
var tabId = details.tabId;
if (tabId in tabIdToPortMap && tabId in isFreshPage && !(tabId in isPolymerPage)) {
// If the panel has told us that this page is fresh, the panel needs to be
// re-initialized. This has to be done only if it is a Polymer page, otherwise
// content script will send a message 'polymer-ready' which should take care of it.
var port = tabIdToPortMap[tabId];
port.postMessage({
name: 'refresh'
});
}
});
})();