Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: chrome/browser/resources/extensions/update_node.js

Issue 893453002: Stop rebuilding all elements in chrome://extensions to preserve focus on refresh (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: DNC - Apply feedback before merging back into 1 file Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/resources/extensions/extension_list.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // TODO(hcarmona): Remove this temporary file.
2
3 /**
4 * Updates an HTML element for the extension metadata given in |extension|.
5 * @param {ExtensionData} extension A dictionary of extension metadata.
6 * @param {Element} node The node that is being updated.
7 * @private
8 */
9 updateNode_: function(extension, node) {
10 node.classList.remove('to-remove');
11 node.classList.toggle('inactive-extension',
12 !extension.enabled || extension.terminated);
13
14 var toRemove = ['policy-controlled', 'may-not-modify', 'may-not-remove'];
15 node.classList.remove.apply(node.classList, toRemove);
16 var classes = [];
17 if (extension.managedInstall) {
18 classes.push('policy-controlled', 'may-not-modify');
19 } else if (extension.dependentExtensions.length > 0) {
20 classes.push('may-not-remove', 'may-not-modify');
21 } else if (extension.recommendedInstall) {
22 classes.push('may-not-remove');
23 } else if (extension.suspiciousInstall ||
24 extension.corruptInstall ||
25 extension.updateRequiredByPolicy) {
26 classes.push('may-not-modify');
27 }
28 node.classList.add.apply(node.classList, classes);
29
30 node.classList.toggle('extension-highlight',
31 node.id == this.getIdQueryParam_());
32
33 var item = node.querySelector('.extension-list-item');
34 // Prevent the image cache of extension icon by using the reloaded
35 // timestamp as a query string. The timestamp is recorded when the user
36 // clicks the 'Reload' link. http://crbug.com/159302.
37 if (extensionReloadedTimestamp[extension.id]) {
38 item.style.backgroundImage =
39 'url(' + extension.icon + '?' +
40 extensionReloadedTimestamp[extension.id] + ')';
41 } else {
42 item.style.backgroundImage = 'url(' + extension.icon + ')';
43 }
44
45 this.setTextContent_(node, '.extension-title', extension.name);
46 this.setTextContent_(node, '.extension-version', extension.version);
47 this.setTextContent_(node, '.location-text', extension.locationText);
48 this.setTextContent_(node, '.blacklist-text', extension.blacklistText);
49 this.setTextContent_(node, '.extension-description',
50 extension.description);
51
52 // The 'Show Browser Action' button.
53 this.updateVisibility_(node, '.show-button',
54 extension.enable_show_button);
55
56 // The 'allow in incognito' checkbox.
57 this.updateVisibility_(node, '.incognito-control',
58 this.data_.incognitoAvailable, function(item) {
59 var incognito = item.querySelector('input');
60 incognito.disabled = !extension.incognitoCanBeEnabled;
61 incognito.checked = extension.enabledIncognito;
62 });
63
64 // Hide butterBar if incognito is not enabled for the extension.
65 var butterBar = node.querySelector('.butter-bar');
66 butterBar.hidden = butterBar.hidden || !extension.enabledIncognito;
67
68 // The 'collect errors' checkbox. This should only be visible if the
69 // error console is enabled - we can detect this by the existence of the
70 // |errorCollectionEnabled| property.
71 this.updateVisibility_(node, '.error-collection-control',
72 extension.wantsErrorCollection, function(item) {
73 item.querySelector('input').checked = extension.errorCollectionEnabled;
74 });
75
76 // The 'allow on all urls' checkbox. This should only be visible if
77 // active script restrictions are enabled. If they are not enabled, no
78 // extensions should want all urls.
79 this.updateVisibility_(node, '.all-urls-control', extension.wantsAllUrls,
80 function(item) {
81 item.querySelector('input').checked = extension.allowAllUrls;
82 });
83
84 // The 'allow file:// access' checkbox.
85 this.updateVisibility_(node, '.file-access-control',
86 extension.wantsFileAccess, function(item) {
87 item.querySelector('input').checked = extension.allowFileAccess;
88 });
89
90 // The 'Options' button or link, depending on its behaviour.
91 var optionsEnabled = extension.enabled && extension.optionsUrl;
92 this.updateVisibility_(node, '.options-link', optionsEnabled &&
93 extension.optionsOpenInTab);
94 this.updateVisibility_(node, '.options-button', optionsEnabled &&
95 !extension.optionsOpenInTab);
96
97 // The 'View in Web Store/View Web Site' link.
98 var siteLinkEnabled = extension.homepageUrl &&
99 !extension.enableExtensionInfoDialog;
100 this.updateVisibility_(node, '.site-link', siteLinkEnabled,
101 function(item) {
102 item.href = extension.homepageUrl;
103 item.textContent = loadTimeData.getString(
104 extension.homepageProvided ? 'extensionSettingsVisitWebsite' :
105 'extensionSettingsVisitWebStore');
106 });
107
108 // The 'Reload' link.
109 this.updateVisibility_(node, '.reload-link', extension.allow_reload);
110
111 // The 'Launch' link.
112 this.updateVisibility_(node, '.launch-link', extension.allow_reload &&
113 extension.is_platform_app);
114
115 // The 'Reload' terminated link.
116 var isTerminated = extension.terminated;
117 this.updateVisibility_(node, '.terminated-reload-link', isTerminated);
118
119 // The 'Repair' corrupted link.
120 var canRepair = !isTerminated && extension.corruptInstall &&
121 extension.isFromStore;
122 this.updateVisibility_(node, '.corrupted-repair-button', canRepair);
123
124 // The 'Enabled' checkbox.
125 var isOK = !isTerminated && !canRepair;
126 this.updateVisibility_(node, '.enable-checkbox', isOK, function(item) {
127 var enableCheckboxDisabled = extension.managedInstall ||
128 extension.suspiciousInstall ||
129 extension.corruptInstall ||
130 extension.updateRequiredByPolicy ||
131 extension.dependentExtensions.length > 0;
132 item.querySelector('input').disabled = enableCheckboxDisabled;
133 item.querySelector('input').checked = isOK && extension.enabled;
hcarmona 2015/02/11 02:22:07 isOK is redundant. Removed it in merged version.
134 });
135
136 // Button for extensions controlled by policy.
hcarmona 2015/02/11 02:22:07 This was confusing when reviewing changes.
137 var controlNode = node.querySelector('.enable-controls');
138 if (extension.managedInstall &&
139 !controlNode.querySelector('.controlled-extension-indicator')) {
140 var indicator = new cr.ui.ControlledIndicator();
141 indicator.classList.add('controlled-extension-indicator');
142 indicator.setAttribute('controlled-by', 'policy');
143 indicator.setAttribute('textpolicy', extension.policyText || '');
144 controlNode.appendChild(indicator);
145 } else if (!extension.managedInstall) {
146 var indicator = controlNode.querySelector(
147 '.controlled-extension-indicator');
148 if (indicator)
149 controlNode.removeChild(indicator);
150 }
151
152 // Developer mode ////////////////////////////////////////////////////////
153
154 // First we have the id.
155 var idLabel = node.querySelector('.extension-id');
156 idLabel.textContent = ' ' + extension.id;
157
158 // Then the path, if provided by unpacked extension.
159 this.updateVisibility_(node, '.load-path', extension.isUnpacked,
160 function() {
hcarmona 2015/02/11 02:22:07 Changed in merged version: function(item) {
161 item.querySelector('a:nth-of-type(1)').textContent =
162 ' ' + extension.prettifiedPath;
163 });
164
165 // Then the 'managed, cannot uninstall/disable' message.
166 var isRequired = extension.managedInstall || extension.recommendedInstall;
167 this.updateVisibility_(node, '.managed-message', isRequired);
hcarmona 2015/02/11 02:22:07 Changed the condition to prevent from overriding f
168
169 // Then the 'This isn't from the webstore, looks suspicious' message.
170 this.updateVisibility_(node, '.suspicious-install-message', !isRequired &&
171 extension.suspiciousInstall);
172
173 // Then the 'This is a corrupt extension' message.
174 this.updateVisibility_(node, '.corrupt-install-message', !isRequired &&
175 extension.corruptInstall);
176
177 // Then the 'An update required by enterprise policy' message. Note that
178 // a force-installed extension might be disabled due to being outdated
179 // as well.
180 this.updateVisibility_(node, '.update-required-message',
181 extension.updateRequiredByPolicy);
182 // We would like to hide managed installed message since this
183 // extension is disabled.
184 this.updateVisibility_(node, '.managed-message',
hcarmona 2015/02/11 02:22:07 This was overriding the hidden value of '.managed-
185 !extension.updateRequiredByPolicy);
186
187 // The 'following extensions depend on this extension' list.
188 var hasDependents = extension.dependentExtensions.length > 0;
189 node.classList.toggle('developer-extras', hasDependents);
190 this.updateVisibility_(node, '.dependent-extensions-message',
191 hasDependents, function(item) {
192 var dependentList = item.querySelector('ul');
193 dependentList.textContent = '';
194 var dependentTemplate = $('template-collection').querySelector(
195 '.dependent-list-item');
196 extension.dependentExtensions.forEach(function(elem) {
197 var depNode = dependentTemplate.cloneNode(true);
198 depNode.querySelector('.dep-extension-title').textContent =
hcarmona 2015/02/11 02:22:07 This fits in 1 line again.
199 elem.name;
200 depNode.querySelector('.dep-extension-id').textContent = elem.id;
201 dependentList.appendChild(depNode);
202 });
203 });
204
205 // The active views.
206 this.updateVisibility_(node, '.active-views', extension.views.length > 0,
207 function(item) {
208 var link = item.querySelector('a');
209
210 // Link needs to be an only child before the list is updated.
211 while (link.nextElementSibling)
212 item.removeChild(link.nextElementSibling);
213
214 // Link needs to be cleaned up if it was used before.
215 link.textContent = '';
216 if (link.clickHandler)
217 link.removeEventListener('click', link.clickHandler);
218
219 extension.views.forEach(function(view, i) {
220 var displayName = view.generatedBackgroundPage ?
221 loadTimeData.getString('backgroundPage') : view.path;
222 var label = displayName +
223 (view.incognito ?
224 ' ' + loadTimeData.getString('viewIncognito') : '') +
225 (view.renderProcessId == -1 ?
226 ' ' + loadTimeData.getString('viewInactive') : '');
227 link.textContent = label;
228 link.clickHandler = function(e) {
229 // TODO(estade): remove conversion to string?
230 chrome.send('extensionSettingsInspect', [
231 String(extension.id),
232 String(view.renderProcessId),
233 String(view.renderViewId),
234 view.incognito
235 ]);
236 };
237 link.addEventListener('click', link.clickHandler);
238
239 if (i < extension.views.length - 1) {
240 link = link.cloneNode(true);
241 item.appendChild(link);
242 }
243 });
244 });
245
246 // The extension warnings (describing runtime issues).
247 this.updateVisibility_(node, '.extension-warnings', extension.warnings,
248 function(item) {
249 var warningList = item.querySelector('ul');
250 warningList.textContent = '';
251 if (extension.warnings) {
hcarmona 2015/02/11 02:22:07 if (extension.warnings) will always be true. Remov
252 extension.warnings.forEach(function(warning) {
253 var li = document.createElement('li');
254 warningList.appendChild(li).innerText = warning;
255 });
256 }
257 });
258
259 // If the ErrorConsole is enabled, we should have manifest and/or runtime
260 // errors. Otherwise, we may have install warnings. We should not have
261 // both ErrorConsole errors and install warnings.
262 // Errors.
263 this.updateErrors_(node.querySelector('.manifest-errors'),
264 extension.manifestErrors);
265 this.updateErrors_(node.querySelector('.runtime-errors'),
266 extension.runtimeErrors);
267
268 // Install warnings.
269 this.updateVisibility_(node, '.install-warnings',
270 extension.installWarnings, function(item) {
271 var installWarningList = installWarningPanel.querySelector('ul');
hcarmona 2015/02/11 02:22:07 installWarningPanel -> item since installWarningP
272 installWarningList.textContent = '';
273 if (extension.installWarnings) {
274 extension.installWarnings.forEach(function(warning) {
275 var li = document.createElement('li');
276 li.innerText = warning.message;
277 installWarningList.appendChild(li);
278 });
279 }
280 });
281
282 if (location.hash.substr(1) == extension.id) {
283 // Scroll beneath the fixed header so that the extension is not
284 // obscured.
285 var topScroll = node.offsetTop - $('page-header').offsetHeight;
286 var pad = parseInt(window.getComputedStyle(node, null).marginTop, 10);
287 if (!isNaN(pad))
288 topScroll -= pad / 2;
289 setScrollTopForDocument(document, topScroll);
290 }
291 },
OLDNEW
« no previous file with comments | « chrome/browser/resources/extensions/extension_list.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698