Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1228)

Unified Diff: chrome/browser/resources/options/language_list.js

Issue 7003007: Apply content-security-policy to the HTML options page. This is a (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/options/language_list.js
===================================================================
--- chrome/browser/resources/options/language_list.js (revision 84868)
+++ chrome/browser/resources/options/language_list.js (working copy)
@@ -1,483 +0,0 @@
-// 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('options', function() {
- const ArrayDataModel = cr.ui.ArrayDataModel;
- const DeletableItem = options.DeletableItem;
- const DeletableItemList = options.DeletableItemList;
- const List = cr.ui.List;
- const ListItem = cr.ui.ListItem;
- const ListSingleSelectionModel = cr.ui.ListSingleSelectionModel;
-
- /**
- * Creates a new Language list item.
- * @param {String} languageCode the languageCode.
- * @constructor
- * @extends {DeletableItem.ListItem}
- */
- function LanguageListItem(languageCode) {
- var el = cr.doc.createElement('li');
- el.__proto__ = LanguageListItem.prototype;
- el.languageCode_ = languageCode;
- el.decorate();
- return el;
- };
-
- LanguageListItem.prototype = {
- __proto__: DeletableItem.prototype,
-
- /**
- * The language code of this language.
- * @type {String}
- * @private
- */
- languageCode_: null,
-
- /** @inheritDoc */
- decorate: function() {
- DeletableItem.prototype.decorate.call(this);
-
- var languageCode = this.languageCode_;
- var languageOptions = options.LanguageOptions.getInstance();
- this.deletable = languageOptions.languageIsDeletable(languageCode);
- this.languageCode = languageCode;
- this.contentElement.textContent =
- LanguageList.getDisplayNameFromLanguageCode(languageCode);
- this.title =
- LanguageList.getNativeDisplayNameFromLanguageCode(languageCode);
- this.draggable = true;
- },
- };
-
- /**
- * Creates a new language list.
- * @param {Object=} opt_propertyBag Optional properties.
- * @constructor
- * @extends {cr.ui.List}
- */
- var LanguageList = cr.ui.define('list');
-
- /**
- * Gets display name from the given language code.
- * @param {string} languageCode Language code (ex. "fr").
- */
- LanguageList.getDisplayNameFromLanguageCode = function(languageCode) {
- // Build the language code to display name dictionary at first time.
- if (!this.languageCodeToDisplayName_) {
- this.languageCodeToDisplayName_ = {};
- var languageList = templateData.languageList;
- for (var i = 0; i < languageList.length; i++) {
- var language = languageList[i];
- this.languageCodeToDisplayName_[language.code] = language.displayName;
- }
- }
-
- return this.languageCodeToDisplayName_[languageCode];
- }
-
- /**
- * Gets native display name from the given language code.
- * @param {string} languageCode Language code (ex. "fr").
- */
- LanguageList.getNativeDisplayNameFromLanguageCode = function(languageCode) {
- // Build the language code to display name dictionary at first time.
- if (!this.languageCodeToNativeDisplayName_) {
- this.languageCodeToNativeDisplayName_ = {};
- var languageList = templateData.languageList;
- for (var i = 0; i < languageList.length; i++) {
- var language = languageList[i];
- this.languageCodeToNativeDisplayName_[language.code] =
- language.nativeDisplayName;
- }
- }
-
- return this.languageCodeToNativeDisplayName_[languageCode];
- }
-
- /**
- * Returns true if the given language code is valid.
- * @param {string} languageCode Language code (ex. "fr").
- */
- LanguageList.isValidLanguageCode = function(languageCode) {
- // Having the display name for the language code means that the
- // language code is valid.
- if (LanguageList.getDisplayNameFromLanguageCode(languageCode)) {
- return true;
- }
- return false;
- }
-
- LanguageList.prototype = {
- __proto__: DeletableItemList.prototype,
-
- // The list item being dragged.
- draggedItem: null,
- // The drop position information: "below" or "above".
- dropPos: null,
- // The preference is a CSV string that describes preferred languages
- // in Chrome OS. The language list is used for showing the language
- // list in "Language and Input" options page.
- preferredLanguagesPref: 'settings.language.preferred_languages',
- // The preference is a CSV string that describes accept languages used
- // for content negotiation. To be more precise, the list will be used
- // in "Accept-Language" header in HTTP requests.
- acceptLanguagesPref: 'intl.accept_languages',
-
- /** @inheritDoc */
- decorate: function() {
- DeletableItemList.prototype.decorate.call(this);
- this.selectionModel = new ListSingleSelectionModel;
-
- // HACK(arv): http://crbug.com/40902
- window.addEventListener('resize', this.redraw.bind(this));
-
- // Listen to pref change.
- if (cr.isChromeOS) {
- Preferences.getInstance().addEventListener(this.preferredLanguagesPref,
- this.handlePreferredLanguagesPrefChange_.bind(this));
- } else {
- Preferences.getInstance().addEventListener(this.acceptLanguagesPref,
- this.handleAcceptLanguagesPrefChange_.bind(this));
- }
-
- // Listen to drag and drop events.
- this.addEventListener('dragstart', this.handleDragStart_.bind(this));
- this.addEventListener('dragenter', this.handleDragEnter_.bind(this));
- this.addEventListener('dragover', this.handleDragOver_.bind(this));
- this.addEventListener('drop', this.handleDrop_.bind(this));
- this.addEventListener('dragleave', this.handleDragLeave_.bind(this));
- },
-
- createItem: function(languageCode) {
- return new LanguageListItem(languageCode);
- },
-
- /*
- * For each item, determines whether it's deletable.
- */
- updateDeletable: function() {
- for (var i = 0; i < this.items.length; ++i) {
- var item = this.getListItemByIndex(i);
- var languageCode = item.languageCode;
- var languageOptions = options.LanguageOptions.getInstance();
- item.deletable = languageOptions.languageIsDeletable(languageCode);
- }
- },
-
- /*
- * Adds a language to the language list.
- * @param {string} languageCode language code (ex. "fr").
- */
- addLanguage: function(languageCode) {
- // It shouldn't happen but ignore the language code if it's
- // null/undefined, or already present.
- if (!languageCode || this.dataModel.indexOf(languageCode) >= 0) {
- return;
- }
- this.dataModel.push(languageCode);
- // Select the last item, which is the language added.
- this.selectionModel.selectedIndex = this.dataModel.length - 1;
-
- this.savePreference_();
- },
-
- /*
- * Gets the language codes of the currently listed languages.
- */
- getLanguageCodes: function() {
- return this.dataModel.slice();
- },
-
- /*
- * Gets the language code of the selected language.
- */
- getSelectedLanguageCode: function() {
- return this.selectedItem;
- },
-
- /*
- * Selects the language by the given language code.
- * @returns {boolean} True if the operation is successful.
- */
- selectLanguageByCode: function(languageCode) {
- var index = this.dataModel.indexOf(languageCode);
- if (index >= 0) {
- this.selectionModel.selectedIndex = index;
- return true;
- }
- return false;
- },
-
- /** @inheritDoc */
- deleteItemAtIndex: function(index) {
- if (index >= 0) {
- this.dataModel.splice(index, 1);
- // Once the selected item is removed, there will be no selected item.
- // Select the item pointed by the lead index.
- index = this.selectionModel.leadIndex;
- this.savePreference_();
- }
- return index;
- },
-
- /*
- * Computes the target item of drop event.
- * @param {Event} e The drop or dragover event.
- * @private
- */
- getTargetFromDropEvent_ : function(e) {
- var target = e.target;
- // e.target may be an inner element of the list item
- while (target != null && !(target instanceof ListItem)) {
- target = target.parentNode;
- }
- return target;
- },
-
- /*
- * Handles the dragstart event.
- * @param {Event} e The dragstart event.
- * @private
- */
- handleDragStart_: function(e) {
- var target = e.target;
- // ListItem should be the only draggable element type in the page,
- // but just in case.
- if (target instanceof ListItem) {
- this.draggedItem = target;
- e.dataTransfer.effectAllowed = 'move';
- // We need to put some kind of data in the drag or it will be
- // ignored. Use the display name in case the user drags to a text
- // field or the desktop.
- e.dataTransfer.setData('text/plain', target.title);
- }
- },
-
- /*
- * Handles the dragenter event.
- * @param {Event} e The dragenter event.
- * @private
- */
- handleDragEnter_: function(e) {
- e.preventDefault();
- },
-
- /*
- * Handles the dragover event.
- * @param {Event} e The dragover event.
- * @private
- */
- handleDragOver_: function(e) {
- var dropTarget = this.getTargetFromDropEvent_(e);
- // Determines whether the drop target is to accept the drop.
- // The drop is only successful on another ListItem.
- if (!(dropTarget instanceof ListItem) ||
- dropTarget == this.draggedItem) {
- this.hideDropMarker_();
- return;
- }
- // Compute the drop postion. Should we move the dragged item to
- // below or above the drop target?
- var rect = dropTarget.getBoundingClientRect();
- var dy = e.clientY - rect.top;
- var yRatio = dy / rect.height;
- var dropPos = yRatio <= .5 ? 'above' : 'below';
- this.dropPos = dropPos;
- this.showDropMarker_(dropTarget, dropPos);
- e.preventDefault();
- },
-
- /*
- * Handles the drop event.
- * @param {Event} e The drop event.
- * @private
- */
- handleDrop_: function(e) {
- var dropTarget = this.getTargetFromDropEvent_(e);
- this.hideDropMarker_();
-
- // Delete the language from the original position.
- var languageCode = this.draggedItem.languageCode;
- var originalIndex = this.dataModel.indexOf(languageCode);
- this.dataModel.splice(originalIndex, 1);
- // Insert the language to the new position.
- var newIndex = this.dataModel.indexOf(dropTarget.languageCode);
- if (this.dropPos == 'below')
- newIndex += 1;
- this.dataModel.splice(newIndex, 0, languageCode);
- // The cursor should move to the moved item.
- this.selectionModel.selectedIndex = newIndex;
- // Save the preference.
- this.savePreference_();
- },
-
- /*
- * Handles the dragleave event.
- * @param {Event} e The dragleave event
- * @private
- */
- handleDragLeave_ : function(e) {
- this.hideDropMarker_();
- },
-
- /*
- * Shows and positions the marker to indicate the drop target.
- * @param {HTMLElement} target The current target list item of drop
- * @param {string} pos 'below' or 'above'
- * @private
- */
- showDropMarker_ : function(target, pos) {
- window.clearTimeout(this.hideDropMarkerTimer_);
- var marker = $('language-options-list-dropmarker');
- var rect = target.getBoundingClientRect();
- var markerHeight = 8;
- if (pos == 'above') {
- marker.style.top = (rect.top - markerHeight/2) + 'px';
- } else {
- marker.style.top = (rect.bottom - markerHeight/2) + 'px';
- }
- marker.style.width = rect.width + 'px';
- marker.style.left = rect.left + 'px';
- marker.style.display = 'block';
- },
-
- /*
- * Hides the drop marker.
- * @private
- */
- hideDropMarker_ : function() {
- // Hide the marker in a timeout to reduce flickering as we move between
- // valid drop targets.
- window.clearTimeout(this.hideDropMarkerTimer_);
- this.hideDropMarkerTimer_ = window.setTimeout(function() {
- $('language-options-list-dropmarker').style.display = '';
- }, 100);
- },
-
- /**
- * Handles preferred languages pref change.
- * @param {Event} e The change event object.
- * @private
- */
- handlePreferredLanguagesPrefChange_: function(e) {
- var languageCodesInCsv = e.value.value;
- var languageCodes = languageCodesInCsv.split(',');
-
- // Add the UI language to the initial list of languages. This is to avoid
- // a bug where the UI language would be removed from the preferred
- // language list by sync on first login.
- // See: crosbug.com/14283
- languageCodes.push(navigator.language);
- languageCodes = this.filterBadLanguageCodes_(languageCodes);
- this.load_(languageCodes);
- },
-
- /**
- * Handles accept languages pref change.
- * @param {Event} e The change event object.
- * @private
- */
- handleAcceptLanguagesPrefChange_: function(e) {
- var languageCodesInCsv = e.value.value;
- var languageCodes = this.filterBadLanguageCodes_(
- languageCodesInCsv.split(','));
- this.load_(languageCodes);
- },
-
- /**
- * Loads given language list.
- * @param {Array} languageCodes List of language codes.
- * @private
- */
- load_: function(languageCodes) {
- // Preserve the original selected index. See comments below.
- var originalSelectedIndex = (this.selectionModel ?
- this.selectionModel.selectedIndex : -1);
- this.dataModel = new ArrayDataModel(languageCodes);
- if (originalSelectedIndex >= 0 &&
- originalSelectedIndex < this.dataModel.length) {
- // Restore the original selected index if the selected index is
- // valid after the data model is loaded. This is neeeded to keep
- // the selected language after the languge is added or removed.
- this.selectionModel.selectedIndex = originalSelectedIndex;
- // The lead index should be updated too.
- this.selectionModel.leadIndex = originalSelectedIndex;
- } else if (this.dataModel.length > 0){
- // Otherwise, select the first item if it's not empty.
- // Note that ListSingleSelectionModel won't select an item
- // automatically, hence we manually select the first item here.
- this.selectionModel.selectedIndex = 0;
- }
- },
-
- /**
- * Saves the preference.
- */
- savePreference_: function() {
- // Encode the language codes into a CSV string.
- if (cr.isChromeOS)
- Preferences.setStringPref(this.preferredLanguagesPref,
- this.dataModel.slice().join(','));
- // Save the same language list as accept languages preference as
- // well, but we need to expand the language list, to make it more
- // acceptable. For instance, some web sites don't understand 'en-US'
- // but 'en'. See crosbug.com/9884.
- var acceptLanguages = this.expandLanguageCodes(this.dataModel.slice());
- Preferences.setStringPref(this.acceptLanguagesPref,
- acceptLanguages.join(','));
- cr.dispatchSimpleEvent(this, 'save');
- },
-
- /**
- * Expands language codes to make these more suitable for Accept-Language.
- * Example: ['en-US', 'ja', 'en-CA'] => ['en-US', 'en', 'ja', 'en-CA'].
- * 'en' won't appear twice as this function eliminates duplicates.
- * @param {Array} languageCodes List of language codes.
- * @private
- */
- expandLanguageCodes: function(languageCodes) {
- var expandedLanguageCodes = [];
- var seen = {}; // Used to eliminiate duplicates.
- for (var i = 0; i < languageCodes.length; i++) {
- var languageCode = languageCodes[i];
- if (!(languageCode in seen)) {
- expandedLanguageCodes.push(languageCode);
- seen[languageCode] = true;
- }
- var parts = languageCode.split('-');
- if (!(parts[0] in seen)) {
- expandedLanguageCodes.push(parts[0]);
- seen[parts[0]] = true;
- }
- }
- return expandedLanguageCodes;
- },
-
- /**
- * Filters bad language codes in case bad language codes are
- * stored in the preference. Removes duplicates as well.
- * @param {Array} languageCodes List of language codes.
- * @private
- */
- filterBadLanguageCodes_: function(languageCodes) {
- var filteredLanguageCodes = [];
- var seen = {};
- for (var i = 0; i < languageCodes.length; i++) {
- // Check if the the language code is valid, and not
- // duplicate. Otherwise, skip it.
- if (LanguageList.isValidLanguageCode(languageCodes[i]) &&
- !(languageCodes[i] in seen)) {
- filteredLanguageCodes.push(languageCodes[i]);
- seen[languageCodes[i]] = true;
- }
- }
- return filteredLanguageCodes;
- },
- };
-
- return {
- LanguageList: LanguageList,
- LanguageListItem: LanguageListItem
- };
-});

Powered by Google App Engine
This is Rietveld 408576698