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

Unified Diff: chrome/browser/resources/history2.js

Issue 8079010: Change history2 to allow multi-deletion without entering a separate mode. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 3 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/history2.js
diff --git a/chrome/browser/resources/history2.js b/chrome/browser/resources/history2.js
index 5b840c09db4890cc2aae6916bcdbf20eb2d28050..fa21fb806476190a4005a2b2c05d80e3b29c34f2 100644
--- a/chrome/browser/resources/history2.js
+++ b/chrome/browser/resources/history2.js
@@ -104,14 +104,24 @@ function Page(result, continued, model, id) {
Page.prototype.getResultDOM = function(searchResultFlag) {
var node = createElementWithClassName('li', 'entry');
var time = createElementWithClassName('div', 'time');
- var entryBox = createElementWithClassName('div', 'entry-box');
+ var entryBox = createElementWithClassName('label', 'entry-box');
var domain = createElementWithClassName('div', 'domain');
+
var dropDown = createElementWithClassName('button', 'drop-down');
dropDown.value = 'Open action menu';
dropDown.title = localStrings.getString('actionMenuDescription');
dropDown.setAttribute('menu', '#action-menu');
cr.ui.decorate(dropDown, MenuButton);
+ // Checkbox is always created, but only visible on hover & when checked.
+ var checkbox = document.createElement('input');
+ checkbox.type = 'checkbox';
+ checkbox.id = 'checkbox-' + this.id_;
+ checkbox.time = this.time.getTime();
+ checkbox.addEventListener("click", checkboxClicked);
arv (Not doing code reviews) 2011/10/04 23:26:30 use single quotes
Patrick Dubroy 2011/10/05 12:47:45 Done.
+ idToCheckbox[this.id_] = checkbox;
arv (Not doing code reviews) 2011/10/04 23:26:30 This doesn't seem necessary. Can you remove this m
Patrick Dubroy 2011/10/05 12:47:45 Done.
+ time.appendChild(checkbox);
+
// Keep track of the drop down that triggered the menu, so we know
// which element to apply the command to.
// TODO(dubroy): Ideally we'd use 'activate', but MenuButton swallows it.
@@ -125,7 +135,15 @@ Page.prototype.getResultDOM = function(searchResultFlag) {
domain.style.backgroundImage =
'url(chrome://favicon/' + encodeURIForCSS(this.url_) + ')';
domain.textContent = this.domain_;
- // Use a wrapper div so that the entry contents will be shinkwrapped.
+
+ // Clicking anywhere in the entryBox will check/uncheck the checkbox.
+ entryBox["for"] = checkbox.id;
arv (Not doing code reviews) 2011/10/04 23:26:30 entryBox.htmlFor or entryBox.setAttribute
Patrick Dubroy 2011/10/05 12:47:45 Done.
+ entryBox.addEventListener('mousedown', entryBoxMousedown, false);
+
+ // Prevent clicks on the drop down from affecting the checkbox.
+ dropDown.addEventListener('click', function(e) { e.preventDefault(); });
+
+ // We use a wrapper div so that the entry contents will be shinkwrapped.
entryBox.appendChild(time);
entryBox.appendChild(domain);
entryBox.appendChild(this.getTitleDOM_());
@@ -140,15 +158,6 @@ Page.prototype.getResultDOM = function(searchResultFlag) {
this.model_.getSearchText());
node.appendChild(snippet);
} else {
- if (this.model_.getEditMode()) {
- var checkbox = document.createElement('input');
- checkbox.type = 'checkbox';
- checkbox.name = this.id_;
- checkbox.time = this.time.toString();
- checkbox.addEventListener("click", checkboxClicked);
- idToCheckbox[this.id_] = checkbox;
- time.appendChild(checkbox);
- }
time.appendChild(document.createTextNode(this.dateTimeOfDay));
}
@@ -234,7 +243,7 @@ Page.prototype.showMoreFromSite_ = function() {
};
/**
- * Remove the page from the history.
+ * Remove a single entry from the history.
*/
Page.prototype.removeFromHistory_ = function() {
var self = this;
@@ -271,8 +280,6 @@ Page.pregQuote_ = function(str) {
*/
function HistoryModel() {
this.clearModel_();
- this.setEditMode(false);
- this.view_;
}
// HistoryModel, Public: ------------------------------------------------------
@@ -400,21 +407,6 @@ HistoryModel.prototype.getNumberedRange = function(start, end) {
return this.pages_.slice(start, end);
};
-/**
- * @return {boolean} Whether we are in edit mode where history items can be
- * deleted
- */
-HistoryModel.prototype.getEditMode = function() {
- return this.editMode_;
-};
-
-/**
- * @param {boolean} edit_mode Control whether we are in edit mode.
- */
-HistoryModel.prototype.setEditMode = function(edit_mode) {
- this.editMode_ = edit_mode;
-};
-
// HistoryModel, Private: -----------------------------------------------------
HistoryModel.prototype.clearModel_ = function() {
this.inFlight_ = false; // Whether a query is inflight.
@@ -533,11 +525,9 @@ function HistoryView(model) {
window.onresize = function() {
self.updateEntryAnchorWidth_();
};
- self.updateEditControls_();
- this.boundUpdateRemoveButton_ = function(e) {
- return self.updateRemoveButton_(e);
- };
+ $('clear-browsing-data').addEventListener('click', openClearBrowsingData);
+ $('remove-selected').addEventListener('click', removeItems);
}
// HistoryView, public: -------------------------------------------------------
@@ -551,38 +541,7 @@ HistoryView.prototype.setSearch = function(term, opt_page) {
this.pageIndex_ = parseInt(opt_page || 0, 10);
window.scrollTo(0, 0);
this.model_.setSearchText(term, this.pageIndex_);
- if (term) {
- this.setEditMode(false);
- }
- this.updateEditControls_();
- pageState.setUIState(this.model_.getEditMode(), term, this.pageIndex_);
-};
-
-/**
- * Controls edit mode where history can be deleted.
- * @param {boolean} edit_mode Whether to enable edit mode.
- */
-HistoryView.prototype.setEditMode = function(edit_mode) {
- this.model_.setEditMode(edit_mode);
- pageState.setUIState(this.model_.getEditMode(), this.model_.getSearchText(),
- this.pageIndex_);
-};
-
-/**
- * Toggles the edit mode and triggers UI update.
- */
-HistoryView.prototype.toggleEditMode = function() {
- var editMode = !this.model_.getEditMode();
- this.setEditMode(editMode);
- this.updateEditControls_();
-};
-
-/**
- * @return {boolean} Whether we are in edit mode where history items can be
- * deleted
- */
-HistoryView.prototype.getEditMode = function() {
- return this.model_.getEditMode();
+ pageState.setUIState(term, this.pageIndex_);
};
/**
@@ -590,6 +549,7 @@ HistoryView.prototype.getEditMode = function() {
*/
HistoryView.prototype.reload = function() {
this.model_.reload();
+ this.updateRemoveButton();
};
/**
@@ -601,8 +561,7 @@ HistoryView.prototype.setPage = function(page) {
this.pageIndex_ = parseInt(page, 10);
window.scrollTo(0, 0);
this.model_.requestPage(page);
- pageState.setUIState(this.model_.getEditMode(), this.model_.getSearchText(),
- this.pageIndex_);
+ pageState.setUIState(this.model_.getSearchText(), this.pageIndex_);
};
/**
@@ -620,6 +579,14 @@ HistoryView.prototype.onModelReady = function() {
this.displayResults_();
};
+/**
+ * Enables or disables the 'Remove selected items' button as appropriate.
+ */
+HistoryView.prototype.updateRemoveButton = function() {
+ var anyChecked = document.querySelector('.entry input:checked') != null;
+ $('remove-selected').disabled = !anyChecked;
+}
+
// HistoryView, private: ------------------------------------------------------
/**
* Clear the results in the view. Since we add results piecemeal, we need
@@ -721,64 +688,6 @@ HistoryView.prototype.displaySummaryBar_ = function() {
};
/**
- * Update the widgets related to edit mode.
- */
-HistoryView.prototype.updateEditControls_ = function() {
- // Display a button (looking like a link) to enable/disable edit mode.
- var oldButton = this.editButtonTd_.firstChild;
- if (this.model_.getSearchText()) {
- this.editButtonTd_.replaceChild(document.createElement('p'), oldButton);
- this.editingControlsDiv_.textContent = '';
- return;
- }
-
- var editMode = this.model_.getEditMode();
- var button = createElementWithClassName('button', 'edit-button');
- button.onclick = toggleEditMode;
- button.textContent = localStrings.getString(editMode ?
- 'doneediting' : 'edithistory');
- this.editButtonTd_.replaceChild(button, oldButton);
-
- this.editingControlsDiv_.textContent = '';
-
- if (editMode) {
- // Button to delete the selected items.
- button = document.createElement('button');
- button.onclick = removeItems;
- button.textContent = localStrings.getString('removeselected');
- button.disabled = true;
- this.editingControlsDiv_.appendChild(button);
- this.removeButton_ = button;
-
- // Button that opens up the clear browsing data dialog.
- button = document.createElement('button');
- button.onclick = openClearBrowsingData;
- button.textContent = localStrings.getString('clearallhistory');
- this.editingControlsDiv_.appendChild(button);
-
- // Listen for clicks in the page to sync the disabled state.
- document.addEventListener('click', this.boundUpdateRemoveButton_);
- } else {
- this.removeButton_ = null;
- document.removeEventListener('click', this.boundUpdateRemoveButton_);
- }
-};
-
-/**
- * Updates the disabled state of the remove button when in editing mode.
- * @param {!Event} e The click event object.
- * @private
- */
-HistoryView.prototype.updateRemoveButton_ = function(e) {
- if (e.target.tagName != 'INPUT')
- return;
-
- var anyChecked = document.querySelector('.entry input:checked') != null;
- if (this.removeButton_)
- this.removeButton_.disabled = !anyChecked;
-};
-
-/**
* Update the pagination tools.
*/
HistoryView.prototype.displayNavBar_ = function() {
@@ -811,8 +720,7 @@ HistoryView.prototype.createPageNav_ = function(page, name) {
anchor = document.createElement('a');
anchor.className = 'page-navigation';
anchor.textContent = name;
- var hashString = PageState.getHashString(this.model_.getEditMode(),
- this.model_.getSearchText(), page);
+ var hashString = PageState.getHashString(this.model_.getSearchText(), page);
var link = 'chrome://history2/' + (hashString ? '#' + hashString : '');
anchor.href = link;
anchor.onclick = function() {
@@ -921,13 +829,12 @@ PageState.prototype.getHashData = function() {
* @param {string} term The current search string.
* @param {string} page The page currently being viewed.
*/
-PageState.prototype.setUIState = function(editMode, term, page) {
+PageState.prototype.setUIState = function(term, page) {
// Make sure the form looks pretty.
document.forms[0].term.value = term;
var currentHash = this.getHashData();
- if (Boolean(currentHash.e) != editMode || currentHash.q != term ||
- currentHash.p != page) {
- window.location.hash = PageState.getHashString(editMode, term, page);
+ if (currentHash.q != term || currentHash.p != page) {
+ window.location.hash = PageState.getHashString(term, page);
}
};
@@ -937,11 +844,8 @@ PageState.prototype.setUIState = function(editMode, term, page) {
* @param {string} page The page currently being viewed.
* @return {string} The string to be used in a hash.
*/
-PageState.getHashString = function(editMode, term, page) {
+PageState.getHashString = function(term, page) {
var newHash = [];
- if (editMode) {
- newHash.push('e=1');
- }
if (term) {
newHash.push('q=' + encodeURIComponent(term));
}
@@ -967,9 +871,6 @@ function load() {
// Create default view.
var hashData = pageState.getHashData();
- if (Boolean(hashData.e)) {
- historyView.toggleEditMode();
- }
historyView.setSearch(hashData.q, hashData.p);
// Setup click handlers.
@@ -1015,17 +916,6 @@ function setPage(page) {
}
/**
- * TODO(glen): Get rid of this function.
- * Toggles edit mode.
- */
-function toggleEditMode() {
- if (historyView) {
- historyView.toggleEditMode();
- historyView.reload();
- }
-}
-
-/**
* Delete the next item in our deletion queue.
*/
function deleteNextInQueue() {
@@ -1058,6 +948,10 @@ function queueURLsForDeletion(date, urls, opt_callback) {
deleteQueue.push({ 'date': date, 'urls': urls, 'callback': opt_callback });
}
+function reloadHistory() {
+ historyView.reload();
+}
+
/**
* Collect IDs from checked checkboxes and send to Chrome for deletion.
*/
@@ -1081,7 +975,7 @@ function removeItems() {
urls = [];
date = cbDate;
}
- var link = $('id-' + checkbox.name);
+ var link = checkbox.parentNode.parentNode.querySelector('a');
checkbox.disabled = true;
link.classList.add('to-be-removed');
disabledItems.push(checkbox);
@@ -1092,15 +986,19 @@ function removeItems() {
}
if (checked.length > 0 && confirm(localStrings.getString('deletewarning'))) {
for (var i = 0; i < queue.length; i++) {
- queueURLsForDeletion(queue[i][0], queue[i][1]);
+ // Reload the page when the final entry has been deleted.
+ var callback = (i == 0) ? reloadHistory : null;
arv (Not doing code reviews) 2011/10/04 23:26:30 useless parens
Patrick Dubroy 2011/10/05 12:47:45 Done.
+
+ queueURLsForDeletion(queue[i][0], queue[i][1], callback);
}
deleteNextInQueue();
} else {
// If the remove is cancelled, return the checkboxes to their
// enabled, non-line-through state.
for (var i = 0; i < disabledItems.length; i++) {
- var link = $('id-' + disabledItems[i].name);
- disabledItems[i].disabled = false;
+ var checkbox = disabledItems[i];
+ var link = checkbox.parentNode.parentNode.querySelector('a');
+ checkbox.disabled = false;
link.classList.remove('to-be-removed');
}
}
@@ -1111,18 +1009,36 @@ function removeItems() {
* Toggle state of checkbox and handle Shift modifier.
*/
function checkboxClicked(event) {
+ var id = parseInt(this.id.slice("checkbox-".length));
arv (Not doing code reviews) 2011/10/04 23:26:30 var id = Number(...); or parseInt(..., 10)
Patrick Dubroy 2011/10/05 12:47:45 Done.
if (event.shiftKey && (selectionAnchor != -1)) {
var checked = this.checked;
// Set all checkboxes from the anchor up to the clicked checkbox to the
// state of the clicked one.
- var begin = Math.min(this.name, selectionAnchor);
- var end = Math.max(this.name, selectionAnchor);
+ var begin = Math.min(id, selectionAnchor);
+ var end = Math.max(id, selectionAnchor);
for (var i = begin; i <= end; i++) {
idToCheckbox[i].checked = checked;
}
}
- selectionAnchor = this.name;
- this.focus();
+ selectionAnchor = id;
+
+ historyView.updateRemoveButton();
+}
+
+function entryBoxMousedown(event) {
+ // Prevent text selection when shift-clicking to select multiple entries.
+ if (event.shiftKey) {
+ event.preventDefault();
+ }
+}
+
+function removeNode(node) {
+ node.classList.add('fade-out-200'); // Trigger CSS fade out animation.
+
+ // Delete the node when the animation is complete.
+ setTimeout(function() {
+ node.parentNode.removeChild(node);
+ }, 200);
}
/**
@@ -1132,22 +1048,23 @@ function checkboxClicked(event) {
function removeEntryFromView(entry) {
var nextEntry = entry.nextSibling;
var previousEntry = entry.previousSibling;
- entry.parentNode.removeChild(entry);
+
+ removeNode(entry);
// if there is no previous entry, and the next entry is a gap, remove it
if (!previousEntry && nextEntry && nextEntry.className == 'gap') {
- nextEntry.parentNode.removeChild(nextEntry);
+ removeNode(nextEntry);
}
// if there is no next entry, and the previous entry is a gap, remove it
if (!nextEntry && previousEntry && previousEntry.className == 'gap') {
- previousEntry.parentNode.removeChild(previousEntry);
+ removeNode(previousEntry);
}
// if both the next and previous entries are gaps, remove one
if (nextEntry && nextEntry.className == 'gap' &&
previousEntry && previousEntry.className == 'gap') {
- nextEntry.parentNode.removeChild(nextEntry);
+ removeNode(nextEntry);
}
}
@@ -1167,7 +1084,7 @@ function deleteComplete() {
if (deleteQueue.length > 0) {
// Remove the successfully deleted entry from the queue.
if (deleteQueue[0].callback)
- deleteQueue[0].callback();
+ deleteQueue[0].callback.apply();
arv (Not doing code reviews) 2011/10/04 23:26:30 I assume this is so that 'this' is undefined?
Patrick Dubroy 2011/10/05 12:47:45 Yes, that was the idea. Not sure that it's necessa
deleteQueue.splice(0, 1);
deleteNextInQueue();
} else {
@@ -1193,9 +1110,9 @@ function deleteFailed() {
function historyDeleted() {
window.console.log('History deleted');
var anyChecked = document.querySelector('.entry input:checked') != null;
- // Reload the page, unless the user is actively editing.
+ // Reload the page, unless the user has any items checked.
// TODO(dubroy): We should just reload the page & restore the checked items.
- if (!(historyView.getEditMode() && anyChecked))
+ if (!anyChecked)
historyView.reload();
}
« chrome/browser/resources/history2.html ('K') | « chrome/browser/resources/history2.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698