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:
bzbarsky%mit.edu 2004-07-30 06:04:57 +00:00
parent a58e66f6ff
commit e628e82cc1
10 changed files with 283 additions and 397 deletions

View File

@ -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.

View File

@ -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

View File

@ -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);
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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.

View File

@ -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.

View File

@ -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);