OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 cr.define('extensions', function() { |
| 6 'use strict'; |
| 7 |
| 8 /** |
| 9 * Returns whether or not a given |link| is associated with an extension. |
| 10 * @param {string} link The link to examine. |
| 11 * @param {string} extensionUrl The url of the extension. |
| 12 * @return {boolean} Whether or not the link is prefixed by the prefix. |
| 13 */ |
| 14 function isExtensionLink(link, extensionUrl) { |
| 15 return link.substring(0, extensionUrl) === extensionUrl; |
| 16 } |
| 17 |
| 18 /** |
| 19 * Get the link relative to the main extension url. If the link is |
| 20 * unassociated with the extension, this will be the full link. |
| 21 * @param {link} The link to make relative. |
| 22 * @param {extensionUrl} The host for which the link is relative. |
| 23 * @return {string} The link relative to the host. |
| 24 */ |
| 25 function getRelativeLink(link, extensionUrl) { |
| 26 return isExtensionLink(link, extensionUrl) ? |
| 27 link.substring(extensionUrl.length) : link; |
| 28 } |
| 29 |
| 30 /** |
| 31 * Clone a template within the extension error template collection. |
| 32 * @param {string} templateName The class name of the template to clone. |
| 33 * @return {HTMLElement} The clone of the template. |
| 34 */ |
| 35 function cloneTemplate(templateName) { |
| 36 return $('template-collection-extension-error') |
| 37 .querySelector(templateName).cloneNode(true); |
| 38 } |
| 39 |
| 40 /** |
| 41 * Creates a new ExtensionError HTMLElement. |
| 42 * @param {Object} error The error the element should represent. |
| 43 * @return {HTMLElement} The created error element. |
| 44 */ |
| 45 function ExtensionError(error) { |
| 46 var div = document.createElement('div'); |
| 47 div.__proto__ = ExtensionError.prototype; |
| 48 div.className = 'extension-error-simple-wrapper'; |
| 49 div.error_ = error; |
| 50 div.decorate(); |
| 51 return div; |
| 52 } |
| 53 |
| 54 ExtensionError.prototype = { |
| 55 __proto__: HTMLDivElement.prototype, |
| 56 |
| 57 /** @override */ |
| 58 decorate: function() { |
| 59 var metadata = cloneTemplate('.extension-error-metadata'); |
| 60 |
| 61 // Set an icon for the level of severity... |
| 62 var iconNode = metadata.querySelector('img'); |
| 63 iconNode.className = |
| 64 this.error_.level == 0 ? 'extension-error-icon-log' : |
| 65 this.error_.level == 1 ? 'extension-error-icon-warn' : |
| 66 'extension-error-icon-error'; |
| 67 |
| 68 // Add a property for the extension's base url in order to determine if |
| 69 // a link belongs to the extension. |
| 70 this.extensionUrl_ = |
| 71 'chrome-extension://' + this.error_.extensionID + '/'; |
| 72 |
| 73 // The error message... |
| 74 metadata.querySelector('.extension-error-message').innerText = |
| 75 this.error_.message; |
| 76 |
| 77 // The error source... |
| 78 metadata.querySelector('.extension-error-source').innerText = |
| 79 '(' + getRelativeLink(this.error_.source, this.extensionUrl_) + ')'; |
| 80 |
| 81 this.appendChild(metadata); |
| 82 this.addViewLinkToNode_(this, this.error_.source); |
| 83 }, |
| 84 |
| 85 /** |
| 86 * Add a "view" link to the given node, if a user can view the source of the |
| 87 * specified link. |
| 88 * @param {HTMLElement} node The node to which we append the view link. |
| 89 * @param {string} link The link to the resource to view. |
| 90 */ |
| 91 addViewLinkToNode_: function(node, link) { |
| 92 if (this.canViewSource_(link)) |
| 93 node.appendChild(this.getViewSourceLink_(link)); |
| 94 }, |
| 95 |
| 96 /** |
| 97 * Determine whether we can view the source of a given link. |
| 98 * @param {string} link The link to the resource to view. |
| 99 * @return {boolean} Whether or not we can view the source for the link. |
| 100 */ |
| 101 canViewSource_: function(link) { |
| 102 return isExtensionLink(link, this.extensionUrl_) || |
| 103 link === 'manifest.json'; |
| 104 }, |
| 105 |
| 106 /** |
| 107 * Create a clickable node to view the source for the given link. |
| 108 * @param {string} link The link t othe resource to view. |
| 109 * @return {HTMLElement} The clickable node to view the source. |
| 110 */ |
| 111 getViewSourceLink_: function(link) { |
| 112 var node = document.createElement('a'); |
| 113 node.innerText = loadTimeData.getString('extensionErrorViewSource'); |
| 114 |
| 115 var relativeLink = getRelativeLink(link, this.extensionUrl_); |
| 116 node.addEventListener('click', function(e) { |
| 117 chrome.send('extensionErrorRequestFileSource', |
| 118 [{ |
| 119 'extensionId': this.error_.extensionId, |
| 120 'errorMessage': this.error_.message, |
| 121 'fileType': 'manifest', |
| 122 'pathSuffix': relativeLink, |
| 123 'feature': this.error_.manifestKey, |
| 124 'specific': this.error_.manifestSpecific |
| 125 }]); |
| 126 }.bind(this)); |
| 127 return node; |
| 128 } |
| 129 }; |
| 130 |
| 131 function ExtensionErrorList(errors) { |
| 132 var div = cloneTemplate('.extension-error-list'); |
| 133 div.__proto__ = ExtensionErrorList.prototype; |
| 134 div.errors_ = errors; |
| 135 div.decorate(); |
| 136 return div; |
| 137 } |
| 138 |
| 139 ExtensionErrorList.prototype = { |
| 140 __proto__: HTMLDivElement.prototype, |
| 141 |
| 142 kMaxErrorsToShow_: 3, |
| 143 |
| 144 /** @override */ |
| 145 decorate: function() { |
| 146 this.contents_ = this.querySelector('.extension-error-list-contents'); |
| 147 this.errors_.forEach(function(error) { |
| 148 this.contents_.appendChild(document.createElement('li')).appendChild( |
| 149 new ExtensionError(error)); |
| 150 }.bind(this)); |
| 151 |
| 152 if (this.contents_.children.length > this.kMaxErrorsToShow_) { |
| 153 for (var i = this.kMaxErrorsToShow_; |
| 154 i < this.contents_.children.length; ++i) |
| 155 this.contents_.children[i].hidden = true; |
| 156 this.initShowMoreButton_(); |
| 157 } |
| 158 }, |
| 159 |
| 160 initShowMoreButton_: function() { |
| 161 var button = this.querySelector('.extension-error-list-show-more') |
| 162 .querySelector('a'); |
| 163 button.hidden = false; |
| 164 button.isShowingAll = false; |
| 165 button.addEventListener('click', function(e) { |
| 166 if (button.isShowingAll) { |
| 167 for (var i = this.kMaxErrorsToShow_; |
| 168 i < this.contents_.children.length; ++i) { |
| 169 this.contents_.children[i].hidden = true; |
| 170 } |
| 171 button.innerText = loadTimeData.getString('extensionErrorsShowMore'); |
| 172 } else { |
| 173 for (var i = this.kMaxErrorsToShow_; |
| 174 i < this.contents_.children.length; ++i) { |
| 175 this.contents_.children[i].hidden = false; |
| 176 } |
| 177 button.innerText = loadTimeData.getString('extensionErrorsShowFewer'); |
| 178 } |
| 179 |
| 180 button.isShowingAll = !button.isShowingAll; |
| 181 }.bind(this)); |
| 182 } |
| 183 }; |
| 184 |
| 185 return { |
| 186 ExtensionErrorList: ExtensionErrorList |
| 187 }; |
| 188 }); |
OLD | NEW |