mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Remove some knowledge about drag-drop innards from nsFrame.cpp by refactoring
shared code into utility methods in nsContentUtils. Use the new methods to fix up nsContentAreaDragAndDrop to make it possible to drag image <objects> and image inputs. Bug 251775 and bug 244859, r=biesi, sr=jst
This commit is contained in:
parent
a58e66f6ff
commit
e628e82cc1
@ -69,6 +69,8 @@ class imgIRequest;
|
||||
class imgILoader;
|
||||
class nsIPrefBranch;
|
||||
class nsIPref;
|
||||
class nsIImage;
|
||||
class nsIImageLoadingContent;
|
||||
|
||||
class nsContentUtils
|
||||
{
|
||||
@ -334,6 +336,57 @@ public:
|
||||
PRInt32 aLoadFlags,
|
||||
imgIRequest** aRequest);
|
||||
|
||||
/**
|
||||
* Method to get an nsIImage from an image loading content
|
||||
*
|
||||
* @param aContent The image loading content. Must not be null.
|
||||
* @return the nsIImage corresponding to the first frame of the image
|
||||
*/
|
||||
static already_AddRefed<nsIImage> GetImageFromContent(nsIImageLoadingContent* aContent);
|
||||
|
||||
/**
|
||||
* Method that decides whether a content node is draggable
|
||||
*
|
||||
* @param aContent The content node to test.
|
||||
* @return whether it's draggable
|
||||
*/
|
||||
static PRBool ContentIsDraggable(nsIContent* aContent) {
|
||||
return IsDraggableImage(aContent) || IsDraggableLink(aContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method that decides whether a content node is a draggable image
|
||||
*
|
||||
* @param aContent The content node to test.
|
||||
* @return whether it's a draggable image
|
||||
*/
|
||||
static PRBool IsDraggableImage(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Method that decides whether a content node is a draggable link
|
||||
*
|
||||
* @param aContent The content node to test.
|
||||
* @return whether it's a draggable link
|
||||
*/
|
||||
static PRBool IsDraggableLink(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Method that gets the URI of the link content. If the content
|
||||
* isn't a link, return null.
|
||||
*
|
||||
* @param aContent The link content
|
||||
* @return the URI the link points to
|
||||
*/
|
||||
static already_AddRefed<nsIURI> GetLinkURI(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Method that gets the XLink uri for a content node, if it's an XLink
|
||||
*
|
||||
* @param aContent The content node, possibly an XLink
|
||||
* @return Null if aContent is not an XLink, the URI it points to otherwise
|
||||
*/
|
||||
static already_AddRefed<nsIURI> GetXLinkURI(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Convenience method to create a new nodeinfo that differs only by name
|
||||
* from aNodeInfo.
|
||||
|
@ -45,7 +45,6 @@ class nsISelection;
|
||||
class nsIDocument;
|
||||
class nsIImageLoadingContent;
|
||||
class nsIContent;
|
||||
class nsIImage;
|
||||
class nsITransferable;
|
||||
|
||||
class nsCopySupport
|
||||
@ -63,12 +62,6 @@ class nsCopySupport
|
||||
static nsresult GetContents(const nsACString& aMimeType, PRUint32 aFlags, nsISelection *aSel, nsIDocument *aDoc, nsAString& outdata);
|
||||
|
||||
static nsresult ImageCopy(nsIImageLoadingContent* imageElement, PRInt16 aClipboardID);
|
||||
|
||||
protected:
|
||||
|
||||
// these are ripped from nsContentAreaDragDrop. This so needs factoring.
|
||||
static nsresult GetImageFromDOMNode(nsIImageLoadingContent* inNode, nsIImage**outImage);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -62,12 +62,8 @@
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsIDOMHTMLLinkElement.h"
|
||||
#include "nsIDOMHTMLAreaElement.h"
|
||||
#include "nsIDOMHTMLImageElement.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIDOMHTMLBodyElement.h"
|
||||
#include "nsIDOMHTMLHtmlElement.h"
|
||||
#include "nsITransferable.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIDragSession.h"
|
||||
@ -96,14 +92,11 @@
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsRange.h"
|
||||
#include "nsIWebBrowserPersist.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
// private clipboard data flavors for html copy, used by editor when pasting
|
||||
#define kHTMLContext "text/_moz_htmlcontext"
|
||||
@ -136,10 +129,9 @@ private:
|
||||
nsresult ConvertStringsToTransferable(nsITransferable** outTrans);
|
||||
static nsresult GetDraggableSelectionData(nsISelection* inSelection, nsIDOMNode* inRealTargetNode,
|
||||
nsIDOMNode **outImageOrLinkNode, PRBool* outDragSelectedText);
|
||||
static void FindParentLinkNode(nsIDOMNode* inNode, nsIDOMNode** outParent);
|
||||
static already_AddRefed<nsIDOMNode> FindParentLinkNode(nsIDOMNode* inNode);
|
||||
static void GetAnchorURL(nsIDOMNode* inNode, nsAString& outURL);
|
||||
static void GetNodeString(nsIDOMNode* inNode, nsAString & outNodeString);
|
||||
static nsresult GetImageFromDOMNode(nsIDOMNode* inNode, nsIImage** outImage);
|
||||
static void CreateLinkText(const nsAString& inURL, const nsAString & inText,
|
||||
nsAString& outLinkText);
|
||||
static void GetSelectedLink(nsISelection* inSelection, nsIDOMNode **outLinkNode);
|
||||
@ -856,79 +848,25 @@ mFlavorDataProvider(inFlavorDataProvider)
|
||||
//
|
||||
// FindParentLinkNode
|
||||
//
|
||||
// Finds the parent with the given link tag starting at |inNode|. If it gets
|
||||
// up to <body> or <html> or the top document w/out finding it, we
|
||||
// stop looking and |outParent| will be null.
|
||||
// Finds the parent with the given link tag starting at |inNode|. If
|
||||
// it gets up to the root without finding it, we stop looking and
|
||||
// return null.
|
||||
//
|
||||
void
|
||||
nsTransferableFactory::FindParentLinkNode(nsIDOMNode* inNode,
|
||||
nsIDOMNode** outParent)
|
||||
already_AddRefed<nsIDOMNode>
|
||||
nsTransferableFactory::FindParentLinkNode(nsIDOMNode* inNode)
|
||||
{
|
||||
if ( !inNode || !outParent )
|
||||
return;
|
||||
*outParent = nsnull;
|
||||
nsCOMPtr<nsIDOMNode> node(inNode); // to make refcounting easier
|
||||
|
||||
PRUint16 nodeType = 0;
|
||||
inNode->GetNodeType(&nodeType);
|
||||
if ( nodeType == nsIDOMNode::TEXT_NODE )
|
||||
inNode->GetParentNode(getter_AddRefs(node));
|
||||
|
||||
static NS_NAMED_LITERAL_STRING(document, "#document");
|
||||
static NS_NAMED_LITERAL_STRING(simple, "simple");
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(inNode));
|
||||
if (!content) {
|
||||
// That must have been the document node; nothing else to do here;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
while ( node ) {
|
||||
// (X)HTML body or html?
|
||||
node->GetNodeType(&nodeType);
|
||||
if ( nodeType == nsIDOMNode::ELEMENT_NODE ) {
|
||||
// body?
|
||||
nsCOMPtr<nsIDOMHTMLBodyElement> body(do_QueryInterface(node));
|
||||
if (body) {
|
||||
return;
|
||||
}
|
||||
|
||||
// html?
|
||||
nsCOMPtr<nsIDOMHTMLHtmlElement> html(do_QueryInterface(node));
|
||||
if (html) {
|
||||
return;
|
||||
}
|
||||
for ( ; content; content = content->GetParent()) {
|
||||
if (nsContentUtils::IsDraggableLink(content)) {
|
||||
nsIDOMNode* node = nsnull;
|
||||
CallQueryInterface(content, &node);
|
||||
return node;
|
||||
}
|
||||
|
||||
// Other document root?
|
||||
nsAutoString localName;
|
||||
node->GetLocalName(localName);
|
||||
if ( localName.IsEmpty() )
|
||||
return;
|
||||
if ( localName.Equals(document, nsCaseInsensitiveStringComparator()) )
|
||||
return; // XXX Check if #document always lower case
|
||||
|
||||
if ( nodeType == nsIDOMNode::ELEMENT_NODE ) {
|
||||
PRBool found = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> a(do_QueryInterface(node));
|
||||
if (a) {
|
||||
found = PR_TRUE;
|
||||
} else {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
||||
NS_WARN_IF_FALSE(content, "DOM node is not content?");
|
||||
if (!content)
|
||||
return;
|
||||
nsAutoString value;
|
||||
content->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::type, value);
|
||||
if (value.Equals(simple)) {
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
*outParent = node;
|
||||
NS_ADDREF(*outParent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// keep going, up to parent
|
||||
nsIDOMNode* temp;
|
||||
node->GetParentNode(&temp);
|
||||
node = dont_AddRef(temp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -943,47 +881,20 @@ void
|
||||
nsTransferableFactory::GetAnchorURL(nsIDOMNode* inNode, nsAString& outURL)
|
||||
{
|
||||
outURL.Truncate();
|
||||
|
||||
// a?
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(inNode));
|
||||
if ( anchor ) {
|
||||
anchor->GetHref(outURL);
|
||||
if ( outURL.IsEmpty() )
|
||||
anchor->GetName(outURL);
|
||||
} else {
|
||||
// area?
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(inNode));
|
||||
if ( area ) {
|
||||
area->GetHref(outURL);
|
||||
if ( outURL.IsEmpty() ) {
|
||||
nsCOMPtr<nsIDOMHTMLElement> e(do_QueryInterface(inNode));
|
||||
e->GetId(outURL);
|
||||
}
|
||||
} else {
|
||||
// Try XLink next...
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(inNode));
|
||||
nsAutoString value;
|
||||
content->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::type, value);
|
||||
if (value.EqualsLiteral("simple")) {
|
||||
content->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, value);
|
||||
if (!value.IsEmpty()) {
|
||||
nsCOMPtr<nsIURI> baseURI = content->GetBaseURI();
|
||||
if (baseURI) {
|
||||
nsCAutoString absoluteSpec;
|
||||
baseURI->Resolve(NS_ConvertUCS2toUTF8(value), absoluteSpec);
|
||||
CopyUTF8toUTF16(absoluteSpec, outURL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// ... or just get the ID
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(inNode));
|
||||
nsCOMPtr<nsIAtom> id;
|
||||
if (xml && NS_SUCCEEDED(xml->GetID(getter_AddRefs(id))) && id) {
|
||||
id->ToString(outURL);
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(inNode));
|
||||
if (!content) {
|
||||
// Not a link
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> linkURI = nsContentUtils::GetLinkURI(content);
|
||||
if (!linkURI) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCAutoString spec;
|
||||
linkURI->GetSpec(spec);
|
||||
CopyUTF8toUTF16(spec, outURL);
|
||||
}
|
||||
|
||||
|
||||
@ -1090,15 +1001,18 @@ nsTransferableFactory::Produce(nsITransferable** outTrans)
|
||||
|
||||
// only drag form elements by using the alt key,
|
||||
// otherwise buttons and select widgets are hard to use
|
||||
|
||||
// Note that while <object> elements implement nsIFormControl, we should
|
||||
// really allow dragging them if they happen to be images.
|
||||
nsCOMPtr<nsIFormControl> form(do_QueryInterface(target));
|
||||
if (form && !isAltKeyDown)
|
||||
if (form && !isAltKeyDown && form->GetType() != NS_FORM_OBJECT)
|
||||
return NS_OK;
|
||||
|
||||
draggedNode = do_QueryInterface(target);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area; // client-side image map
|
||||
nsCOMPtr<nsIDOMHTMLImageElement> image;
|
||||
nsCOMPtr<nsIImageLoadingContent> image;
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> link;
|
||||
|
||||
{
|
||||
@ -1137,7 +1051,7 @@ nsTransferableFactory::Produce(nsITransferable** outTrans)
|
||||
|
||||
// if the alt key is down, don't start a drag if we're in an anchor because
|
||||
// we want to do selection.
|
||||
FindParentLinkNode(draggedNode, getter_AddRefs(parentLink));
|
||||
parentLink = FindParentLinkNode(draggedNode);
|
||||
if (parentLink && isAltKeyDown)
|
||||
return NS_OK;
|
||||
|
||||
@ -1173,8 +1087,19 @@ nsTransferableFactory::Produce(nsITransferable** outTrans)
|
||||
mIsAnchor = PR_TRUE;
|
||||
// grab the href as the url, use alt text as the title of the area if it's there.
|
||||
// the drag data is the image tag and src attribute.
|
||||
image->GetSrc(mUrlString);
|
||||
image->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
|
||||
nsCOMPtr<nsIURI> imageURI;
|
||||
image->GetCurrentURI(getter_AddRefs(imageURI));
|
||||
if (imageURI) {
|
||||
nsCAutoString spec;
|
||||
imageURI->GetSpec(spec);
|
||||
CopyUTF8toUTF16(spec, mUrlString);
|
||||
}
|
||||
nsCOMPtr<nsIDOMElement> imageElement(do_QueryInterface(image));
|
||||
// XXXbz Shouldn't we use the "title" attr for title? Using
|
||||
// "alt" seems very wrong....
|
||||
if (imageElement) {
|
||||
imageElement->GetAttribute(NS_LITERAL_STRING("alt"), mTitleString);
|
||||
}
|
||||
if (mTitleString.IsEmpty())
|
||||
mTitleString = mUrlString;
|
||||
|
||||
@ -1182,7 +1107,7 @@ nsTransferableFactory::Produce(nsITransferable** outTrans)
|
||||
mImageSourceString = mUrlString;
|
||||
|
||||
// also grab the image data
|
||||
GetImageFromDOMNode(draggedNode, getter_AddRefs(mImage));
|
||||
mImage = nsContentUtils::GetImageFromContent(image);
|
||||
|
||||
if (parentLink)
|
||||
{
|
||||
@ -1411,11 +1336,8 @@ nsresult nsTransferableFactory::GetDraggableSelectionData(nsISelection* inSelect
|
||||
selStartContent->GetChildAt(childOffset);
|
||||
// if we find an image, we'll fall into the node-dragging code,
|
||||
// rather the the selection-dragging code
|
||||
nsCOMPtr<nsIDOMHTMLImageElement> selectedImage =
|
||||
do_QueryInterface(childContent);
|
||||
if (selectedImage)
|
||||
{
|
||||
CallQueryInterface(selectedImage, outImageOrLinkNode); // addrefs
|
||||
if (nsContentUtils::IsDraggableImage(childContent)) {
|
||||
CallQueryInterface(childContent, outImageOrLinkNode); // addrefs
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
@ -1450,10 +1372,9 @@ void nsTransferableFactory::GetSelectedLink(nsISelection* inSelection,
|
||||
|
||||
if (selectionStart == selectionEnd)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> link;
|
||||
FindParentLinkNode(selectionStart, getter_AddRefs(link));
|
||||
nsCOMPtr<nsIDOMNode> link = FindParentLinkNode(selectionStart);
|
||||
if (link)
|
||||
NS_IF_ADDREF(*outLinkNode = link);
|
||||
link.swap(*outLinkNode);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1534,12 +1455,10 @@ void nsTransferableFactory::GetSelectedLink(nsISelection* inSelection,
|
||||
|
||||
// see if the leading & trailing nodes are part of the
|
||||
// same anchor - if so, return the anchor node
|
||||
nsCOMPtr<nsIDOMNode> link;
|
||||
FindParentLinkNode(selectionStart, getter_AddRefs(link));
|
||||
nsCOMPtr<nsIDOMNode> link = FindParentLinkNode(selectionStart);
|
||||
if (link)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> link2;
|
||||
FindParentLinkNode(selectionEnd, getter_AddRefs(link2));
|
||||
nsCOMPtr<nsIDOMNode> link2 = FindParentLinkNode(selectionEnd);
|
||||
if (link == link2)
|
||||
NS_IF_ADDREF(*outLinkNode = link);
|
||||
}
|
||||
@ -1618,50 +1537,3 @@ nsTransferableFactory::SerializeNodeOrSelection(serializationMode inMode, PRUint
|
||||
return encoder->EncodeToStringWithContext(outResultString, outContext, outInfo);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// GetImage
|
||||
//
|
||||
// Given a dom node that's an image, finds the nsIImage associated with it.
|
||||
//
|
||||
nsresult
|
||||
nsTransferableFactory::GetImageFromDOMNode(nsIDOMNode* inNode, nsIImage**outImage)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(outImage);
|
||||
*outImage = nsnull;
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(inNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imgRequest));
|
||||
if (!imgRequest) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
|
||||
if (!imgContainer) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetFrameAt(0, getter_AddRefs(imgFrame));
|
||||
|
||||
if (!imgFrame) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(imgFrame);
|
||||
|
||||
if (!ir) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return CallGetInterface(ir.get(), outImage);
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,14 @@
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "imgIDecoderObserver.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgILoader.h"
|
||||
#include "nsIImage.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsDOMString.h"
|
||||
@ -1702,6 +1709,119 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
||||
aRequest);
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsIImage>
|
||||
nsContentUtils::GetImageFromContent(nsIImageLoadingContent* aContent)
|
||||
{
|
||||
NS_ENSURE_TRUE(aContent, nsnull);
|
||||
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
aContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imgRequest));
|
||||
if (!imgRequest) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
|
||||
if (!imgContainer) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetFrameAt(0, getter_AddRefs(imgFrame));
|
||||
|
||||
if (!imgFrame) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(imgFrame);
|
||||
|
||||
if (!ir) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIImage* image = nsnull;
|
||||
CallGetInterface(ir.get(), &image);
|
||||
return image;
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsContentUtils::IsDraggableImage(nsIContent* aContent)
|
||||
{
|
||||
NS_PRECONDITION(aContent, "Must have content node to test");
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> imageContent(do_QueryInterface(aContent));
|
||||
if (!imageContent) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
imageContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imgRequest));
|
||||
|
||||
// XXXbz It may be draggable even if the request resulted in an error. Why?
|
||||
// Not sure; that's what the old nsContentAreaDragDrop/nsFrame code did.
|
||||
return imgRequest != nsnull;
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsContentUtils::IsDraggableLink(nsIContent* aContent) {
|
||||
nsCOMPtr<nsIURI> linkURI = GetLinkURI(aContent);
|
||||
|
||||
// Does it have a URI? If not, it's not draggable
|
||||
return linkURI != nsnull;
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsIURI>
|
||||
nsContentUtils::GetLinkURI(nsIContent* aContent)
|
||||
{
|
||||
NS_PRECONDITION(aContent, "Must have content node to work with");
|
||||
|
||||
nsCOMPtr<nsILink> link(do_QueryInterface(aContent));
|
||||
if (link) {
|
||||
nsIURI* uri = nsnull;
|
||||
link->GetHrefURI(&uri);
|
||||
if (uri) {
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
// It could still be an XLink
|
||||
return GetXLinkURI(aContent);
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<nsIURI>
|
||||
nsContentUtils::GetXLinkURI(nsIContent* aContent)
|
||||
{
|
||||
NS_PRECONDITION(aContent, "Must have content node to work with");
|
||||
|
||||
nsAutoString value;
|
||||
aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::type, value);
|
||||
if (value.EqualsLiteral("simple")) {
|
||||
// Check that we have a URI
|
||||
aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, value);
|
||||
|
||||
if (!value.IsEmpty()) {
|
||||
// Resolve it relative to aContent's base URI.
|
||||
nsCOMPtr<nsIURI> baseURI = aContent->GetBaseURI();
|
||||
|
||||
nsIURI* uri = nsnull;
|
||||
nsContentUtils::NewURIWithDocumentCharset(&uri, value,
|
||||
aContent->GetDocument(),
|
||||
baseURI);
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// static
|
||||
nsAdoptingCString
|
||||
nsContentUtils::GetCharPref(const char *aPref)
|
||||
|
@ -61,12 +61,9 @@
|
||||
|
||||
// image copy stuff
|
||||
#include "nsIImageLoadingContent.h"
|
||||
#include "imgIContainer.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
||||
@ -367,9 +364,7 @@ nsCopySupport::ImageCopy(nsIImageLoadingContent* imageElement, PRInt16 aClipboar
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIImage> image;
|
||||
rv = GetImageFromDOMNode(imageElement, getter_AddRefs(image));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIImage> image = nsContentUtils::GetImageFromContent(imageElement);
|
||||
if (!image) return NS_ERROR_FAILURE;
|
||||
|
||||
// Get the Clipboard
|
||||
@ -392,48 +387,3 @@ nsCopySupport::ImageCopy(nsIImageLoadingContent* imageElement, PRInt16 aClipboar
|
||||
// put the transferable on the clipboard
|
||||
return clipboard->SetData(trans, nsnull, aClipboardID);
|
||||
}
|
||||
|
||||
//
|
||||
// GetImage
|
||||
//
|
||||
// Given a dom node that's an image, finds the nsIImage associated with it.
|
||||
//
|
||||
// XXX see also nsContentAreaDragDrop, and factor!
|
||||
nsresult
|
||||
nsCopySupport::GetImageFromDOMNode(nsIImageLoadingContent* content, nsIImage**outImage)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(outImage);
|
||||
*outImage = nsnull;
|
||||
|
||||
nsCOMPtr<imgIRequest> imgRequest;
|
||||
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
|
||||
getter_AddRefs(imgRequest));
|
||||
if (!imgRequest) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<imgIContainer> imgContainer;
|
||||
imgRequest->GetImage(getter_AddRefs(imgContainer));
|
||||
|
||||
if (!imgContainer) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<gfxIImageFrame> imgFrame;
|
||||
imgContainer->GetFrameAt(0, getter_AddRefs(imgFrame));
|
||||
|
||||
if (!imgFrame) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_QueryInterface(imgFrame);
|
||||
|
||||
if (!ir) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return CallGetInterface(ir.get(), outImage);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
// XXX This is here because nsCachedStyleData is accessed outside of
|
||||
// the content module; e.g., by nsCSSFrameConstructor.
|
||||
@ -483,22 +484,8 @@ PRBool nsStyleUtil::IsSimpleXlink(nsIContent *aContent, nsIPresContext *aPresCon
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val.EqualsLiteral("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
// is it bad to re-use val here?
|
||||
aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, val);
|
||||
|
||||
// It's an XLink. Resolve it relative to aContent's base URI.
|
||||
nsCOMPtr<nsIURI> baseURI = aContent->GetBaseURI();
|
||||
|
||||
nsCOMPtr<nsIURI> absURI;
|
||||
// XXX should we make sure to get the right charset off the document?
|
||||
(void) NS_NewURI(getter_AddRefs(absURI), val, nsnull, baseURI);
|
||||
|
||||
nsCOMPtr<nsIURI> absURI = nsContentUtils::GetXLinkURI(aContent);
|
||||
if (absURI) {
|
||||
nsILinkHandler *linkHandler = aPresContext->GetLinkHandler();
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(absURI, *aState);
|
||||
|
@ -313,9 +313,8 @@ nsXMLElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
||||
}
|
||||
nsAutoString show, href;
|
||||
nsLinkVerb verb = eLinkVerb_Undefined; // basically means same as replace
|
||||
nsGenericElement::GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href,
|
||||
href);
|
||||
if (href.IsEmpty()) {
|
||||
nsCOMPtr<nsIURI> uri = nsContentUtils::GetXLinkURI(this);
|
||||
if (!uri) {
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
break;
|
||||
}
|
||||
@ -335,15 +334,8 @@ nsXMLElement::HandleDOMEvent(nsIPresContext* aPresContext,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
ret = nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(uri),
|
||||
href,
|
||||
mDocument,
|
||||
baseURI);
|
||||
if (NS_SUCCEEDED(ret)) {
|
||||
ret = TriggerLink(aPresContext, verb, baseURI, uri, EmptyString(),
|
||||
PR_TRUE, PR_TRUE);
|
||||
}
|
||||
ret = TriggerLink(aPresContext, verb, baseURI, uri,
|
||||
EmptyString(), PR_TRUE, PR_TRUE);
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
|
@ -520,6 +520,10 @@ nsFrame::Init(nsIPresContext* aPresContext,
|
||||
NS_IF_ADDREF(mContent);
|
||||
mParent = aParent;
|
||||
|
||||
if (mContent) {
|
||||
mContent->SetMayHaveFrame(PR_TRUE);
|
||||
}
|
||||
|
||||
if (aPrevInFlow) {
|
||||
// Make sure the general flags bits are the same
|
||||
nsFrameState state = aPrevInFlow->GetStateBits();
|
||||
@ -1274,9 +1278,9 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
|
||||
if (!shell)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// if we are in Navigator and the click is in a link, we don't want to start
|
||||
// selection because we don't want to interfere with a potential drag of said
|
||||
// link and steal all its glory.
|
||||
// if we are in Navigator and the click is in a draggable node, we don't want
|
||||
// to start selection because we don't want to interfere with a potential
|
||||
// drag of said node and steal all its glory.
|
||||
PRInt16 isEditor = 0;
|
||||
shell->GetSelectionFlags ( &isEditor );
|
||||
//weaaak. only the editor can display frame selction not just text and images
|
||||
@ -1284,64 +1288,26 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
|
||||
|
||||
nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
|
||||
if (!isEditor && !keyEvent->isAlt) {
|
||||
static NS_NAMED_LITERAL_STRING(simple, "simple");
|
||||
|
||||
for (nsIContent* content = mContent; content;
|
||||
content = content->GetParent()) {
|
||||
// are we a link with an href? If so, bail out now!
|
||||
nsAutoString href;
|
||||
// a?
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> a(do_QueryInterface(content));
|
||||
if (a) {
|
||||
a->GetHref(href);
|
||||
} else {
|
||||
// area?
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(content));
|
||||
if (area) {
|
||||
area->GetHref(href);
|
||||
} else {
|
||||
// img?
|
||||
nsCOMPtr<nsIDOMHTMLImageElement> img(do_QueryInterface(content));
|
||||
if (img) {
|
||||
img->GetSrc(href);
|
||||
} else {
|
||||
// input (image type) ?
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(content));
|
||||
if (inputElement) {
|
||||
nsAutoString type;
|
||||
rv = inputElement->GetType(type);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
type.LowerCaseEqualsLiteral("image"))
|
||||
inputElement->GetSrc(href);
|
||||
} else {
|
||||
// XLink ?
|
||||
nsAutoString value;
|
||||
content->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::type, value);
|
||||
if (value.Equals(simple))
|
||||
content->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, href);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fix for bug #53326: Make sure we bail only
|
||||
// in the presence of an href with a value!
|
||||
if ( !href.IsEmpty() ) {
|
||||
// coordinate stuff is the fix for bug #55921
|
||||
nsIView *dummyView = 0;
|
||||
nsRect frameRect = mRect;
|
||||
nsPoint offsetPoint;
|
||||
if ( nsContentUtils::ContentIsDraggable(content) ) {
|
||||
// coordinate stuff is the fix for bug #55921
|
||||
nsIView *dummyView = 0;
|
||||
nsRect frameRect = mRect;
|
||||
nsPoint offsetPoint;
|
||||
|
||||
GetOffsetFromView(aPresContext, offsetPoint, &dummyView);
|
||||
GetOffsetFromView(aPresContext, offsetPoint, &dummyView);
|
||||
|
||||
frameRect.x = offsetPoint.x;
|
||||
frameRect.y = offsetPoint.y;
|
||||
frameRect.x = offsetPoint.x;
|
||||
frameRect.y = offsetPoint.y;
|
||||
|
||||
if (frameRect.x <= aEvent->point.x && (frameRect.x + frameRect.width >= aEvent->point.x) &&
|
||||
frameRect.y <= aEvent->point.y && (frameRect.y + frameRect.height >= aEvent->point.y))
|
||||
return NS_OK;
|
||||
}
|
||||
} // if browser, not editor
|
||||
}
|
||||
if (frameRect.x <= aEvent->point.x && (frameRect.x + frameRect.width >= aEvent->point.x) &&
|
||||
frameRect.y <= aEvent->point.y && (frameRect.y + frameRect.height >= aEvent->point.y))
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
} // if browser, not editor
|
||||
|
||||
// check whether style allows selection
|
||||
// if not, don't tell selection the mouse event even occurred.
|
||||
|
@ -520,6 +520,10 @@ nsFrame::Init(nsIPresContext* aPresContext,
|
||||
NS_IF_ADDREF(mContent);
|
||||
mParent = aParent;
|
||||
|
||||
if (mContent) {
|
||||
mContent->SetMayHaveFrame(PR_TRUE);
|
||||
}
|
||||
|
||||
if (aPrevInFlow) {
|
||||
// Make sure the general flags bits are the same
|
||||
nsFrameState state = aPrevInFlow->GetStateBits();
|
||||
@ -1274,9 +1278,9 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
|
||||
if (!shell)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// if we are in Navigator and the click is in a link, we don't want to start
|
||||
// selection because we don't want to interfere with a potential drag of said
|
||||
// link and steal all its glory.
|
||||
// if we are in Navigator and the click is in a draggable node, we don't want
|
||||
// to start selection because we don't want to interfere with a potential
|
||||
// drag of said node and steal all its glory.
|
||||
PRInt16 isEditor = 0;
|
||||
shell->GetSelectionFlags ( &isEditor );
|
||||
//weaaak. only the editor can display frame selction not just text and images
|
||||
@ -1284,64 +1288,26 @@ nsFrame::HandlePress(nsIPresContext* aPresContext,
|
||||
|
||||
nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
|
||||
if (!isEditor && !keyEvent->isAlt) {
|
||||
static NS_NAMED_LITERAL_STRING(simple, "simple");
|
||||
|
||||
for (nsIContent* content = mContent; content;
|
||||
content = content->GetParent()) {
|
||||
// are we a link with an href? If so, bail out now!
|
||||
nsAutoString href;
|
||||
// a?
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> a(do_QueryInterface(content));
|
||||
if (a) {
|
||||
a->GetHref(href);
|
||||
} else {
|
||||
// area?
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(content));
|
||||
if (area) {
|
||||
area->GetHref(href);
|
||||
} else {
|
||||
// img?
|
||||
nsCOMPtr<nsIDOMHTMLImageElement> img(do_QueryInterface(content));
|
||||
if (img) {
|
||||
img->GetSrc(href);
|
||||
} else {
|
||||
// input (image type) ?
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> inputElement(do_QueryInterface(content));
|
||||
if (inputElement) {
|
||||
nsAutoString type;
|
||||
rv = inputElement->GetType(type);
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
type.LowerCaseEqualsLiteral("image"))
|
||||
inputElement->GetSrc(href);
|
||||
} else {
|
||||
// XLink ?
|
||||
nsAutoString value;
|
||||
content->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::type, value);
|
||||
if (value.Equals(simple))
|
||||
content->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, href);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fix for bug #53326: Make sure we bail only
|
||||
// in the presence of an href with a value!
|
||||
if ( !href.IsEmpty() ) {
|
||||
// coordinate stuff is the fix for bug #55921
|
||||
nsIView *dummyView = 0;
|
||||
nsRect frameRect = mRect;
|
||||
nsPoint offsetPoint;
|
||||
if ( nsContentUtils::ContentIsDraggable(content) ) {
|
||||
// coordinate stuff is the fix for bug #55921
|
||||
nsIView *dummyView = 0;
|
||||
nsRect frameRect = mRect;
|
||||
nsPoint offsetPoint;
|
||||
|
||||
GetOffsetFromView(aPresContext, offsetPoint, &dummyView);
|
||||
GetOffsetFromView(aPresContext, offsetPoint, &dummyView);
|
||||
|
||||
frameRect.x = offsetPoint.x;
|
||||
frameRect.y = offsetPoint.y;
|
||||
frameRect.x = offsetPoint.x;
|
||||
frameRect.y = offsetPoint.y;
|
||||
|
||||
if (frameRect.x <= aEvent->point.x && (frameRect.x + frameRect.width >= aEvent->point.x) &&
|
||||
frameRect.y <= aEvent->point.y && (frameRect.y + frameRect.height >= aEvent->point.y))
|
||||
return NS_OK;
|
||||
}
|
||||
} // if browser, not editor
|
||||
}
|
||||
if (frameRect.x <= aEvent->point.x && (frameRect.x + frameRect.width >= aEvent->point.x) &&
|
||||
frameRect.y <= aEvent->point.y && (frameRect.y + frameRect.height >= aEvent->point.y))
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
} // if browser, not editor
|
||||
|
||||
// check whether style allows selection
|
||||
// if not, don't tell selection the mouse event even occurred.
|
||||
|
@ -50,6 +50,7 @@
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
// XXX This is here because nsCachedStyleData is accessed outside of
|
||||
// the content module; e.g., by nsCSSFrameConstructor.
|
||||
@ -483,22 +484,8 @@ PRBool nsStyleUtil::IsSimpleXlink(nsIContent *aContent, nsIPresContext *aPresCon
|
||||
// first see if we have an XML element
|
||||
nsCOMPtr<nsIXMLContent> xml(do_QueryInterface(aContent));
|
||||
if (xml) {
|
||||
// see if it is type=simple (we don't deal with other types)
|
||||
nsAutoString val;
|
||||
aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::type, val);
|
||||
if (val.EqualsLiteral("simple")) {
|
||||
// see if there is an xlink namespace'd href attribute:
|
||||
// - get it if there is, if not no big deal, it is not required for xlinks
|
||||
// is it bad to re-use val here?
|
||||
aContent->GetAttr(kNameSpaceID_XLink, nsHTMLAtoms::href, val);
|
||||
|
||||
// It's an XLink. Resolve it relative to aContent's base URI.
|
||||
nsCOMPtr<nsIURI> baseURI = aContent->GetBaseURI();
|
||||
|
||||
nsCOMPtr<nsIURI> absURI;
|
||||
// XXX should we make sure to get the right charset off the document?
|
||||
(void) NS_NewURI(getter_AddRefs(absURI), val, nsnull, baseURI);
|
||||
|
||||
nsCOMPtr<nsIURI> absURI = nsContentUtils::GetXLinkURI(aContent);
|
||||
if (absURI) {
|
||||
nsILinkHandler *linkHandler = aPresContext->GetLinkHandler();
|
||||
if (linkHandler) {
|
||||
linkHandler->GetLinkState(absURI, *aState);
|
||||
|
Loading…
Reference in New Issue
Block a user