1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 * An implementation for a Gecko-style content sink that knows how
9 * to build a content model (the "prototype" document) from XUL.
11 * For more information on XUL,
12 * see http://developer.mozilla.org/en/docs/XUL
15 #include "nsXULContentSink.h"
17 #include "jsfriendapi.h"
20 #include "nsIContentSink.h"
21 #include "mozilla/dom/Document.h"
22 #include "nsIFormControl.h"
23 #include "mozilla/dom/NodeInfo.h"
24 #include "nsIScriptContext.h"
25 #include "nsIScriptGlobalObject.h"
26 #include "nsNameSpaceManager.h"
27 #include "nsParserBase.h"
28 #include "nsViewManager.h"
29 #include "nsIScriptSecurityManager.h"
30 #include "nsLayoutCID.h"
31 #include "nsNetUtil.h"
33 #include "nsReadableUtils.h"
34 #include "nsXULElement.h"
35 #include "mozilla/Logging.h"
38 #include "nsXULPrototypeDocument.h" // XXXbe temporary
39 #include "mozilla/css/Loader.h"
41 #include "nsUnicharUtils.h"
42 #include "nsGkAtoms.h"
43 #include "nsContentUtils.h"
44 #include "nsAttrName.h"
45 #include "nsXMLContentSink.h"
46 #include "nsIScriptError.h"
47 #include "nsContentTypeParser.h"
49 static mozilla::LazyLogModule
gContentSinkLog("nsXULContentSink");
51 using namespace mozilla
;
52 using namespace mozilla::dom
;
53 //----------------------------------------------------------------------
55 XULContentSinkImpl::ContextStack::ContextStack() : mTop(nullptr), mDepth(0) {}
57 XULContentSinkImpl::ContextStack::~ContextStack() {
65 void XULContentSinkImpl::ContextStack::Push(RefPtr
<nsXULPrototypeNode
>&& aNode
,
67 mTop
= new Entry(std::move(aNode
), aState
, mTop
);
71 nsresult
XULContentSinkImpl::ContextStack::Pop(State
* aState
) {
72 if (mDepth
== 0) return NS_ERROR_UNEXPECTED
;
78 *aState
= entry
->mState
;
84 nsresult
XULContentSinkImpl::ContextStack::GetTopNode(
85 RefPtr
<nsXULPrototypeNode
>& aNode
) {
86 if (mDepth
== 0) return NS_ERROR_UNEXPECTED
;
92 nsresult
XULContentSinkImpl::ContextStack::GetTopChildren(
93 nsPrototypeArray
** aChildren
) {
94 if (mDepth
== 0) return NS_ERROR_UNEXPECTED
;
96 *aChildren
= &(mTop
->mChildren
);
100 void XULContentSinkImpl::ContextStack::Clear() {
103 // Release the root element (and its descendants).
104 Entry
* next
= cur
->mNext
;
113 void XULContentSinkImpl::ContextStack::Traverse(
114 nsCycleCollectionTraversalCallback
& aCb
) {
115 nsCycleCollectionTraversalCallback
& cb
= aCb
;
116 for (ContextStack::Entry
* tmp
= mTop
; tmp
; tmp
= tmp
->mNext
) {
117 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNode
)
118 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildren
)
122 //----------------------------------------------------------------------
124 XULContentSinkImpl::XULContentSinkImpl()
128 mConstrainSize(true),
131 XULContentSinkImpl::~XULContentSinkImpl() {
132 // The context stack _should_ be empty, unless something has gone wrong.
133 NS_ASSERTION(mContextStack
.Depth() == 0, "Context stack not empty?");
134 mContextStack
.Clear();
139 //----------------------------------------------------------------------
140 // nsISupports interface
142 NS_IMPL_CYCLE_COLLECTION_CLASS(XULContentSinkImpl
)
144 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XULContentSinkImpl
)
145 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNodeInfoManager
)
146 tmp
->mContextStack
.Clear();
147 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrototype
)
148 NS_IMPL_CYCLE_COLLECTION_UNLINK(mParser
)
149 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
151 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XULContentSinkImpl
)
152 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNodeInfoManager
)
153 tmp
->mContextStack
.Traverse(cb
);
154 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrototype
)
155 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParser
)
156 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
158 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULContentSinkImpl
)
159 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIXMLContentSink
)
160 NS_INTERFACE_MAP_ENTRY(nsIXMLContentSink
)
161 NS_INTERFACE_MAP_ENTRY(nsIExpatSink
)
162 NS_INTERFACE_MAP_ENTRY(nsIContentSink
)
165 NS_IMPL_CYCLE_COLLECTING_ADDREF(XULContentSinkImpl
)
166 NS_IMPL_CYCLE_COLLECTING_RELEASE(XULContentSinkImpl
)
168 //----------------------------------------------------------------------
169 // nsIContentSink interface
172 XULContentSinkImpl::DidBuildModel(bool aTerminated
) {
173 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
);
175 mPrototype
->NotifyLoadDone();
179 // Drop our reference to the parser to get rid of a circular
186 XULContentSinkImpl::WillInterrupt(void) {
187 // XXX Notify the docshell, if necessary
191 void XULContentSinkImpl::WillResume() {
192 // XXX Notify the docshell, if necessary
196 XULContentSinkImpl::SetParser(nsParserBase
* aParser
) {
201 void XULContentSinkImpl::SetDocumentCharset(
202 NotNull
<const Encoding
*> aEncoding
) {
203 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
);
205 doc
->SetDocumentCharacterSet(aEncoding
);
209 nsISupports
* XULContentSinkImpl::GetTarget() {
210 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
);
211 return ToSupports(doc
);
214 //----------------------------------------------------------------------
216 nsresult
XULContentSinkImpl::Init(Document
* aDocument
,
217 nsXULPrototypeDocument
* aPrototype
) {
218 MOZ_ASSERT(aDocument
!= nullptr, "null ptr");
219 if (!aDocument
) return NS_ERROR_NULL_POINTER
;
221 mDocument
= do_GetWeakReference(aDocument
);
222 mPrototype
= aPrototype
;
224 mDocumentURL
= mPrototype
->GetURI();
225 mNodeInfoManager
= aPrototype
->GetNodeInfoManager();
226 if (!mNodeInfoManager
) return NS_ERROR_UNEXPECTED
;
232 //----------------------------------------------------------------------
237 bool XULContentSinkImpl::IsDataInBuffer(char16_t
* buffer
, int32_t length
) {
238 for (int32_t i
= 0; i
< length
; ++i
) {
239 if (buffer
[i
] == ' ' || buffer
[i
] == '\t' || buffer
[i
] == '\n' ||
248 nsresult
XULContentSinkImpl::FlushText(bool aCreateTextNode
) {
252 // Don't do anything if there's no text to create a node from, or
253 // if they've told us not to create a text node
254 if (!mTextLength
) break;
256 if (!aCreateTextNode
) break;
258 RefPtr
<nsXULPrototypeNode
> node
;
259 rv
= mContextStack
.GetTopNode(node
);
260 if (NS_FAILED(rv
)) return rv
;
262 bool stripWhitespace
= false;
263 if (node
->mType
== nsXULPrototypeNode::eType_Element
) {
264 mozilla::dom::NodeInfo
* nodeInfo
=
265 static_cast<nsXULPrototypeElement
*>(node
.get())->mNodeInfo
;
267 if (nodeInfo
->NamespaceEquals(kNameSpaceID_XUL
))
268 stripWhitespace
= !nodeInfo
->Equals(nsGkAtoms::label
) &&
269 !nodeInfo
->Equals(nsGkAtoms::description
);
272 // Don't bother if there's nothing but whitespace.
273 if (stripWhitespace
&& !IsDataInBuffer(mText
, mTextLength
)) break;
275 // Don't bother if we're not in XUL document body
276 if (mState
!= eInDocumentElement
|| mContextStack
.Depth() == 0) break;
278 RefPtr
<nsXULPrototypeText
> text
= new nsXULPrototypeText();
279 text
->mValue
.Assign(mText
, mTextLength
);
280 if (stripWhitespace
) text
->mValue
.Trim(" \t\n\r");
283 nsPrototypeArray
* children
= nullptr;
284 rv
= mContextStack
.GetTopChildren(&children
);
285 if (NS_FAILED(rv
)) return rv
;
287 children
->AppendElement(text
.forget());
290 // Reset our text buffer
295 //----------------------------------------------------------------------
297 nsresult
XULContentSinkImpl::NormalizeAttributeString(
298 const char16_t
* aExpatName
, nsAttrName
& aName
) {
300 RefPtr
<nsAtom
> prefix
, localName
;
301 nsContentUtils::SplitExpatName(aExpatName
, getter_AddRefs(prefix
),
302 getter_AddRefs(localName
), &nameSpaceID
);
304 if (nameSpaceID
== kNameSpaceID_None
) {
305 aName
.SetTo(localName
);
310 RefPtr
<mozilla::dom::NodeInfo
> ni
;
311 ni
= mNodeInfoManager
->GetNodeInfo(localName
, prefix
, nameSpaceID
,
312 nsINode::ATTRIBUTE_NODE
);
318 /**** BEGIN NEW APIs ****/
321 XULContentSinkImpl::HandleStartElement(const char16_t
* aName
,
322 const char16_t
** aAtts
,
324 uint32_t aLineNumber
,
325 uint32_t aColumnNumber
) {
326 // XXX Hopefully the parser will flag this before we get here. If
327 // we're in the epilog, there should be no new elements
328 MOZ_ASSERT(mState
!= eInEpilog
, "tag in XUL doc epilog");
329 MOZ_ASSERT(aAttsCount
% 2 == 0, "incorrect aAttsCount");
331 // Adjust aAttsCount so it's the actual number of attributes
334 if (mState
== eInEpilog
) return NS_ERROR_UNEXPECTED
;
336 if (mState
!= eInScript
) {
341 RefPtr
<nsAtom
> prefix
, localName
;
342 nsContentUtils::SplitExpatName(aName
, getter_AddRefs(prefix
),
343 getter_AddRefs(localName
), &nameSpaceID
);
345 RefPtr
<mozilla::dom::NodeInfo
> nodeInfo
;
346 nodeInfo
= mNodeInfoManager
->GetNodeInfo(localName
, prefix
, nameSpaceID
,
347 nsINode::ELEMENT_NODE
);
352 // We're the root document element
353 rv
= OpenRoot(aAtts
, aAttsCount
, nodeInfo
);
356 case eInDocumentElement
:
357 rv
= OpenTag(aAtts
, aAttsCount
, aLineNumber
, nodeInfo
);
363 gContentSinkLog
, LogLevel::Warning
,
364 ("xul: warning: unexpected tags in epilog at line %d", aLineNumber
));
365 rv
= NS_ERROR_UNEXPECTED
; // XXX
373 XULContentSinkImpl::HandleEndElement(const char16_t
* aName
) {
374 // Never EVER return anything but NS_OK or
375 // NS_ERROR_HTMLPARSER_BLOCK from this method. Doing so will blow
376 // the parser's little mind all over the planet.
379 RefPtr
<nsXULPrototypeNode
> node
;
380 rv
= mContextStack
.GetTopNode(node
);
386 switch (node
->mType
) {
387 case nsXULPrototypeNode::eType_Element
: {
388 // Flush any text _now_, so that we'll get text nodes created
389 // before popping the stack.
392 // Pop the context stack and do prototype hookup.
393 nsPrototypeArray
* children
= nullptr;
394 rv
= mContextStack
.GetTopChildren(&children
);
395 if (NS_FAILED(rv
)) return rv
;
397 nsXULPrototypeElement
* element
=
398 static_cast<nsXULPrototypeElement
*>(node
.get());
400 int32_t count
= children
->Length();
402 element
->mChildren
.SetCapacity(count
);
404 for (int32_t i
= 0; i
< count
; ++i
)
405 element
->mChildren
.AppendElement(children
->ElementAt(i
));
409 case nsXULPrototypeNode::eType_Script
: {
410 nsXULPrototypeScript
* script
=
411 static_cast<nsXULPrototypeScript
*>(node
.get());
413 // If given a src= attribute, we must ignore script tag content.
414 if (!script
->mSrcURI
&& !script
->HasStencil()) {
415 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
);
417 script
->mOutOfLine
= false;
419 script
->Compile(mText
, mTextLength
, mDocumentURL
, script
->mLineNo
,
428 NS_ERROR("didn't expect that");
432 rv
= mContextStack
.Pop(&mState
);
433 NS_ASSERTION(NS_SUCCEEDED(rv
), "context stack corrupted");
434 if (NS_FAILED(rv
)) return rv
;
436 if (mContextStack
.Depth() == 0) {
437 // The root element should -always- be an element, because
438 // it'll have been created via XULContentSinkImpl::OpenRoot().
439 NS_ASSERTION(node
->mType
== nsXULPrototypeNode::eType_Element
,
440 "root is not an element");
441 if (node
->mType
!= nsXULPrototypeNode::eType_Element
)
442 return NS_ERROR_UNEXPECTED
;
444 // Now that we're done parsing, set the prototype document's
445 // root element. This transfers ownership of the prototype
446 // element tree to the prototype document.
447 nsXULPrototypeElement
* element
=
448 static_cast<nsXULPrototypeElement
*>(node
.get());
450 mPrototype
->SetRootElement(element
);
458 XULContentSinkImpl::HandleComment(const char16_t
* aName
) {
464 XULContentSinkImpl::HandleCDataSection(const char16_t
* aData
,
467 return AddText(aData
, aLength
);
471 XULContentSinkImpl::HandleDoctypeDecl(const nsAString
& aSubset
,
472 const nsAString
& aName
,
473 const nsAString
& aSystemId
,
474 const nsAString
& aPublicId
,
475 nsISupports
* aCatalogData
) {
480 XULContentSinkImpl::HandleCharacterData(const char16_t
* aData
,
482 if (aData
&& mState
!= eInProlog
&& mState
!= eInEpilog
) {
483 return AddText(aData
, aLength
);
489 XULContentSinkImpl::HandleProcessingInstruction(const char16_t
* aTarget
,
490 const char16_t
* aData
) {
493 const nsDependentString
target(aTarget
);
494 const nsDependentString
data(aData
);
496 // Note: the created nsXULPrototypePI has mRefCnt == 1
497 RefPtr
<nsXULPrototypePI
> pi
= new nsXULPrototypePI();
498 pi
->mTarget
= target
;
501 if (mState
== eInProlog
) {
502 // Note: passing in already addrefed pi
503 return mPrototype
->AddProcessingInstruction(pi
);
507 nsPrototypeArray
* children
= nullptr;
508 rv
= mContextStack
.GetTopChildren(&children
);
513 // XXX(Bug 1631371) Check if this should use a fallible operation as it
514 // pretended earlier.
515 children
->AppendElement(pi
);
521 XULContentSinkImpl::HandleXMLDeclaration(const char16_t
* aVersion
,
522 const char16_t
* aEncoding
,
523 int32_t aStandalone
) {
528 XULContentSinkImpl::ReportError(const char16_t
* aErrorText
,
529 const char16_t
* aSourceText
,
530 nsIScriptError
* aError
, bool* _retval
) {
531 MOZ_ASSERT(aError
&& aSourceText
&& aErrorText
, "Check arguments!!!");
533 // The expat driver should report the error.
538 // make sure to empty the context stack so that
539 // <parsererror> could become the root element.
540 mContextStack
.Clear();
544 // Clear any buffered-up text we have. It's enough to set the length to 0.
545 // The buffer itself is allocated when we're created and deleted in our
546 // destructor, so don't mess with it.
549 // return leaving the document empty if we're asked to not add a <parsererror>
551 nsCOMPtr
<Document
> idoc
= do_QueryReferent(mDocument
);
552 if (idoc
&& idoc
->SuppressParserErrorElement()) {
556 const char16_t
* noAtts
[] = {0, 0};
558 constexpr auto errorNs
=
559 u
"http://www.mozilla.org/newlayout/xml/parsererror.xml"_ns
;
561 nsAutoString
parsererror(errorNs
);
562 parsererror
.Append((char16_t
)0xFFFF);
563 parsererror
.AppendLiteral("parsererror");
565 rv
= HandleStartElement(parsererror
.get(), noAtts
, 0, 0, 0);
566 NS_ENSURE_SUCCESS(rv
, rv
);
568 rv
= HandleCharacterData(aErrorText
, NS_strlen(aErrorText
));
569 NS_ENSURE_SUCCESS(rv
, rv
);
571 nsAutoString
sourcetext(errorNs
);
572 sourcetext
.Append((char16_t
)0xFFFF);
573 sourcetext
.AppendLiteral("sourcetext");
575 rv
= HandleStartElement(sourcetext
.get(), noAtts
, 0, 0, 0);
576 NS_ENSURE_SUCCESS(rv
, rv
);
578 rv
= HandleCharacterData(aSourceText
, NS_strlen(aSourceText
));
579 NS_ENSURE_SUCCESS(rv
, rv
);
581 rv
= HandleEndElement(sourcetext
.get());
582 NS_ENSURE_SUCCESS(rv
, rv
);
584 rv
= HandleEndElement(parsererror
.get());
585 NS_ENSURE_SUCCESS(rv
, rv
);
590 nsresult
XULContentSinkImpl::OpenRoot(const char16_t
** aAttributes
,
591 const uint32_t aAttrLen
,
592 mozilla::dom::NodeInfo
* aNodeInfo
) {
593 NS_ASSERTION(mState
== eInProlog
, "how'd we get here?");
594 if (mState
!= eInProlog
) return NS_ERROR_UNEXPECTED
;
596 if (aNodeInfo
->Equals(nsGkAtoms::script
, kNameSpaceID_XHTML
) ||
597 aNodeInfo
->Equals(nsGkAtoms::script
, kNameSpaceID_XUL
)) {
598 MOZ_LOG(gContentSinkLog
, LogLevel::Error
,
599 ("xul: script tag not allowed as root content element"));
601 return NS_ERROR_UNEXPECTED
;
604 // Create the element
605 RefPtr
<nsXULPrototypeElement
> element
= new nsXULPrototypeElement(aNodeInfo
);
607 // Add the attributes
608 nsresult rv
= AddAttributes(aAttributes
, aAttrLen
, element
);
609 if (NS_FAILED(rv
)) return rv
;
611 // Push the element onto the context stack, so that child
612 // containers will hook up to us as their parent.
613 mContextStack
.Push(std::move(element
), mState
);
615 mState
= eInDocumentElement
;
619 nsresult
XULContentSinkImpl::OpenTag(const char16_t
** aAttributes
,
620 const uint32_t aAttrLen
,
621 const uint32_t aLineNumber
,
622 mozilla::dom::NodeInfo
* aNodeInfo
) {
623 // Create the element
624 RefPtr
<nsXULPrototypeElement
> element
= new nsXULPrototypeElement(aNodeInfo
);
626 // Link this element to its parent.
627 nsPrototypeArray
* children
= nullptr;
628 nsresult rv
= mContextStack
.GetTopChildren(&children
);
633 // Add the attributes
634 rv
= AddAttributes(aAttributes
, aAttrLen
, element
);
635 if (NS_FAILED(rv
)) return rv
;
637 children
->AppendElement(element
);
639 if (aNodeInfo
->Equals(nsGkAtoms::script
, kNameSpaceID_XHTML
) ||
640 aNodeInfo
->Equals(nsGkAtoms::script
, kNameSpaceID_XUL
)) {
641 // Do scripty things now
642 rv
= OpenScript(aAttributes
, aLineNumber
);
643 NS_ENSURE_SUCCESS(rv
, rv
);
645 NS_ASSERTION(mState
== eInScript
|| mState
== eInDocumentElement
,
647 if (mState
== eInScript
) {
648 // OpenScript has pushed the nsPrototypeScriptElement onto the
649 // stack, so we're done.
654 // Push the element onto the context stack, so that child
655 // containers will hook up to us as their parent.
656 mContextStack
.Push(std::move(element
), mState
);
658 mState
= eInDocumentElement
;
662 nsresult
XULContentSinkImpl::OpenScript(const char16_t
** aAttributes
,
663 const uint32_t aLineNumber
) {
664 bool isJavaScript
= true;
667 // Look for SRC attribute and look for a LANGUAGE attribute
669 while (*aAttributes
) {
670 const nsDependentString
key(aAttributes
[0]);
671 if (key
.EqualsLiteral("src")) {
672 src
.Assign(aAttributes
[1]);
673 } else if (key
.EqualsLiteral("type")) {
674 nsDependentString
str(aAttributes
[1]);
675 nsContentTypeParser
parser(str
);
676 nsAutoString mimeType
;
677 rv
= parser
.GetType(mimeType
);
679 if (rv
== NS_ERROR_INVALID_ARG
) {
680 // Fail immediately rather than checking if later things
684 // We do want the warning here
685 NS_ENSURE_SUCCESS(rv
, rv
);
688 // NOTE(emilio): Module scripts don't pass this test, aren't cached yet.
689 // If they become cached, then we need to tweak
690 // PrototypeDocumentContentSink and remove the special cases there.
691 if (nsContentUtils::IsJavascriptMIMEType(mimeType
)) {
694 // Get the version string, and ensure that JavaScript supports it.
695 nsAutoString versionName
;
696 rv
= parser
.GetParameter("version", versionName
);
698 if (NS_SUCCEEDED(rv
)) {
699 nsContentUtils::ReportToConsoleNonLocalized(
700 u
"Versioned JavaScripts are no longer supported. "
701 "Please remove the version parameter."_ns
,
702 nsIScriptError::errorFlag
, "XUL Document"_ns
, nullptr,
703 mDocumentURL
, u
""_ns
, aLineNumber
);
704 isJavaScript
= false;
705 } else if (rv
!= NS_ERROR_INVALID_ARG
) {
709 isJavaScript
= false;
711 } else if (key
.EqualsLiteral("language")) {
712 // Language is deprecated, and the impl in ScriptLoader ignores the
713 // various version strings anyway. So we make no attempt to support
714 // languages other than JS for language=
715 nsAutoString
lang(aAttributes
[1]);
716 if (nsContentUtils::IsJavaScriptLanguage(lang
)) {
723 // Don't process scripts that aren't JavaScript.
728 nsCOMPtr
<Document
> doc(do_QueryReferent(mDocument
));
729 nsCOMPtr
<nsIScriptGlobalObject
> globalObject
;
730 if (doc
) globalObject
= do_QueryInterface(doc
->GetWindow());
731 RefPtr
<nsXULPrototypeScript
> script
= new nsXULPrototypeScript(aLineNumber
);
733 // If there is a SRC attribute...
734 if (!src
.IsEmpty()) {
735 // Use the SRC attribute value to load the URL
736 rv
= NS_NewURI(getter_AddRefs(script
->mSrcURI
), src
, nullptr, mDocumentURL
);
738 // Check if this document is allowed to load a script from this source
739 // NOTE: if we ever allow scripts added via the DOM to run, we need to
740 // add a CheckLoadURI call for that as well.
741 if (NS_SUCCEEDED(rv
)) {
743 mSecMan
= do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID
, &rv
);
744 if (NS_SUCCEEDED(rv
)) {
745 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
, &rv
);
747 if (NS_SUCCEEDED(rv
)) {
748 rv
= mSecMan
->CheckLoadURIWithPrincipal(
749 doc
->NodePrincipal(), script
->mSrcURI
,
750 nsIScriptSecurityManager::ALLOW_CHROME
, doc
->InnerWindowID());
759 // Attempt to deserialize an out-of-line script from the FastLoad
760 // file right away. Otherwise we'll end up reloading the script and
761 // corrupting the FastLoad file trying to serialize it, in the case
762 // where it's already there.
763 script
->DeserializeOutOfLine(nullptr, mPrototype
);
766 nsPrototypeArray
* children
= nullptr;
767 rv
= mContextStack
.GetTopChildren(&children
);
772 children
->AppendElement(script
);
774 mConstrainSize
= false;
776 mContextStack
.Push(script
, mState
);
782 nsresult
XULContentSinkImpl::AddAttributes(const char16_t
** aAttributes
,
783 const uint32_t aAttrLen
,
784 nsXULPrototypeElement
* aElement
) {
785 // Add tag attributes to the element
788 // Create storage for the attributes
789 nsXULPrototypeAttribute
* attrs
= nullptr;
791 attrs
= aElement
->mAttributes
.AppendElements(aAttrLen
);
794 // Copy the attributes into the prototype
796 for (i
= 0; i
< aAttrLen
; ++i
) {
797 rv
= NormalizeAttributeString(aAttributes
[i
* 2], attrs
[i
].mName
);
798 NS_ENSURE_SUCCESS(rv
, rv
);
800 rv
= aElement
->SetAttrAt(i
, nsDependentString(aAttributes
[i
* 2 + 1]),
802 NS_ENSURE_SUCCESS(rv
, rv
);
804 if (MOZ_LOG_TEST(gContentSinkLog
, LogLevel::Debug
)) {
805 nsAutoString extraWhiteSpace
;
806 int32_t cnt
= mContextStack
.Depth();
807 while (--cnt
>= 0) extraWhiteSpace
.AppendLiteral(" ");
808 nsAutoString qnameC
, valueC
;
809 qnameC
.Assign(aAttributes
[0]);
810 valueC
.Assign(aAttributes
[1]);
811 MOZ_LOG(gContentSinkLog
, LogLevel::Debug
,
812 ("xul: %.5d. %s %s=%s",
813 -1, // XXX pass in line number
814 NS_ConvertUTF16toUTF8(extraWhiteSpace
).get(),
815 NS_ConvertUTF16toUTF8(qnameC
).get(),
816 NS_ConvertUTF16toUTF8(valueC
).get()));
823 nsresult
XULContentSinkImpl::AddText(const char16_t
* aText
, int32_t aLength
) {
824 // Create buffer when we first need it
825 if (0 == mTextSize
) {
826 mText
= (char16_t
*)malloc(sizeof(char16_t
) * 4096);
827 if (nullptr == mText
) {
828 return NS_ERROR_OUT_OF_MEMORY
;
833 // Copy data from string into our buffer; flush buffer when it fills up
835 while (0 != aLength
) {
836 int32_t amount
= mTextSize
- mTextLength
;
837 if (amount
> aLength
) {
841 if (mConstrainSize
) {
842 nsresult rv
= FlushText();
847 CheckedInt32 size
= mTextSize
;
849 if (!size
.isValid()) {
850 return NS_ERROR_OUT_OF_MEMORY
;
852 mTextSize
= size
.value();
854 mText
= (char16_t
*)realloc(mText
, sizeof(char16_t
) * mTextSize
);
855 if (nullptr == mText
) {
856 return NS_ERROR_OUT_OF_MEMORY
;
860 memcpy(&mText
[mTextLength
], aText
+ offset
, sizeof(char16_t
) * amount
);
862 mTextLength
+= amount
;