1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Daniel Glazman <glazman@netscape.com>
24 : * Ms2ger <ms2ger@gmail.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or 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.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "mozilla/Util.h"
41 :
42 : #include "nscore.h"
43 : #include "nsCOMPtr.h"
44 : #include "nsIDOMHTMLBodyElement.h"
45 : #include "nsIDOMEventTarget.h"
46 : #include "nsGenericHTMLElement.h"
47 : #include "nsGkAtoms.h"
48 : #include "nsStyleConsts.h"
49 : #include "nsPresContext.h"
50 : #include "nsIPresShell.h"
51 : #include "nsIDocument.h"
52 : #include "nsIHTMLDocument.h"
53 : #include "nsHTMLStyleSheet.h"
54 : #include "nsIContentViewer.h"
55 : #include "nsIMarkupDocumentViewer.h"
56 : #include "nsMappedAttributes.h"
57 : #include "nsRuleData.h"
58 : #include "nsIFrame.h"
59 : #include "nsIDocShell.h"
60 : #include "nsIEditorDocShell.h"
61 : #include "nsCOMPtr.h"
62 : #include "nsRuleWalker.h"
63 : #include "jsapi.h"
64 :
65 : //----------------------------------------------------------------------
66 :
67 : using namespace mozilla;
68 :
69 : class nsHTMLBodyElement;
70 :
71 : class BodyRule: public nsIStyleRule {
72 : public:
73 : BodyRule(nsHTMLBodyElement* aPart);
74 : virtual ~BodyRule();
75 :
76 : NS_DECL_ISUPPORTS
77 :
78 : // nsIStyleRule interface
79 : virtual void MapRuleInfoInto(nsRuleData* aRuleData);
80 : #ifdef DEBUG
81 : virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
82 : #endif
83 :
84 : nsHTMLBodyElement* mPart; // not ref-counted, cleared by content
85 : };
86 :
87 : //----------------------------------------------------------------------
88 :
89 : class nsHTMLBodyElement : public nsGenericHTMLElement,
90 : public nsIDOMHTMLBodyElement
91 : {
92 : public:
93 : using nsGenericElement::GetText;
94 : using nsGenericElement::SetText;
95 :
96 : nsHTMLBodyElement(already_AddRefed<nsINodeInfo> aNodeInfo);
97 : virtual ~nsHTMLBodyElement();
98 :
99 : // nsISupports
100 : NS_DECL_ISUPPORTS_INHERITED
101 :
102 : // nsIDOMNode
103 1 : NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
104 :
105 : // nsIDOMElement
106 0 : NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
107 :
108 : // nsIDOMHTMLElement
109 0 : NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
110 :
111 : // nsIDOMHTMLBodyElement
112 : NS_DECL_NSIDOMHTMLBODYELEMENT
113 :
114 : // Event listener stuff; we need to declare only the ones we need to
115 : // forward to window that don't come from nsIDOMHTMLBodyElement.
116 : #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the shim */
117 : #define FORWARDED_EVENT(name_, id_, type_, struct_) \
118 : NS_IMETHOD GetOn##name_(JSContext *cx, jsval *vp); \
119 : NS_IMETHOD SetOn##name_(JSContext *cx, const jsval &v);
120 : #include "nsEventNameList.h"
121 : #undef FORWARDED_EVENT
122 : #undef EVENT
123 :
124 : virtual bool ParseAttribute(PRInt32 aNamespaceID,
125 : nsIAtom* aAttribute,
126 : const nsAString& aValue,
127 : nsAttrValue& aResult);
128 : virtual void UnbindFromTree(bool aDeep = true,
129 : bool aNullParent = true);
130 : virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
131 : NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
132 : NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
133 : virtual already_AddRefed<nsIEditor> GetAssociatedEditor();
134 : virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
135 : virtual nsXPCClassInfo* GetClassInfo();
136 : private:
137 : nsresult GetColorHelper(nsIAtom* aAtom, nsAString& aColor);
138 :
139 : protected:
140 : BodyRule* mContentStyleRule;
141 : };
142 :
143 : //----------------------------------------------------------------------
144 :
145 0 : BodyRule::BodyRule(nsHTMLBodyElement* aPart)
146 : {
147 0 : mPart = aPart;
148 0 : }
149 :
150 0 : BodyRule::~BodyRule()
151 : {
152 0 : }
153 :
154 0 : NS_IMPL_ISUPPORTS1(BodyRule, nsIStyleRule)
155 :
156 : /* virtual */ void
157 0 : BodyRule::MapRuleInfoInto(nsRuleData* aData)
158 : {
159 0 : if (!(aData->mSIDs & NS_STYLE_INHERIT_BIT(Margin)) || !mPart)
160 0 : return; // We only care about margins.
161 :
162 0 : PRInt32 bodyMarginWidth = -1;
163 0 : PRInt32 bodyMarginHeight = -1;
164 0 : PRInt32 bodyTopMargin = -1;
165 0 : PRInt32 bodyBottomMargin = -1;
166 0 : PRInt32 bodyLeftMargin = -1;
167 0 : PRInt32 bodyRightMargin = -1;
168 :
169 : // check the mode (fortunately, the ruleData has a presContext for us to use!)
170 0 : NS_ASSERTION(aData->mPresContext, "null presContext in ruleNode was unexpected");
171 0 : nsCompatibility mode = aData->mPresContext->CompatibilityMode();
172 :
173 :
174 : const nsAttrValue* value;
175 0 : if (mPart->GetAttrCount() > 0) {
176 : // if marginwidth/marginheight are set, reflect them as 'margin'
177 0 : value = mPart->GetParsedAttr(nsGkAtoms::marginwidth);
178 0 : if (value && value->Type() == nsAttrValue::eInteger) {
179 0 : bodyMarginWidth = value->GetIntegerValue();
180 0 : if (bodyMarginWidth < 0) bodyMarginWidth = 0;
181 0 : nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
182 0 : if (marginLeft->GetUnit() == eCSSUnit_Null)
183 0 : marginLeft->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel);
184 0 : nsCSSValue* marginRight = aData->ValueForMarginRightValue();
185 0 : if (marginRight->GetUnit() == eCSSUnit_Null)
186 0 : marginRight->SetFloatValue((float)bodyMarginWidth, eCSSUnit_Pixel);
187 : }
188 :
189 0 : value = mPart->GetParsedAttr(nsGkAtoms::marginheight);
190 0 : if (value && value->Type() == nsAttrValue::eInteger) {
191 0 : bodyMarginHeight = value->GetIntegerValue();
192 0 : if (bodyMarginHeight < 0) bodyMarginHeight = 0;
193 0 : nsCSSValue* marginTop = aData->ValueForMarginTop();
194 0 : if (marginTop->GetUnit() == eCSSUnit_Null)
195 0 : marginTop->SetFloatValue((float)bodyMarginHeight, eCSSUnit_Pixel);
196 0 : nsCSSValue* marginBottom = aData->ValueForMarginBottom();
197 0 : if (marginBottom->GetUnit() == eCSSUnit_Null)
198 0 : marginBottom->SetFloatValue((float)bodyMarginHeight, eCSSUnit_Pixel);
199 : }
200 :
201 0 : if (eCompatibility_NavQuirks == mode){
202 : // topmargin (IE-attribute)
203 0 : value = mPart->GetParsedAttr(nsGkAtoms::topmargin);
204 0 : if (value && value->Type() == nsAttrValue::eInteger) {
205 0 : bodyTopMargin = value->GetIntegerValue();
206 0 : if (bodyTopMargin < 0) bodyTopMargin = 0;
207 0 : nsCSSValue* marginTop = aData->ValueForMarginTop();
208 0 : if (marginTop->GetUnit() == eCSSUnit_Null)
209 0 : marginTop->SetFloatValue((float)bodyTopMargin, eCSSUnit_Pixel);
210 : }
211 :
212 : // bottommargin (IE-attribute)
213 0 : value = mPart->GetParsedAttr(nsGkAtoms::bottommargin);
214 0 : if (value && value->Type() == nsAttrValue::eInteger) {
215 0 : bodyBottomMargin = value->GetIntegerValue();
216 0 : if (bodyBottomMargin < 0) bodyBottomMargin = 0;
217 0 : nsCSSValue* marginBottom = aData->ValueForMarginBottom();
218 0 : if (marginBottom->GetUnit() == eCSSUnit_Null)
219 0 : marginBottom->SetFloatValue((float)bodyBottomMargin, eCSSUnit_Pixel);
220 : }
221 :
222 : // leftmargin (IE-attribute)
223 0 : value = mPart->GetParsedAttr(nsGkAtoms::leftmargin);
224 0 : if (value && value->Type() == nsAttrValue::eInteger) {
225 0 : bodyLeftMargin = value->GetIntegerValue();
226 0 : if (bodyLeftMargin < 0) bodyLeftMargin = 0;
227 0 : nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
228 0 : if (marginLeft->GetUnit() == eCSSUnit_Null)
229 0 : marginLeft->SetFloatValue((float)bodyLeftMargin, eCSSUnit_Pixel);
230 : }
231 :
232 : // rightmargin (IE-attribute)
233 0 : value = mPart->GetParsedAttr(nsGkAtoms::rightmargin);
234 0 : if (value && value->Type() == nsAttrValue::eInteger) {
235 0 : bodyRightMargin = value->GetIntegerValue();
236 0 : if (bodyRightMargin < 0) bodyRightMargin = 0;
237 0 : nsCSSValue* marginRight = aData->ValueForMarginRightValue();
238 0 : if (marginRight->GetUnit() == eCSSUnit_Null)
239 0 : marginRight->SetFloatValue((float)bodyRightMargin, eCSSUnit_Pixel);
240 : }
241 : }
242 :
243 : }
244 :
245 : // if marginwidth or marginheight is set in the <frame> and not set in the <body>
246 : // reflect them as margin in the <body>
247 0 : if (bodyMarginWidth == -1 || bodyMarginHeight == -1) {
248 0 : nsCOMPtr<nsISupports> container = aData->mPresContext->GetContainer();
249 0 : if (container) {
250 0 : nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
251 0 : if (docShell) {
252 0 : nscoord frameMarginWidth=-1; // default value
253 0 : nscoord frameMarginHeight=-1; // default value
254 0 : docShell->GetMarginWidth(&frameMarginWidth); // -1 indicates not set
255 0 : docShell->GetMarginHeight(&frameMarginHeight);
256 0 : if ((frameMarginWidth >= 0) && (bodyMarginWidth == -1)) { // set in <frame> & not in <body>
257 0 : if (eCompatibility_NavQuirks == mode) {
258 0 : if ((bodyMarginHeight == -1) && (0 > frameMarginHeight)) // nav quirk
259 0 : frameMarginHeight = 0;
260 : }
261 : }
262 0 : if ((frameMarginHeight >= 0) && (bodyMarginHeight == -1)) { // set in <frame> & not in <body>
263 0 : if (eCompatibility_NavQuirks == mode) {
264 0 : if ((bodyMarginWidth == -1) && (0 > frameMarginWidth)) // nav quirk
265 0 : frameMarginWidth = 0;
266 : }
267 : }
268 :
269 0 : if ((bodyMarginWidth == -1) && (frameMarginWidth >= 0)) {
270 0 : nsCSSValue* marginLeft = aData->ValueForMarginLeftValue();
271 0 : if (marginLeft->GetUnit() == eCSSUnit_Null)
272 0 : marginLeft->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel);
273 0 : nsCSSValue* marginRight = aData->ValueForMarginRightValue();
274 0 : if (marginRight->GetUnit() == eCSSUnit_Null)
275 0 : marginRight->SetFloatValue((float)frameMarginWidth, eCSSUnit_Pixel);
276 : }
277 :
278 0 : if ((bodyMarginHeight == -1) && (frameMarginHeight >= 0)) {
279 0 : nsCSSValue* marginTop = aData->ValueForMarginTop();
280 0 : if (marginTop->GetUnit() == eCSSUnit_Null)
281 0 : marginTop->SetFloatValue((float)frameMarginHeight, eCSSUnit_Pixel);
282 0 : nsCSSValue* marginBottom = aData->ValueForMarginBottom();
283 0 : if (marginBottom->GetUnit() == eCSSUnit_Null)
284 0 : marginBottom->SetFloatValue((float)frameMarginHeight, eCSSUnit_Pixel);
285 : }
286 : }
287 : }
288 : }
289 : }
290 :
291 : #ifdef DEBUG
292 : /* virtual */ void
293 0 : BodyRule::List(FILE* out, PRInt32 aIndent) const
294 : {
295 0 : }
296 : #endif
297 :
298 : //----------------------------------------------------------------------
299 :
300 :
301 470 : NS_IMPL_NS_NEW_HTML_ELEMENT(Body)
302 :
303 :
304 235 : nsHTMLBodyElement::nsHTMLBodyElement(already_AddRefed<nsINodeInfo> aNodeInfo)
305 : : nsGenericHTMLElement(aNodeInfo),
306 235 : mContentStyleRule(nsnull)
307 : {
308 235 : }
309 :
310 705 : nsHTMLBodyElement::~nsHTMLBodyElement()
311 : {
312 235 : if (mContentStyleRule) {
313 0 : mContentStyleRule->mPart = nsnull;
314 0 : NS_RELEASE(mContentStyleRule);
315 : }
316 940 : }
317 :
318 :
319 2457 : NS_IMPL_ADDREF_INHERITED(nsHTMLBodyElement, nsGenericElement)
320 2457 : NS_IMPL_RELEASE_INHERITED(nsHTMLBodyElement, nsGenericElement)
321 :
322 1 : DOMCI_NODE_DATA(HTMLBodyElement, nsHTMLBodyElement)
323 :
324 : // QueryInterface implementation for nsHTMLBodyElement
325 7520 : NS_INTERFACE_TABLE_HEAD(nsHTMLBodyElement)
326 7520 : NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLBodyElement, nsIDOMHTMLBodyElement)
327 7519 : NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLBodyElement,
328 : nsGenericHTMLElement)
329 234 : NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLBodyElement)
330 :
331 0 : NS_IMPL_ELEMENT_CLONE(nsHTMLBodyElement)
332 :
333 :
334 0 : NS_IMPL_STRING_ATTR(nsHTMLBodyElement, Background, background)
335 0 : NS_IMPL_STRING_ATTR(nsHTMLBodyElement, VLink, vlink)
336 0 : NS_IMPL_STRING_ATTR(nsHTMLBodyElement, ALink, alink)
337 0 : NS_IMPL_STRING_ATTR(nsHTMLBodyElement, Link, link)
338 0 : NS_IMPL_STRING_ATTR(nsHTMLBodyElement, Text, text)
339 0 : NS_IMPL_STRING_ATTR(nsHTMLBodyElement, BgColor, bgcolor)
340 :
341 : bool
342 0 : nsHTMLBodyElement::ParseAttribute(PRInt32 aNamespaceID,
343 : nsIAtom* aAttribute,
344 : const nsAString& aValue,
345 : nsAttrValue& aResult)
346 : {
347 0 : if (aNamespaceID == kNameSpaceID_None) {
348 0 : if (aAttribute == nsGkAtoms::bgcolor ||
349 : aAttribute == nsGkAtoms::text ||
350 : aAttribute == nsGkAtoms::link ||
351 : aAttribute == nsGkAtoms::alink ||
352 : aAttribute == nsGkAtoms::vlink) {
353 0 : return aResult.ParseColor(aValue);
354 : }
355 0 : if (aAttribute == nsGkAtoms::marginwidth ||
356 : aAttribute == nsGkAtoms::marginheight ||
357 : aAttribute == nsGkAtoms::topmargin ||
358 : aAttribute == nsGkAtoms::bottommargin ||
359 : aAttribute == nsGkAtoms::leftmargin ||
360 : aAttribute == nsGkAtoms::rightmargin) {
361 0 : return aResult.ParseIntWithBounds(aValue, 0);
362 : }
363 : }
364 :
365 : return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
366 0 : aResult);
367 : }
368 :
369 : void
370 404 : nsHTMLBodyElement::UnbindFromTree(bool aDeep, bool aNullParent)
371 : {
372 404 : if (mContentStyleRule) {
373 0 : mContentStyleRule->mPart = nsnull;
374 :
375 : // destroy old style rule
376 0 : NS_RELEASE(mContentStyleRule);
377 : }
378 :
379 404 : nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
380 404 : }
381 :
382 : static
383 0 : void MapAttributesIntoRule(const nsMappedAttributes* aAttributes, nsRuleData* aData)
384 : {
385 0 : if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Display)) {
386 : // When display if first asked for, go ahead and get our colors set up.
387 0 : nsIPresShell *presShell = aData->mPresContext->GetPresShell();
388 0 : if (presShell) {
389 0 : nsIDocument *doc = presShell->GetDocument();
390 0 : if (doc) {
391 0 : nsHTMLStyleSheet* styleSheet = doc->GetAttributeStyleSheet();
392 0 : if (styleSheet) {
393 : const nsAttrValue* value;
394 : nscolor color;
395 0 : value = aAttributes->GetAttr(nsGkAtoms::link);
396 0 : if (value && value->GetColorValue(color)) {
397 0 : styleSheet->SetLinkColor(color);
398 : }
399 :
400 0 : value = aAttributes->GetAttr(nsGkAtoms::alink);
401 0 : if (value && value->GetColorValue(color)) {
402 0 : styleSheet->SetActiveLinkColor(color);
403 : }
404 :
405 0 : value = aAttributes->GetAttr(nsGkAtoms::vlink);
406 0 : if (value && value->GetColorValue(color)) {
407 0 : styleSheet->SetVisitedLinkColor(color);
408 : }
409 : }
410 : }
411 : }
412 : }
413 :
414 0 : if (aData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
415 0 : nsCSSValue *colorValue = aData->ValueForColor();
416 0 : if (colorValue->GetUnit() == eCSSUnit_Null &&
417 0 : aData->mPresContext->UseDocumentColors()) {
418 : // color: color
419 : nscolor color;
420 0 : const nsAttrValue* value = aAttributes->GetAttr(nsGkAtoms::text);
421 0 : if (value && value->GetColorValue(color))
422 0 : colorValue->SetColorValue(color);
423 : }
424 : }
425 :
426 0 : nsGenericHTMLElement::MapBackgroundAttributesInto(aAttributes, aData);
427 0 : nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
428 0 : }
429 :
430 : nsMapRuleToAttributesFunc
431 0 : nsHTMLBodyElement::GetAttributeMappingFunction() const
432 : {
433 0 : return &MapAttributesIntoRule;
434 : }
435 :
436 : NS_IMETHODIMP
437 0 : nsHTMLBodyElement::WalkContentStyleRules(nsRuleWalker* aRuleWalker)
438 : {
439 0 : nsGenericHTMLElement::WalkContentStyleRules(aRuleWalker);
440 :
441 0 : if (!mContentStyleRule && IsInDoc()) {
442 : // XXXbz should this use OwnerDoc() or GetCurrentDoc()?
443 : // sXBL/XBL2 issue!
444 0 : mContentStyleRule = new BodyRule(this);
445 0 : NS_IF_ADDREF(mContentStyleRule);
446 : }
447 0 : if (aRuleWalker && mContentStyleRule) {
448 0 : aRuleWalker->Forward(mContentStyleRule);
449 : }
450 0 : return NS_OK;
451 : }
452 :
453 : NS_IMETHODIMP_(bool)
454 0 : nsHTMLBodyElement::IsAttributeMapped(const nsIAtom* aAttribute) const
455 : {
456 : static const MappedAttributeEntry attributes[] = {
457 : { &nsGkAtoms::link },
458 : { &nsGkAtoms::vlink },
459 : { &nsGkAtoms::alink },
460 : { &nsGkAtoms::text },
461 : // These aren't mapped through attribute mapping, but they are
462 : // mapped through a style rule, so it is attribute dependent style.
463 : // XXXldb But we don't actually replace the body rule when we have
464 : // dynamic changes...
465 : { &nsGkAtoms::marginwidth },
466 : { &nsGkAtoms::marginheight },
467 : { nsnull },
468 : };
469 :
470 : static const MappedAttributeEntry* const map[] = {
471 : attributes,
472 : sCommonAttributeMap,
473 : sBackgroundAttributeMap,
474 : };
475 :
476 0 : return FindAttributeDependence(aAttribute, map);
477 : }
478 :
479 : already_AddRefed<nsIEditor>
480 0 : nsHTMLBodyElement::GetAssociatedEditor()
481 : {
482 0 : nsIEditor* editor = nsnull;
483 0 : if (NS_SUCCEEDED(GetEditorInternal(&editor)) && editor) {
484 0 : return editor;
485 : }
486 :
487 : // Make sure this is the actual body of the document
488 0 : if (!IsCurrentBodyElement()) {
489 0 : return nsnull;
490 : }
491 :
492 : // For designmode, try to get document's editor
493 0 : nsPresContext* presContext = GetPresContext();
494 0 : if (!presContext) {
495 0 : return nsnull;
496 : }
497 :
498 0 : nsCOMPtr<nsISupports> container = presContext->GetContainer();
499 0 : nsCOMPtr<nsIEditorDocShell> editorDocShell = do_QueryInterface(container);
500 0 : if (!editorDocShell) {
501 0 : return nsnull;
502 : }
503 :
504 0 : editorDocShell->GetEditor(&editor);
505 0 : return editor;
506 : }
507 :
508 : // Event listener stuff
509 : // FIXME (https://bugzilla.mozilla.org/show_bug.cgi?id=431767)
510 : // nsDocument::GetInnerWindow can return an outer window in some
511 : // cases. We don't want to stick an event listener on an outer
512 : // window, so bail if it does. See also similar code in
513 : // nsGenericHTMLElement::GetEventListenerManagerForAttr.
514 : #define EVENT(name_, id_, type_, struct_) /* nothing; handled by the superclass */
515 : #define FORWARDED_EVENT(name_, id_, type_, struct_) \
516 : NS_IMETHODIMP nsHTMLBodyElement::GetOn##name_(JSContext *cx, \
517 : jsval *vp) { \
518 : /* XXXbz note to self: add tests for this! */ \
519 : nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow(); \
520 : if (win && win->IsInnerWindow()) { \
521 : nsCOMPtr<nsIInlineEventHandlers> ev = do_QueryInterface(win); \
522 : return ev->GetOn##name_(cx, vp); \
523 : } \
524 : *vp = JSVAL_NULL; \
525 : return NS_OK; \
526 : } \
527 : NS_IMETHODIMP nsHTMLBodyElement::SetOn##name_(JSContext *cx, \
528 : const jsval &v) { \
529 : nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow(); \
530 : if (win && win->IsInnerWindow()) { \
531 : nsCOMPtr<nsIInlineEventHandlers> ev = do_QueryInterface(win); \
532 : return ev->SetOn##name_(cx, v); \
533 : } \
534 : return NS_OK; \
535 : }
536 : #define WINDOW_EVENT(name_, id_, type_, struct_) \
537 : NS_IMETHODIMP nsHTMLBodyElement::GetOn##name_(JSContext *cx, \
538 : jsval *vp) { \
539 : nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow(); \
540 : if (win && win->IsInnerWindow()) { \
541 : return win->GetOn##name_(cx, vp); \
542 : } \
543 : *vp = JSVAL_NULL; \
544 : return NS_OK; \
545 : } \
546 : NS_IMETHODIMP nsHTMLBodyElement::SetOn##name_(JSContext *cx, \
547 : const jsval &v) { \
548 : nsPIDOMWindow* win = OwnerDoc()->GetInnerWindow(); \
549 : if (win && win->IsInnerWindow()) { \
550 : return win->SetOn##name_(cx, v); \
551 : } \
552 : return NS_OK; \
553 : }
554 : #include "nsEventNameList.h"
555 : #undef WINDOW_EVENT
556 : #undef FORWARDED_EVENT
557 : #undef EVENT
|