Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / layout / style / nsInspectorCSSUtils.cpp
blob0e38d7f8d38f3f664e98faf4c35047f605a3c191
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 // vim:cindent:ts=8:et:sw=4:
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 mozilla.org code.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2002
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * L. David Baron <dbaron@dbaron.org> (original author)
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 /* XPCOM interface to provide some internal information to DOM inspector */
42 #include "nsInspectorCSSUtils.h"
43 #include "nsIStyleRule.h"
44 #include "nsRuleNode.h"
45 #include "nsString.h"
46 #include "nsGkAtoms.h"
47 #include "nsIDocument.h"
48 #include "nsIPresShell.h"
49 #include "nsAutoPtr.h"
50 #include "nsIFrame.h"
51 #include "nsStyleSet.h"
52 #include "nsXBLBinding.h"
53 #include "nsXBLPrototypeBinding.h"
54 #include "nsIDOMElement.h"
55 #include "nsIMutableArray.h"
56 #include "nsBindingManager.h"
58 nsInspectorCSSUtils::nsInspectorCSSUtils()
60 nsCSSProps::AddRefTable();
63 nsInspectorCSSUtils::~nsInspectorCSSUtils()
65 nsCSSProps::ReleaseTable();
68 NS_IMPL_ISUPPORTS1(nsInspectorCSSUtils, nsIInspectorCSSUtils)
70 NS_IMETHODIMP
71 nsInspectorCSSUtils::LookupCSSProperty(const nsAString& aName, nsCSSProperty *aProp)
73 *aProp = nsCSSProps::LookupProperty(aName);
74 return NS_OK;
77 NS_IMETHODIMP
78 nsInspectorCSSUtils::GetRuleNodeParent(nsRuleNode *aNode, nsRuleNode **aParent)
80 *aParent = aNode->GetParent();
81 return NS_OK;
84 NS_IMETHODIMP
85 nsInspectorCSSUtils::GetRuleNodeRule(nsRuleNode *aNode, nsIStyleRule **aRule)
87 *aRule = aNode->GetRule();
88 NS_IF_ADDREF(*aRule);
89 return NS_OK;
92 NS_IMETHODIMP
93 nsInspectorCSSUtils::IsRuleNodeRoot(nsRuleNode *aNode, PRBool *aIsRoot)
95 *aIsRoot = aNode->IsRoot();
96 return NS_OK;
99 /* static */
100 nsStyleContext*
101 nsInspectorCSSUtils::GetStyleContextForFrame(nsIFrame* aFrame)
103 nsStyleContext* styleContext = aFrame->GetStyleContext();
104 if (!styleContext)
105 return nsnull;
107 /* For tables the primary frame is the "outer frame" but the style
108 * rules are applied to the "inner frame". Luckily, the "outer
109 * frame" actually inherits style from the "inner frame" so we can
110 * just move one level up in the style context hierarchy....
112 if (aFrame->GetType() == nsGkAtoms::tableOuterFrame)
113 return styleContext->GetParent();
115 return styleContext;
118 /* static */
119 already_AddRefed<nsStyleContext>
120 nsInspectorCSSUtils::GetStyleContextForContent(nsIContent* aContent,
121 nsIAtom* aPseudo,
122 nsIPresShell* aPresShell)
124 if (!aPseudo) {
125 aPresShell->FlushPendingNotifications(Flush_Style);
126 nsIFrame* frame = aPresShell->GetPrimaryFrameFor(aContent);
127 if (frame) {
128 nsStyleContext* result = GetStyleContextForFrame(frame);
129 // this function returns an addrefed style context
130 if (result)
131 result->AddRef();
132 return result;
136 // No frame has been created or we have a pseudo, so resolve the
137 // style ourselves
138 nsRefPtr<nsStyleContext> parentContext;
139 nsIContent* parent = aPseudo ? aContent : aContent->GetParent();
140 if (parent)
141 parentContext = GetStyleContextForContent(parent, nsnull, aPresShell);
143 nsPresContext *presContext = aPresShell->GetPresContext();
144 if (!presContext)
145 return nsnull;
147 nsStyleSet *styleSet = aPresShell->StyleSet();
149 if (!aContent->IsNodeOfType(nsINode::eELEMENT)) {
150 NS_ASSERTION(!aPseudo, "Shouldn't have a pseudo for a non-element!");
151 return styleSet->ResolveStyleForNonElement(parentContext);
154 if (aPseudo) {
155 return styleSet->ResolvePseudoStyleFor(aContent, aPseudo, parentContext);
158 return styleSet->ResolveStyleFor(aContent, parentContext);
161 NS_IMETHODIMP
162 nsInspectorCSSUtils::GetRuleNodeForContent(nsIContent* aContent,
163 nsRuleNode** aRuleNode)
165 *aRuleNode = nsnull;
167 nsIDocument* doc = aContent->GetDocument();
168 NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
170 nsIPresShell *presShell = doc->GetPrimaryShell();
171 NS_ENSURE_TRUE(presShell, NS_ERROR_UNEXPECTED);
173 nsRefPtr<nsStyleContext> sContext =
174 GetStyleContextForContent(aContent, nsnull, presShell);
175 *aRuleNode = sContext->GetRuleNode();
176 return NS_OK;
179 NS_IMETHODIMP
180 nsInspectorCSSUtils::GetBindingURLs(nsIDOMElement *aElement,
181 nsIArray **aResult)
183 *aResult = nsnull;
185 nsCOMPtr<nsIMutableArray> urls = do_CreateInstance(NS_ARRAY_CONTRACTID);
186 if (!urls)
187 return NS_ERROR_FAILURE;
189 nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
190 NS_ASSERTION(content, "elements must implement nsIContent");
192 nsIDocument *ownerDoc = content->GetOwnerDoc();
193 if (ownerDoc) {
194 nsXBLBinding *binding =
195 ownerDoc->BindingManager()->GetBinding(content);
197 while (binding) {
198 urls->AppendElement(binding->PrototypeBinding()->BindingURI(),
199 PR_FALSE);
200 binding = binding->GetBaseBinding();
204 NS_ADDREF(*aResult = urls);
205 return NS_OK;