Index: chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list.js |
diff --git a/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list.js b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..789f7c55cd2188b65e1f8e9dbef7f7dfba81e285 |
--- /dev/null |
+++ b/chrome/common/extensions/docs/examples/extensions/plugin_settings/js/rule_list.js |
@@ -0,0 +1,347 @@ |
+// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+cr.define('pluginSettings.ui', function() { |
+ const InlineEditableItemList = options.InlineEditableItemList; |
+ const InlineEditableItem = options.InlineEditableItem; |
+ const ArrayDataModel = cr.ui.ArrayDataModel; |
+ |
+ /** |
+ * Creates a new rule list item. |
+ * @param {RuleList} list The rule list containing this item. |
+ * @param {Object} rule The content setting rule. |
+ * @constructor |
+ * @extends {options.InlineEditableItem} |
+ */ |
+ function RuleListItem(list, rule) { |
+ var el = cr.doc.createElement('li'); |
+ |
+ el.dataItem_ = rule; |
+ el.list_ = list; |
+ el.__proto__ = RuleListItem.prototype; |
+ el.decorate(); |
+ |
+ return el; |
+ } |
+ |
+ RuleListItem.prototype = { |
+ __proto__: InlineEditableItem.prototype, |
+ |
+ /** |
+ * The content setting rule. |
+ * @type {Object} |
+ * @private |
+ */ |
+ dataItem_: null, |
+ |
+ /** |
+ * The rule list containing this item. |
+ * @type {RuleList} |
+ * @private |
+ */ |
+ list_: null, |
+ |
+ /** |
+ * Called when an element is decorated as a list item. |
+ */ |
+ decorate: function() { |
+ InlineEditableItem.prototype.decorate.call(this); |
+ |
+ this.isPlaceholder = !this.pattern; |
+ var patternCell = this.createEditableTextCell(this.pattern); |
+ patternCell.className = 'rule-pattern'; |
+ patternCell.classList.add('weakrtl'); |
+ this.contentElement.appendChild(patternCell); |
+ if (this.pattern) |
+ this.patternLabel = patternCell.querySelector('.static-text'); |
+ var input = patternCell.querySelector('input'); |
+ |
+ // TODO(stuartmorgan): Create an createEditableSelectCell abstracting |
+ // this code. |
+ // Setting label for display mode. |pattern| will be null for the 'add new |
+ // exception' row. |
+ if (this.pattern) { |
+ var settingLabel = cr.doc.createElement('span'); |
+ settingLabel.textContent = this.settingForDisplay(); |
+ settingLabel.className = 'rule-behavior'; |
+ settingLabel.setAttribute('displaymode', 'static'); |
+ this.contentElement.appendChild(settingLabel); |
+ this.settingLabel = settingLabel; |
+ } |
+ |
+ // Setting select element for edit mode. |
+ var select = cr.doc.createElement('select'); |
+ var optionAllow = cr.doc.createElement('option'); |
+ optionAllow.textContent = chrome.i18n.getMessage("allowRule"); |
+ optionAllow.value = 'allow'; |
+ select.appendChild(optionAllow); |
+ |
+ var optionBlock = cr.doc.createElement('option'); |
+ optionBlock.textContent = chrome.i18n.getMessage("blockRule"); |
+ optionBlock.value = 'block'; |
+ select.appendChild(optionBlock); |
+ |
+ this.contentElement.appendChild(select); |
+ select.className = 'rule-behavior'; |
+ if (this.pattern) |
+ select.setAttribute('displaymode', 'edit'); |
+ |
+ this.input = input; |
+ this.select = select; |
+ |
+ this.updateEditables(); |
+ |
+ // Listen for edit events. |
+ this.addEventListener('canceledit', this.onEditCancelled_); |
+ this.addEventListener('commitedit', this.onEditCommitted_); |
+ }, |
+ |
+ /** |
+ * The pattern (e.g., a URL) for the rule. |
+ * @type {string} |
+ */ |
+ get pattern() { |
+ return this.dataItem_['primaryPattern']; |
+ }, |
+ set pattern(pattern) { |
+ this.dataItem_['primaryPattern'] = pattern; |
+ }, |
+ |
+ /** |
+ * The setting (allow/block) for the rule. |
+ * @type {string} |
+ */ |
+ get setting() { |
+ return this.dataItem_['setting']; |
+ }, |
+ set setting(setting) { |
+ this.dataItem_['setting'] = setting; |
+ }, |
+ |
+ /** |
+ * Gets a human-readable setting string. |
+ * @type {string} |
+ */ |
+ settingForDisplay: function() { |
+ var setting = this.setting; |
+ if (setting == 'allow') |
+ return chrome.i18n.getMessage("allowRule"); |
+ else if (setting == 'block') |
+ return chrome.i18n.getMessage("blockRule"); |
+ }, |
+ |
+ /** |
+ * Set the <input> to its original contents. Used when the user quits |
+ * editing. |
+ */ |
+ resetInput: function() { |
+ this.input.value = this.pattern; |
+ }, |
+ |
+ /** |
+ * Copy the data model values to the editable nodes. |
+ */ |
+ updateEditables: function() { |
+ this.resetInput(); |
+ |
+ var settingOption = |
+ this.select.querySelector('[value=\'' + this.setting + '\']'); |
+ if (settingOption) |
+ settingOption.selected = true; |
+ }, |
+ |
+ /** @inheritDoc */ |
+ get hasBeenEdited() { |
+ var livePattern = this.input.value; |
+ var liveSetting = this.select.value; |
+ return livePattern != this.pattern || liveSetting != this.setting; |
+ }, |
+ |
+ /** |
+ * Called when committing an edit. |
+ * @param {Event} e The end event. |
+ * @private |
+ */ |
+ onEditCommitted_: function(e) { |
+ var newPattern = this.input.value; |
+ var newSetting = this.select.value; |
+ |
+ this.finishEdit(newPattern, newSetting); |
+ }, |
+ |
+ /** |
+ * Called when cancelling an edit; resets the control states. |
+ * @param {Event} e The cancel event. |
+ * @private |
+ */ |
+ onEditCancelled_: function() { |
+ this.updateEditables(); |
+ }, |
+ |
+ /** |
+ * Editing is complete; update the model. |
+ * @param {string} newPattern The pattern that the user entered. |
+ * @param {string} newSetting The setting the user chose. |
+ */ |
+ finishEdit: function(newPattern, newSetting) { |
+ this.patternLabel.textContent = newPattern; |
+ this.settingLabel.textContent = this.settingForDisplay(); |
+ var oldPattern = this.pattern; |
+ this.pattern = newPattern; |
+ this.setting = newSetting; |
+ |
+ this.list_.settings.update(oldPattern, newPattern, newSetting); |
+ } |
+ }; |
+ |
+ /** |
+ * Create a new list item to add a rule. |
+ * @param {RuleList} list The rule list containing this item. |
+ * @constructor |
+ * @extends {AddRuleListItem} |
+ */ |
+ function AddRuleListItem(list) { |
+ var el = cr.doc.createElement('div'); |
+ el.dataItem_ = {}; |
+ el.list_ = list; |
+ el.__proto__ = AddRuleListItem.prototype; |
+ el.decorate(); |
+ |
+ return el; |
+ } |
+ |
+ AddRuleListItem.prototype = { |
+ __proto__: RuleListItem.prototype, |
+ |
+ /** |
+ * Initializes the element. |
+ */ |
+ decorate: function() { |
+ RuleListItem.prototype.decorate.call(this); |
+ |
+ this.setting = 'allow'; |
+ }, |
+ |
+ /** |
+ * Clear the <input> and let the placeholder text show again. |
+ */ |
+ resetInput: function() { |
+ this.input.value = ''; |
+ }, |
+ |
+ /** @inheritDoc */ |
+ get hasBeenEdited() { |
+ return this.input.value != ''; |
+ }, |
+ |
+ /** |
+ * Editing is complete; update the model. As long as the pattern isn't |
+ * empty, we'll just add it. |
+ * @param {string} newPattern The pattern that the user entered. |
+ * @param {string} newSetting The setting the user chose. |
+ */ |
+ finishEdit: function(newPattern, newSetting) { |
+ this.resetInput(); |
+ this.list_.settings.set(newPattern, newSetting); |
+ }, |
+ }; |
+ |
+ /** |
+ * Creates a new rule list. |
+ * @constructor |
+ * @extends {cr.ui.List} |
+ */ |
+ var RuleList = cr.ui.define('list'); |
+ |
+ RuleList.prototype = { |
+ __proto__: InlineEditableItemList.prototype, |
+ |
+ /** |
+ * The content settings model for this list. |
+ * @type {Settings} |
+ */ |
+ settings: null, |
+ |
+ /** |
+ * Called when an element is decorated as a list. |
+ */ |
+ decorate: function() { |
+ InlineEditableItemList.prototype.decorate.call(this); |
+ |
+ this.classList.add('settings-list'); |
+ |
+ this.autoExpands = true; |
+ this.reset(); |
+ }, |
+ |
+ /** |
+ * Creates an item to go in the list. |
+ * @param {Object} entry The element from the data model for this row. |
+ */ |
+ createItem: function(entry) { |
+ if (entry) { |
+ return new RuleListItem(this, entry); |
+ } else { |
+ var addRuleItem = new AddRuleListItem(this); |
+ addRuleItem.deletable = false; |
+ return addRuleItem; |
+ } |
+ }, |
+ |
+ /** |
+ * Sets the rules in the js model. |
+ * @param {Object} entries A list of dictionaries of values, each dictionary |
+ * represents a rule. |
+ */ |
+ setRules_: function(entries) { |
+ var deleteCount = this.dataModel.length - 1; |
+ |
+ var args = [0, deleteCount]; |
+ args.push.apply(args, entries); |
+ this.dataModel.splice.apply(this.dataModel, args); // ??? |
+ }, |
+ |
+ /** |
+ * Called when the list of content setting rules changes. |
+ */ |
+ handleSettingsChange_: function(e) { |
+ this.setRules_(this.settings.getAll()); |
+ }, |
+ |
+ /** |
+ * Binds this list to the content settings model. |
+ * @param {Settings} settings The content settings model. |
+ */ |
+ setPluginSettings: function(settings) { |
+ this.settings = settings; |
+ this.setRules_(settings.getAll()); |
+ settings.addEventListener('change', |
+ this.handleSettingsChange_.bind(this)); |
+ }, |
+ |
+ /** |
+ * Removes all rules from the js model. |
+ */ |
+ reset: function() { |
+ // The null creates the Add New Rule row. |
+ this.dataModel = new ArrayDataModel([null]); |
+ }, |
+ |
+ /** @inheritDoc */ |
+ deleteItemAtIndex: function(index) { |
+ var listItem = this.getListItemByIndex(index); |
+ if (listItem.undeletable) |
+ return; |
+ |
+ this.settings.clear(listItem.setting); |
+ }, |
+ }; |
+ |
+ return { |
+ RuleListItem: RuleListItem, |
+ AddRuleListItem: AddRuleListItem, |
+ RuleList: RuleList, |
+ } |
+}); |
+ |