зеркало из https://github.com/mozilla/gecko-dev.git
315940 - more D&D fixes. makes sure the right elements are selected post drop, fix js errors and save selection. NPOB
This commit is contained in:
Родитель
571c2d267c
Коммит
17846e8ef2
|
@ -87,13 +87,33 @@ function STACK(args) {
|
|||
* The folderId of the parent container
|
||||
* @param index
|
||||
* The index within the container where we should insert
|
||||
* @param orientation
|
||||
* The orientation of the insertion. NOTE: the adjustments to the
|
||||
* insertion point to accommodate the orientation should be done by
|
||||
* the person who constructs the IP, not the user. The orientation
|
||||
* is provided for informational purposes only!
|
||||
* @constructor
|
||||
*/
|
||||
function InsertionPoint(folderId, index) {
|
||||
function InsertionPoint(folderId, index, orientation) {
|
||||
this.folderId = folderId;
|
||||
this.index = index;
|
||||
this.orientation = orientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization Configuration for a View
|
||||
*/
|
||||
function ViewConfig(dropTypes, dropOnTypes, filterOptions, firstDropIndex) {
|
||||
this.dropTypes = dropTypes;
|
||||
this.dropOnTypes = dropOnTypes;
|
||||
this.filterOptions = filterOptions;
|
||||
this.firstDropIndex = firstDropIndex;
|
||||
}
|
||||
ViewConfig.GENERIC_DROP_TYPES = [TYPE_X_MOZ_PLACE_CONTAINER, TYPE_X_MOZ_PLACE,
|
||||
TYPE_X_MOZ_URL];
|
||||
ViewConfig.GENERIC_FILTER_OPTIONS = Ci.nsINavHistoryQuery.INCLUDE_ITEMS +
|
||||
Ci.nsINavHistoryQuery.INCLUDE_QUERIES;
|
||||
|
||||
/**
|
||||
* The Master Places Controller
|
||||
*/
|
||||
|
@ -123,6 +143,45 @@ var PlacesController = {
|
|||
}
|
||||
return this.__hist;
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates a HistoryResult for the contents of a folder.
|
||||
* @param folderId
|
||||
* The folder to open
|
||||
* @param filterOptions
|
||||
* Options regarding the type of items to be returned. See
|
||||
* documentation in nsINavHistoryQuery for the |itemTypes| property.
|
||||
* @returns A HistoryResult containing the contents of the folder.
|
||||
*/
|
||||
getFolderContents: function PC_getFolderContents(folderId, filterOptions) {
|
||||
var query = this._hist.getNewQuery();
|
||||
query.setFolders([folderId], 1);
|
||||
query.itemTypes = filterOptions;
|
||||
var options = this._hist.getNewQueryOptions();
|
||||
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
|
||||
return this._hist.executeQuery(query, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the pivot node for a given insertion point in a container populated
|
||||
* with the specified filter options.
|
||||
* @param insertionPoint
|
||||
* The point at which content is to be inserted
|
||||
* @param filterOptions
|
||||
* Filter options for the view/container. See documentation in
|
||||
* nsINavHistoryQuery for the |itemTypes| property.
|
||||
* @returns A HistoryResultNode at which content is to be inserted.
|
||||
*/
|
||||
getInsertionNode:
|
||||
function PC_getInsertionNode(insertionPoint, filterOptions) {
|
||||
var result = this.getFolderContents(insertionPoint.folderId, filterOptions);
|
||||
var index = insertionPoint.index - 1;
|
||||
if (insertionPoint.index == 0)
|
||||
index = 0;
|
||||
else if (insertionPoint.index == -1)
|
||||
index = result.childCount - 1;
|
||||
return index > -1 ? result.getChild(index) : null;
|
||||
},
|
||||
|
||||
_activeView: null,
|
||||
get activeView() {
|
||||
|
@ -221,8 +280,6 @@ var PlacesController = {
|
|||
* @returns true if the node is a Bookmark folder, false otherwise
|
||||
*/
|
||||
nodeIsFolder: function PC_nodeIsFolder(node) {
|
||||
if (!node)
|
||||
STACK(arguments);
|
||||
return (node.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
|
||||
node.folderId > 0);
|
||||
},
|
||||
|
@ -1009,18 +1066,18 @@ var PlacesControllerDragHelper = {
|
|||
* The AVI-implementing object that received the drop.
|
||||
* @param insertionPoint
|
||||
* The insertion point where the items should be dropped
|
||||
* @param orientation
|
||||
* The orientation of the drop
|
||||
* @param visibleInsertCount
|
||||
* The number of visible items to be inserted. This can be zero
|
||||
* even when items are dropped because this is how many items will
|
||||
* be _visible_ in the resulting tree.
|
||||
*/
|
||||
onDrop: function PCDH_onDrop(sourceView, targetView, insertionPoint,
|
||||
orientation) {
|
||||
visibleInsertCount) {
|
||||
var session = this._getSession();
|
||||
if (!session)
|
||||
return;
|
||||
|
||||
var copy = session.dragAction & Ci.nsIDragService.DRAGDROP_ACTION_COPY;
|
||||
var transactions = [];
|
||||
var xferable = this._initTransferable(targetView, orientation);
|
||||
var xferable = this._initTransferable(targetView,
|
||||
insertionPoint.orientation);
|
||||
var dropCount = session.numDropItems;
|
||||
for (var i = 0; i < dropCount; ++i) {
|
||||
session.getData(xferable, i);
|
||||
|
@ -1048,8 +1105,9 @@ var PlacesControllerDragHelper = {
|
|||
if (sourceView)
|
||||
sourceView.willReloadView(RELOAD_ACTION_REMOVE, sourceView, null,
|
||||
dropCount);
|
||||
PlacesController.willReloadView(RELOAD_ACTION_INSERT, targetView,
|
||||
insertionPoint, dropCount);
|
||||
var action = visibleInsertCount == 0 ? RELOAD_ACTION_NOTHING
|
||||
: RELOAD_ACTION_INSERT;
|
||||
targetView.willReloadView(action, targetView, insertionPoint, dropCount);
|
||||
}
|
||||
var txn = new PlacesAggregateTransaction("DropItems", transactions);
|
||||
PlacesController._hist.transactionManager.doTransaction(txn);
|
||||
|
|
|
@ -94,6 +94,17 @@ var PlacesUIHook = {
|
|||
},
|
||||
};
|
||||
|
||||
function ViewConfig(dropTypes, dropOnTypes, filterOptions, firstDropIndex) {
|
||||
this.dropTypes = dropTypes;
|
||||
this.dropOnTypes = dropOnTypes;
|
||||
this.filterOptions = filterOptions;
|
||||
this.firstDropIndex = firstDropIndex;
|
||||
}
|
||||
ViewConfig.GENERIC_DROP_TYPES = [TYPE_X_MOZ_PLACE_CONTAINER, TYPE_X_MOZ_PLACE,
|
||||
TYPE_X_MOZ_URL];
|
||||
ViewConfig.GENERIC_FILTER_OPTIONS = [Ci.nsINavHistoryQuery.INCLUDE_ITEMS +
|
||||
Ci.nsINavHistoryQuery.INCLUDE_QUERIES];
|
||||
|
||||
var PlacesPage = {
|
||||
_content: null,
|
||||
_places: null,
|
||||
|
@ -105,17 +116,13 @@ var PlacesPage = {
|
|||
this._places.controllers.appendController(PlacesController);
|
||||
this._content.controllers.appendController(PlacesController);
|
||||
|
||||
this._places.supportedDropTypes = [TYPE_X_MOZ_PLACE_CONTAINER];
|
||||
this._places.supportedDropOnTypes = [TYPE_X_MOZ_PLACE_CONTAINER,
|
||||
TYPE_X_MOZ_PLACE, TYPE_X_MOZ_URL];
|
||||
this._content.supportedDropTypes = [TYPE_X_MOZ_PLACE_CONTAINER,
|
||||
TYPE_X_MOZ_PLACE, TYPE_X_MOZ_URL];
|
||||
this._content.supportedDropOnTypes = this._content.supportedDropTypes;
|
||||
this._places.filterOptions = [Ci.nsINavHistoryQuery.INCLUDE_QUERIES];
|
||||
this._content.filterOptions = [Ci.nsINavHistoryQuery.INCLUDE_ITEMS +
|
||||
Ci.nsINavHistoryQuery.INCLUDE_QUERIES];
|
||||
this._places.firstDropIndex = 2;
|
||||
this._content.firstDropIndex = 0;
|
||||
this._places.init(new ViewConfig([TYPE_X_MOZ_PLACE_CONTAINER],
|
||||
ViewConfig.GENERIC_DROP_TYPES,
|
||||
Ci.nsINavHistoryQuery.INCLUDE_QUERIES,
|
||||
ViewConfig.GENERIC_FILTER_OPTIONS, 2));
|
||||
this._content.init(new ViewConfig(ViewConfig.GENERIC_DROP_TYPES,
|
||||
ViewConfig.GENERIC_DROP_TYPES,
|
||||
ViewConfig.GENERIC_FILTER_OPTIONS, 0));
|
||||
|
||||
// Hook the browser UI
|
||||
PlacesUIHook.init(this._content);
|
||||
|
|
|
@ -38,6 +38,16 @@
|
|||
PlacesController.removeViewObserver(this);
|
||||
]]></destructor>
|
||||
|
||||
<method name="init">
|
||||
<parameter name="viewConfig"/>
|
||||
<body><![CDATA[
|
||||
this.supportedDropTypes = viewConfig.dropTypes;
|
||||
this.supportedDropOnTypes = viewConfig.dropOnTypes;
|
||||
this.filterOptions = viewConfig.filterOptions;
|
||||
this.firstDropIndex = viewConfig.firstDropIndex;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_fireEvent">
|
||||
<parameter name="name"/>
|
||||
<body><![CDATA[
|
||||
|
@ -202,14 +212,8 @@
|
|||
var min = { }, max = { };
|
||||
selection.getRangeAt(i, min, max);
|
||||
|
||||
try {
|
||||
for (var j = min.value; j <= max.value; ++j)
|
||||
nodes.push(result.nodeForTreeIndex(j));
|
||||
}
|
||||
catch (e) {
|
||||
LOG("j = " + j + ", max.value = " + max.value);
|
||||
STACK(arguments);
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
]]></body>
|
||||
|
@ -265,7 +269,13 @@
|
|||
var min = { }, max = { };
|
||||
selection.getRangeAt(rc - 1, min, max);
|
||||
|
||||
return this._getInsertionPoint(max.value, 1);
|
||||
const DROP_AFTER = Ci.nsINavHistoryResultViewObserver.DROP_AFTER;
|
||||
const DROP_ON = Ci.nsINavHistoryResultViewObserver.DROP_ON;
|
||||
var orientation = DROP_AFTER;
|
||||
if (this.view.isContainer(max.value) &&
|
||||
this.view.isContainerOpen(max.value))
|
||||
orientation = DROP_ON;
|
||||
return this._getInsertionPoint(max.value, 1, orientation);
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
|
@ -299,7 +309,7 @@
|
|||
index = orientation == NHRVO.DROP_BEFORE ? lsi - 1 : lsi;
|
||||
}
|
||||
}
|
||||
return new InsertionPoint(container.folderId, index);
|
||||
return new InsertionPoint(container.folderId, index, orientation);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -307,7 +317,7 @@
|
|||
<property name="browserWindow" onget="return this._browserWindow"/>
|
||||
|
||||
<!-- AVI Method -->
|
||||
<field name="firstDropIndex">null</field>
|
||||
<field name="firstDropIndex">0</field>
|
||||
|
||||
<!-- AVI Method -->
|
||||
<field name="supportedDropTypes">null</field>
|
||||
|
@ -315,6 +325,12 @@
|
|||
<!-- AVI Method -->
|
||||
<field name="supportedDropOnTypes">null</field>
|
||||
|
||||
<!-- AVI Method -->
|
||||
<field name="filterOptions">null</field>
|
||||
|
||||
<!-- AVI Method -->
|
||||
<field name="dropOnFilterOptions">null</field>
|
||||
|
||||
<!-- AVI Method -->
|
||||
<method name="selectAll">
|
||||
<body><![CDATA[
|
||||
|
@ -373,12 +389,21 @@
|
|||
while (sourceView && sourceView.localName != "tree")
|
||||
sourceView = sourceView.parentNode;
|
||||
|
||||
// Determine how many items will be visible in the target view after
|
||||
// the drop operation completes. This can be zero if all items are
|
||||
// dropped into a closed folder.
|
||||
var visibleInsertCount = session.numDropItems;
|
||||
if (orientation == Ci.nsINavHistoryResultViewObserver.DROP_ON &&
|
||||
this._self.view.isContainer(index) &&
|
||||
!this._self.view.isContainerOpen(index))
|
||||
visibleInsertCount = 0;
|
||||
|
||||
// We are responsible for translating the |index| and |orientation|
|
||||
// parameters into a container id and index within the container,
|
||||
// since this information is specific to the tree view.
|
||||
var ip = this._self._getInsertionPoint(index, orientation);
|
||||
PlacesControllerDragHelper.onDrop(sourceView, this._self, ip,
|
||||
orientation);
|
||||
visibleInsertCount);
|
||||
},
|
||||
|
||||
_states: { },
|
||||
|
@ -470,6 +495,7 @@
|
|||
if (view != this)
|
||||
action = RELOAD_ACTION_NOTHING;
|
||||
|
||||
const NHRVO = Ci.nsINavHistoryResultViewObserver;
|
||||
switch (action) {
|
||||
case RELOAD_ACTION_NOTHING:
|
||||
for (var i = 0; i < rc; ++i) {
|
||||
|
@ -479,42 +505,42 @@
|
|||
}
|
||||
break;
|
||||
case RELOAD_ACTION_MOVE:
|
||||
// Drop before selection A
|
||||
// Drop in selection B
|
||||
// Drop after selection C
|
||||
//
|
||||
// Drop Point: Index Computation:
|
||||
// Before Selection index
|
||||
// Inside Selection
|
||||
// After Selection index
|
||||
|
||||
// Insert index of insertion and number of rows to insert
|
||||
var query = this._places.getNewQuery();
|
||||
query.setFolders([insertionPoint.folderId], 1);
|
||||
query.itemTypes = this.filterOptions;
|
||||
var options = this._places.getNewQueryOptions();
|
||||
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
|
||||
var result = this._places.executeQuery(query, options);
|
||||
if (insertionPoint.index > -1) {
|
||||
var node = result.getChild(insertionPoint.index - 1);
|
||||
var index = this.getResult().treeIndexForNode(node);
|
||||
if (insertionPoint.index == result.childCount)
|
||||
++index;
|
||||
}
|
||||
else
|
||||
index = this.getResult().childCount;
|
||||
var filterOptions = this.filterOptions;
|
||||
if (insertionPoint.orientation == NHRVO.DROP_ON)
|
||||
filterOptions = ViewConfig.GENERIC_FILTER_OPTIONS;
|
||||
var result = PlacesController.getFolderContents(insertionPoint.folderId,
|
||||
filterOptions);
|
||||
var node = null;
|
||||
if (insertionPoint.index > -1)
|
||||
node = result.getChild(insertionPoint.index - 1);
|
||||
else
|
||||
node = result.getChild(result.childCount - 1);
|
||||
var index = this.getResult().treeIndexForNode(node);
|
||||
var max = index + count - 1;
|
||||
this._selection = [{ min: index, max: max }];
|
||||
break;
|
||||
case RELOAD_ACTION_INSERT:
|
||||
// Insert index of insertion and number of rows to insert
|
||||
var query = this._places.getNewQuery();
|
||||
query.setFolders([insertionPoint.folderId], 1);
|
||||
query.itemTypes = this.filterOptions;
|
||||
var options = this._places.getNewQueryOptions();
|
||||
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
|
||||
var result = this._places.executeQuery(query, options);
|
||||
if (insertionPoint.index > -1) {
|
||||
var node = result.getChild(insertionPoint.index - 1);
|
||||
var index = this.getResult().treeIndexForNode(node);
|
||||
if (insertionPoint.index == result.childCount)
|
||||
++index;
|
||||
}
|
||||
var filterOptions = this.filterOptions;
|
||||
if (insertionPoint.orientation == NHRVO.DROP_ON)
|
||||
filterOptions = ViewConfig.GENERIC_FILTER_OPTIONS;
|
||||
var node = PlacesController.getInsertionNode(insertionPoint,
|
||||
filterOptions);
|
||||
var index = this.getResult().treeIndexForNode(node);
|
||||
if (insertionPoint.index == 0)
|
||||
this._selection = [{ min: index, max: index + count - 1 }];
|
||||
else
|
||||
index = this.getResult().childCount;
|
||||
var max = index + count - 1;
|
||||
this._selection = [{ min: index, max: max }];
|
||||
this._selection = [{ min: index + 1, max: index + count }];
|
||||
break;
|
||||
case RELOAD_ACTION_REMOVE:
|
||||
min = { }, max = { };
|
||||
|
|
Загрузка…
Ссылка в новой задаче