Add wrapper libraries for clipboard and drag and drop.

This commit is contained in:
ben%netscape.com 2000-05-31 12:18:10 +00:00
Родитель 980e8f5eec
Коммит c5894fe52f
8 изменённых файлов: 571 добавлений и 0 удалений

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

@ -40,4 +40,9 @@ tabBindings.xml
treeBindings.xml
xulBindings.xml
xul.css
nsClipboard.js
nsDragAndDrop.js
nsJSSupportsUtils.js
nsTransferable.js
nsJSComponentManager.js

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

@ -84,6 +84,11 @@ CHROME_CONTENT= \
tabBindings.xml \
treeBindings.xml \
xulBindings.xml \
nsClipboard.js \
nsDragAndDrop.js \
nsJSSupportsUtils.js \
nsTransferable.js \
nsJSComponentManager.js\
xul.css \
$(NULL)

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

@ -75,6 +75,11 @@ CHROME_CONTENT= \
.\radioBindings.xml \
.\tabBindings.xml \
.\treeBindings.xml \
.\nsClipboard.js \
.\nsDragAndDrop.js \
.\nsJSSupportsUtils.js \
.\nsTransferable.js \
.\nsJSComponentManager.js \
.\xul.css \
$(NULL)

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

@ -0,0 +1,76 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author:
* Ben Matthew Goodger <ben@netscape.com>
*
* Contributor(s):
*/
/**
* nsClipboard - wrapper around nsIClipboard and nsITransferable
* that simplifies access to the clipboard.
**/
var nsClipboard = {
get mClipboard()
{
return nsJSComponentManager.getService("component://netscape/widget/clipboard",
"nsIClipboard");
},
mCurrentClipboard: null,
/**
* Array/Object read (Object aFlavourList, long aClipboard, Bool aAnyFlag) ;
*
* returns the data in the clipboard
*
* @param Object aFlavourList
* formatted list of desired flavours
* @param long aClipboard
* the clipboard to read data from (kSelectionClipboard/kGlobalClipboard)
* @param Bool aAnyFlag
* should be false.
**/
read: function (aFlavourList, aClipboard, aAnyFlag)
{
this.mCurrentClipboard = aClipboard;
var data = nsTransferable.get(aFlavourList, this.getClipboardTransferable, aAnyFlag);
return data;
},
/**
* nsISupportsArray getClipboardTransferable (Object aFlavourList) ;
*
* returns a nsISupportsArray of the item on the clipboard
*
* @param Object aFlavourList
* formatted list of desired flavours.
**/
getClipboardTransferable: function (aFlavourList)
{
var supportsArray = nsJSSupportsUtils.createSupportsArray();
var trans = nsTransferable.createTransferable();
for (var flavour in aFlavourList)
trans.addDataFlavor(flavour);
nsClipboard.mClipboard.getData(trans, nsClipboard.mCurrentClipboard)
supportsArray.AppendElement(trans);
return supportsArray;
}
};

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

