fix for bug #387007: with lots of places data on the clipboard, command update is very slow: Places inefficiently determines whether or not it is able to paste patch=Christine Yen <christineyen+bugs@gmail.com> r=sspitzer

This commit is contained in:
sspitzer@mozilla.org 2007-08-11 09:08:52 -07:00
parent 4eac080665
commit e9786b6582

View File

@ -104,7 +104,7 @@ PlacesController.prototype = {
case "cmd_copy": case "cmd_copy":
return this._view.hasSelection; return this._view.hasSelection;
case "cmd_paste": case "cmd_paste":
return this._canInsert() && this._canPaste(); return this._canInsert() && this._isClipboardDataPasteable();
case "cmd_selectAll": case "cmd_selectAll":
if (this._view.selType != "single") { if (this._view.selType != "single") {
var result = this._view.getResult(); var result = this._view.getResult();
@ -381,67 +381,63 @@ PlacesController.prototype = {
} }
return false; return false;
}, },
/** /**
* Looks at the data on the clipboard to see if it is paste-able. * Looks at the data on the clipboard to see if it is paste-able.
* Paste-able data is: * Paste-able data is:
* - in a format that the view can receive * - in a format that the view can receive
* @returns true if the data is paste-able, false if the clipboard data * @returns true if: - clipboard data is of a TYPE_X_MOZ_PLACE_* flavor,
* cannot be pasted - clipboard data is of type TEXT_UNICODE and
is a valid URI.
*/ */
_canPaste: function PC__canPaste() { _isClipboardDataPasteable: function PC__isClipboardDataPasteable() {
var types = this._view.peerDropTypes; // if the clipboard contains TYPE_X_MOZ_PLACE_* data, it is definitely
var flavors = // pasteable, with no need to unwrap all the nodes.
Cc["@mozilla.org/supports-array;1"].
createInstance(Ci.nsISupportsArray); var placeTypes = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
for (var i = 0; i < types.length; ++i) { PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
var cstring = PlacesUtils.TYPE_X_MOZ_PLACE];
Cc["@mozilla.org/supports-cstring;1"]. var flavors = Cc["@mozilla.org/supports-array;1"].
createInstance(Ci.nsISupportsCString); createInstance(Ci.nsISupportsArray);
cstring.data = types[i]; for (var i = 0; i < placeTypes.length; ++i) {
var cstring = Cc["@mozilla.org/supports-cstring;1"].
createInstance(Ci.nsISupportsCString);
cstring.data = placeTypes[i];
flavors.AppendElement(cstring); flavors.AppendElement(cstring);
} }
var clipboard = Cc["@mozilla.org/widget/clipboard;1"].
var clipboard = getService(Ci.nsIClipboard);
Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); var hasPlacesData = clipboard.hasDataMatchingFlavors(flavors,
var hasClipboardData = clipboard.hasDataMatchingFlavors(flavors,
Ci.nsIClipboard.kGlobalClipboard); Ci.nsIClipboard.kGlobalClipboard);
if (!hasClipboardData) if (hasPlacesData)
return false; return this._view.insertionPoint != null;
// if the clipboard doesn't have TYPE_X_MOZ_PLACE_* data, we also allow
// pasting of valid "text/unicode" and "text/x-moz-url" data
var xferable = Cc["@mozilla.org/widget/transferable;1"].
createInstance(Ci.nsITransferable);
// XXX todo xferable.addDataFlavor(PlacesUtils.TYPE_X_MOZ_URL);
// see bug #387007 for an idea on how to make this more efficient xferable.addDataFlavor(PlacesUtils.TYPE_UNICODE);
// right now, we are pulling data off the clipboard and using
// unwrapNodes() to verify it.
var xferable =
Cc["@mozilla.org/widget/transferable;1"].
createInstance(Ci.nsITransferable);
for (var j = 0; j < types.length; ++j) {
xferable.addDataFlavor(types[j]);
}
clipboard.getData(xferable, Ci.nsIClipboard.kGlobalClipboard); clipboard.getData(xferable, Ci.nsIClipboard.kGlobalClipboard);
try { try {
// getAnyTransferData can throw if no data is available. // getAnyTransferData will throw if no data is available.
var data = { }, type = { }; var data = { }, type = { };
xferable.getAnyTransferData(type, data, { }); xferable.getAnyTransferData(type, data, { });
data = data.value.QueryInterface(Ci.nsISupportsString).data; data = data.value.QueryInterface(Ci.nsISupportsString).data;
if (this._view.peerDropTypes.indexOf(type.value) == -1) if (type.value != PlacesUtils.TYPE_X_MOZ_URL &&
type.value != PlacesUtils.TYPE_UNICODE)
return false; return false;
// unwrapNodes() will throw if the data blob is malformed. // unwrapNodes() will throw if the data blob is malformed.
var unwrappedNodes = PlacesUtils.unwrapNodes(data, type.value); var unwrappedNodes = PlacesUtils.unwrapNodes(data, type.value);
return this._view.insertionPoint != null; return this._view.insertionPoint != null;
} }
catch (e) { catch (e) {
// unwrapeNodes() failed, possibly because a field that should have // getAnyTransferData or unwrapNodes failed
// contained a URI did not actually contain something that is
// parse-able as a URI.
return false; return false;
} }
return false;
}, },
/** /**