1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is the Mozilla browser.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications, Inc.
20 * Portions created by the Initial Developer are Copyright (C) 1999
21 * the Initial Developer. All Rights Reserved.
24 * Chris Saari <saari@netscape.com>
25 * Conrad Carlen <ccarlen@netscape.com>
26 * Pierre Chanial <p_ch@verizon.net>
28 * Alternatively, the contents of this file may be used under the terms of
29 * either the GNU General Public License Version 2 or later (the "GPL"), or
30 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 * in which case the provisions of the GPL or the LGPL are applicable instead
32 * of those above. If you wish to allow use of your version of this file only
33 * under the terms of either the GPL or the LGPL, and not to allow others to
34 * use your version of this file under the terms of the MPL, indicate your
35 * decision by deleting the provisions above and replace them with the notice
36 * and other provisions required by the GPL or the LGPL. If you do not delete
37 * the provisions above, a recipient may use your version of this file under
38 * the terms of any one of the MPL, the GPL or the LGPL.
40 * ***** END LICENSE BLOCK ***** */
42 #include "nsContextMenuInfo.h"
44 #include "nsIImageLoadingContent.h"
45 #include "imgILoader.h"
46 #include "nsIDOMDocument.h"
47 #include "nsIDOMHTMLDocument.h"
48 #include "nsIDOMHTMLElement.h"
49 #include "nsIDOMHTMLHtmlElement.h"
50 #include "nsIDOMHTMLAnchorElement.h"
51 #include "nsIDOMHTMLImageElement.h"
52 #include "nsIDOMHTMLAreaElement.h"
53 #include "nsIDOMHTMLLinkElement.h"
54 #include "nsIDOMDocumentView.h"
55 #include "nsIDOMAbstractView.h"
56 #include "nsIDOMViewCSS.h"
57 #include "nsIDOMCSSStyleDeclaration.h"
58 #include "nsIDOMCSSValue.h"
59 #include "nsIDOMCSSPrimitiveValue.h"
60 #include "nsNetUtil.h"
61 #include "nsUnicharUtils.h"
63 //*****************************************************************************
64 // class nsContextMenuInfo
65 //*****************************************************************************
67 NS_IMPL_ISUPPORTS1(nsContextMenuInfo
, nsIContextMenuInfo
)
69 nsContextMenuInfo::nsContextMenuInfo()
73 nsContextMenuInfo::~nsContextMenuInfo()
77 /* readonly attribute nsIDOMEvent mouseEvent; */
79 nsContextMenuInfo::GetMouseEvent(nsIDOMEvent
**aEvent
)
81 NS_ENSURE_ARG_POINTER(aEvent
);
82 NS_IF_ADDREF(*aEvent
= mMouseEvent
);
86 /* readonly attribute nsIDOMNode targetNode; */
88 nsContextMenuInfo::GetTargetNode(nsIDOMNode
**aNode
)
90 NS_ENSURE_ARG_POINTER(aNode
);
91 NS_IF_ADDREF(*aNode
= mDOMNode
);
95 /* readonly attribute AString associatedLink; */
97 nsContextMenuInfo::GetAssociatedLink(nsAString
& aHRef
)
99 NS_ENSURE_STATE(mAssociatedLink
);
102 nsCOMPtr
<nsIDOMElement
> content(do_QueryInterface(mAssociatedLink
));
103 nsAutoString localName
;
105 content
->GetLocalName(localName
);
107 nsCOMPtr
<nsIDOMElement
> linkContent
;
108 ToLowerCase(localName
);
109 if (localName
.EqualsLiteral("a") ||
110 localName
.EqualsLiteral("area") ||
111 localName
.EqualsLiteral("link")) {
113 content
->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr
);
115 linkContent
= content
;
116 nsCOMPtr
<nsIDOMHTMLAnchorElement
> anchor(do_QueryInterface(linkContent
));
118 anchor
->GetHref(aHRef
);
120 nsCOMPtr
<nsIDOMHTMLAreaElement
> area(do_QueryInterface(linkContent
));
122 area
->GetHref(aHRef
);
124 nsCOMPtr
<nsIDOMHTMLLinkElement
> link(do_QueryInterface(linkContent
));
126 link
->GetHref(aHRef
);
132 nsCOMPtr
<nsIDOMNode
> curr
;
133 mAssociatedLink
->GetParentNode(getter_AddRefs(curr
));
135 content
= do_QueryInterface(curr
);
138 content
->GetLocalName(localName
);
139 ToLowerCase(localName
);
140 if (localName
.EqualsLiteral("a")) {
142 content
->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr
);
144 linkContent
= content
;
145 nsCOMPtr
<nsIDOMHTMLAnchorElement
> anchor(do_QueryInterface(linkContent
));
147 anchor
->GetHref(aHRef
);
150 linkContent
= nsnull
; // Links can't be nested.
154 nsCOMPtr
<nsIDOMNode
> temp
= curr
;
155 temp
->GetParentNode(getter_AddRefs(curr
));
162 /* readonly attribute imgIContainer imageContainer; */
164 nsContextMenuInfo::GetImageContainer(imgIContainer
**aImageContainer
)
166 NS_ENSURE_ARG_POINTER(aImageContainer
);
167 NS_ENSURE_STATE(mDOMNode
);
169 nsCOMPtr
<imgIRequest
> request
;
170 GetImageRequest(mDOMNode
, getter_AddRefs(request
));
172 return request
->GetImage(aImageContainer
);
174 return NS_ERROR_FAILURE
;
177 /* readonly attribute nsIURI imageSrc; */
179 nsContextMenuInfo::GetImageSrc(nsIURI
**aURI
)
181 NS_ENSURE_ARG_POINTER(aURI
);
182 NS_ENSURE_STATE(mDOMNode
);
184 nsCOMPtr
<nsIImageLoadingContent
> content(do_QueryInterface(mDOMNode
));
185 NS_ENSURE_TRUE(content
, NS_ERROR_FAILURE
);
186 return content
->GetCurrentURI(aURI
);
189 /* readonly attribute imgIContainer backgroundImageContainer; */
191 nsContextMenuInfo::GetBackgroundImageContainer(imgIContainer
**aImageContainer
)
193 NS_ENSURE_ARG_POINTER(aImageContainer
);
194 NS_ENSURE_STATE(mDOMNode
);
196 nsCOMPtr
<imgIRequest
> request
;
197 GetBackgroundImageRequest(mDOMNode
, getter_AddRefs(request
));
199 return request
->GetImage(aImageContainer
);
201 return NS_ERROR_FAILURE
;
204 /* readonly attribute nsIURI backgroundImageSrc; */
206 nsContextMenuInfo::GetBackgroundImageSrc(nsIURI
**aURI
)
208 NS_ENSURE_ARG_POINTER(aURI
);
209 NS_ENSURE_STATE(mDOMNode
);
211 nsCOMPtr
<imgIRequest
> request
;
212 GetBackgroundImageRequest(mDOMNode
, getter_AddRefs(request
));
214 return request
->GetURI(aURI
);
216 return NS_ERROR_FAILURE
;
219 //*****************************************************************************
222 nsContextMenuInfo::GetImageRequest(nsIDOMNode
*aDOMNode
, imgIRequest
**aRequest
)
224 NS_ENSURE_ARG(aDOMNode
);
225 NS_ENSURE_ARG_POINTER(aRequest
);
228 nsCOMPtr
<nsIImageLoadingContent
> content(do_QueryInterface(aDOMNode
));
229 NS_ENSURE_TRUE(content
, NS_ERROR_FAILURE
);
231 return content
->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST
,
236 nsContextMenuInfo::HasBackgroundImage(nsIDOMNode
* aDOMNode
)
238 NS_ENSURE_TRUE(aDOMNode
, PR_FALSE
);
240 nsCOMPtr
<imgIRequest
> request
;
241 GetBackgroundImageRequest(aDOMNode
, getter_AddRefs(request
));
243 return (request
!= nsnull
);
247 nsContextMenuInfo::GetBackgroundImageRequest(nsIDOMNode
*aDOMNode
, imgIRequest
**aRequest
)
250 NS_ENSURE_ARG(aDOMNode
);
251 NS_ENSURE_ARG_POINTER(aRequest
);
253 nsCOMPtr
<nsIDOMNode
> domNode
= aDOMNode
;
255 // special case for the <html> element: if it has no background-image
256 // we'll defer to <body>
257 nsCOMPtr
<nsIDOMHTMLHtmlElement
> htmlElement
= do_QueryInterface(domNode
);
259 nsAutoString nameSpace
;
260 htmlElement
->GetNamespaceURI(nameSpace
);
261 if (nameSpace
.IsEmpty()) {
262 nsresult rv
= GetBackgroundImageRequestInternal(domNode
, aRequest
);
263 if (NS_SUCCEEDED(rv
) && *aRequest
)
266 // no background-image found
267 nsCOMPtr
<nsIDOMDocument
> document
;
268 domNode
->GetOwnerDocument(getter_AddRefs(document
));
269 nsCOMPtr
<nsIDOMHTMLDocument
> htmlDocument(do_QueryInterface(document
));
270 NS_ENSURE_TRUE(htmlDocument
, NS_ERROR_FAILURE
);
272 nsCOMPtr
<nsIDOMHTMLElement
> body
;
273 htmlDocument
->GetBody(getter_AddRefs(body
));
274 domNode
= do_QueryInterface(body
);
275 NS_ENSURE_TRUE(domNode
, NS_ERROR_FAILURE
);
278 return GetBackgroundImageRequestInternal(domNode
, aRequest
);
282 nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode
*aDOMNode
, imgIRequest
**aRequest
)
284 NS_ENSURE_ARG_POINTER(aDOMNode
);
286 nsCOMPtr
<nsIDOMNode
> domNode
= aDOMNode
;
287 nsCOMPtr
<nsIDOMNode
> parentNode
;
289 nsCOMPtr
<nsIDOMDocument
> document
;
290 domNode
->GetOwnerDocument(getter_AddRefs(document
));
291 nsCOMPtr
<nsIDOMDocumentView
> docView(do_QueryInterface(document
));
292 NS_ENSURE_TRUE(docView
, NS_ERROR_FAILURE
);
294 nsCOMPtr
<nsIDOMAbstractView
> defaultView
;
295 docView
->GetDefaultView(getter_AddRefs(defaultView
));
296 nsCOMPtr
<nsIDOMViewCSS
> defaultCSSView(do_QueryInterface(defaultView
));
297 NS_ENSURE_TRUE(defaultCSSView
, NS_ERROR_FAILURE
);
299 nsCOMPtr
<nsIDOMCSSPrimitiveValue
> primitiveValue
;
300 nsAutoString bgStringValue
;
303 nsCOMPtr
<nsIDOMElement
> domElement(do_QueryInterface(domNode
));
304 // bail for the parent node of the root element or null argument
308 nsCOMPtr
<nsIDOMCSSStyleDeclaration
> computedStyle
;
309 defaultCSSView
->GetComputedStyle(domElement
, EmptyString(),
310 getter_AddRefs(computedStyle
));
312 nsCOMPtr
<nsIDOMCSSValue
> cssValue
;
313 computedStyle
->GetPropertyCSSValue(NS_LITERAL_STRING("background-image"),
314 getter_AddRefs(cssValue
));
315 primitiveValue
= do_QueryInterface(cssValue
);
316 if (primitiveValue
) {
317 primitiveValue
->GetStringValue(bgStringValue
);
318 if (!bgStringValue
.EqualsLiteral("none")) {
319 nsCOMPtr
<nsIURI
> bgUri
;
320 NS_NewURI(getter_AddRefs(bgUri
), bgStringValue
);
321 NS_ENSURE_TRUE(bgUri
, NS_ERROR_FAILURE
);
323 nsCOMPtr
<imgILoader
> il(do_GetService(
324 "@mozilla.org/image/loader;1"));
325 NS_ENSURE_TRUE(il
, NS_ERROR_FAILURE
);
327 return il
->LoadImage(bgUri
, nsnull
, nsnull
, nsnull
, nsnull
, nsnull
,
328 nsIRequest::LOAD_NORMAL
, nsnull
, nsnull
,
333 // bail if we encounter non-transparent background-color
334 computedStyle
->GetPropertyCSSValue(NS_LITERAL_STRING("background-color"),
335 getter_AddRefs(cssValue
));
336 primitiveValue
= do_QueryInterface(cssValue
);
337 if (primitiveValue
) {
338 primitiveValue
->GetStringValue(bgStringValue
);
339 if (!bgStringValue
.EqualsLiteral("transparent"))
340 return NS_ERROR_FAILURE
;
344 domNode
->GetParentNode(getter_AddRefs(parentNode
));
345 domNode
= parentNode
;
348 return NS_ERROR_FAILURE
;