|
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/. */ |
|
5 |
|
6 #include "nsScriptElement.h" |
|
7 #include "mozilla/BasicEvents.h" |
|
8 #include "mozilla/EventDispatcher.h" |
|
9 #include "mozilla/dom/Element.h" |
|
10 #include "nsContentUtils.h" |
|
11 #include "nsPresContext.h" |
|
12 #include "nsScriptLoader.h" |
|
13 #include "nsIParser.h" |
|
14 #include "nsAutoPtr.h" |
|
15 #include "nsGkAtoms.h" |
|
16 #include "nsContentSink.h" |
|
17 |
|
18 using namespace mozilla; |
|
19 using namespace mozilla::dom; |
|
20 |
|
21 NS_IMETHODIMP |
|
22 nsScriptElement::ScriptAvailable(nsresult aResult, |
|
23 nsIScriptElement *aElement, |
|
24 bool aIsInline, |
|
25 nsIURI *aURI, |
|
26 int32_t aLineNo) |
|
27 { |
|
28 if (!aIsInline && NS_FAILED(aResult)) { |
|
29 return FireErrorEvent(); |
|
30 } |
|
31 return NS_OK; |
|
32 } |
|
33 |
|
34 /* virtual */ nsresult |
|
35 nsScriptElement::FireErrorEvent() |
|
36 { |
|
37 nsCOMPtr<nsIContent> cont = |
|
38 do_QueryInterface((nsIScriptElement*) this); |
|
39 |
|
40 return nsContentUtils::DispatchTrustedEvent(cont->OwnerDoc(), |
|
41 cont, |
|
42 NS_LITERAL_STRING("error"), |
|
43 false /* bubbles */, |
|
44 false /* cancelable */); |
|
45 } |
|
46 |
|
47 NS_IMETHODIMP |
|
48 nsScriptElement::ScriptEvaluated(nsresult aResult, |
|
49 nsIScriptElement *aElement, |
|
50 bool aIsInline) |
|
51 { |
|
52 nsresult rv = NS_OK; |
|
53 if (!aIsInline) { |
|
54 nsCOMPtr<nsIContent> cont = |
|
55 do_QueryInterface((nsIScriptElement*) this); |
|
56 |
|
57 nsRefPtr<nsPresContext> presContext = |
|
58 nsContentUtils::GetContextForContent(cont); |
|
59 |
|
60 nsEventStatus status = nsEventStatus_eIgnore; |
|
61 uint32_t type = NS_SUCCEEDED(aResult) ? NS_LOAD : NS_LOAD_ERROR; |
|
62 WidgetEvent event(true, type); |
|
63 // Load event doesn't bubble. |
|
64 event.mFlags.mBubbles = (type != NS_LOAD); |
|
65 |
|
66 EventDispatcher::Dispatch(cont, presContext, &event, nullptr, &status); |
|
67 } |
|
68 |
|
69 return rv; |
|
70 } |
|
71 |
|
72 void |
|
73 nsScriptElement::CharacterDataChanged(nsIDocument *aDocument, |
|
74 nsIContent* aContent, |
|
75 CharacterDataChangeInfo* aInfo) |
|
76 { |
|
77 MaybeProcessScript(); |
|
78 } |
|
79 |
|
80 void |
|
81 nsScriptElement::AttributeChanged(nsIDocument* aDocument, |
|
82 Element* aElement, |
|
83 int32_t aNameSpaceID, |
|
84 nsIAtom* aAttribute, |
|
85 int32_t aModType) |
|
86 { |
|
87 MaybeProcessScript(); |
|
88 } |
|
89 |
|
90 void |
|
91 nsScriptElement::ContentAppended(nsIDocument* aDocument, |
|
92 nsIContent* aContainer, |
|
93 nsIContent* aFirstNewContent, |
|
94 int32_t aNewIndexInContainer) |
|
95 { |
|
96 MaybeProcessScript(); |
|
97 } |
|
98 |
|
99 void |
|
100 nsScriptElement::ContentInserted(nsIDocument *aDocument, |
|
101 nsIContent* aContainer, |
|
102 nsIContent* aChild, |
|
103 int32_t aIndexInContainer) |
|
104 { |
|
105 MaybeProcessScript(); |
|
106 } |
|
107 |
|
108 bool |
|
109 nsScriptElement::MaybeProcessScript() |
|
110 { |
|
111 nsCOMPtr<nsIContent> cont = |
|
112 do_QueryInterface((nsIScriptElement*) this); |
|
113 |
|
114 NS_ASSERTION(cont->DebugGetSlots()->mMutationObservers.Contains(this), |
|
115 "You forgot to add self as observer"); |
|
116 |
|
117 if (mAlreadyStarted || !mDoneAddingChildren || !cont->IsInDoc() || |
|
118 mMalformed || !HasScriptContent()) { |
|
119 return false; |
|
120 } |
|
121 |
|
122 FreezeUriAsyncDefer(); |
|
123 |
|
124 mAlreadyStarted = true; |
|
125 |
|
126 nsIDocument* ownerDoc = cont->OwnerDoc(); |
|
127 nsCOMPtr<nsIParser> parser = ((nsIScriptElement*) this)->GetCreatorParser(); |
|
128 if (parser) { |
|
129 nsCOMPtr<nsIContentSink> sink = parser->GetContentSink(); |
|
130 if (sink) { |
|
131 nsCOMPtr<nsIDocument> parserDoc = do_QueryInterface(sink->GetTarget()); |
|
132 if (ownerDoc != parserDoc) { |
|
133 // Willful violation of HTML5 as of 2010-12-01 |
|
134 return false; |
|
135 } |
|
136 } |
|
137 } |
|
138 |
|
139 nsRefPtr<nsScriptLoader> loader = ownerDoc->ScriptLoader(); |
|
140 return loader->ProcessScriptElement(this); |
|
141 } |