Upstream version 10.39.225.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 {options.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    * @constructor
80    * @extends {options.InlineEditableItemList}
81    */
82   var DictionaryWordsList = cr.ui.define('list');
83
84   DictionaryWordsList.prototype = {
85     __proto__: InlineEditableItemList.prototype,
86
87     /**
88      * The function to notify that the word list has changed.
89      * @type {?Function}
90      */
91     onWordListChanged: null,
92
93     /**
94      * The list of all words in the dictionary. Used to generate a filtered word
95      * list in the |search(searchTerm)| method.
96      * @type {Array}
97      * @private
98      */
99     allWordsList_: null,
100
101     /**
102      * The list of words that the user removed, but |DictionaryWordList| has not
103      * received a notification of their removal yet.
104      * @type {Array}
105      * @private
106      */
107     removedWordsList_: [],
108
109     /**
110      * Adds a dictionary word.
111      * @param {string} dictionaryWord The word to add.
112      * @private
113      */
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]);
119     },
120
121     /**
122      * Searches the list for the matching words.
123      * @param {string} searchTerm The search term.
124      */
125     search: function(searchTerm) {
126       var filteredWordList = this.allWordsList_.filter(
127           function(element, index, array) {
128             return element.indexOf(searchTerm) > -1;
129           });
130       filteredWordList.push('');
131       this.dataModel = new cr.ui.ArrayDataModel(filteredWordList);
132       this.onWordListChanged();
133     },
134
135     /**
136      * Sets the list of dictionary words.
137      * @param {Array} entries The list of dictionary words.
138      */
139     setWordList: function(entries) {
140       this.allWordsList_ = entries.slice(0);
141       // Empty string is a placeholder for entering new words.
142       entries.push('');
143       this.dataModel = new cr.ui.ArrayDataModel(entries);
144       this.onWordListChanged();
145     },
146
147     /**
148      * Adds non-duplicate dictionary words.
149      * @param {Array} entries The list of dictionary words.
150      */
151     addWords: function(entries) {
152       var toAdd = [];
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]);
157         }
158       }
159       if (toAdd.length == 0)
160         return;
161       for (var i = 0; i < toAdd.length; i++)
162         this.dataModel.splice(this.dataModel.length - 1, 0, toAdd[i]);
163       this.onWordListChanged();
164     },
165
166     /**
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.
170      */
171     removeWords: function(entries) {
172       var index;
173       var toRemove = [];
174       for (var i = 0; i < entries.length; i++) {
175         index = this.removedWordsList_.indexOf(entries[i]);
176         if (index > -1) {
177           this.removedWordsList_.splice(index, 1);
178         } else {
179           index = this.allWordsList_.indexOf(entries[i]);
180           if (index > -1) {
181             this.allWordsList_.splice(index, 1);
182             toRemove.push(entries[i]);
183           }
184         }
185       }
186       if (toRemove.length == 0)
187         return;
188       for (var i = 0; i < toRemove.length; i++) {
189         index = this.dataModel.indexOf(toRemove[i]);
190         if (index > -1)
191           this.dataModel.splice(index, 1);
192       }
193       this.onWordListChanged();
194     },
195
196     /**
197      * Returns true if the data model contains no words, otherwise returns
198      * false.
199      * @type {boolean}
200      */
201     get empty() {
202       // A data model without dictionary words contains one placeholder for
203       // entering new words.
204       return this.dataModel.length < 2;
205     },
206
207     /**
208      * @override
209      * @param {string} dictionaryWord
210      */
211     createItem: function(dictionaryWord) {
212       return new DictionaryWordsListItem(
213           dictionaryWord,
214           this.addDictionaryWord_.bind(this));
215     },
216
217     /** @override */
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]);
230     },
231
232     /** @override */
233     shouldFocusPlaceholder: function() {
234       return false;
235     },
236   };
237
238   return {
239     DictionaryWordsList: DictionaryWordsList
240   };
241
242 });
243