| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview 'settings-manage-input-methods-page' is a sub-page for enabling | 6 * @fileoverview 'settings-manage-input-methods-page' is a sub-page for enabling |
| 7 * and disabling input methods. Input methods are grouped by base languages to | 7 * and disabling input methods. Input methods are grouped by base languages to |
| 8 * avoid showing duplicate or ambiguous input methods. | 8 * avoid showing duplicate or ambiguous input methods. |
| 9 * | 9 * |
| 10 * @group Chrome Settings Elements | 10 * @group Chrome Settings Elements |
| 11 * @element settings-manage-input-methods-page | 11 * @element settings-manage-input-methods-page |
| 12 */ | 12 */ |
| 13 Polymer({ | 13 Polymer({ |
| 14 is: 'settings-manage-input-methods-page', | 14 is: 'settings-manage-input-methods-page', |
| 15 | 15 |
| 16 properties: { | 16 properties: { |
| 17 /** @type {!LanguagesModel|undefined} */ | 17 /** @type {!LanguagesModel|undefined} */ |
| 18 languages: { | 18 languages: { |
| 19 type: Object, | 19 type: Object, |
| 20 notify: true, | 20 notify: true, |
| 21 }, | 21 }, |
| 22 | 22 |
| 23 /** @type {!LanguageHelper} */ |
| 24 languageHelper: Object, |
| 25 |
| 23 /** | 26 /** |
| 24 * List of enabled languages with the input methods to show. | 27 * List of enabled languages with the input methods to show. |
| 25 * @private {!Array< | 28 * @private {!Array< |
| 26 * !{language: !chrome.languageSettingsPrivate.Language, | 29 * !{language: !chrome.languageSettingsPrivate.Language, |
| 27 * inputMethods: !Array<!chrome.languageSettingsPrivate.InputMethod> | 30 * inputMethods: !Array<!chrome.languageSettingsPrivate.InputMethod> |
| 28 * }>} | 31 * }>} |
| 29 */ | 32 */ |
| 30 languageList_: { | 33 languageList_: { |
| 31 type: Array, | 34 type: Array, |
| 32 value: function() { return []; }, | 35 value: function() { return []; }, |
| 33 }, | 36 }, |
| 34 }, | 37 }, |
| 35 | 38 |
| 36 observers: [ | 39 observers: [ |
| 37 'availableInputMethodsChanged_(languages.enabled.*,' + | 40 'availableInputMethodsChanged_(languages.enabled.*,' + |
| 38 'languages.inputMethods.supported.*)', | 41 'languages.inputMethods.supported.*)', |
| 39 'enabledInputMethodsChanged_(languages.inputMethods.enabled.*)', | 42 'enabledInputMethodsChanged_(languages.inputMethods.enabled.*)', |
| 40 ], | 43 ], |
| 41 | 44 |
| 42 /** @override */ | |
| 43 created: function() { | |
| 44 this.languageHelper_ = LanguageHelperImpl.getInstance(); | |
| 45 }, | |
| 46 | |
| 47 /** @private */ | 45 /** @private */ |
| 48 availableInputMethodsChanged_: function() { | 46 availableInputMethodsChanged_: function() { |
| 49 this.populateLanguageList_(); | 47 this.populateLanguageList_(); |
| 50 }, | 48 }, |
| 51 | 49 |
| 52 /** @private */ | 50 /** @private */ |
| 53 enabledInputMethodsChanged_: function() { | 51 enabledInputMethodsChanged_: function() { |
| 54 this.populateLanguageList_(); | 52 this.populateLanguageList_(); |
| 55 }, | 53 }, |
| 56 | 54 |
| 57 /** | 55 /** |
| 58 * Handler for an input method checkbox. | 56 * Handler for an input method checkbox. |
| 59 * @param {!{model: !{item: chrome.languageSettingsPrivate.InputMethod}, | 57 * @param {!{model: !{item: chrome.languageSettingsPrivate.InputMethod}, |
| 60 * target: !PaperCheckboxElement}} e | 58 * target: !PaperCheckboxElement}} e |
| 61 * @private | 59 * @private |
| 62 */ | 60 */ |
| 63 onCheckboxChange_: function(e) { | 61 onCheckboxChange_: function(e) { |
| 64 // TODO(michaelpg): Show confirmation dialog for 3rd-party IMEs. | 62 // TODO(michaelpg): Show confirmation dialog for 3rd-party IMEs. |
| 65 var id = e.model.item.id; | 63 var id = e.model.item.id; |
| 66 if (e.target.checked) | 64 if (e.target.checked) |
| 67 this.languageHelper_.addInputMethod(id); | 65 this.languageHelper.addInputMethod(id); |
| 68 else | 66 else |
| 69 this.languageHelper_.removeInputMethod(id); | 67 this.languageHelper.removeInputMethod(id); |
| 70 }, | 68 }, |
| 71 | 69 |
| 72 /** | 70 /** |
| 73 * Returns true if the input method can be removed. | 71 * Returns true if the input method can be removed. |
| 74 * @param {!chrome.languageSettingsPrivate.InputMethod} targetInputMethod | 72 * @param {!chrome.languageSettingsPrivate.InputMethod} targetInputMethod |
| 75 * @param {!Object} change Polymer change object (provided in the HTML so this | 73 * @param {!Object} change Polymer change object (provided in the HTML so this |
| 76 * gets called whenever languages.inputMethods.enabled.* changes). | 74 * gets called whenever languages.inputMethods.enabled.* changes). |
| 77 * @return {boolean} | 75 * @return {boolean} |
| 78 * @private | 76 * @private |
| 79 */ | 77 */ |
| 80 enableInputMethodCheckbox_: function(targetInputMethod, change) { | 78 enableInputMethodCheckbox_: function(targetInputMethod, change) { |
| 81 if (!targetInputMethod.enabled) | 79 if (!targetInputMethod.enabled) |
| 82 return true; | 80 return true; |
| 83 | 81 |
| 84 // Third-party IMEs can always be removed. | 82 // Third-party IMEs can always be removed. |
| 85 if (!this.languageHelper_.isComponentIme(targetInputMethod)) | 83 if (!this.languageHelper.isComponentIme(targetInputMethod)) |
| 86 return true; | 84 return true; |
| 87 | 85 |
| 88 // Can be removed as long as there is another component IME. | 86 // Can be removed as long as there is another component IME. |
| 89 return this.languages.inputMethods.enabled.some(function(inputMethod) { | 87 return this.languages.inputMethods.enabled.some(function(inputMethod) { |
| 90 return inputMethod != targetInputMethod && | 88 return inputMethod != targetInputMethod && |
| 91 this.languageHelper_.isComponentIme(inputMethod); | 89 this.languageHelper.isComponentIme(inputMethod); |
| 92 }, this); | 90 }, this); |
| 93 }, | 91 }, |
| 94 | 92 |
| 95 /** | 93 /** |
| 96 * Creates the list of languages and their input methods as the data source | 94 * Creates the list of languages and their input methods as the data source |
| 97 * for the view. | 95 * for the view. |
| 98 * @private | 96 * @private |
| 99 */ | 97 */ |
| 100 populateLanguageList_: function() { | 98 populateLanguageList_: function() { |
| 101 var languageList = []; | 99 var languageList = []; |
| 102 | 100 |
| 103 // Languages that have already been listed further up. | 101 // Languages that have already been listed further up. |
| 104 var /** !Set<string> */ usedLanguages = new Set(); | 102 var /** !Set<string> */ usedLanguages = new Set(); |
| 105 | 103 |
| 106 // Add languages in preference order. However, if there are multiple | 104 // Add languages in preference order. However, if there are multiple |
| 107 // enabled variants of the same base language, group them all as the base | 105 // enabled variants of the same base language, group them all as the base |
| 108 // language instead of showing each variant individually. This prevents us | 106 // language instead of showing each variant individually. This prevents us |
| 109 // from displaying duplicate input methods under different variants. | 107 // from displaying duplicate input methods under different variants. |
| 110 for (var i = 0; i < this.languages.enabled.length; i++) { | 108 for (var i = 0; i < this.languages.enabled.length; i++) { |
| 111 var languageState = this.languages.enabled[i]; | 109 var languageState = this.languages.enabled[i]; |
| 112 // Skip the language if we have already included it or its base language. | 110 // Skip the language if we have already included it or its base language. |
| 113 if (usedLanguages.has(languageState.language.code)) | 111 if (usedLanguages.has(languageState.language.code)) |
| 114 continue; | 112 continue; |
| 115 var baseLanguageCode = this.languageHelper_.getLanguageCodeWithoutRegion( | 113 var baseLanguageCode = this.languageHelper.getLanguageCodeWithoutRegion( |
| 116 languageState.language.code); | 114 languageState.language.code); |
| 117 if (usedLanguages.has(baseLanguageCode)) | 115 if (usedLanguages.has(baseLanguageCode)) |
| 118 continue; | 116 continue; |
| 119 | 117 |
| 120 // Find the other languages further down in the preferred languages list | 118 // Find the other languages further down in the preferred languages list |
| 121 // which also use this language's base language code. | 119 // which also use this language's base language code. |
| 122 var languageFamilyCodes = [languageState.language.code]; | 120 var languageFamilyCodes = [languageState.language.code]; |
| 123 for (var j = i + 1; j < this.languages.enabled.length; j++) { | 121 for (var j = i + 1; j < this.languages.enabled.length; j++) { |
| 124 var otherCode = this.languages.enabled[j].language.code; | 122 var otherCode = this.languages.enabled[j].language.code; |
| 125 if (this.languageHelper_.getLanguageCodeWithoutRegion(otherCode) == | 123 if (this.languageHelper.getLanguageCodeWithoutRegion(otherCode) == |
| 126 baseLanguageCode) { | 124 baseLanguageCode) { |
| 127 languageFamilyCodes.push(this.languages.enabled[j].language.code); | 125 languageFamilyCodes.push(this.languages.enabled[j].language.code); |
| 128 } | 126 } |
| 129 } | 127 } |
| 130 | 128 |
| 131 var combinedInputMethods = | 129 var combinedInputMethods = |
| 132 this.getInputMethodsForLanguages(languageFamilyCodes); | 130 this.getInputMethodsForLanguages(languageFamilyCodes); |
| 133 | 131 |
| 134 // Skip the language if it has no new input methods. | 132 // Skip the language if it has no new input methods. |
| 135 if (!combinedInputMethods.length) | 133 if (!combinedInputMethods.length) |
| 136 continue; | 134 continue; |
| 137 | 135 |
| 138 // Add the language or base language. | 136 // Add the language or base language. |
| 139 var displayLanguage = languageState.language; | 137 var displayLanguage = languageState.language; |
| 140 if (languageFamilyCodes.length > 1) { | 138 if (languageFamilyCodes.length > 1) { |
| 141 var baseLanguage = this.languageHelper_.getLanguage(baseLanguageCode); | 139 var baseLanguage = this.languageHelper.getLanguage(baseLanguageCode); |
| 142 if (baseLanguage) | 140 if (baseLanguage) |
| 143 displayLanguage = baseLanguage; | 141 displayLanguage = baseLanguage; |
| 144 } | 142 } |
| 145 languageList.push({ | 143 languageList.push({ |
| 146 language: displayLanguage, | 144 language: displayLanguage, |
| 147 inputMethods: combinedInputMethods, | 145 inputMethods: combinedInputMethods, |
| 148 }); | 146 }); |
| 149 for (var languageCode of languageFamilyCodes) | 147 for (var languageCode of languageFamilyCodes) |
| 150 usedLanguages.add(languageCode); | 148 usedLanguages.add(languageCode); |
| 151 } | 149 } |
| 152 | 150 |
| 153 this.languageList_ = languageList; | 151 this.languageList_ = languageList; |
| 154 this.notifyInputMethodsChanged_(); | 152 this.notifyInputMethodsChanged_(); |
| 155 }, | 153 }, |
| 156 | 154 |
| 157 /** | 155 /** |
| 158 * Returns the input methods that support any of the given languages. | 156 * Returns the input methods that support any of the given languages. |
| 159 * @param {!Array<string>} languageCodes | 157 * @param {!Array<string>} languageCodes |
| 160 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} | 158 * @return {!Array<!chrome.languageSettingsPrivate.InputMethod>} |
| 161 * @private | 159 * @private |
| 162 */ | 160 */ |
| 163 getInputMethodsForLanguages: function(languageCodes) { | 161 getInputMethodsForLanguages: function(languageCodes) { |
| 164 // Input methods that have already been listed for this language. | 162 // Input methods that have already been listed for this language. |
| 165 var /** !Set<string> */ usedInputMethods = new Set(); | 163 var /** !Set<string> */ usedInputMethods = new Set(); |
| 166 /** @type {!Array<chrome.languageSettingsPrivate.InputMethod>} */ | 164 /** @type {!Array<chrome.languageSettingsPrivate.InputMethod>} */ |
| 167 var combinedInputMethods = []; | 165 var combinedInputMethods = []; |
| 168 for (var languageCode of languageCodes) { | 166 for (var languageCode of languageCodes) { |
| 169 var inputMethods = this.languageHelper_.getInputMethodsForLanguage( | 167 var inputMethods = this.languageHelper.getInputMethodsForLanguage( |
| 170 languageCode); | 168 languageCode); |
| 171 // Get the language's unused input methods and mark them as used. | 169 // Get the language's unused input methods and mark them as used. |
| 172 var newInputMethods = inputMethods.filter(function(inputMethod) { | 170 var newInputMethods = inputMethods.filter(function(inputMethod) { |
| 173 if (usedInputMethods.has(inputMethod.id)) | 171 if (usedInputMethods.has(inputMethod.id)) |
| 174 return false; | 172 return false; |
| 175 usedInputMethods.add(inputMethod.id); | 173 usedInputMethods.add(inputMethod.id); |
| 176 return true; | 174 return true; |
| 177 }); | 175 }); |
| 178 [].push.apply(combinedInputMethods, newInputMethods); | 176 [].push.apply(combinedInputMethods, newInputMethods); |
| 179 } | 177 } |
| 180 return combinedInputMethods; | 178 return combinedInputMethods; |
| 181 }, | 179 }, |
| 182 | 180 |
| 183 // TODO(Polymer/polymer#3603): We have to notify Polymer of properties that | 181 // TODO(Polymer/polymer#3603): We have to notify Polymer of properties that |
| 184 // may have changed on nested objects, even when the outer property itself | 182 // may have changed on nested objects, even when the outer property itself |
| 185 // is set to a new array. | 183 // is set to a new array. |
| 186 // TODO(michaelpg): Test this behavior. | 184 // TODO(michaelpg): Test this behavior. |
| 187 /** @private */ | 185 /** @private */ |
| 188 notifyInputMethodsChanged_: function() { | 186 notifyInputMethodsChanged_: function() { |
| 189 for (var i = 0; i < this.languageList_.length; i++) { | 187 for (var i = 0; i < this.languageList_.length; i++) { |
| 190 for (var j = 0; j < this.languageList_[i].inputMethods.length; j++) { | 188 for (var j = 0; j < this.languageList_[i].inputMethods.length; j++) { |
| 191 this.notifyPath( | 189 this.notifyPath( |
| 192 'languageList_.' + i + '.inputMethods.' + j + '.enabled', | 190 'languageList_.' + i + '.inputMethods.' + j + '.enabled', |
| 193 this.languageList_[i].inputMethods[j].enabled); | 191 this.languageList_[i].inputMethods[j].enabled); |
| 194 } | 192 } |
| 195 } | 193 } |
| 196 }, | 194 }, |
| 197 }); | 195 }); |
| OLD | NEW |