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

Unified Diff: chrome/browser/resources/options2/browser_options_startup_page_list.js

Issue 8895023: Options2: Pull the trigger. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: DIAF. Created 9 years 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/options2/browser_options_startup_page_list.js
diff --git a/chrome/browser/resources/options2/browser_options_startup_page_list.js b/chrome/browser/resources/options2/browser_options_startup_page_list.js
new file mode 100644
index 0000000000000000000000000000000000000000..cd107293c40a2228167f55ca35be481aae1359c1
--- /dev/null
+++ b/chrome/browser/resources/options2/browser_options_startup_page_list.js
@@ -0,0 +1,310 @@
+// 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.browser_options', function() {
+ const AutocompleteList = options.AutocompleteList;
+ const InlineEditableItem = options.InlineEditableItem;
+ const InlineEditableItemList = options.InlineEditableItemList;
+
+ /**
+ * Creates a new startup page list item.
+ * @param {Object} pageInfo The page this item represents.
+ * @constructor
+ * @extends {cr.ui.ListItem}
+ */
+ function StartupPageListItem(pageInfo) {
+ var el = cr.doc.createElement('div');
+ el.pageInfo_ = pageInfo;
+ StartupPageListItem.decorate(el);
+ return el;
+ }
+
+ /**
+ * Decorates an element as a startup page list item.
+ * @param {!HTMLElement} el The element to decorate.
+ */
+ StartupPageListItem.decorate = function(el) {
+ el.__proto__ = StartupPageListItem.prototype;
+ el.decorate();
+ };
+
+ StartupPageListItem.prototype = {
+ __proto__: InlineEditableItem.prototype,
+
+ /**
+ * Input field for editing the page url.
+ * @type {HTMLElement}
+ * @private
+ */
+ urlField_: null,
+
+ /** @inheritDoc */
+ decorate: function() {
+ InlineEditableItem.prototype.decorate.call(this);
+
+ var pageInfo = this.pageInfo_;
+
+ if (pageInfo['modelIndex'] == '-1') {
+ this.isPlaceholder = true;
+ pageInfo['title'] = localStrings.getString('startupAddLabel');
+ pageInfo['url'] = '';
+ }
+
+ var titleEl = this.ownerDocument.createElement('div');
+ titleEl.className = 'title';
+ titleEl.classList.add('favicon-cell');
+ titleEl.classList.add('weakrtl');
+ titleEl.textContent = pageInfo['title'];
+ if (!this.isPlaceholder) {
+ titleEl.style.backgroundImage = url('chrome://favicon/' +
+ pageInfo['url']);
+ titleEl.title = pageInfo['tooltip'];
+ }
+
+ this.contentElement.appendChild(titleEl);
+
+ var urlEl = this.createEditableTextCell(pageInfo['url']);
+ urlEl.className = 'url';
+ urlEl.classList.add('weakrtl');
+ this.contentElement.appendChild(urlEl);
+
+ var urlField = urlEl.querySelector('input')
+ urlField.required = true;
+ urlField.className = 'weakrtl';
+ this.urlField_ = urlField;
+
+ this.addEventListener('commitedit', this.onEditCommitted_);
+
+ var self = this;
+ urlField.addEventListener('focus', function(event) {
+ self.parentNode.autocompleteList.attachToInput(urlField);
+ });
+ urlField.addEventListener('blur', function(event) {
+ self.parentNode.autocompleteList.detach();
+ });
+
+ if (!this.isPlaceholder)
+ this.draggable = true;
+ },
+
+ /** @inheritDoc */
+ get currentInputIsValid() {
+ return this.urlField_.validity.valid;
+ },
+
+ /** @inheritDoc */
+ get hasBeenEdited() {
+ return this.urlField_.value != this.pageInfo_['url'];
+ },
+
+ /**
+ * Called when committing an edit; updates the model.
+ * @param {Event} e The end event.
+ * @private
+ */
+ onEditCommitted_: function(e) {
+ var url = this.urlField_.value;
+ if (this.isPlaceholder)
+ chrome.send('addStartupPage', [url]);
+ else
+ chrome.send('editStartupPage', [this.pageInfo_['modelIndex'], url]);
+ },
+ };
+
+ var StartupPageList = cr.ui.define('list');
+
+ StartupPageList.prototype = {
+ __proto__: InlineEditableItemList.prototype,
+
+ /**
+ * An autocomplete suggestion list for URL editing.
+ * @type {AutocompleteList}
+ */
+ autocompleteList: null,
+
+ /**
+ * The drop position information: "below" or "above".
+ */
+ dropPos: null,
+
+ /** @inheritDoc */
+ decorate: function() {
+ InlineEditableItemList.prototype.decorate.call(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));
+ this.addEventListener('dragend', this.handleDragEnd_.bind(this));
+ },
+
+ /** @inheritDoc */
+ createItem: function(pageInfo) {
+ var item = new StartupPageListItem(pageInfo);
+ item.urlField_.disabled = this.disabled;
+ return item;
+ },
+
+ /** @inheritDoc */
+ deleteItemAtIndex: function(index) {
+ chrome.send('removeStartupPages', [String(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 StartupPageListItem)) {
+ target = target.parentNode;
+ }
+ return target;
+ },
+
+ /*
+ * Handles the dragstart event.
+ * @param {Event} e The dragstart event.
+ * @private
+ */
+ handleDragStart_: function(e) {
+ // Prevent dragging if the list is disabled.
+ if (this.disabled) {
+ e.preventDefault();
+ return false;
+ }
+
+ var target = e.target;
+ // StartupPageListItem should be the only draggable element type in the
+ // page but let's make sure.
+ if (target instanceof StartupPageListItem) {
+ this.draggedItem = target;
+ this.draggedItem.editable = false;
+ e.dataTransfer.effectAllowed = 'move';
+ // We need to put some kind of data in the drag or it will be
+ // ignored. Use the URL in case the user drags to a text field or the
+ // desktop.
+ e.dataTransfer.setData('text/plain', target.urlField_.value);
+ }
+ },
+
+ /*
+ * 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 StartupPageListItem.
+ if (!(dropTarget instanceof StartupPageListItem) ||
+ dropTarget == this.draggedItem || dropTarget.isPlaceholder) {
+ 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_();
+
+ // Insert the selection at the new position.
+ var newIndex = this.dataModel.indexOf(dropTarget.pageInfo_);
+ if (this.dropPos == 'below')
+ newIndex += 1;
+
+ var selected = this.selectionModel.selectedIndexes;
+ var stringized_selected = [];
+ for (var j = 0; j < selected.length; j++)
+ stringized_selected.push(String(selected[j]));
+
+ chrome.send('dragDropStartupPage',
+ [String(newIndex), stringized_selected] );
+ },
+
+ /*
+ * Handles the dragleave event.
+ * @param {Event} e The dragleave event
+ * @private
+ */
+ handleDragLeave_: function(e) {
+ this.hideDropMarker_();
+ },
+
+ /**
+ * Handles the dragend event.
+ * @param {Event} e The dragend event
+ * @private
+ */
+ handleDragEnd_: function(e) {
+ this.draggedItem.editable = true;
+ this.draggedItem.updateEditState();
+ },
+
+ /*
+ * 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 = $('startupPagesListDropmarker');
+ var rect = target.getBoundingClientRect();
+ var markerHeight = 6;
+ 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() {
+ $('startupPagesListDropmarker').style.display = '';
+ }, 100);
+ },
+ };
+
+ return {
+ StartupPageList: StartupPageList
+ };
+});

Powered by Google App Engine
This is Rietveld 408576698