@ -0,0 +1,168 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author:
* Ben Matthew Goodger <ben@netscape.com>
*
* Contributor(s):
*/
/**
* nsDragAndDrop - a convenience wrapper for nsTransferable, nsITransferable
* and nsIDragService/nsIDragSession.
*
* Use: map the handler functions to the 'ondraggesture', 'ondragover' and
* 'ondragdrop' event handlers on your XML element, e.g.
* <xmlelement ondraggesture="nsDragAndDrop.startDrag(event, observer);"
* ondragover="nsDragAndDrop.startDrag(event, observer);"
* ondragdrop="nsDragAndDrop.drop(event, observer);"/>
*
* You need to create an observer js object with the following member
* functions:
* Object onDragStart (event) // called when drag initiated,
* // returns flavour list with data
* // to stuff into transferable
* void onDragOver (Object flavour) // called when element is dragged
* // over, so that it can perform
* // any drag-over feedback for provided
* // flavour
* void onDrop (Object data) // formatted data object dropped.
* Object getSupportedFlavours () // returns a flavour list so that
* // nsTransferable can determine whether
* // or not to accept drop.
**/
var nsDragAndDrop = {
get mDragService()
{
return nsJSComponentManager.getService("component://netscape/widget/dragservice",
"nsIDragService");
},
/**
* void startDrag (DOMEvent aEvent, Object aDragDropObserver) ;
*
* called when a drag on an element is started.
*
* @param DOMEvent aEvent
* the DOM event fired by the drag init
* @param Object aDragDropObserver
* javascript object of format described above that specifies
* the way in which the element responds to drag events.
**/
startDrag: function (aEvent, aDragDropObserver)
{
if (aDragDropObserver.onDragStart)
flavourList = aDragDropObserver.onDragStart(aEvent);
var trans = nsTransferable.set(flavourList);
trans = trans ? trans.QueryInterface(Components.interfaces.nsISupports) : trans;
var transArray = nsJSSupportsUtils.createSupportsArray();
transArray.AppendElement(trans);
var dragServiceIID = Components.interfaces.nsIDragService;
this.mDragService.invokeDragSession(aEvent.target, transArray, null,
dragServiceIID.DRAGDROP_ACTION_COPY + dragServiceIID.DRAGDROP_ACTION_MOVE);
aEvent.preventBubble();
},
/**
* void dragOver (DOMEvent aEvent, Object aDragDropObserver) ;
*
* called when a drag passes over this element
*
* @param DOMEvent aEvent
* the DOM event fired by the drag init
* @param Object aDragDropObserver
* javascript object of format described above that specifies
* the way in which the element responds to drag events.
**/
dragOver: function (aEvent, aDragDropObserver)
{
var dragSession = this.mDragService.getCurrentSession();
if (dragSession)
{
var flavourList = aDragDropObserver.getSupportedFlavours();
for (var flavour in flavourList)
{
if (dragSession.isDataFlavorSupported(flavour))
{
dragSession.canDrop = true;
if (aDragDropObserver.onDragOver)
aDragDropObserver.onDragOver(flavour);
aEvent.preventBubble();
break;
}
}
}
},
mDragSession: null,
/**
* void drop (DOMEvent aEvent, Object aDragDropObserver) ;
*
* called when the user drops on the element
*
* @param DOMEvent aEvent
* the DOM event fired by the drag init
* @param Object aDragDropObserver
* javascript object of format described above that specifies
* the way in which the element responds to drag events.
**/
drop: function (aEvent, aDragDropObserver)
{
this.mDragSession = this.mDragService.getCurrentSession();
if (this.mDragSession)
{
var flavourList = aDragDropObserver.getSupportedFlavours();
var dragData = nsTransferable.get(flavourList, this.getDragData, true);
aEvent.preventBubble();
// hand over to the client to respond to dropped data
if (aDragDropObserver.onDrop)
aDragDropObserver.onDrop(dragData);
}
},
/**
* nsISupportsArray getDragData (Object aFlavourList)
*
* Creates a nsISupportsArray of all droppable items for the given
* set of supported flavours.
*
* @param Object aFlavourList
* formatted flavour list.
**/
getDragData: function (aFlavourList)
{
var supportsArray = nsJSSupportsUtils.createSupportsArray();
for (var i = 0; i < nsDragAndDrop.mDragSession.numDropItems; ++i)
{
var trans = nsTransferable.createTransferable();
for (var flavour in aFlavourList)
trans.addDataFlavor(flavour);
nsDragAndDrop.mDragSession.getData(trans, i);
supportsArray.AppendElement(trans);
}
return supportsArray;
}
};

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

@ -0,0 +1,74 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author:
* Ben Matthew Goodger <ben@netscape.com>
*
* Contributor(s):
*/
var nsJSComponentManager = {
createInstance: function (aProgID, aIID)
{
try
{
var iid = Components.interfaces[aIID];
return Components.classes[aProgID].createInstance(iid);
}
catch(e)
{
}
},
createInstanceByID: function (aID, aIID)
{
try
{
var iid = Components.interfaces[aIID];
return Components.classesByID[aID].createInstance(iid);
}
catch(e)
{
}
},
getService: function (aProgID, aIID)
{
try
{
var iid = Components.interfaces[aIID];
return Components.classes[aProgID].getService(iid);
}
catch(e)
{
}
},
getServiceByID: function (aID, aIID)
{
try
{
var iid = Components.interfaces[aIID];
return Components.classes[aID].getService(iid);
}
catch(e)
{
}
}
};

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

@ -0,0 +1,46 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author:
* Ben Matthew Goodger <ben@netscape.com>
*
* Contributor(s):
*/
var nsJSSupportsUtils = {
createSupportsArray: function ()
{
return nsJSComponentManager.createInstance("component://netscape/supports-array",
"nsISupportsArray");
},
createSupportsWString: function ()
{
return nsJSComponentManager.createInstance("component://netscape/supports-wstring",
"nsISupportsWString");
},
createSupportsString: function ()
{
return nsJSComponentManager.createInstance("component://netscape/supports-string",
"nsISupportsString");
}
};

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

