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 "nsHTMLStyleSheet.h"
21 #include "nsIContentSink.h"
22 #include "mozilla/dom/Document.h"
23 #include "nsIFormControl.h"
24 #include "mozilla/dom/NodeInfo.h"
25 #include "nsIScriptContext.h"
26 #include "nsIScriptGlobalObject.h"
27 #include "nsNameSpaceManager.h"
28 #include "nsParserBase.h"
29 #include "nsViewManager.h"
30 #include "nsIScriptSecurityManager.h"
31 #include "nsLayoutCID.h"
32 #include "nsNetUtil.h"
34 #include "nsReadableUtils.h"
35 #include "nsXULElement.h"
36 #include "mozilla/Logging.h"
39 #include "nsXULPrototypeDocument.h" // XXXbe temporary
40 #include "mozilla/css/Loader.h"
42 #include "nsUnicharUtils.h"
43 #include "nsGkAtoms.h"
44 #include "nsContentUtils.h"
45 #include "nsAttrName.h"
46 #include "nsXMLContentSink.h"
47 #include "nsIScriptError.h"
48 #include "nsContentTypeParser.h"
50 static mozilla::LazyLogModule
gContentSinkLog("nsXULContentSink");
52 using namespace mozilla
;
53 using namespace mozilla::dom
;
54 //----------------------------------------------------------------------
56 XULContentSinkImpl::ContextStack::ContextStack() : mTop(nullptr), mDepth(0) {}
58 XULContentSinkImpl::ContextStack::~ContextStack() {
66 void XULContentSinkImpl::ContextStack::Push(RefPtr
<nsXULPrototypeNode
>&& aNode
,
68 mTop
= new Entry(std::move(aNode
), aState
, mTop
);
72 nsresult
XULContentSinkImpl::ContextStack::Pop(State
* aState
) {
73 if (mDepth
== 0) return NS_ERROR_UNEXPECTED
;
79 *aState
= entry
->mState
;
85 nsresult
XULContentSinkImpl::ContextStack::GetTopNode(
86 RefPtr
<nsXULPrototypeNode
>& aNode
) {
87 if (mDepth
== 0) return NS_ERROR_UNEXPECTED
;
93 nsresult
XULContentSinkImpl::ContextStack::GetTopChildren(
94 nsPrototypeArray
** aChildren
) {
95 if (mDepth
== 0) return NS_ERROR_UNEXPECTED
;
97 *aChildren
= &(mTop
->mChildren
);
101 void XULContentSinkImpl::ContextStack::Clear() {
104 // Release the root element (and its descendants).
105 Entry
* next
= cur
->mNext
;
114 void XULContentSinkImpl::ContextStack::Traverse(
115 nsCycleCollectionTraversalCallback
& aCb
) {
116 nsCycleCollectionTraversalCallback
& cb
= aCb
;
117 for (ContextStack::Entry
* tmp
= mTop
; tmp
; tmp
= tmp
->mNext
) {
118 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNode
)
119 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildren
)
123 //----------------------------------------------------------------------
125 XULContentSinkImpl::XULContentSinkImpl()
129 mConstrainSize(true),
132 XULContentSinkImpl::~XULContentSinkImpl() {
133 // The context stack _should_ be empty, unless something has gone wrong.
134 NS_ASSERTION(mContextStack
.Depth() == 0, "Context stack not empty?");
135 mContextStack
.Clear();
140 //----------------------------------------------------------------------
141 // nsISupports interface
143 NS_IMPL_CYCLE_COLLECTION_CLASS(XULContentSinkImpl
)
145 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XULContentSinkImpl
)
146 NS_IMPL_CYCLE_COLLECTION_UNLINK(mNodeInfoManager
)
147 tmp
->mContextStack
.Clear();
148 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPrototype
)
149 NS_IMPL_CYCLE_COLLECTION_UNLINK(mParser
)
150 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
152 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XULContentSinkImpl
)
153 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNodeInfoManager
)
154 tmp
->mContextStack
.Traverse(cb
);
155 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrototype
)
156 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParser
)
157 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
159 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(XULContentSinkImpl
)
160 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIXMLContentSink
)
161 NS_INTERFACE_MAP_ENTRY(nsIXMLContentSink
)
162 NS_INTERFACE_MAP_ENTRY(nsIExpatSink
)
163 NS_INTERFACE_MAP_ENTRY(nsIContentSink
)
166 NS_IMPL_CYCLE_COLLECTING_ADDREF(XULContentSinkImpl
)
167 NS_IMPL_CYCLE_COLLECTING_RELEASE(XULContentSinkImpl
)
169 //----------------------------------------------------------------------
170 // nsIContentSink interface
173 XULContentSinkImpl::WillBuildModel(nsDTDMode aDTDMode
) {
175 if (!mParentContentSink
) {
176 // If we're _not_ an overlay, then notify the document that
177 // the load is beginning.
178 mDocument
->BeginLoad();
186 XULContentSinkImpl::DidBuildModel(bool aTerminated
) {
187 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
);
189 mPrototype
->NotifyLoadDone();
193 // Drop our reference to the parser to get rid of a circular
200 XULContentSinkImpl::WillInterrupt(void) {
201 // XXX Notify the docshell, if necessary
206 XULContentSinkImpl::WillResume(void) {
207 // XXX Notify the docshell, if necessary
212 XULContentSinkImpl::SetParser(nsParserBase
* aParser
) {
217 void XULContentSinkImpl::SetDocumentCharset(
218 NotNull
<const Encoding
*> aEncoding
) {
219 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
);
221 doc
->SetDocumentCharacterSet(aEncoding
);
225 nsISupports
* XULContentSinkImpl::GetTarget() {
226 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
);
227 return ToSupports(doc
);
230 //----------------------------------------------------------------------
232 nsresult
XULContentSinkImpl::Init(Document
* aDocument
,
233 nsXULPrototypeDocument
* aPrototype
) {
234 MOZ_ASSERT(aDocument
!= nullptr, "null ptr");
235 if (!aDocument
) return NS_ERROR_NULL_POINTER
;
237 mDocument
= do_GetWeakReference(aDocument
);
238 mPrototype
= aPrototype
;
240 mDocumentURL
= mPrototype
->GetURI();
241 mNodeInfoManager
= aPrototype
->GetNodeInfoManager();
242 if (!mNodeInfoManager
) return NS_ERROR_UNEXPECTED
;
248 //----------------------------------------------------------------------
253 bool XULContentSinkImpl::IsDataInBuffer(char16_t
* buffer
, int32_t length
) {
254 for (int32_t i
= 0; i
< length
; ++i
) {
255 if (buffer
[i
] == ' ' || buffer
[i
] == '\t' || buffer
[i
] == '\n' ||
264 nsresult
XULContentSinkImpl::FlushText(bool aCreateTextNode
) {
268 // Don't do anything if there's no text to create a node from, or
269 // if they've told us not to create a text node
270 if (!mTextLength
) break;
272 if (!aCreateTextNode
) break;
274 RefPtr
<nsXULPrototypeNode
> node
;
275 rv
= mContextStack
.GetTopNode(node
);
276 if (NS_FAILED(rv
)) return rv
;
278 bool stripWhitespace
= false;
279 if (node
->mType
== nsXULPrototypeNode::eType_Element
) {
280 mozilla::dom::NodeInfo
* nodeInfo
=
281 static_cast<nsXULPrototypeElement
*>(node
.get())->mNodeInfo
;
283 if (nodeInfo
->NamespaceEquals(kNameSpaceID_XUL
))
284 stripWhitespace
= !nodeInfo
->Equals(nsGkAtoms::label
) &&
285 !nodeInfo
->Equals(nsGkAtoms::description
);
288 // Don't bother if there's nothing but whitespace.
289 if (stripWhitespace
&& !IsDataInBuffer(mText
, mTextLength
)) break;
291 // Don't bother if we're not in XUL document body
292 if (mState
!= eInDocumentElement
|| mContextStack
.Depth() == 0) break;
294 RefPtr
<nsXULPrototypeText
> text
= new nsXULPrototypeText();
295 text
->mValue
.Assign(mText
, mTextLength
);
296 if (stripWhitespace
) text
->mValue
.Trim(" \t\n\r");
299 nsPrototypeArray
* children
= nullptr;
300 rv
= mContextStack
.GetTopChildren(&children
);
301 if (NS_FAILED(rv
)) return rv
;
303 children
->AppendElement(text
.forget());
306 // Reset our text buffer
311 //----------------------------------------------------------------------
313 nsresult
XULContentSinkImpl::NormalizeAttributeString(
314 const char16_t
* aExpatName
, nsAttrName
& aName
) {
316 RefPtr
<nsAtom
> prefix
, localName
;
317 nsContentUtils::SplitExpatName(aExpatName
, getter_AddRefs(prefix
),
318 getter_AddRefs(localName
), &nameSpaceID
);
320 if (nameSpaceID
== kNameSpaceID_None
) {
321 aName
.SetTo(localName
);
326 RefPtr
<mozilla::dom::NodeInfo
> ni
;
327 ni
= mNodeInfoManager
->GetNodeInfo(localName
, prefix
, nameSpaceID
,
328 nsINode::ATTRIBUTE_NODE
);
334 /**** BEGIN NEW APIs ****/
337 XULContentSinkImpl::HandleStartElement(const char16_t
* aName
,
338 const char16_t
** aAtts
,
340 uint32_t aLineNumber
,
341 uint32_t aColumnNumber
) {
342 // XXX Hopefully the parser will flag this before we get here. If
343 // we're in the epilog, there should be no new elements
344 MOZ_ASSERT(mState
!= eInEpilog
, "tag in XUL doc epilog");
345 MOZ_ASSERT(aAttsCount
% 2 == 0, "incorrect aAttsCount");
347 // Adjust aAttsCount so it's the actual number of attributes
350 if (mState
== eInEpilog
) return NS_ERROR_UNEXPECTED
;
352 if (mState
!= eInScript
) {
357 RefPtr
<nsAtom
> prefix
, localName
;
358 nsContentUtils::SplitExpatName(aName
, getter_AddRefs(prefix
),
359 getter_AddRefs(localName
), &nameSpaceID
);
361 RefPtr
<mozilla::dom::NodeInfo
> nodeInfo
;
362 nodeInfo
= mNodeInfoManager
->GetNodeInfo(localName
, prefix
, nameSpaceID
,
363 nsINode::ELEMENT_NODE
);
368 // We're the root document element
369 rv
= OpenRoot(aAtts
, aAttsCount
, nodeInfo
);
372 case eInDocumentElement
:
373 rv
= OpenTag(aAtts
, aAttsCount
, aLineNumber
, nodeInfo
);
379 gContentSinkLog
, LogLevel::Warning
,
380 ("xul: warning: unexpected tags in epilog at line %d", aLineNumber
));
381 rv
= NS_ERROR_UNEXPECTED
; // XXX
389 XULContentSinkImpl::HandleEndElement(const char16_t
* aName
) {
390 // Never EVER return anything but NS_OK or
391 // NS_ERROR_HTMLPARSER_BLOCK from this method. Doing so will blow
392 // the parser's little mind all over the planet.
395 RefPtr
<nsXULPrototypeNode
> node
;
396 rv
= mContextStack
.GetTopNode(node
);
402 switch (node
->mType
) {
403 case nsXULPrototypeNode::eType_Element
: {
404 // Flush any text _now_, so that we'll get text nodes created
405 // before popping the stack.
408 // Pop the context stack and do prototype hookup.
409 nsPrototypeArray
* children
= nullptr;
410 rv
= mContextStack
.GetTopChildren(&children
);
411 if (NS_FAILED(rv
)) return rv
;
413 nsXULPrototypeElement
* element
=
414 static_cast<nsXULPrototypeElement
*>(node
.get());
416 int32_t count
= children
->Length();
418 element
->mChildren
.SetCapacity(count
);
420 for (int32_t i
= 0; i
< count
; ++i
)
421 element
->mChildren
.AppendElement(children
->ElementAt(i
));
425 case nsXULPrototypeNode::eType_Script
: {
426 nsXULPrototypeScript
* script
=
427 static_cast<nsXULPrototypeScript
*>(node
.get());
429 // If given a src= attribute, we must ignore script tag content.
430 if (!script
->mSrcURI
&& !script
->HasStencil()) {
431 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
);
433 script
->mOutOfLine
= false;
435 script
->Compile(mText
, mTextLength
, JS::SourceOwnership::Borrowed
,
436 mDocumentURL
, script
->mLineNo
, doc
);
444 NS_ERROR("didn't expect that");
448 rv
= mContextStack
.Pop(&mState
);
449 NS_ASSERTION(NS_SUCCEEDED(rv
), "context stack corrupted");
450 if (NS_FAILED(rv
)) return rv
;
452 if (mContextStack
.Depth() == 0) {
453 // The root element should -always- be an element, because
454 // it'll have been created via XULContentSinkImpl::OpenRoot().
455 NS_ASSERTION(node
->mType
== nsXULPrototypeNode::eType_Element
,
456 "root is not an element");
457 if (node
->mType
!= nsXULPrototypeNode::eType_Element
)
458 return NS_ERROR_UNEXPECTED
;
460 // Now that we're done parsing, set the prototype document's
461 // root element. This transfers ownership of the prototype
462 // element tree to the prototype document.
463 nsXULPrototypeElement
* element
=
464 static_cast<nsXULPrototypeElement
*>(node
.get());
466 mPrototype
->SetRootElement(element
);
474 XULContentSinkImpl::HandleComment(const char16_t
* aName
) {
480 XULContentSinkImpl::HandleCDataSection(const char16_t
* aData
,
483 return AddText(aData
, aLength
);
487 XULContentSinkImpl::HandleDoctypeDecl(const nsAString
& aSubset
,
488 const nsAString
& aName
,
489 const nsAString
& aSystemId
,
490 const nsAString
& aPublicId
,
491 nsISupports
* aCatalogData
) {
496 XULContentSinkImpl::HandleCharacterData(const char16_t
* aData
,
498 if (aData
&& mState
!= eInProlog
&& mState
!= eInEpilog
) {
499 return AddText(aData
, aLength
);
505 XULContentSinkImpl::HandleProcessingInstruction(const char16_t
* aTarget
,
506 const char16_t
* aData
) {
509 const nsDependentString
target(aTarget
);
510 const nsDependentString
data(aData
);
512 // Note: the created nsXULPrototypePI has mRefCnt == 1
513 RefPtr
<nsXULPrototypePI
> pi
= new nsXULPrototypePI();
514 pi
->mTarget
= target
;
517 if (mState
== eInProlog
) {
518 // Note: passing in already addrefed pi
519 return mPrototype
->AddProcessingInstruction(pi
);
523 nsPrototypeArray
* children
= nullptr;
524 rv
= mContextStack
.GetTopChildren(&children
);
529 // XXX(Bug 1631371) Check if this should use a fallible operation as it
530 // pretended earlier.
531 children
->AppendElement(pi
);
537 XULContentSinkImpl::HandleXMLDeclaration(const char16_t
* aVersion
,
538 const char16_t
* aEncoding
,
539 int32_t aStandalone
) {
544 XULContentSinkImpl::ReportError(const char16_t
* aErrorText
,
545 const char16_t
* aSourceText
,
546 nsIScriptError
* aError
, bool* _retval
) {
547 MOZ_ASSERT(aError
&& aSourceText
&& aErrorText
, "Check arguments!!!");
549 // The expat driver should report the error.
554 // make sure to empty the context stack so that
555 // <parsererror> could become the root element.
556 mContextStack
.Clear();
560 // Clear any buffered-up text we have. It's enough to set the length to 0.
561 // The buffer itself is allocated when we're created and deleted in our
562 // destructor, so don't mess with it.
565 // return leaving the document empty if we're asked to not add a <parsererror>
567 nsCOMPtr
<Document
> idoc
= do_QueryReferent(mDocument
);
568 if (idoc
&& idoc
->SuppressParserErrorElement()) {
572 const char16_t
* noAtts
[] = {0, 0};
574 constexpr auto errorNs
=
575 u
"http://www.mozilla.org/newlayout/xml/parsererror.xml"_ns
;
577 nsAutoString
parsererror(errorNs
);
578 parsererror
.Append((char16_t
)0xFFFF);
579 parsererror
.AppendLiteral("parsererror");
581 rv
= HandleStartElement(parsererror
.get(), noAtts
, 0, 0, 0);
582 NS_ENSURE_SUCCESS(rv
, rv
);
584 rv
= HandleCharacterData(aErrorText
, NS_strlen(aErrorText
));
585 NS_ENSURE_SUCCESS(rv
, rv
);
587 nsAutoString
sourcetext(errorNs
);
588 sourcetext
.Append((char16_t
)0xFFFF);
589 sourcetext
.AppendLiteral("sourcetext");
591 rv
= HandleStartElement(sourcetext
.get(), noAtts
, 0, 0, 0);
592 NS_ENSURE_SUCCESS(rv
, rv
);
594 rv
= HandleCharacterData(aSourceText
, NS_strlen(aSourceText
));
595 NS_ENSURE_SUCCESS(rv
, rv
);
597 rv
= HandleEndElement(sourcetext
.get());
598 NS_ENSURE_SUCCESS(rv
, rv
);
600 rv
= HandleEndElement(parsererror
.get());
601 NS_ENSURE_SUCCESS(rv
, rv
);
606 nsresult
XULContentSinkImpl::OpenRoot(const char16_t
** aAttributes
,
607 const uint32_t aAttrLen
,
608 mozilla::dom::NodeInfo
* aNodeInfo
) {
609 NS_ASSERTION(mState
== eInProlog
, "how'd we get here?");
610 if (mState
!= eInProlog
) return NS_ERROR_UNEXPECTED
;
612 if (aNodeInfo
->Equals(nsGkAtoms::script
, kNameSpaceID_XHTML
) ||
613 aNodeInfo
->Equals(nsGkAtoms::script
, kNameSpaceID_XUL
)) {
614 MOZ_LOG(gContentSinkLog
, LogLevel::Error
,
615 ("xul: script tag not allowed as root content element"));
617 return NS_ERROR_UNEXPECTED
;
620 // Create the element
621 RefPtr
<nsXULPrototypeElement
> element
= new nsXULPrototypeElement(aNodeInfo
);
623 // Add the attributes
624 nsresult rv
= AddAttributes(aAttributes
, aAttrLen
, element
);
625 if (NS_FAILED(rv
)) return rv
;
627 // Push the element onto the context stack, so that child
628 // containers will hook up to us as their parent.
629 mContextStack
.Push(std::move(element
), mState
);
631 mState
= eInDocumentElement
;
635 nsresult
XULContentSinkImpl::OpenTag(const char16_t
** aAttributes
,
636 const uint32_t aAttrLen
,
637 const uint32_t aLineNumber
,
638 mozilla::dom::NodeInfo
* aNodeInfo
) {
639 // Create the element
640 RefPtr
<nsXULPrototypeElement
> element
= new nsXULPrototypeElement(aNodeInfo
);
642 // Link this element to its parent.
643 nsPrototypeArray
* children
= nullptr;
644 nsresult rv
= mContextStack
.GetTopChildren(&children
);
649 // Add the attributes
650 rv
= AddAttributes(aAttributes
, aAttrLen
, element
);
651 if (NS_FAILED(rv
)) return rv
;
653 children
->AppendElement(element
);
655 if (aNodeInfo
->Equals(nsGkAtoms::script
, kNameSpaceID_XHTML
) ||
656 aNodeInfo
->Equals(nsGkAtoms::script
, kNameSpaceID_XUL
)) {
657 // Do scripty things now
658 rv
= OpenScript(aAttributes
, aLineNumber
);
659 NS_ENSURE_SUCCESS(rv
, rv
);
661 NS_ASSERTION(mState
== eInScript
|| mState
== eInDocumentElement
,
663 if (mState
== eInScript
) {
664 // OpenScript has pushed the nsPrototypeScriptElement onto the
665 // stack, so we're done.
670 // Push the element onto the context stack, so that child
671 // containers will hook up to us as their parent.
672 mContextStack
.Push(std::move(element
), mState
);
674 mState
= eInDocumentElement
;
678 nsresult
XULContentSinkImpl::OpenScript(const char16_t
** aAttributes
,
679 const uint32_t aLineNumber
) {
680 bool isJavaScript
= true;
683 // Look for SRC attribute and look for a LANGUAGE attribute
685 while (*aAttributes
) {
686 const nsDependentString
key(aAttributes
[0]);
687 if (key
.EqualsLiteral("src")) {
688 src
.Assign(aAttributes
[1]);
689 } else if (key
.EqualsLiteral("type")) {
690 nsDependentString
str(aAttributes
[1]);
691 nsContentTypeParser
parser(str
);
692 nsAutoString mimeType
;
693 rv
= parser
.GetType(mimeType
);
695 if (rv
== NS_ERROR_INVALID_ARG
) {
696 // Fail immediately rather than checking if later things
700 // We do want the warning here
701 NS_ENSURE_SUCCESS(rv
, rv
);
704 // NOTE(emilio): Module scripts don't pass this test, aren't cached yet.
705 // If they become cached, then we need to tweak
706 // PrototypeDocumentContentSink and remove the special cases there.
707 if (nsContentUtils::IsJavascriptMIMEType(mimeType
)) {
710 // Get the version string, and ensure that JavaScript supports it.
711 nsAutoString versionName
;
712 rv
= parser
.GetParameter("version", versionName
);
714 if (NS_SUCCEEDED(rv
)) {
715 nsContentUtils::ReportToConsoleNonLocalized(
716 u
"Versioned JavaScripts are no longer supported. "
717 "Please remove the version parameter."_ns
,
718 nsIScriptError::errorFlag
, "XUL Document"_ns
, nullptr,
719 mDocumentURL
, u
""_ns
, aLineNumber
);
720 isJavaScript
= false;
721 } else if (rv
!= NS_ERROR_INVALID_ARG
) {
725 isJavaScript
= false;
727 } else if (key
.EqualsLiteral("language")) {
728 // Language is deprecated, and the impl in ScriptLoader ignores the
729 // various version strings anyway. So we make no attempt to support
730 // languages other than JS for language=
731 nsAutoString
lang(aAttributes
[1]);
732 if (nsContentUtils::IsJavaScriptLanguage(lang
)) {
739 // Don't process scripts that aren't JavaScript.
744 nsCOMPtr
<Document
> doc(do_QueryReferent(mDocument
));
745 nsCOMPtr
<nsIScriptGlobalObject
> globalObject
;
746 if (doc
) globalObject
= do_QueryInterface(doc
->GetWindow());
747 RefPtr
<nsXULPrototypeScript
> script
= new nsXULPrototypeScript(aLineNumber
);
749 // If there is a SRC attribute...
750 if (!src
.IsEmpty()) {
751 // Use the SRC attribute value to load the URL
752 rv
= NS_NewURI(getter_AddRefs(script
->mSrcURI
), src
, nullptr, mDocumentURL
);
754 // Check if this document is allowed to load a script from this source
755 // NOTE: if we ever allow scripts added via the DOM to run, we need to
756 // add a CheckLoadURI call for that as well.
757 if (NS_SUCCEEDED(rv
)) {
759 mSecMan
= do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID
, &rv
);
760 if (NS_SUCCEEDED(rv
)) {
761 nsCOMPtr
<Document
> doc
= do_QueryReferent(mDocument
, &rv
);
763 if (NS_SUCCEEDED(rv
)) {
764 rv
= mSecMan
->CheckLoadURIWithPrincipal(
765 doc
->NodePrincipal(), script
->mSrcURI
,
766 nsIScriptSecurityManager::ALLOW_CHROME
, doc
->InnerWindowID());
775 // Attempt to deserialize an out-of-line script from the FastLoad
776 // file right away. Otherwise we'll end up reloading the script and
777 // corrupting the FastLoad file trying to serialize it, in the case
778 // where it's already there.
779 script
->DeserializeOutOfLine(nullptr, mPrototype
);
782 nsPrototypeArray
* children
= nullptr;
783 rv
= mContextStack
.GetTopChildren(&children
);
788 children
->AppendElement(script
);
790 mConstrainSize
= false;
792 mContextStack
.Push(script
, mState
);
798 nsresult
XULContentSinkImpl::AddAttributes(const char16_t
** aAttributes
,
799 const uint32_t aAttrLen
,
800 nsXULPrototypeElement
* aElement
) {
801 // Add tag attributes to the element
804 // Create storage for the attributes
805 nsXULPrototypeAttribute
* attrs
= nullptr;
807 attrs
= aElement
->mAttributes
.AppendElements(aAttrLen
);
810 // Copy the attributes into the prototype
812 for (i
= 0; i
< aAttrLen
; ++i
) {
813 rv
= NormalizeAttributeString(aAttributes
[i
* 2], attrs
[i
].mName
);
814 NS_ENSURE_SUCCESS(rv
, rv
);
816 rv
= aElement
->SetAttrAt(i
, nsDependentString(aAttributes
[i
* 2 + 1]),
818 NS_ENSURE_SUCCESS(rv
, rv
);
820 if (MOZ_LOG_TEST(gContentSinkLog
, LogLevel::Debug
)) {
821 nsAutoString extraWhiteSpace
;
822 int32_t cnt
= mContextStack
.Depth();
823 while (--cnt
>= 0) extraWhiteSpace
.AppendLiteral(" ");
824 nsAutoString qnameC
, valueC
;
825 qnameC
.Assign(aAttributes
[0]);
826 valueC
.Assign(aAttributes
[1]);
827 MOZ_LOG(gContentSinkLog
, LogLevel::Debug
,
828 ("xul: %.5d. %s %s=%s",
829 -1, // XXX pass in line number
830 NS_ConvertUTF16toUTF8(extraWhiteSpace
).get(),
831 NS_ConvertUTF16toUTF8(qnameC
).get(),
832 NS_ConvertUTF16toUTF8(valueC
).get()));
839 nsresult
XULContentSinkImpl::AddText(const char16_t
* aText
, int32_t aLength
) {
840 // Create buffer when we first need it
841 if (0 == mTextSize
) {
842 mText
= (char16_t
*)malloc(sizeof(char16_t
) * 4096);
843 if (nullptr == mText
) {
844 return NS_ERROR_OUT_OF_MEMORY
;
849 // Copy data from string into our buffer; flush buffer when it fills up
851 while (0 != aLength
) {
852 int32_t amount
= mTextSize
- mTextLength
;
853 if (amount
> aLength
) {
857 if (mConstrainSize
) {
858 nsresult rv
= FlushText();
863 CheckedInt32 size
= mTextSize
;
865 if (!size
.isValid()) {
866 return NS_ERROR_OUT_OF_MEMORY
;
868 mTextSize
= size
.value();
870 mText
= (char16_t
*)realloc(mText
, sizeof(char16_t
) * mTextSize
);
871 if (nullptr == mText
) {
872 return NS_ERROR_OUT_OF_MEMORY
;
876 memcpy(&mText
[mTextLength
], aText
+ offset
, sizeof(char16_t
) * amount
);
878 mTextLength
+= amount
;