Bug 831916 - Hide and delete tiles in Bookmarks and History tile groups r=mbrubeck

This commit is contained in:
Rodrigo Silveira 2013-04-16 23:16:34 -07:00
Родитель f45d8aee3a
Коммит f7c909f8e7
12 изменённых файлов: 1588 добавлений и 117 удалений

Просмотреть файл

@ -396,7 +396,7 @@ TopSitesView.prototype = {
onPageChanged: function(aURI, aWhat, aValue) {
},
onPageExpired: function(aURI, aVisitTime, aWholeEntry) {
onDeleteVisits: function (aURI, aVisitTime, aGUID, aReason, aTransitionType) {
},
QueryInterface: function(iid) {

Просмотреть файл

@ -18,6 +18,8 @@ var Appbar = {
window.addEventListener('MozContextActionsChange', this, false);
Elements.browsers.addEventListener('URLChanged', this, true);
Elements.tabList.addEventListener('TabSelect', this, true);
Elements.panelUI.addEventListener('ToolPanelShown', this, false);
Elements.panelUI.addEventListener('ToolPanelHidden', this, false);
this._updateDebugButtons();
this._updateZoomButtons();
@ -30,6 +32,8 @@ var Appbar = {
switch (aEvent.type) {
case 'URLChanged':
case 'TabSelect':
case 'ToolPanelShown':
case 'ToolPanelHidden':
this.appbar.dismiss();
break;
case 'MozAppbarShowing':

Просмотреть файл

@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
/**
* Utility singleton for manipulating bookmarks.
*/
@ -72,16 +74,21 @@ var Bookmarks = {
* @param {Number} aLimit Maximum number of items to show in the view.
* @param aRoot Bookmark root to show in the view.
*/
function BookmarksView(aSet, aLimit, aRoot) {
function BookmarksView(aSet, aLimit, aRoot, aFilterUnpinned) {
this._set = aSet;
this._set.controller = this;
this._limit = aLimit;
this._filterUnpinned = aFilterUnpinned;
this._bookmarkService = PlacesUtils.bookmarks;
this._navHistoryService = gHistSvc;
this._changes = new BookmarkChangeListener(this);
PlacesUtils.bookmarks.addObserver(this._changes, false);
this._pinHelper = new ItemPinHelper("metro.bookmarks.unpinned");
this._bookmarkService.addObserver(this._changes, false);
window.addEventListener('MozAppbarDismissing', this, false);
window.addEventListener('BookmarksNeedsRefresh', this, false);
// This also implicitly calls `getBookmarks`
this.root = aRoot;
}
@ -91,6 +98,7 @@ BookmarksView.prototype = {
_changes: null,
_root: null,
_sort: 0, // Natural bookmark order.
_toRemove: null,
get sort() {
return this._sort;
@ -98,6 +106,7 @@ BookmarksView.prototype = {
set sort(aSort) {
this._sort = aSort;
this.clearBookmarks();
this.getBookmarks();
},
@ -107,7 +116,6 @@ BookmarksView.prototype = {
set root(aRoot) {
this._root = aRoot;
this.getBookmarks();
},
handleItemClick: function bv_handleItemClick(aItem) {
@ -120,7 +128,7 @@ BookmarksView.prototype = {
},
_getBookmarkIdForItem: function bv__getBookmarkForItem(aItem) {
return aItem.getAttribute("bookmarkId");
return +aItem.getAttribute("bookmarkId");
},
_updateItemWithAttrs: function dv__updateItemWithAttrs(anItem, aAttrs) {
@ -128,45 +136,69 @@ BookmarksView.prototype = {
anItem.setAttribute(name, aAttrs[name]);
},
getBookmarks: function bv_getBookmarks() {
let options = gHistSvc.getNewQueryOptions();
getBookmarks: function bv_getBookmarks(aRefresh) {
let options = this._navHistoryService.getNewQueryOptions();
options.queryType = options.QUERY_TYPE_BOOKMARKS;
options.excludeQueries = true; // Don't include "smart folders"
options.maxResults = this._limit;
options.sortingMode = this._sort;
let query = gHistSvc.getNewQuery();
let limit = this._limit || Infinity;
let query = this._navHistoryService.getNewQuery();
query.setFolders([Bookmarks.metroRoot], 1);
let result = gHistSvc.executeQuery(query, options);
let result = this._navHistoryService.executeQuery(query, options);
let rootNode = result.root;
rootNode.containerOpen = true;
let childCount = rootNode.childCount;
for (let i = 0; i < childCount; i++) {
for (let i = 0, addedCount = 0; i < childCount && addedCount < limit; i++) {
let node = rootNode.getChild(i);
// Ignore folders, separators, undefined item types, etc.
if (node.type != node.RESULT_TYPE_URI)
continue;
this.addBookmark(node.itemId);
// If item is marked for deletion, skip it.
if (this._toRemove && this._toRemove.indexOf(node.itemId) !== -1)
continue;
let item = this._getItemForBookmarkId(node.itemId);
// Item has been unpinned.
if (this._filterUnpinned && !this._pinHelper.isPinned(node.itemId)) {
if (item)
this.removeBookmark(node.itemId);
continue;
}
if (!aRefresh || !item) {
// If we're not refreshing or the item is not in the grid, add it.
this.addBookmark(node.itemId, addedCount);
} else if (aRefresh && item) {
// Update context action in case it changed in another view.
this._setContextActions(item);
}
addedCount++;
}
// Remove extra items in case a refresh added more than the limit.
// This can happen when undoing a delete.
if (aRefresh) {
while (this._set.itemCount > limit)
this._set.removeItemAt(this._set.itemCount - 1);
}
rootNode.containerOpen = false;
},
inCurrentView: function bv_inCurrentView(aParentId, aIndex, aItemType) {
inCurrentView: function bv_inCurrentView(aParentId, aItemId) {
if (this._root && aParentId != this._root)
return false;
if (this._limit && aIndex >= this._limit)
return false;
if (aItemType != PlacesUtils.bookmarks.TYPE_BOOKMARK)
return false;
return true;
return !!this._getItemForBookmarkId(aItemId);
},
clearBookmarks: function bv_clearBookmarks() {
@ -174,22 +206,27 @@ BookmarksView.prototype = {
this._set.removeItemAt(0);
},
addBookmark: function bv_addBookmark(aBookmarkId) {
let bookmarks = PlacesUtils.bookmarks;
let index = bookmarks.getItemIndex(aBookmarkId);
let uri = bookmarks.getBookmarkURI(aBookmarkId);
let title = bookmarks.getItemTitle(aBookmarkId) || uri.spec;
let item = this._set.insertItemAt(index, title, uri.spec);
addBookmark: function bv_addBookmark(aBookmarkId, aPos) {
let index = this._bookmarkService.getItemIndex(aBookmarkId);
let uri = this._bookmarkService.getBookmarkURI(aBookmarkId);
let title = this._bookmarkService.getItemTitle(aBookmarkId) || uri.spec;
let item = this._set.insertItemAt(aPos || index, title, uri.spec);
item.setAttribute("bookmarkId", aBookmarkId);
this._setContextActions(item);
this._updateFavicon(aBookmarkId, item, uri);
},
_updateFavicon: function _updateFavicon(aBookmarkId, aItem, aUri) {
_setContextActions: function bv__setContextActions(aItem) {
let itemId = this._getBookmarkIdForItem(aItem);
aItem.setAttribute("data-contextactions", "delete," + (this._pinHelper.isPinned(itemId) ? "unpin" : "pin"));
if (aItem.refresh) aItem.refresh();
},
_updateFavicon: function bv__updateFavicon(aBookmarkId, aItem, aUri) {
PlacesUtils.favicons.getFaviconURLForPage(aUri, this._gotIcon.bind(this, aBookmarkId, aItem));
},
_gotIcon: function _gotIcon(aBookmarkId, aItem, aIconUri) {
_gotIcon: function bv__gotIcon(aBookmarkId, aItem, aIconUri) {
aItem.setAttribute("iconURI", aIconUri ? aIconUri.spec : "");
if (!aIconUri) {
return;
@ -203,15 +240,21 @@ BookmarksView.prototype = {
});
},
_sendNeedsRefresh: function bv__sendNeedsRefresh(){
// Event sent when all view instances need to refresh.
let event = document.createEvent("Events");
event.initEvent("BookmarksNeedsRefresh", true, false);
window.dispatchEvent(event);
},
updateBookmark: function bv_updateBookmark(aBookmarkId) {
let item = this._getItemForBookmarkId(aBookmarkId);
if (!item)
return;
let bookmarks = PlacesUtils.bookmarks;
let oldIndex = this._set.getIndexOfItem(item);
let index = bookmarks.getItemIndex(aBookmarkId);
let index = this._bookmarkService.getItemIndex(aBookmarkId);
if (oldIndex != index) {
this.removeBookmark(aBookmarkId);
@ -219,8 +262,8 @@ BookmarksView.prototype = {
return;
}
let uri = bookmarks.getBookmarkURI(aBookmarkId);
let title = bookmarks.getItemTitle(aBookmarkId) || uri.spec;
let uri = this._bookmarkService.getBookmarkURI(aBookmarkId);
let title = this._bookmarkService.getItemTitle(aBookmarkId) || uri.spec;
item.setAttribute("value", uri.spec);
item.setAttribute("label", title);
@ -235,7 +278,97 @@ BookmarksView.prototype = {
},
destruct: function bv_destruct() {
PlacesUtils.bookmarks.removeObserver(this._changes);
this._bookmarkService.removeObserver(this._changes);
window.removeEventListener('MozAppbarDismissing', this, false);
window.removeEventListener('BookmarksNeedsRefresh', this, false);
},
doActionOnSelectedTiles: function bv_doActionOnSelectedTiles(aActionName, aEvent) {
let tileGroup = this._set;
let selectedTiles = tileGroup.selectedItems;
switch (aActionName){
case "delete":
Array.forEach(selectedTiles, function(aNode) {
if (!this._toRemove) {
this._toRemove = [];
}
let itemId = this._getBookmarkIdForItem(aNode);
this._toRemove.push(itemId);
this.removeBookmark(itemId);
}, this);
// stop the appbar from dismissing
aEvent.preventDefault();
// at next tick, re-populate the context appbar.
setTimeout(function(){
// fire a MozContextActionsChange event to update the context appbar
let event = document.createEvent("Events");
// we need the restore button to show (the tile node will go away though)
event.actions = ["restore"];
event.initEvent("MozContextActionsChange", true, false);
tileGroup.dispatchEvent(event);
}, 0);
break;
case "restore":
// clear toRemove and let _sendNeedsRefresh update the items.
this._toRemove = null;
break;
case "unpin":
Array.forEach(selectedTiles, function(aNode) {
let itemId = this._getBookmarkIdForItem(aNode);
if (this._filterUnpinned)
this.removeBookmark(itemId);
this._pinHelper.setUnpinned(itemId);
}, this);
break;
case "pin":
Array.forEach(selectedTiles, function(aNode) {
let itemId = this._getBookmarkIdForItem(aNode);
this._pinHelper.setPinned(itemId);
}, this);
break;
default:
return;
}
// Send refresh event so all view are in sync.
this._sendNeedsRefresh();
},
handleEvent: function bv_handleEvent(aEvent) {
switch (aEvent.type){
case "MozAppbarDismissing":
// If undo wasn't pressed, time to do definitive actions.
if (this._toRemove) {
for (let bookmarkId of this._toRemove) {
this._bookmarkService.removeItem(bookmarkId);
}
this._toRemove = null;
this._set.clearSelection();
// Clear context app bar
let event = document.createEvent("Events");
event.initEvent("MozContextActionsChange", true, false);
this._set.dispatchEvent(event);
}
break;
case "BookmarksNeedsRefresh":
this.getBookmarks(true);
break;
}
}
};
@ -244,7 +377,8 @@ var BookmarksStartView = {
get _grid() { return document.getElementById("start-bookmarks-grid"); },
init: function init() {
this._view = new BookmarksView(this._grid, StartUI.maxResultsPerSection, Bookmarks.metroRoot);
this._view = new BookmarksView(this._grid, StartUI.maxResultsPerSection, Bookmarks.metroRoot, true);
this._view.getBookmarks();
},
uninit: function uninit() {
@ -267,6 +401,7 @@ var BookmarksPanelView = {
},
show: function show() {
this._view.getBookmarks(true);
this._grid.arrangeItems();
},
@ -282,7 +417,7 @@ var BookmarksPanelView = {
*/
function BookmarkChangeListener(aView) {
this._view = aView;
};
}
BookmarkChangeListener.prototype = {
//////////////////////////////////////////////////////////////////////////////
@ -291,37 +426,37 @@ BookmarkChangeListener.prototype = {
onEndUpdateBatch: function () { },
onItemAdded: function bCL_onItemAdded(aItemId, aParentId, aIndex, aItemType, aURI, aTitle, aDateAdded, aGUID, aParentGUID) {
if (!this._view.inCurrentView(aParentId, aIndex, aItemType))
return;
this._view.addBookmark(aItemId);
this._view.getBookmarks(true);
},
onItemChanged: function bCL_onItemChanged(aItemId, aProperty, aIsAnnotationProperty, aNewValue, aLastModified, aItemType, aParentId, aGUID, aParentGUID) {
let itemIndex = PlacesUtils.bookmarks.getItemIndex(aItemId);
if (!this._view.inCurrentView(aParentId, itemIndex, aItemType))
if (!this._view.inCurrentView(aParentId, aItemId))
return;
this._view.updateBookmark(aItemId);
},
onItemMoved: function bCL_onItemMoved(aItemId, aOldParentId, aOldIndex, aNewParentId, aNewIndex, aItemType, aGUID, aOldParentGUID, aNewParentGUID) {
let wasInView = this._view.inCurrentView(aOldParentId, aOldIndex, aItemType);
let nowInView = this._view.inCurrentView(aNewParentId, aNewIndex, aItemType);
let wasInView = this._view.inCurrentView(aOldParentId, aItemId);
let nowInView = this._view.inCurrentView(aNewParentId, aItemId);
if (!wasInView && nowInView)
this._view.addBookmark(aItemId, aParentId, aIndex, aItemType, aURI, aTitle, aDateAdded);
this._view.addBookmark(aItemId);
if (wasInView && !nowInView)
this._view.removeBookmark(aItemId);
this._view.getBookmarks(true);
},
onBeforeItemRemoved: function (aItemId, aItemType, aParentId, aGUID, aParentGUID) { },
onItemRemoved: function bCL_onItemRemoved(aItemId, aParentId, aIndex, aItemType, aURI, aGUID, aParentGUID) {
if (!this._view.inCurrentView(aParentId, aIndex, aItemType))
if (!this._view.inCurrentView(aParentId, aItemId))
return;
this._view.removeBookmark(aItemId);
this._view.getBookmarks(true);
},
onItemVisited: function(aItemId, aVisitId, aTime, aTransitionType, aURI, aParentId, aGUID, aParentGUID) { },

Просмотреть файл

@ -132,6 +132,7 @@ let ScriptContexts = {};
["Sanitizer", "chrome://browser/content/sanitize.js"],
["SanitizeUI", "chrome://browser/content/sanitizeUI.js"],
["SSLExceptions", "chrome://browser/content/exceptions.js"],
["ItemPinHelper", "chrome://browser/content/helperui/ItemPinHelper.js"],
#ifdef MOZ_SERVICES_SYNC
["WeaveGlue", "chrome://browser/content/sync.js"],
["SyncPairDevice", "chrome://browser/content/sync.js"],

Просмотреть файл

@ -268,7 +268,8 @@
<richgrid id="start-bookmarks-grid" seltype="multiple" flex="1"/>
</vbox>
<vbox id="start-history" class="meta-section">
<label class="meta-section-title" value="&startHistoryHeader.label;"/>
<label class="meta-section-title" value="&startHistoryHeader.label;"
onclick="PanelUI.show('history-container');"/>
<richgrid id="start-history-grid" seltype="multiple" flex="1"/>
</vbox>
<vbox id="start-remotetabs" class="meta-section">
@ -311,30 +312,6 @@
<textbox id="find-helper-textbox" class="search-bar content-navigator-item" oncommand="FindHelperUI.search(this.value)" oninput="FindHelperUI.updateCommands(this.value);" type="search"/>
</vbox>
<!-- Windows 8 Appbar -->
<appbar id="appbar" mousethrough="never" observes="bcast_windowState">
<!-- contextual actions temporarily hidden, pending #800996 -->
<hbox id="contextualactions-tray" flex="1">
<toolbarbutton id="delete-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('delete')"/>
<toolbarbutton id="restore-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('restore')"/>
<toolbarbutton id="pin-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('pin')"/>
<toolbarbutton id="unpin-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('unpin')"/>
<toolbarbutton id="clear-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('clear')"/>
</hbox>
<hbox flex="1">
<toolbarbutton id="download-button" oncommand="Appbar.onDownloadButton()"/>
<toolbarbutton id="console-button" oncommand="Appbar.onConsoleButton()"/>
<toolbarbutton id="jsshell-button" oncommand="Appbar.onJSShellButton()"/>
</hbox>
<hbox>
<toolbarbutton id="more-button" onclick="Appbar.onMoreButton(event)" />
<toolbarbutton id="zoomout-button" oncommand="Appbar.onZoomOutButton()"/>
<toolbarbutton id="zoomin-button" oncommand="Appbar.onZoomInButton()"/>
<toolbarbutton id="star-button" type="checkbox" oncommand="Appbar.onStarButton()"/>
<toolbarbutton id="pin-button" type="checkbox" oncommand="Appbar.onPinButton()"/>
</hbox>
</appbar>
<vbox id="panel-container" hidden="true" class="window-width window-height meta" observes="bcast_windowState">
<hbox id="panel-header">
<toolbarbutton id="panel-close-button" command="cmd_panel"/>
@ -352,10 +329,10 @@
<deck id="panel-items" selectedIndex="0" flex="1" >
<scrollbox id="bookmarks-container" flex="1">
<richgrid id="bookmarks-list" class="canSnapTiles" seltype="single" flex="1"/>
<richgrid id="bookmarks-list" class="canSnapTiles" seltype="multiple" flex="1"/>
</scrollbox>
<scrollbox id="history-container" flex="1">
<richgrid id="history-list" class="canSnapTiles" seltype="single" flex="1"/>
<richgrid id="history-list" class="canSnapTiles" seltype="multiple" flex="1"/>
</scrollbox>
<scrollbox id="downloads-container" flex="1">
<richgrid id="downloads-list" class="canSnapTiles" seltype="single" flex="1"/>
@ -387,6 +364,29 @@
</deck>
</vbox>
<!-- Windows 8 Appbar -->
<appbar id="appbar" mousethrough="never" observes="bcast_windowState">
<hbox id="contextualactions-tray" flex="1">
<toolbarbutton id="delete-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('delete')"/>
<toolbarbutton id="restore-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('restore')"/>
<toolbarbutton id="pin-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('pin')"/>
<toolbarbutton id="unpin-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('unpin')"/>
<toolbarbutton id="clear-selected-button" hidden="true" fade="true" oncommand="Appbar.dispatchContextualAction('clear')"/>
</hbox>
<hbox flex="1">
<toolbarbutton id="download-button" oncommand="Appbar.onDownloadButton()"/>
<toolbarbutton id="console-button" oncommand="Appbar.onConsoleButton()"/>
<toolbarbutton id="jsshell-button" oncommand="Appbar.onJSShellButton()"/>
</hbox>
<hbox>
<toolbarbutton id="more-button" onclick="Appbar.onMoreButton(event)" />
<toolbarbutton id="zoomout-button" oncommand="Appbar.onZoomOutButton()"/>
<toolbarbutton id="zoomin-button" oncommand="Appbar.onZoomInButton()"/>
<toolbarbutton id="star-button" type="checkbox" oncommand="Appbar.onStarButton()"/>
<toolbarbutton id="pin-button" type="checkbox" oncommand="Appbar.onPinButton()"/>
</hbox>
</appbar>
<!-- Selection overlay - this should be below any content that can have selectable text -->
<!-- onclick addresses dom bug 835175, str in bug 832957 -->
<box onclick="false" class="selection-overlay-hidden" id="selection-overlay"/>

Просмотреть файл

@ -0,0 +1,59 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
function ItemPinHelper(aUnpinnedPrefName) {
this._prefKey = aUnpinnedPrefName;
}
// Cache preferences on a static variable shared
// by all instances registered to the same pref key.
ItemPinHelper._prefValue = {};
ItemPinHelper.prototype = {
_getPrefValue: function _getPrefValue() {
if (ItemPinHelper._prefValue[this._prefKey])
return ItemPinHelper._prefValue[this._prefKey];
try {
// getComplexValue throws if pref never set. Really.
let prefValue = Services.prefs.getComplexValue(this._prefKey, Ci.nsISupportsString);
ItemPinHelper._prefValue[this._prefKey] = JSON.parse(prefValue.data);
} catch(e) {
ItemPinHelper._prefValue[this._prefKey] = [];
}
return ItemPinHelper._prefValue[this._prefKey];
},
_setPrefValue: function _setPrefValue(aNewValue) {
let stringified = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
stringified.data = JSON.stringify(aNewValue);
Services.prefs.setComplexValue(this._prefKey, Ci.nsISupportsString, stringified);
ItemPinHelper._prefValue[this._prefKey] = aNewValue;
},
isPinned: function isPinned(aItemId) {
// Bookmarks are visible on StartUI (pinned) by default
return this._getPrefValue().indexOf(aItemId) === -1;
},
setUnpinned: function setPinned(aItemId) {
let unpinned = this._getPrefValue();
unpinned.push(aItemId);
this._setPrefValue(unpinned);
},
setPinned: function unsetPinned(aItemId) {
let unpinned = this._getPrefValue();
let index = unpinned.indexOf(aItemId);
unpinned.splice(index, 1);
this._setPrefValue(unpinned);
},
}

Просмотреть файл

@ -4,67 +4,208 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
'use strict';
function HistoryView(aSet) {
function HistoryView(aSet, aLimit, aFilterUnpinned) {
this._set = aSet;
this._set.controller = this;
this._inBatch = false;
let history = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
history.addObserver(this, false);
this._limit = aLimit;
this._filterUnpinned = aFilterUnpinned;
this._historyService = PlacesUtils.history;
this._navHistoryService = gHistSvc;
this._pinHelper = new ItemPinHelper("metro.history.unpinned");
this._historyService.addObserver(this, false);
window.addEventListener('MozAppbarDismissing', this, false);
window.addEventListener('HistoryNeedsRefresh', this, false);
}
HistoryView.prototype = {
_set:null,
_set: null,
_toRemove: null,
handleItemClick: function tabview_handleItemClick(aItem) {
let url = aItem.getAttribute("value");
BrowserUI.goToURI(url);
},
populateGrid: function populateGrid() {
let query = gHistSvc.getNewQuery();
let options = gHistSvc.getNewQueryOptions();
populateGrid: function populateGrid(aRefresh) {
let query = this._navHistoryService.getNewQuery();
let options = this._navHistoryService.getNewQueryOptions();
options.excludeQueries = true;
options.queryType = options.QUERY_TYPE_HISTORY;
options.maxResults = StartUI.maxResultsPerSection;
options.resultType = options.RESULTS_AS_URI;
options.sortingMode = options.SORT_BY_DATE_DESCENDING;
let result = gHistSvc.executeQuery(query, options);
let limit = this._limit || Infinity;
let result = this._navHistoryService.executeQuery(query, options);
let rootNode = result.root;
rootNode.containerOpen = true;
let childCount = rootNode.childCount;
for (let i = 0; i < childCount; i++) {
for (let i = 0, addedCount = 0; i < childCount && addedCount < limit; i++) {
let node = rootNode.getChild(i);
let uri = node.uri;
let title = node.title || uri;
this.addItemToSet(uri, title, node.icon);
// If item is marked for deletion, skip it.
if (this._toRemove && this._toRemove.indexOf(uri) !== -1)
continue;
let items = this._set.getItemsByUrl(uri);
// Item has been unpinned, skip if filterUnpinned set.
if (this._filterUnpinned && !this._pinHelper.isPinned(uri)) {
if (items.length > 0)
this.removeHistory(uri);
continue;
}
if (!aRefresh || items.length === 0) {
// If we're not refreshing or the item is not in the grid, add it.
this.addItemToSet(uri, title, node.icon, addedCount);
} else if (aRefresh && items.length > 0) {
// Update context action in case it changed in another view.
for (let item of items) {
this._setContextActions(item);
}
}
addedCount++;
}
// Remove extra items in case a refresh added more than the limit.
// This can happen when undoing a delete.
if (aRefresh) {
while (this._set.itemCount > limit)
this._set.removeItemAt(this._set.itemCount - 1);
}
rootNode.containerOpen = false;
},
destruct: function destruct() {
this._historyService.removeObserver(this);
window.removeEventListener('MozAppbarDismissing', this, false);
window.removeEventListener('HistoryNeedsRefresh', this, false);
},
addItemToSet: function addItemToSet(aURI, aTitle, aIcon, aPos) {
let item = this._set.insertItemAt(aPos || 0, aTitle, aURI, this._inBatch);
item.setAttribute("iconURI", aIcon);
this._setContextActions(item);
},
_setContextActions: function bv__setContextActions(aItem) {
let uri = aItem.getAttribute("value");
aItem.setAttribute("data-contextactions", "delete," + (this._pinHelper.isPinned(uri) ? "unpin" : "pin"));
if (aItem.refresh) aItem.refresh();
},
_sendNeedsRefresh: function bv__sendNeedsRefresh(){
// Event sent when all views need to refresh.
let event = document.createEvent("Events");
event.initEvent("HistoryNeedsRefresh", true, false);
window.dispatchEvent(event);
},
removeHistory: function (aUri) {
let items = this._set.getItemsByUrl(aUri);
for (let item of items)
this._set.removeItem(item, this._inBatch);
},
doActionOnSelectedTiles: function bv_doActionOnSelectedTiles(aActionName, aEvent) {
let tileGroup = this._set;
let selectedTiles = tileGroup.selectedItems;
switch (aActionName){
case "delete":
Array.forEach(selectedTiles, function(aNode) {
if (!this._toRemove) {
this._toRemove = [];
}
let uri = aNode.getAttribute("value");
this._toRemove.push(uri);
this.removeHistory(uri);
}, this);
// stop the appbar from dismissing
aEvent.preventDefault();
// at next tick, re-populate the context appbar.
setTimeout(function(){
// fire a MozContextActionsChange event to update the context appbar
let event = document.createEvent("Events");
// we need the restore button to show (the tile node will go away though)
event.actions = ["restore"];
event.initEvent("MozContextActionsChange", true, false);
tileGroup.dispatchEvent(event);
}, 0);
break;
case "restore":
// clear toRemove and let _sendNeedsRefresh update the items.
this._toRemove = null;
break;
case "unpin":
Array.forEach(selectedTiles, function(aNode) {
let uri = aNode.getAttribute("value");
if (this._filterUnpinned)
this.removeHistory(uri);
this._pinHelper.setUnpinned(uri);
}, this);
break;
case "pin":
Array.forEach(selectedTiles, function(aNode) {
let uri = aNode.getAttribute("value");
this._pinHelper.setPinned(uri);
}, this);
break;
default:
return;
}
// Send refresh event so all view are in sync.
this._sendNeedsRefresh();
},
handleEvent: function bv_handleEvent(aEvent) {
switch (aEvent.type){
case "MozAppbarDismissing":
// If undo wasn't pressed, time to do definitive actions.
if (this._toRemove) {
for (let uri of this._toRemove) {
this._historyService.removePage(NetUtil.newURI(uri));
}
// Clear context app bar
let event = document.createEvent("Events");
event.initEvent("MozContextActionsChange", true, false);
this._set.dispatchEvent(event);
this._toRemove = null;
this._set.clearSelection();
}
break;
case "HistoryNeedsRefresh":
this.populateGrid(true);
break;
}
},
// nsINavHistoryObserver & helpers
addItemToSet: function addItemToSet(uri, title, icon) {
let item = this._set.appendItem(title, uri, this._inBatch);
item.setAttribute("iconURI", icon);
},
// TODO rebase/merge Alert: bug 831916 's patch merges in,
// this can be replaced with the updated calls to populateGrid()
refreshAndRepopulate: function() {
this._set.clearAll();
this.populateGrid();
},
onBeginUpdateBatch: function() {
// Avoid heavy grid redraws while a batch is in process
this._inBatch = true;
@ -72,13 +213,13 @@ HistoryView.prototype = {
onEndUpdateBatch: function() {
this._inBatch = false;
this.refreshAndRepopulate();
this.populateGrid(true);
},
onVisit: function(aURI, aVisitID, aTime, aSessionID,
aReferringID, aTransitionType) {
if (!this._inBatch) {
this.refreshAndRepopulate();
this.populateGrid(true);
}
},
@ -90,9 +231,7 @@ HistoryView.prototype = {
},
onDeleteURI: function(aURI) {
for (let item of this._set.getItemsByUrl(aURI.spec)) {
this._set.removeItem(item, this._inBatch);
}
this.removeHistory(aURI.spec);
},
onClearHistory: function() {
@ -113,7 +252,7 @@ HistoryView.prototype = {
onDeleteVisits: function (aURI, aVisitTime, aGUID, aReason, aTransitionType) {
if ((aReason == Ci.nsINavHistoryObserver.REASON_DELETED) && !this._inBatch) {
this.refreshAndRepopulate();
this.populateGrid(true);
}
},
@ -135,7 +274,7 @@ let HistoryStartView = {
},
init: function init() {
this._view = new HistoryView(this._grid);
this._view = new HistoryView(this._grid, StartUI.maxResultsPerSection, true);
this._view.populateGrid();
},
@ -150,12 +289,12 @@ let HistoryPanelView = {
get visible() { return PanelUI.isPaneVisible("history-container"); },
show: function show() {
this._view.populateGrid(true);
this._grid.arrangeItems();
},
init: function init() {
this._view = new HistoryView(this._grid);
this._view.populateGrid();
this._view = new HistoryView(this._grid, StartUI.maxResultsPerSection, false);
},
uninit: function uninit() {

Просмотреть файл

@ -42,6 +42,7 @@ chrome.jar:
content/helperui/SelectionHelperUI.js (content/helperui/SelectionHelperUI.js)
content/helperui/FormHelperUI.js (content/helperui/FormHelperUI.js)
content/helperui/FindHelperUI.js (content/helperui/FindHelperUI.js)
content/helperui/ItemPinHelper.js (content/helperui/ItemPinHelper.js)
content/contenthandlers/ContextMenuHandler.js (content/contenthandlers/ContextMenuHandler.js)
content/contenthandlers/PluginCTPHandler.js (content/contenthandlers/PluginCTPHandler.js)

Просмотреть файл

@ -28,6 +28,8 @@ BROWSER_TESTS = \
browser_prefs_ui.js \
browser_topsites.js \
browser_tabs.js \
browser_bookmarks.js \
browser_history.js \
$(NULL)
# disabled due to timeouts and lack of plugin support.

Просмотреть файл

@ -0,0 +1,560 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
let gStartView = BookmarksStartView._view;
let gPanelView = BookmarksPanelView._view;
function test() {
runTests();
}
function setup() {
PanelUI.hide();
BookmarksTestHelper.setup();
if (StartUI.isStartPageVisible)
return;
yield addTab("about:start");
yield waitForCondition(() => StartUI.isStartPageVisible);
yield hideContextUI();
}
function tearDown() {
PanelUI.hide();
BookmarksTestHelper.restore();
}
var BookmarksTestHelper = {
_originalNavHistoryService: null,
MockNavHistoryService: {
getNewQueryOptions: function () {
return {};
},
getNewQuery: function () {
return {
setFolders: function(){}
};
},
executeQuery: function () {
return {
root: {
get childCount() {
return Object.keys(BookmarksTestHelper._nodes).length;
},
getChild: function (aIndex) BookmarksTestHelper._nodes[Object.keys(BookmarksTestHelper._nodes)[aIndex]]
}
}
}
},
_originalBookmarkService: null,
MockBookmarkService: {
getItemIndex: function (aIndex) aIndex,
getBookmarkURI: function (aId) BookmarksTestHelper._nodes[aId].uri,
getItemTitle: function (aId) BookmarksTestHelper._nodes[aId].title,
removeItem: function (aId) {
delete BookmarksTestHelper._nodes[aId];
// Simulate observer notification
gStartView._changes.onItemRemoved(aId, gStartView._root);
gPanelView._changes.onItemRemoved(aId, gPanelView._root);
},
},
Node: function (aTitle, aId) {
this.type = this.RESULT_TYPE_URI = 0;
this.title = aTitle;
this.itemId = aId;
this.uri = "http://" + aTitle + ".com.br";
this.pinned = true
},
_nodes: null,
createNodes: function (aMany) {
this._nodes = {};
for (let i=0; i<aMany; i++) {
this._nodes[i] = new this.Node("Mock-Bookmark" + i, i);
}
},
_originalPinHelper: null,
MockPinHelper: {
isPinned: function (aItem) BookmarksTestHelper._nodes[aItem].pinned,
setUnpinned: function (aItem) BookmarksTestHelper._nodes[aItem].pinned = false,
setPinned: function (aItem) BookmarksTestHelper._nodes[aItem].pinned = true,
},
_originalUpdateFavicon: null,
setup: function setup() {
// Just enough items so that there will be one less then the limit
// after removing 4 items.
this.createNodes(gStartView._limit + 3);
this._originalNavHistoryService = gStartView._navHistoryService;
gStartView._navHistoryService = this.MockNavHistoryService;
gPanelView._navHistoryService = this.MockNavHistoryService;
this._originalBookmarkService = gStartView._bookmarkService;
gStartView._bookmarkService= this.MockBookmarkService;
gPanelView._bookmarkService= this.MockBookmarkService;
this._originalPinHelper = gStartView._pinHelper;
gStartView._pinHelper = this.MockPinHelper;
gPanelView._pinHelper = this.MockPinHelper;
this._originalUpdateFavicon = gStartView._updateFavicon;
gStartView._updateFavicon = function () {};
gPanelView._updateFavicon = function () {};
gStartView.clearBookmarks();
gStartView.getBookmarks();
gPanelView.clearBookmarks();
gPanelView.getBookmarks();
},
restore: function () {
gStartView._navHistoryService = this._originalNavHistoryService;
gStartView._bookmarkService= this._originalBookmarkService;
gStartView._pinHelper = this._originalPinHelper;
gStartView._updateFavicon = this._originalUpdateFavicon;
gPanelView._navHistoryService = this._originalNavHistoryService;
gPanelView._bookmarkService= this._originalBookmarkService;
gPanelView._pinHelper = this._originalPinHelper;
gPanelView._updateFavicon = this._originalUpdateFavicon;
gStartView.clearBookmarks();
gStartView.getBookmarks();
gPanelView.clearBookmarks();
gPanelView.getBookmarks();
}
};
gTests.push({
desc: "Test bookmarks StartUI unpin",
setUp: setup,
tearDown: tearDown,
run: function testBookmarksStartUnpin() {
let unpinButton = document.getElementById("unpin-selected-button");
// --------- unpin item 2
let item = gStartView._getItemForBookmarkId(2);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!unpinButton.hidden, "Unpin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
yield promise;
item = gStartView._getItemForBookmarkId(2);
ok(!item, "Item not in grid");
ok(!gStartView._pinHelper.isPinned(2), "Item unpinned");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
// --------- unpin multiple items
let item1 = gStartView._getItemForBookmarkId(0);
let item2 = gStartView._getItemForBookmarkId(5);
let item3 = gStartView._getItemForBookmarkId(12);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!unpinButton.hidden, "Unpin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
yield promise;
item1 = gStartView._getItemForBookmarkId(0);
item2 = gStartView._getItemForBookmarkId(5);
item3 = gStartView._getItemForBookmarkId(12);
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(!gStartView._pinHelper.isPinned(0) && !gStartView._pinHelper.isPinned(5) && !gStartView._pinHelper.isPinned(12) , "Items unpinned");
ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
}
});
gTests.push({
desc: "Test bookmarks StartUI delete",
setUp: setup,
tearDown: tearDown,
run: function testBookmarksStartDelete() {
let restoreButton = document.getElementById("restore-selected-button");
let deleteButton = document.getElementById("delete-selected-button");
// --------- delete item 2 and restore
let item = gStartView._getItemForBookmarkId(2);
let initialLocation = gStartView._set.getIndexOfItem(item);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item = gStartView._getItemForBookmarkId(2);
ok(!item, "Item not in grid");
ok(BookmarksTestHelper._nodes[2], "Item not deleted yet");
ok(!restoreButton.hidden, "Restore button is visible.");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
let promise = waitForEvent(Elements.appbar, "transitionend");
EventUtils.synthesizeMouse(restoreButton, 10, 10, {}, window);
yield promise;
item = gStartView._getItemForBookmarkId(2);
ok(item, "Item back in grid");
ok(gStartView._set.getIndexOfItem(item) === initialLocation, "Back in same position.");
// --------- delete item 2 for realz
let item = gStartView._getItemForBookmarkId(2);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item = gStartView._getItemForBookmarkId(2);
ok(!item, "Item not in grid");
ok(BookmarksTestHelper._nodes[2], "Item not deleted yet");
ok(!restoreButton.hidden, "Restore button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
Elements.appbar.dismiss();
yield promise;
item = gStartView._getItemForBookmarkId(2);
ok(!item, "Item not in grid");
ok(!BookmarksTestHelper._nodes[2], "Item RIP");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
// --------- delete multiple items and restore
let item1 = gStartView._getItemForBookmarkId(0);
let item2 = gStartView._getItemForBookmarkId(5);
let item3 = gStartView._getItemForBookmarkId(12);
let initialLocation1 = gStartView._set.getIndexOfItem(item1);
let initialLocation2 = gStartView._set.getIndexOfItem(item2);
let initialLocation3 = gStartView._set.getIndexOfItem(item3);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item1 = gStartView._getItemForBookmarkId(0);
item2 = gStartView._getItemForBookmarkId(5);
item3 = gStartView._getItemForBookmarkId(12);
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(BookmarksTestHelper._nodes[0] && BookmarksTestHelper._nodes[5] && BookmarksTestHelper._nodes[12],
"Items not deleted yet");
ok(!restoreButton.hidden, "Restore button is visible.");
ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
let promise = waitForEvent(Elements.appbar, "transitionend");
EventUtils.synthesizeMouse(restoreButton, 10, 10, {}, window);
yield promise;
item1 = gStartView._getItemForBookmarkId(0);
item2 = gStartView._getItemForBookmarkId(5);
item3 = gStartView._getItemForBookmarkId(12);
ok(item1 && item2 && item3, "Items are back in grid");
ok(gStartView._set.getIndexOfItem(item1) === initialLocation1 &&
gStartView._set.getIndexOfItem(item2) === initialLocation2 &&
gStartView._set.getIndexOfItem(item3) === initialLocation3, "Items back in the same position.");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
// --------- delete multiple items for good
let item1 = gStartView._getItemForBookmarkId(0);
let item2 = gStartView._getItemForBookmarkId(5);
let item3 = gStartView._getItemForBookmarkId(12);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item1 = gStartView._getItemForBookmarkId(0);
item2 = gStartView._getItemForBookmarkId(5);
item3 = gStartView._getItemForBookmarkId(12);
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(BookmarksTestHelper._nodes[0] && BookmarksTestHelper._nodes[5] && BookmarksTestHelper._nodes[12],
"Items not deleted yet");
ok(!restoreButton.hidden, "Restore button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
Elements.appbar.dismiss();
yield promise;
item1 = gStartView._getItemForBookmarkId(0);
item2 = gStartView._getItemForBookmarkId(5);
item3 = gStartView._getItemForBookmarkId(12);
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(!BookmarksTestHelper._nodes[0] && !BookmarksTestHelper._nodes[5] && !BookmarksTestHelper._nodes[12],
"Items are gone");
ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
}
});
gTests.push({
desc: "Test bookmarks PanelUI unpin",
setUp: setup,
tearDown: tearDown,
run: function testBookmarksPanelUnpin() {
PanelUI.show('bookmarks-container');
let pinButton = document.getElementById("pin-selected-button");
let unpinButton = document.getElementById("unpin-selected-button");
// --------- unpin item 2
let item = gPanelView._getItemForBookmarkId(2);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!unpinButton.hidden, "Unpin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
yield promise;
item = gPanelView._getItemForBookmarkId(2);
let startItem = gStartView._getItemForBookmarkId(2);
ok(item, "Item is in grid");
ok(!startItem, "Item not in start grid");
ok(!gPanelView._pinHelper.isPinned(2), "Item unpinned");
// --------- unpin multiple items
let item1 = gPanelView._getItemForBookmarkId(0);
let item2 = gPanelView._getItemForBookmarkId(5);
let item3 = gPanelView._getItemForBookmarkId(12);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!unpinButton.hidden, "Unpin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
yield promise;
item1 = gPanelView._getItemForBookmarkId(0);
item2 = gPanelView._getItemForBookmarkId(5);
item3 = gPanelView._getItemForBookmarkId(12);
let startItem1 = gStartView._getItemForBookmarkId(0);
let startItem2 = gStartView._getItemForBookmarkId(5);
let startItem3 = gStartView._getItemForBookmarkId(12);
ok(item1 && item2 && item3, "Items are in grid");
ok(!startItem1 && !startItem2 && !startItem3, "Items are not in start grid");
ok(!gPanelView._pinHelper.isPinned(0) && !gPanelView._pinHelper.isPinned(5) && !gPanelView._pinHelper.isPinned(12) , "Items unpinned");
// --------- pin item 2
let item = gPanelView._getItemForBookmarkId(2);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
// Make sure app bar is updated
yield waitForCondition(() => !pinButton.hidden);
ok(!pinButton.hidden, "Pin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
EventUtils.synthesizeMouse(pinButton, 10, 10, {}, window);
yield promise;
item = gPanelView._getItemForBookmarkId(2);
let startItem = gStartView._getItemForBookmarkId(2);
ok(item, "Item is in grid");
ok(startItem, "Item is back in start grid");
ok(gPanelView._pinHelper.isPinned(2), "Item pinned");
// --------- pin multiple items
let item1 = gPanelView._getItemForBookmarkId(0);
let item2 = gPanelView._getItemForBookmarkId(5);
let item3 = gPanelView._getItemForBookmarkId(12);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
// Make sure app bar is updated
yield waitForCondition(() => !pinButton.hidden);
ok(!pinButton.hidden, "pin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
EventUtils.synthesizeMouse(pinButton, 10, 10, {}, window);
yield promise;
item1 = gPanelView._getItemForBookmarkId(0);
item2 = gPanelView._getItemForBookmarkId(5);
item3 = gPanelView._getItemForBookmarkId(12);
let startItem1 = gStartView._getItemForBookmarkId(0);
let startItem2 = gStartView._getItemForBookmarkId(5);
let startItem3 = gStartView._getItemForBookmarkId(12);
ok(item1 && item2 && item3, "Items are in grid");
ok(startItem1 && startItem2 && startItem3, "Items are back in start grid");
ok(gPanelView._pinHelper.isPinned(0) && gPanelView._pinHelper.isPinned(5) && gPanelView._pinHelper.isPinned(12) , "Items pinned");
}
});
gTests.push({
desc: "Test bookmarks PanelUI delete",
setUp: setup,
tearDown: tearDown,
run: function testBookmarksPanelDelete() {
PanelUI.show('bookmarks-container');
let restoreButton = document.getElementById("restore-selected-button");
let deleteButton = document.getElementById("delete-selected-button");
// --------- delete item 2
let item = gPanelView._getItemForBookmarkId(2);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item = gPanelView._getItemForBookmarkId(2);
let startItem = gStartView._getItemForBookmarkId(2);
ok(!item, "Item is not in grid");
ok(startItem, "Item is not deleted from start grid yet");
ok(BookmarksTestHelper._nodes[2], "Item exists");
ok(!restoreButton.hidden, "Restore button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend");
Elements.appbar.dismiss();
yield promise;
item = gPanelView._getItemForBookmarkId(2);
startItem = gStartView._getItemForBookmarkId(2);
ok(!item, "Item gone from grid");
ok(!startItem, "Item gone from start grid");
ok(!BookmarksTestHelper._nodes[2], "Item RIP");
// --------- delete multiple items
let item1 = gPanelView._getItemForBookmarkId(0);
let item2 = gPanelView._getItemForBookmarkId(5);
let item3 = gPanelView._getItemForBookmarkId(12);
let promise = waitForEvent(Elements.appbar, "transitionend");
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item1 = gPanelView._getItemForBookmarkId(0);
item2 = gPanelView._getItemForBookmarkId(5);
item3 = gPanelView._getItemForBookmarkId(12);
let startItem1 = gStartView._getItemForBookmarkId(0);
let startItem2 = gStartView._getItemForBookmarkId(5);
let startItem3 = gStartView._getItemForBookmarkId(12);
ok(!restoreButton.hidden, "Restore button is visible.");
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(startItem1 && startItem2 && startItem3, "Items are still in start grid");
ok(BookmarksTestHelper._nodes[0] && BookmarksTestHelper._nodes[5] && BookmarksTestHelper._nodes[12],
"Items not deleted yet");
let promise = waitForEvent(Elements.appbar, "transitionend");
Elements.appbar.dismiss();
yield promise;
item1 = gPanelView._getItemForBookmarkId(0);
item2 = gPanelView._getItemForBookmarkId(5);
item3 = gPanelView._getItemForBookmarkId(12);
let startItem1 = gStartView._getItemForBookmarkId(0);
let startItem2 = gStartView._getItemForBookmarkId(5);
let startItem3 = gStartView._getItemForBookmarkId(12);
ok(!item1 && !item2 && !item3, "Items are gone from grid");
ok(!startItem1 && !startItem2 && !startItem3, "Items are gone from start grid");
ok(!BookmarksTestHelper._nodes[0] && !BookmarksTestHelper._nodes[5] && !BookmarksTestHelper._nodes[12],
"Items are gone for good");
}
});

Просмотреть файл

@ -0,0 +1,561 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
let gStartView = HistoryStartView._view;
let gPanelView = HistoryPanelView._view;
function test() {
runTests();
}
function setup() {
PanelUI.hide();
HistoryTestHelper.setup();
if (StartUI.isStartPageVisible)
return;
yield addTab("about:start");
yield waitForCondition(() => StartUI.isStartPageVisible);
yield hideContextUI();
}
function tearDown() {
PanelUI.hide();
HistoryTestHelper.restore();
}
var HistoryTestHelper = {
_originalNavHistoryService: null,
MockNavHistoryService: {
getNewQueryOptions: function () {
return {};
},
getNewQuery: function () {
return {
setFolders: function(){}
};
},
executeQuery: function () {
return {
root: {
get childCount() {
return Object.keys(HistoryTestHelper._nodes).length;
},
getChild: function (aIndex) HistoryTestHelper._nodes[Object.keys(HistoryTestHelper._nodes)[aIndex]]
}
}
}
},
_originalHistoryService: null,
MockHistoryService: {
removePage: function (aURI) {
delete HistoryTestHelper._nodes[aURI.spec];
// Simulate observer notification
gStartView.onDeleteURI(aURI);
gPanelView.onDeleteURI(aURI);
},
},
Node: function (aTitle, aURISpec) {
this.title = aTitle;
this.uri = aURISpec;
this.pinned = true
},
_nodes: null,
createNodes: function (aMany) {
this._nodes = {};
for (let i=0; i<aMany; i++) {
let title = "mock-history-" + i;
let uri = "http://" + title + ".com.br/";
this._nodes[uri] = new this.Node(title, uri);
}
},
_originalPinHelper: null,
MockPinHelper: {
isPinned: function (aItem) HistoryTestHelper._nodes[aItem].pinned,
setUnpinned: function (aItem) HistoryTestHelper._nodes[aItem].pinned = false,
setPinned: function (aItem) HistoryTestHelper._nodes[aItem].pinned = true,
},
setup: function setup() {
// Just enough items so that there will be one less then the limit
// after removing 4 items.
this.createNodes(gStartView._limit + 3);
this._originalNavHistoryService = gStartView._navHistoryService;
gStartView._navHistoryService = this.MockNavHistoryService;
gPanelView._navHistoryService = this.MockNavHistoryService;
this._originalHistoryService = gStartView._historyService;
gStartView._historyService= this.MockHistoryService;
gPanelView._historyService= this.MockHistoryService;
this._originalPinHelper = gStartView._pinHelper;
gStartView._pinHelper = this.MockPinHelper;
gPanelView._pinHelper = this.MockPinHelper;
gStartView._set.clearAll();
gStartView.populateGrid();
gPanelView._set.clearAll();
gPanelView.populateGrid();
},
restore: function () {
gStartView._navHistoryService = this._originalNavHistoryService;
gStartView._historyService= this._originalHistoryService;
gStartView._pinHelper = this._originalPinHelper;
gPanelView._navHistoryService = this._originalNavHistoryService;
gPanelView._historyService= this._originalHistoryService;
gPanelView._pinHelper = this._originalPinHelper;
gStartView._set.clearAll();
gStartView.populateGrid();
gPanelView._set.clearAll();
gPanelView.populateGrid();
}
};
function uriFromIndex(aIndex) {
return "http://mock-history-" + aIndex + ".com.br/"
}
gTests.push({
desc: "Test history StartUI unpin",
setUp: setup,
tearDown: tearDown,
run: function testHistoryStartUnpin() {
let unpinButton = document.getElementById("unpin-selected-button");
// --------- unpin item 2
let item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!unpinButton.hidden, "Unpin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
unpinButton.click();
yield promise;
item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(!item, "Item not in grid");
ok(!gStartView._pinHelper.isPinned(uriFromIndex(2)), "Item unpinned");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
// --------- unpin multiple items
let item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
let item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
let item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!unpinButton.hidden, "Unpin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
yield promise;
item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(!gStartView._pinHelper.isPinned(uriFromIndex(0)) && !gStartView._pinHelper.isPinned(uriFromIndex(5)) && !gStartView._pinHelper.isPinned(uriFromIndex(12)) , "Items unpinned");
ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
}
});
gTests.push({
desc: "Test history StartUI delete",
setUp: setup,
tearDown: tearDown,
run: function testHistoryStartDelete() {
let restoreButton = document.getElementById("restore-selected-button");
let deleteButton = document.getElementById("delete-selected-button");
// --------- delete item 2 and restore
let item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
let initialLocation = gStartView._set.getIndexOfItem(item);
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(!item, "Item not in grid");
ok(HistoryTestHelper._nodes[uriFromIndex(2)], "Item not deleted yet");
ok(!restoreButton.hidden, "Restore button is visible.");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
EventUtils.synthesizeMouse(restoreButton, 10, 10, {}, window);
yield promise;
item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(item, "Item back in grid");
ok(gStartView._set.getIndexOfItem(item) === initialLocation, "Back in same position.");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
// --------- delete item 2 for realz
let item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(!item, "Item not in grid");
ok(HistoryTestHelper._nodes[uriFromIndex(2)], "Item not deleted yet");
ok(!restoreButton.hidden, "Restore button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
Elements.appbar.dismiss();
yield promise;
item = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(!item, "Item not in grid");
ok(!HistoryTestHelper._nodes[uriFromIndex(2)], "Item RIP");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
// --------- delete multiple items and restore
let item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
let item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
let item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
let initialLocation1 = gStartView._set.getIndexOfItem(item1);
let initialLocation2 = gStartView._set.getIndexOfItem(item2);
let initialLocation3 = gStartView._set.getIndexOfItem(item3);
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
yield waitForCondition(() => !deleteButton.hidden);
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(HistoryTestHelper._nodes[uriFromIndex(0)] && HistoryTestHelper._nodes[uriFromIndex(5)] && HistoryTestHelper._nodes[uriFromIndex(12)],
"Items not deleted yet");
ok(!restoreButton.hidden, "Restore button is visible.");
ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
EventUtils.synthesizeMouse(restoreButton, 10, 10, {}, window);
yield promise;
item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(item1 && item2 && item3, "Items are back in grid");
ok(gStartView._set.getIndexOfItem(item1) === initialLocation1 &&
gStartView._set.getIndexOfItem(item2) === initialLocation2 &&
gStartView._set.getIndexOfItem(item3) === initialLocation3, "Items back in the same position.");
ok(gStartView._set.itemCount === gStartView._limit, "Grid repopulated");
// --------- delete multiple items for good
let item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
let item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
let item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(HistoryTestHelper._nodes[uriFromIndex(0)] && HistoryTestHelper._nodes[uriFromIndex(5)] && HistoryTestHelper._nodes[uriFromIndex(12)],
"Items not deleted yet");
ok(!restoreButton.hidden, "Restore button is visible.");
ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
Elements.appbar.dismiss();
yield promise;
item1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(!HistoryTestHelper._nodes[uriFromIndex(0)] && !HistoryTestHelper._nodes[uriFromIndex(5)] && !HistoryTestHelper._nodes[uriFromIndex(12)],
"Items are gone");
ok(gStartView._set.itemCount === gStartView._limit - 1, "Grid repopulated");
}
});
gTests.push({
desc: "Test history PanelUI unpin",
setUp: setup,
tearDown: tearDown,
run: function testHistoryPanelUnpin() {
PanelUI.show('history-container');
let pinButton = document.getElementById("pin-selected-button");
let unpinButton = document.getElementById("unpin-selected-button");
// --------- unpin item 2
let item = gPanelView._set.getItemsByUrl(uriFromIndex(2))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
yield waitForCondition(() => !unpinButton.hidden);
ok(!unpinButton.hidden, "Unpin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
yield promise;
item = gPanelView._set.getItemsByUrl(uriFromIndex(2))[0];
let startItem = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(item, "Item is in grid");
ok(!startItem, "Item not in start grid");
ok(!gPanelView._pinHelper.isPinned(uriFromIndex(2)), "Item unpinned");
// --------- unpin multiple items
let item1 = gPanelView._set.getItemsByUrl(uriFromIndex(0))[0];
let item2 = gPanelView._set.getItemsByUrl(uriFromIndex(5))[0];
let item3 = gPanelView._set.getItemsByUrl(uriFromIndex(12))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!unpinButton.hidden, "Unpin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
EventUtils.synthesizeMouse(unpinButton, 10, 10, {}, window);
yield promise;
item1 = gPanelView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gPanelView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gPanelView._set.getItemsByUrl(uriFromIndex(12))[0];
let startItem1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
let startItem2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
let startItem3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(item1 && item2 && item3, "Items are in grid");
ok(!startItem1 && !startItem2 && !startItem3, "Items are not in start grid");
ok(!gPanelView._pinHelper.isPinned(uriFromIndex(0)) && !gPanelView._pinHelper.isPinned(uriFromIndex(5)) && !gPanelView._pinHelper.isPinned(uriFromIndex(12)) , "Items unpinned");
// --------- pin item 2
let item = gPanelView._set.getItemsByUrl(uriFromIndex(2))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
// Make sure app bar is updated
yield waitForCondition(() => !pinButton.hidden);
ok(!pinButton.hidden, "Pin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
EventUtils.synthesizeMouse(pinButton, 10, 10, {}, window);
yield promise;
item = gPanelView._set.getItemsByUrl(uriFromIndex(2))[0];
let startItem = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(item, "Item is in grid");
ok(startItem, "Item is back in start grid");
ok(gPanelView._pinHelper.isPinned(uriFromIndex(2)), "Item pinned");
// --------- pin multiple items
let item1 = gPanelView._set.getItemsByUrl(uriFromIndex(0))[0];
let item2 = gPanelView._set.getItemsByUrl(uriFromIndex(5))[0];
let item3 = gPanelView._set.getItemsByUrl(uriFromIndex(12))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
// Make sure app bar is updated
yield waitForCondition(() => !pinButton.hidden);
ok(!pinButton.hidden, "pin button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
EventUtils.synthesizeMouse(pinButton, 10, 10, {}, window);
yield promise;
item1 = gPanelView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gPanelView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gPanelView._set.getItemsByUrl(uriFromIndex(12))[0];
let startItem1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
let startItem2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
let startItem3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(item1 && item2 && item3, "Items are in grid");
ok(startItem1 && startItem2 && startItem3, "Items are back in start grid");
ok(gPanelView._pinHelper.isPinned(uriFromIndex(0)) && gPanelView._pinHelper.isPinned(uriFromIndex(5)) && gPanelView._pinHelper.isPinned(uriFromIndex(12)) , "Items pinned");
}
});
gTests.push({
desc: "Test history PanelUI delete",
setUp: setup,
tearDown: tearDown,
run: function testHistoryPanelDelete() {
PanelUI.show('history-container');
let restoreButton = document.getElementById("restore-selected-button");
let deleteButton = document.getElementById("delete-selected-button");
// --------- delete item 2
let item = gPanelView._set.getItemsByUrl(uriFromIndex(2))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item = gPanelView._set.getItemsByUrl(uriFromIndex(2))[0];
let startItem = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(!item, "Item is not in grid");
ok(startItem, "Item is not deleted from start grid yet");
ok(HistoryTestHelper._nodes[uriFromIndex(2)], "Item exists");
ok(!restoreButton.hidden, "Restore button is visible.");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
Elements.appbar.dismiss();
yield promise;
item = gPanelView._set.getItemsByUrl(uriFromIndex(2))[0];
startItem = gStartView._set.getItemsByUrl(uriFromIndex(2))[0];
ok(!item, "Item gone from grid");
ok(!startItem, "Item gone from start grid");
ok(!HistoryTestHelper._nodes[uriFromIndex(2)], "Item RIP");
// --------- delete multiple items
let item1 = gPanelView._set.getItemsByUrl(uriFromIndex(0))[0];
let item2 = gPanelView._set.getItemsByUrl(uriFromIndex(5))[0];
let item3 = gPanelView._set.getItemsByUrl(uriFromIndex(12))[0];
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
sendContextMenuClickToElement(window, item1, 10, 10);
sendContextMenuClickToElement(window, item2, 10, 10);
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden);
EventUtils.synthesizeMouse(deleteButton, 10, 10, {}, window);
yield promise;
item1 = gPanelView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gPanelView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gPanelView._set.getItemsByUrl(uriFromIndex(12))[0];
let startItem1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
let startItem2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
let startItem3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(!restoreButton.hidden, "Restore button is visible.");
ok(!item1 && !item2 && !item3, "Items are not in grid");
ok(startItem1 && startItem2 && startItem3, "Items are still in start grid");
ok(HistoryTestHelper._nodes[uriFromIndex(0)] && HistoryTestHelper._nodes[uriFromIndex(5)] && HistoryTestHelper._nodes[uriFromIndex(12)],
"Items not deleted yet");
let promise = waitForEvent(Elements.appbar, "transitionend", null, Elements.appbar);
Elements.appbar.dismiss();
yield promise;
item1 = gPanelView._set.getItemsByUrl(uriFromIndex(0))[0];
item2 = gPanelView._set.getItemsByUrl(uriFromIndex(5))[0];
item3 = gPanelView._set.getItemsByUrl(uriFromIndex(12))[0];
let startItem1 = gStartView._set.getItemsByUrl(uriFromIndex(0))[0];
let startItem2 = gStartView._set.getItemsByUrl(uriFromIndex(5))[0];
let startItem3 = gStartView._set.getItemsByUrl(uriFromIndex(12))[0];
ok(!item1 && !item2 && !item3, "Items are gone from grid");
ok(!startItem1 && !startItem2 && !startItem3, "Items are gone from start grid");
ok(!HistoryTestHelper._nodes[uriFromIndex(0)] && !HistoryTestHelper._nodes[uriFromIndex(5)] && !HistoryTestHelper._nodes[uriFromIndex(12)],
"Items are gone for good");
}
});

Просмотреть файл

@ -158,9 +158,12 @@ function hideContextUI()
purgeEventQueue();
if (ContextUI.isVisible) {
info("is visible, waiting...");
let promise = waitForEvent(Elements.tray, "transitionend");
ContextUI.dismiss();
return promise;
let promise = waitForEvent(Elements.tray, "transitionend", null, Elements.tray);
if (ContextUI.dismiss())
{
return promise;
}
return true;
}
}
@ -230,7 +233,7 @@ function addTab(aUrl) {
* @param aTimeoutMs the number of miliseconds to wait before giving up
* @returns a Promise that resolves to the received event, or to an Error
*/
function waitForEvent(aSubject, aEventName, aTimeoutMs) {
function waitForEvent(aSubject, aEventName, aTimeoutMs, aTarget) {
let eventDeferred = Promise.defer();
let timeoutMs = aTimeoutMs || kDefaultWait;
let timerID = setTimeout(function wfe_canceller() {
@ -239,6 +242,9 @@ function waitForEvent(aSubject, aEventName, aTimeoutMs) {
}, timeoutMs);
function onEvent(aEvent) {
if (aTarget && aTarget !== aEvent.target)
return;
// stop the timeout clock and resume
clearTimeout(timerID);
eventDeferred.resolve(aEvent);
@ -646,19 +652,22 @@ function runTests() {
waitForExplicitFinish();
Task.spawn(function() {
while((gCurrentTest = gTests.shift())){
info("START " + gCurrentTest.desc);
try {
if ('function' == typeof gCurrentTest.setUp) {
info("SETUP " + gCurrentTest.desc);
yield Task.spawn(gCurrentTest.setUp.bind(gCurrentTest));
}
yield Task.spawn(gCurrentTest.run.bind(gCurrentTest));
if ('function' == typeof gCurrentTest.tearDown) {
info("TEARDOWN " + gCurrentTest.desc);
yield Task.spawn(gCurrentTest.tearDown.bind(gCurrentTest));
try {
info("RUN " + gCurrentTest.desc);
yield Task.spawn(gCurrentTest.run.bind(gCurrentTest));
} finally {
if ('function' == typeof gCurrentTest.tearDown) {
info("TEARDOWN " + gCurrentTest.desc);
yield Task.spawn(gCurrentTest.tearDown.bind(gCurrentTest));
}
}
} catch (ex) {
ok(false, "runTests: Task failed - " + ex);
ok(false, "runTests: Task failed - " + ex + ' at ' + ex.stack);
} finally {
info("END " + gCurrentTest.desc);
}