Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / embedding / browser / webBrowser / nsContextMenuInfo.cpp
blob061aa3595f2fe6b31820a93911e2ac4af4e1d737
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
14 * License.
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.
23 * Contributor(s):
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; */
78 NS_IMETHODIMP
79 nsContextMenuInfo::GetMouseEvent(nsIDOMEvent **aEvent)
81 NS_ENSURE_ARG_POINTER(aEvent);
82 NS_IF_ADDREF(*aEvent = mMouseEvent);
83 return NS_OK;
86 /* readonly attribute nsIDOMNode targetNode; */
87 NS_IMETHODIMP
88 nsContextMenuInfo::GetTargetNode(nsIDOMNode **aNode)
90 NS_ENSURE_ARG_POINTER(aNode);
91 NS_IF_ADDREF(*aNode = mDOMNode);
92 return NS_OK;
95 /* readonly attribute AString associatedLink; */
96 NS_IMETHODIMP
97 nsContextMenuInfo::GetAssociatedLink(nsAString& aHRef)
99 NS_ENSURE_STATE(mAssociatedLink);
100 aHRef.Truncate(0);
102 nsCOMPtr<nsIDOMElement> content(do_QueryInterface(mAssociatedLink));
103 nsAutoString localName;
104 if (content)
105 content->GetLocalName(localName);
107 nsCOMPtr<nsIDOMElement> linkContent;
108 ToLowerCase(localName);
109 if (localName.EqualsLiteral("a") ||
110 localName.EqualsLiteral("area") ||
111 localName.EqualsLiteral("link")) {
112 PRBool hasAttr;
113 content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
114 if (hasAttr) {
115 linkContent = content;
116 nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
117 if (anchor)
118 anchor->GetHref(aHRef);
119 else {
120 nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(linkContent));
121 if (area)
122 area->GetHref(aHRef);
123 else {
124 nsCOMPtr<nsIDOMHTMLLinkElement> link(do_QueryInterface(linkContent));
125 if (link)
126 link->GetHref(aHRef);
131 else {
132 nsCOMPtr<nsIDOMNode> curr;
133 mAssociatedLink->GetParentNode(getter_AddRefs(curr));
134 while (curr) {
135 content = do_QueryInterface(curr);
136 if (!content)
137 break;
138 content->GetLocalName(localName);
139 ToLowerCase(localName);
140 if (localName.EqualsLiteral("a")) {
141 PRBool hasAttr;
142 content->HasAttribute(NS_LITERAL_STRING("href"), &hasAttr);
143 if (hasAttr) {
144 linkContent = content;
145 nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(linkContent));
146 if (anchor)
147 anchor->GetHref(aHRef);
149 else
150 linkContent = nsnull; // Links can't be nested.
151 break;
154 nsCOMPtr<nsIDOMNode> temp = curr;
155 temp->GetParentNode(getter_AddRefs(curr));
159 return NS_OK;
162 /* readonly attribute imgIContainer imageContainer; */
163 NS_IMETHODIMP
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));
171 if (request)
172 return request->GetImage(aImageContainer);
174 return NS_ERROR_FAILURE;
177 /* readonly attribute nsIURI imageSrc; */
178 NS_IMETHODIMP
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; */
190 NS_IMETHODIMP
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));
198 if (request)
199 return request->GetImage(aImageContainer);
201 return NS_ERROR_FAILURE;
204 /* readonly attribute nsIURI backgroundImageSrc; */
205 NS_IMETHODIMP
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));
213 if (request)
214 return request->GetURI(aURI);
216 return NS_ERROR_FAILURE;
219 //*****************************************************************************
221 nsresult
222 nsContextMenuInfo::GetImageRequest(nsIDOMNode *aDOMNode, imgIRequest **aRequest)
224 NS_ENSURE_ARG(aDOMNode);
225 NS_ENSURE_ARG_POINTER(aRequest);
227 // Get content
228 nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(aDOMNode));
229 NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
231 return content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
232 aRequest);
235 PRBool
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);
246 nsresult
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);
258 if (htmlElement) {
259 nsAutoString nameSpace;
260 htmlElement->GetNamespaceURI(nameSpace);
261 if (nameSpace.IsEmpty()) {
262 nsresult rv = GetBackgroundImageRequestInternal(domNode, aRequest);
263 if (NS_SUCCEEDED(rv) && *aRequest)
264 return NS_OK;
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);
281 nsresult
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;
302 while (PR_TRUE) {
303 nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(domNode));
304 // bail for the parent node of the root element or null argument
305 if (!domElement)
306 break;
308 nsCOMPtr<nsIDOMCSSStyleDeclaration> computedStyle;
309 defaultCSSView->GetComputedStyle(domElement, EmptyString(),
310 getter_AddRefs(computedStyle));
311 if (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,
329 aRequest);
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;