@ -0,0 +1,192 @@
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Original Author:
* Ben Matthew Goodger <ben@netscape.com>
*
* Contributor(s):
*/
/**
* nsTransferable - a wrapper for nsITransferable that simplifies
* javascript clipboard and drag&drop. for use in
* these situations you should use the nsClipboard
* and nsDragAndDrop wrappers for more convenience
**/
var nsTransferable = {
/**
* Flavour List Format:
* flavourList["text/unicode"].width // width of data
* flavourList["text/unicode"].iid // iid of data type
* flavourList["text/unicode"].data // data to be stored (if any)
**/
/**
* nsITransferable set (Object aFlavourList) ;
*
* Creates a transferable with data for a list of supported types ("flavours")
*
* @param Object aFlavourList
* a javascript object in the format described above
**/
set: function (aFlavourList)
{
var trans = this.createTransferable();
for (var flavour in aFlavourList)
{
trans.addDataFlavor(flavour);
var width = aFlavourList[flavour].width;
var wrapper = this.createEmptyWrapper(width);
if (wrapper)
{
wrapper.data = aFlavourList[flavour].data;
trans.setTransferData(flavour, wrapper, wrapper.data.length * width);
}
}
return trans;
},
/**
* Array/Object get (Object aFlavourList, Function aRetrievalFunc, Boolean aAnyFlag) ;
*
* Retrieves data from the transferable provided in aRetrievalFunc, formatted
* for more convenient access.
*
* @param Object aFlavourList
* a javascript object in the format described above
* @param Function aRetrievalFunc
* a reference to a function that returns a nsISupportsArray of nsITransferables
* for each item from the specified source (clipboard/drag&drop etc)
* @param Boolean aAnyFlag
* a flag specifying whether or not a specific flavour is requested. If false,
* data of the type of the first flavour in the flavourlist parameter is returned,
* otherwise the best flavour supported will be returned.
**/
get: function (aFlavourList, aRetrievalFunc, aAnyFlag)
{
var firstFlavour = null;
for (var flavour in aFlavourList)
{
firstFlavour = flavour;
break;
}
if (aRetrievalFunc)
{
var supportsArray = aRetrievalFunc(aFlavourList);
var dataArray = [];
for (var i = 0; i < supportsArray.Count(); i++)
{
trans = supportsArray.GetElementAt(i);
if (trans)
trans = trans.QueryInterface(Components.interfaces.nsITransferable);
var data = { };
var flavour = { };
var length = { };
if (aAnyFlag)
{
trans.getAnyTransferData(flavour, data, length);
if (data && flavour)
{
var selectedFlavour = aFlavourList[flavour.value];
if (selectedFlavour)
{
data = data.value.QueryInterface(Components.interfaces[selectedFlavour.iid]);
var currData =
{
data: { data: data, length: length.value, width: selectedFlavour.width }, // this.wrapData(data.value, length.value, selectedFlavour.width),
flavour: flavour.value
};
if (supportsArray.Count() == 1)
return currData;
else
dataArray[i] = currData;
}
}
dataArray[i] = null;
}
else
{
trans.getTransferData(firstFlavour, data, length);
var currData = data ? this.wrapData(data.value, length.value, aFlavourList[firstFlavour].width) : null;
if (supportsArray.Count() == 1)
return currData;
else
dataArray[i] = currData;
}
}
return dataArray;
}
else
throw "No data retrieval handler provided!";
},
/**
* nsITransferable createTransferable (void) ;
*
* Creates and returns a transferable object.
**/
createTransferable: function ()
{
return nsJSComponentManager.createInstance("component://netscape/widget/transferable",
"nsITransferable");
},
/**
* nsISupports createEmptyWrapper (int aWidth) ;
*
* Creates a wrapper for string data. XXX - this is bad, we're assuming the data we're
* dragging is string.
*
* @param int aWidth
* the width of the data (single or double byte)
**/
createEmptyWrapper: function (aWidth)
{
return aWidth == 2 ? nsJSSupportsUtils.createSupportsWString() :
nsJSSupportsUtils.createSupportsString();
},
/**
* String wrapData (Object aDataObject, int aLength, int aWidth)
*
* Returns the actual string representation of nsISupports[W]String wrapped
* data.
*
* @param Object aDataObject
* the data to be unwrapped
* @param int aLength
* the integer length of the data
* @param int aWidth
* the unit size
**/
wrapData: function (aDataObject, aLength, aWidth)
{
const IID = aWidth == 2 ? Components.interfaces.nsISupportsWString :
Components.interfaces.nsISupportsString;
var data = aDataObject.QueryInterface(IID);
if (data)
return data.data.substring(0, aLength / aWidth);
},
};