1 // Copyright (c) 2012 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.
5 cr.define('options.dictionary_words', function() {
6 /** @const */ var InlineEditableItemList = options.InlineEditableItemList;
7 /** @const */ var InlineEditableItem = options.InlineEditableItem;
10 * Creates a new dictionary word list item.
11 * @param {string} dictionaryWord The dictionary word.
12 * @param {function(string)} addDictionaryWordCallback Callback for
13 * adding a dictionary word.
15 * @extends {options.InlineEditableItem}
17 function DictionaryWordsListItem(dictionaryWord, addDictionaryWordCallback) {
18 var el = cr.doc.createElement('div');
19 el.dictionaryWord_ = dictionaryWord;
20 el.addDictionaryWordCallback_ = addDictionaryWordCallback;
21 DictionaryWordsListItem.decorate(el);
26 * Decorates an HTML element as a dictionary word list item.
27 * @param {HTMLElement} el The element to decorate.
29 DictionaryWordsListItem.decorate = function(el) {
30 el.__proto__ = DictionaryWordsListItem.prototype;
34 DictionaryWordsListItem.prototype = {
35 __proto__: InlineEditableItem.prototype,
38 decorate: function() {
39 InlineEditableItem.prototype.decorate.call(this);
40 if (this.dictionaryWord_ == '')
41 this.isPlaceholder = true;
43 this.editable = false;
45 var wordEl = this.createEditableTextCell(this.dictionaryWord_);
46 wordEl.classList.add('weakrtl');
47 wordEl.classList.add('language-dictionary-overlay-word-list-item');
48 this.contentElement.appendChild(wordEl);
50 var wordField = wordEl.querySelector('input');
51 wordField.classList.add('language-dictionary-overlay-word-list-item');
52 if (this.isPlaceholder) {
53 wordField.placeholder =
54 loadTimeData.getString('languageDictionaryOverlayAddWordLabel');
57 this.addEventListener('commitedit', this.onEditCommitted_.bind(this));
62 return this.querySelector('input').value.length > 0;
66 * Adds a word to the dictionary.
67 * @param {Event} e Edit committed event.
70 onEditCommitted_: function(e) {
71 var input = e.currentTarget.querySelector('input');
72 this.addDictionaryWordCallback_(input.value);
78 * A list of words in the dictionary.
80 * @extends {options.InlineEditableItemList}
82 var DictionaryWordsList = cr.ui.define('list');
84 DictionaryWordsList.prototype = {
85 __proto__: InlineEditableItemList.prototype,
88 * The function to notify that the word list has changed.
91 onWordListChanged: null,
94 * The list of all words in the dictionary. Used to generate a filtered word
95 * list in the |search(searchTerm)| method.
102 * The list of words that the user removed, but |DictionaryWordList| has not
103 * received a notification of their removal yet.
107 removedWordsList_: [],
110 * Adds a dictionary word.
111 * @param {string} dictionaryWord The word to add.
114 addDictionaryWord_: function(dictionaryWord) {
115 this.allWordsList_.push(dictionaryWord);
116 this.dataModel.splice(this.dataModel.length - 1, 0, dictionaryWord);
117 this.onWordListChanged();
118 chrome.send('addDictionaryWord', [dictionaryWord]);
122 * Searches the list for the matching words.
123 * @param {string} searchTerm The search term.
125 search: function(searchTerm) {
126 var filteredWordList = this.allWordsList_.filter(
127 function(element, index, array) {
128 return element.indexOf(searchTerm) > -1;
130 filteredWordList.push('');
131 this.dataModel = new cr.ui.ArrayDataModel(filteredWordList);
132 this.onWordListChanged();
136 * Sets the list of dictionary words.
137 * @param {Array} entries The list of dictionary words.
139 setWordList: function(entries) {
140 this.allWordsList_ = entries.slice(0);
141 // Empty string is a placeholder for entering new words.
143 this.dataModel = new cr.ui.ArrayDataModel(entries);
144 this.onWordListChanged();
148 * Adds non-duplicate dictionary words.
149 * @param {Array} entries The list of dictionary words.
151 addWords: function(entries) {
153 for (var i = 0; i < entries.length; i++) {
154 if (this.allWordsList_.indexOf(entries[i]) == -1) {
155 this.allWordsList_.push(entries[i]);
156 toAdd.push(entries[i]);
159 if (toAdd.length == 0)
161 for (var i = 0; i < toAdd.length; i++)
162 this.dataModel.splice(this.dataModel.length - 1, 0, toAdd[i]);
163 this.onWordListChanged();
167 * Removes dictionary words that are not in |removedWordsList_|. If a word
168 * is in |removedWordsList_|, then removes the word from there instead.
169 * @param {Array} entries The list of dictionary words.
171 removeWords: function(entries) {
174 for (var i = 0; i < entries.length; i++) {
175 index = this.removedWordsList_.indexOf(entries[i]);
177 this.removedWordsList_.splice(index, 1);
179 index = this.allWordsList_.indexOf(entries[i]);
181 this.allWordsList_.splice(index, 1);
182 toRemove.push(entries[i]);
186 if (toRemove.length == 0)
188 for (var i = 0; i < toRemove.length; i++) {
189 index = this.dataModel.indexOf(toRemove[i]);
191 this.dataModel.splice(index, 1);
193 this.onWordListChanged();
197 * Returns true if the data model contains no words, otherwise returns
202 // A data model without dictionary words contains one placeholder for
203 // entering new words.
204 return this.dataModel.length < 2;
209 * @param {string} dictionaryWord
211 createItem: function(dictionaryWord) {
212 return new DictionaryWordsListItem(
214 this.addDictionaryWord_.bind(this));
218 deleteItemAtIndex: function(index) {
219 // The last element in the data model is an undeletable placeholder for
220 // entering new words.
221 assert(index > -1 && index < this.dataModel.length - 1);
222 var item = this.dataModel.item(index);
223 var allWordsListIndex = this.allWordsList_.indexOf(item);
224 assert(allWordsListIndex > -1);
225 this.allWordsList_.splice(allWordsListIndex, 1);
226 this.dataModel.splice(index, 1);
227 this.removedWordsList_.push(item);
228 this.onWordListChanged();
229 chrome.send('removeDictionaryWord', [item]);
233 shouldFocusPlaceholder: function() {
239 DictionaryWordsList: DictionaryWordsList