1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsContextMenuInfo.h"
8 #include "nsIImageLoadingContent.h"
10 #include "nsIDOMDocument.h"
11 #include "nsIDOMHTMLDocument.h"
12 #include "nsIDOMHTMLElement.h"
13 #include "nsIDOMHTMLHtmlElement.h"
14 #include "nsIDOMHTMLAnchorElement.h"
15 #include "nsIDOMHTMLImageElement.h"
16 #include "nsIDOMHTMLAreaElement.h"
17 #include "nsIDOMHTMLLinkElement.h"
18 #include "nsIDOMWindow.h"
19 #include "nsIDOMCSSStyleDeclaration.h"
20 #include "nsIDOMCSSValue.h"
21 #include "nsIDOMCSSPrimitiveValue.h"
22 #include "nsNetUtil.h"
23 #include "nsUnicharUtils.h"
24 #include "nsIDocument.h"
25 #include "nsIPrincipal.h"
26 #include "nsIContentSecurityPolicy.h"
27 #include "nsIContentPolicy.h"
28 #include "nsAutoPtr.h"
29 #include "imgRequestProxy.h"
32 //*****************************************************************************
33 // class nsContextMenuInfo
34 //*****************************************************************************
36 NS_IMPL_ISUPPORTS(nsContextMenuInfo
, nsIContextMenuInfo
)
38 nsContextMenuInfo::nsContextMenuInfo()
42 nsContextMenuInfo::~nsContextMenuInfo()
46 /* readonly attribute nsIDOMEvent mouseEvent; */
48 nsContextMenuInfo::GetMouseEvent(nsIDOMEvent
**aEvent
)
50 NS_ENSURE_ARG_POINTER(aEvent
);
51 NS_IF_ADDREF(*aEvent
= mMouseEvent
);
55 /* readonly attribute nsIDOMNode targetNode; */
57 nsContextMenuInfo::GetTargetNode(nsIDOMNode
**aNode
)
59 NS_ENSURE_ARG_POINTER(aNode
);
60 NS_IF_ADDREF(*aNode
= mDOMNode
);
64 /* readonly attribute AString associatedLink; */
66 nsContextMenuInfo::GetAssociatedLink(nsAString
& aHRef
)
68 NS_ENSURE_STATE(mAssociatedLink
);
71 nsCOMPtr
<nsIDOMElement
> content(do_QueryInterface(mAssociatedLink
));
72 nsAutoString localName
;
74 content
->GetLocalName(localName
);
76 nsCOMPtr
<nsIDOMElement
> linkContent
;
77 ToLowerCase(localName
);
78 if (localName
.EqualsLiteral("a") ||
79 localName
.EqualsLiteral("area") ||
80 localName
.EqualsLiteral("link")) {
82 content
->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr
);
84 linkContent
= content
;
85 nsCOMPtr
<nsIDOMHTMLAnchorElement
> anchor(do_QueryInterface(linkContent
));
87 anchor
->GetHref(aHRef
);
89 nsCOMPtr
<nsIDOMHTMLAreaElement
> area(do_QueryInterface(linkContent
));
93 nsCOMPtr
<nsIDOMHTMLLinkElement
> link(do_QueryInterface(linkContent
));
101 nsCOMPtr
<nsIDOMNode
> curr
;
102 mAssociatedLink
->GetParentNode(getter_AddRefs(curr
));
104 content
= do_QueryInterface(curr
);
107 content
->GetLocalName(localName
);
108 ToLowerCase(localName
);
109 if (localName
.EqualsLiteral("a")) {
111 content
->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr
);
113 linkContent
= content
;
114 nsCOMPtr
<nsIDOMHTMLAnchorElement
> anchor(do_QueryInterface(linkContent
));
116 anchor
->GetHref(aHRef
);
119 linkContent
= nullptr; // Links can't be nested.
123 nsCOMPtr
<nsIDOMNode
> temp
= curr
;
124 temp
->GetParentNode(getter_AddRefs(curr
));
131 /* readonly attribute imgIContainer imageContainer; */
133 nsContextMenuInfo::GetImageContainer(imgIContainer
**aImageContainer
)
135 NS_ENSURE_ARG_POINTER(aImageContainer
);
136 NS_ENSURE_STATE(mDOMNode
);
138 nsCOMPtr
<imgIRequest
> request
;
139 GetImageRequest(mDOMNode
, getter_AddRefs(request
));
141 return request
->GetImage(aImageContainer
);
143 return NS_ERROR_FAILURE
;
146 /* readonly attribute nsIURI imageSrc; */
148 nsContextMenuInfo::GetImageSrc(nsIURI
**aURI
)
150 NS_ENSURE_ARG_POINTER(aURI
);
151 NS_ENSURE_STATE(mDOMNode
);
153 nsCOMPtr
<nsIImageLoadingContent
> content(do_QueryInterface(mDOMNode
));
154 NS_ENSURE_TRUE(content
, NS_ERROR_FAILURE
);
155 return content
->GetCurrentURI(aURI
);
158 /* readonly attribute imgIContainer backgroundImageContainer; */
160 nsContextMenuInfo::GetBackgroundImageContainer(imgIContainer
**aImageContainer
)
162 NS_ENSURE_ARG_POINTER(aImageContainer
);
163 NS_ENSURE_STATE(mDOMNode
);
165 nsRefPtr
<imgRequestProxy
> request
;
166 GetBackgroundImageRequest(mDOMNode
, getter_AddRefs(request
));
168 return request
->GetImage(aImageContainer
);
170 return NS_ERROR_FAILURE
;
173 /* readonly attribute nsIURI backgroundImageSrc; */
175 nsContextMenuInfo::GetBackgroundImageSrc(nsIURI
**aURI
)
177 NS_ENSURE_ARG_POINTER(aURI
);
178 NS_ENSURE_STATE(mDOMNode
);
180 nsRefPtr
<imgRequestProxy
> request
;
181 GetBackgroundImageRequest(mDOMNode
, getter_AddRefs(request
));
183 return request
->GetURI(aURI
);
185 return NS_ERROR_FAILURE
;
188 //*****************************************************************************
191 nsContextMenuInfo::GetImageRequest(nsIDOMNode
*aDOMNode
, imgIRequest
**aRequest
)
193 NS_ENSURE_ARG(aDOMNode
);
194 NS_ENSURE_ARG_POINTER(aRequest
);
197 nsCOMPtr
<nsIImageLoadingContent
> content(do_QueryInterface(aDOMNode
));
198 NS_ENSURE_TRUE(content
, NS_ERROR_FAILURE
);
200 return content
->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST
,
205 nsContextMenuInfo::HasBackgroundImage(nsIDOMNode
* aDOMNode
)
207 NS_ENSURE_TRUE(aDOMNode
, false);
209 nsRefPtr
<imgRequestProxy
> request
;
210 GetBackgroundImageRequest(aDOMNode
, getter_AddRefs(request
));
212 return (request
!= nullptr);
216 nsContextMenuInfo::GetBackgroundImageRequest(nsIDOMNode
*aDOMNode
, imgRequestProxy
**aRequest
)
219 NS_ENSURE_ARG(aDOMNode
);
220 NS_ENSURE_ARG_POINTER(aRequest
);
222 nsCOMPtr
<nsIDOMNode
> domNode
= aDOMNode
;
224 // special case for the <html> element: if it has no background-image
225 // we'll defer to <body>
226 nsCOMPtr
<nsIDOMHTMLHtmlElement
> htmlElement
= do_QueryInterface(domNode
);
228 nsCOMPtr
<nsIDOMHTMLElement
> element
= do_QueryInterface(domNode
);
229 nsAutoString nameSpace
;
230 element
->GetNamespaceURI(nameSpace
);
231 if (nameSpace
.IsEmpty()) {
232 nsresult rv
= GetBackgroundImageRequestInternal(domNode
, aRequest
);
233 if (NS_SUCCEEDED(rv
) && *aRequest
)
236 // no background-image found
237 nsCOMPtr
<nsIDOMDocument
> document
;
238 domNode
->GetOwnerDocument(getter_AddRefs(document
));
239 nsCOMPtr
<nsIDOMHTMLDocument
> htmlDocument(do_QueryInterface(document
));
240 NS_ENSURE_TRUE(htmlDocument
, NS_ERROR_FAILURE
);
242 nsCOMPtr
<nsIDOMHTMLElement
> body
;
243 htmlDocument
->GetBody(getter_AddRefs(body
));
244 domNode
= do_QueryInterface(body
);
245 NS_ENSURE_TRUE(domNode
, NS_ERROR_FAILURE
);
248 return GetBackgroundImageRequestInternal(domNode
, aRequest
);
252 nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode
*aDOMNode
, imgRequestProxy
**aRequest
)
254 NS_ENSURE_ARG_POINTER(aDOMNode
);
256 nsCOMPtr
<nsIDOMNode
> domNode
= aDOMNode
;
257 nsCOMPtr
<nsIDOMNode
> parentNode
;
259 nsCOMPtr
<nsIDOMDocument
> document
;
260 domNode
->GetOwnerDocument(getter_AddRefs(document
));
261 NS_ENSURE_TRUE(document
, NS_ERROR_FAILURE
);
263 nsCOMPtr
<nsIDOMWindow
> window
;
264 document
->GetDefaultView(getter_AddRefs(window
));
265 NS_ENSURE_TRUE(window
, NS_ERROR_FAILURE
);
267 nsCOMPtr
<nsIDOMCSSPrimitiveValue
> primitiveValue
;
268 nsAutoString bgStringValue
;
270 nsCOMPtr
<nsIDocument
> doc(do_QueryInterface(document
));
271 nsCOMPtr
<nsIPrincipal
> principal
= doc
? doc
->NodePrincipal() : nullptr;
274 nsCOMPtr
<nsIDOMElement
> domElement(do_QueryInterface(domNode
));
275 // bail for the parent node of the root element or null argument
279 nsCOMPtr
<nsIDOMCSSStyleDeclaration
> computedStyle
;
280 window
->GetComputedStyle(domElement
, EmptyString(),
281 getter_AddRefs(computedStyle
));
283 nsCOMPtr
<nsIDOMCSSValue
> cssValue
;
284 computedStyle
->GetPropertyCSSValue(NS_LITERAL_STRING("background-image"),
285 getter_AddRefs(cssValue
));
286 primitiveValue
= do_QueryInterface(cssValue
);
287 if (primitiveValue
) {
288 primitiveValue
->GetStringValue(bgStringValue
);
289 if (!bgStringValue
.EqualsLiteral("none")) {
290 nsCOMPtr
<nsIURI
> bgUri
;
291 NS_NewURI(getter_AddRefs(bgUri
), bgStringValue
);
292 NS_ENSURE_TRUE(bgUri
, NS_ERROR_FAILURE
);
294 nsRefPtr
<imgLoader
> il
= imgLoader::GetInstance();
295 NS_ENSURE_TRUE(il
, NS_ERROR_FAILURE
);
297 return il
->LoadImage(bgUri
, nullptr, nullptr,
298 doc
->GetReferrerPolicy(), principal
, nullptr,
299 nullptr, nullptr, nsIRequest::LOAD_NORMAL
,
300 nullptr, nsIContentPolicy::TYPE_IMAGE
,
301 EmptyString(), aRequest
);
305 // bail if we encounter non-transparent background-color
306 computedStyle
->GetPropertyCSSValue(NS_LITERAL_STRING("background-color"),
307 getter_AddRefs(cssValue
));
308 primitiveValue
= do_QueryInterface(cssValue
);
309 if (primitiveValue
) {
310 primitiveValue
->GetStringValue(bgStringValue
);
311 if (!bgStringValue
.EqualsLiteral("transparent"))
312 return NS_ERROR_FAILURE
;
316 domNode
->GetParentNode(getter_AddRefs(parentNode
));
317 domNode
= parentNode
;
320 return NS_ERROR_FAILURE
;