Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / options / language_dictionary_overlay_word_list.js
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.
4
5 cr.define('options.dictionary_words', function() {
6   /** @const */ var InlineEditableItemList = options.InlineEditableItemList;
7   /** @const */ var InlineEditableItem = options.InlineEditableItem;
8
9   /**
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.
14    * @constructor
15    * @extends {cr.ui.InlineEditableItem}
16    */
17   function DictionaryWordsListItem(dictionaryWord, addDictionaryWordCallback) {
18     var el = cr.doc.createElement('div');
19     el.dictionaryWord_ = dictionaryWord;
20     el.addDictionaryWordCallback_ = addDictionaryWordCallback;
21     DictionaryWordsListItem.decorate(el);
22     return el;
23   }
24
25   /**
26    * Decorates an HTML element as a dictionary word list item.
27    * @param {HTMLElement} el The element to decorate.
28    */
29   DictionaryWordsListItem.decorate = function(el) {
30     el.__proto__ = DictionaryWordsListItem.prototype;
31     el.decorate();
32   };
33
34   DictionaryWordsListItem.prototype = {
35     __proto__: InlineEditableItem.prototype,
36
37     /** @override */
38     decorate: function() {
39       InlineEditableItem.prototype.decorate.call(this);
40       if (this.dictionaryWord_ == '')
41         this.isPlaceholder = true;
42       else
43         this.editable = false;
44
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);
49
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');
55       }
56
57       this.addEventListener('commitedit', this.onEditCommitted_.bind(this));
58     },
59
60     /** @override */
61     get hasBeenEdited() {
62       return this.querySelector('input').value.length > 0;
63     },
64
65     /**
66      * Adds a word to the dictionary.
67      * @param {Event} e Edit committed event.
68      * @private
69      */
70     onEditCommitted_: function(e) {
71       var input = e.currentTarget.querySelector('input');
72       this.addDictionaryWordCallback_(input.value);
73       input.value = '';
74     },
75   };
76
77   /**
78    * A list of words in the dictionary.
79    * @extends {cr.ui.InlineEditableItemList}
80    */
81   var DictionaryWordsList = cr.ui.define('list');
82
83   DictionaryWordsList.prototype = {
84     __proto__: InlineEditableItemList.prototype,
85
86     /**
87      * The function to notify that the word list has changed.
88      * @type {function()}
89      */
90     onWordListChanged: null,
91
92     /**
93      * The list of all words in the dictionary. Used to generate a filtered word
94      * list in the |search(searchTerm)| method.
95      * @type {Array}
96      * @private
97      */
98     allWordsList_: null,
99
100     /**
101      * The list of words that the user removed, but |DictionaryWordList| has not
102      * received a notification of their removal yet.
103      * @type {Array}
104      * @private
105      */
106     removedWordsList_: [],
107
108     /**
109      * Adds a dictionary word.
110      * @param {string} dictionaryWord The word to add.
111      * @private
112      */
113     addDictionaryWord_: function(dictionaryWord) {
114       this.allWordsList_.push(dictionaryWord);
115       this.dataModel.splice(this.dataModel.length - 1, 0, dictionaryWord);
116       this.onWordListChanged();
117       chrome.send('addDictionaryWord', [dictionaryWord]);
118     },
119
120     /**
121      * Searches the list for the matching words.
122      * @param {string} searchTerm The search term.
123      */
124     search: function(searchTerm) {
125       var filteredWordList = this.allWordsList_.filter(
126           function(element, index, array) {
127             return element.indexOf(searchTerm) > -1;
128           });
129       filteredWordList.push('');
130       this.dataModel = new cr.ui.ArrayDataModel(filteredWordList);
131       this.onWordListChanged();
132     },
133
134     /**
135      * Sets the list of dictionary words.
136      * @param {Array} entries The list of dictionary words.
137      */
138     setWordList: function(entries) {
139       this.allWordsList_ = entries.slice(0);
140       // Empty string is a placeholder for entering new words.
141       entries.push('');
142       this.dataModel = new cr.ui.ArrayDataModel(entries);
143       this.onWordListChanged();
144     },
145
146     /**
147      * Adds non-duplicate dictionary words.
148      * @param {Array} entries The list of dictionary words.
149      */
150     addWords: function(entries) {
151       var toAdd = [];
152       for (var i = 0; i < entries.length; i++) {
153         if (this.allWordsList_.indexOf(entries[i]) == -1) {
154           this.allWordsList_.push(entries[i]);
155           toAdd.push(entries[i]);
156         }
157       }
158       if (toAdd.length == 0)
159         return;
160       for (var i = 0; i < toAdd.length; i++)
161         this.dataModel.splice(this.dataModel.length - 1, 0, toAdd[i]);
162       this.onWordListChanged();
163     },
164
165     /**
166      * Removes dictionary words that are not in |removedWordsList_|. If a word
167      * is in |removedWordsList_|, then removes the word from there instead.
168      * @param {Array} entries The list of dictionary words.
169      */
170     removeWords: function(entries) {
171       var index;
172       var toRemove = [];
173       for (var i = 0; i < entries.length; i++) {
174         index = this.removedWordsList_.indexOf(entries[i]);
175         if (index > -1) {
176           this.removedWordsList_.splice(index, 1);
177         } else {
178           index = this.allWordsList_.indexOf(entries[i]);
179           if (index > -1) {
180             this.allWordsList_.splice(index, 1);
181             toRemove.push(entries[i]);
182           }
183         }
184       }
185       if (toRemove.length == 0)
186         return;
187       for (var i = 0; i < toRemove.length; i++) {
188         index = this.dataModel.indexOf(toRemove[i]);
189         if (index > -1)
190           this.dataModel.splice(index, 1);
191       }
192       this.onWordListChanged();
193     },
194
195     /**
196      * Returns true if the data model contains no words, otherwise returns
197      * false.
198      * @type {boolean}
199      */
200     get empty() {
201       // A data model without dictionary words contains one placeholder for
202       // entering new words.
203       return this.dataModel.length < 2;
204     },
205
206     /** @override */
207     createItem: function(dictionaryWord) {
208       return new DictionaryWordsListItem(
209           dictionaryWord,
210           this.addDictionaryWord_.bind(this));
211     },
212
213     /** @override */
214     deleteItemAtIndex: function(index) {
215       // The last element in the data model is an undeletable placeholder for
216       // entering new words.
217       assert(index > -1 && index < this.dataModel.length - 1);
218       var item = this.dataModel.item(index);
219       var allWordsListIndex = this.allWordsList_.indexOf(item);
220       assert(allWordsListIndex > -1);
221       this.allWordsList_.splice(allWordsListIndex, 1);
222       this.dataModel.splice(index, 1);
223       this.removedWordsList_.push(item);
224       this.onWordListChanged();
225       chrome.send('removeDictionaryWord', [item]);
226     },
227
228     /** @override */
229     shouldFocusPlaceholder: function() {
230       return false;
231     },
232   };
233
234   return {
235     DictionaryWordsList: DictionaryWordsList
236   };
237
238 });
239