2018-11-30 22:52:05 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2018-11-30 18:39:55 +03:00
|
|
|
/* vim: set ts=4 sw=2 et tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
1998-12-24 08:07:14 +03:00
|
|
|
|
1999-01-06 00:57:59 +03:00
|
|
|
/*
|
|
|
|
|
1999-10-06 01:13:55 +04:00
|
|
|
An implementation for the XUL document. This implementation serves
|
|
|
|
as the basis for generating an NGLayout content model.
|
1999-01-06 00:57:59 +03:00
|
|
|
|
1999-08-30 06:45:54 +04:00
|
|
|
Notes
|
|
|
|
-----
|
|
|
|
|
2014-09-18 07:36:26 +04:00
|
|
|
1. We do some monkey business in the document observer methods to
|
1999-08-30 06:45:54 +04:00
|
|
|
keep the element map in sync for HTML elements. Why don't we just
|
|
|
|
do it for _all_ elements? Well, in the case of XUL elements,
|
|
|
|
which may be lazily created during frame construction, the
|
|
|
|
document observer methods will never be called because we'll be
|
|
|
|
adding the XUL nodes into the content model "quietly".
|
|
|
|
|
|
|
|
*/
|
1999-01-06 00:57:59 +03:00
|
|
|
|
2013-12-09 06:52:54 +04:00
|
|
|
#include "mozilla/ArrayUtils.h"
|
2011-10-11 09:50:08 +04:00
|
|
|
|
2018-10-23 22:27:16 +03:00
|
|
|
#include <algorithm>
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
#include "XULDocument.h"
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2012-07-27 18:03:27 +04:00
|
|
|
#include "nsError.h"
|
2000-12-10 12:18:57 +03:00
|
|
|
#include "nsIBoxObject.h"
|
1999-10-29 05:21:15 +04:00
|
|
|
#include "nsIChromeRegistry.h"
|
2013-01-03 17:23:11 +04:00
|
|
|
#include "nsView.h"
|
2013-01-05 07:12:24 +04:00
|
|
|
#include "nsViewManager.h"
|
1999-10-29 05:21:15 +04:00
|
|
|
#include "nsIContentViewer.h"
|
1998-12-24 08:07:14 +03:00
|
|
|
#include "nsIStreamListener.h"
|
1999-11-25 01:46:09 +03:00
|
|
|
#include "nsITimer.h"
|
2013-11-15 11:12:43 +04:00
|
|
|
#include "nsDocShell.h"
|
2006-12-26 20:47:52 +03:00
|
|
|
#include "nsGkAtoms.h"
|
2006-11-12 01:27:00 +03:00
|
|
|
#include "nsXMLContentSink.h"
|
2007-03-25 09:02:10 +04:00
|
|
|
#include "nsXULContentSink.h"
|
2001-02-22 06:01:34 +03:00
|
|
|
#include "nsXULContentUtils.h"
|
2014-08-19 18:31:00 +04:00
|
|
|
#include "nsIStringEnumerator.h"
|
2018-04-20 23:55:51 +03:00
|
|
|
#include "nsDocElementCreatedNotificationRunner.h"
|
1999-11-30 07:50:42 +03:00
|
|
|
#include "nsNetUtil.h"
|
1998-12-24 08:07:14 +03:00
|
|
|
#include "nsParserCIID.h"
|
2000-12-10 12:18:57 +03:00
|
|
|
#include "nsPIBoxObject.h"
|
2014-10-15 00:15:21 +04:00
|
|
|
#include "mozilla/dom/BoxObject.h"
|
2017-08-17 08:29:03 +03:00
|
|
|
#include "nsString.h"
|
2001-04-18 10:06:31 +04:00
|
|
|
#include "nsPIDOMWindow.h"
|
2010-02-20 19:07:03 +03:00
|
|
|
#include "nsPIWindowRoot.h"
|
1999-10-20 22:55:32 +04:00
|
|
|
#include "nsXULElement.h"
|
2018-01-31 22:49:27 +03:00
|
|
|
#include "nsXULPrototypeCache.h"
|
2015-05-19 21:15:34 +03:00
|
|
|
#include "mozilla/Logging.h"
|
1999-10-30 06:52:11 +04:00
|
|
|
#include "nsIFrame.h"
|
2012-05-23 22:46:04 +04:00
|
|
|
#include "nsXBLService.h"
|
2001-02-22 06:01:34 +03:00
|
|
|
#include "nsCExternalHandlerService.h"
|
|
|
|
#include "nsMimeTypes.h"
|
2001-07-31 23:05:34 +04:00
|
|
|
#include "nsIObjectInputStream.h"
|
|
|
|
#include "nsIObjectOutputStream.h"
|
2003-02-01 02:21:22 +03:00
|
|
|
#include "nsContentList.h"
|
2017-12-19 17:11:06 +03:00
|
|
|
#include "nsISimpleEnumerator.h"
|
2003-05-30 10:30:27 +04:00
|
|
|
#include "nsIScriptGlobalObject.h"
|
2003-05-02 22:15:30 +04:00
|
|
|
#include "nsIScriptSecurityManager.h"
|
2004-06-25 16:26:02 +04:00
|
|
|
#include "nsNodeInfoManager.h"
|
|
|
|
#include "nsContentCreatorFunctions.h"
|
2004-02-10 12:08:06 +03:00
|
|
|
#include "nsContentUtils.h"
|
|
|
|
#include "nsIParser.h"
|
2012-03-22 18:42:42 +04:00
|
|
|
#include "nsCharsetSource.h"
|
2016-09-26 15:03:25 +03:00
|
|
|
#include "mozilla/StyleSheetInlines.h"
|
2010-06-29 02:49:35 +04:00
|
|
|
#include "mozilla/css/Loader.h"
|
2004-07-15 10:09:36 +04:00
|
|
|
#include "nsIScriptError.h"
|
2006-11-12 01:27:00 +03:00
|
|
|
#include "nsIStyleSheetLinkingElement.h"
|
2006-06-06 18:08:57 +04:00
|
|
|
#include "nsIObserverService.h"
|
2006-07-02 11:23:10 +04:00
|
|
|
#include "nsNodeUtils.h"
|
2006-07-25 04:20:33 +04:00
|
|
|
#include "nsIXULWindow.h"
|
2007-07-04 19:49:38 +04:00
|
|
|
#include "nsXULPopupManager.h"
|
2008-10-08 15:41:52 +04:00
|
|
|
#include "nsCCUncollectableMarker.h"
|
2009-02-16 14:27:22 +03:00
|
|
|
#include "nsURILoader.h"
|
2013-09-25 15:21:22 +04:00
|
|
|
#include "mozilla/BasicEvents.h"
|
2018-09-07 04:28:40 +03:00
|
|
|
#include "mozilla/dom/DocumentL10n.h"
|
2010-05-05 22:18:05 +04:00
|
|
|
#include "mozilla/dom/Element.h"
|
2014-06-20 06:01:40 +04:00
|
|
|
#include "mozilla/dom/NodeInfoInlines.h"
|
2013-04-04 16:01:11 +04:00
|
|
|
#include "mozilla/dom/ProcessingInstruction.h"
|
2014-08-05 17:57:53 +04:00
|
|
|
#include "mozilla/dom/ScriptSettings.h"
|
2013-03-26 19:31:54 +04:00
|
|
|
#include "mozilla/dom/XULDocumentBinding.h"
|
2018-11-07 00:45:20 +03:00
|
|
|
#include "mozilla/dom/XULPersist.h"
|
2014-03-18 08:48:21 +04:00
|
|
|
#include "mozilla/EventDispatcher.h"
|
2014-07-10 10:56:37 +04:00
|
|
|
#include "mozilla/LoadInfo.h"
|
2011-05-29 03:42:57 +04:00
|
|
|
#include "mozilla/Preferences.h"
|
2013-04-04 16:01:08 +04:00
|
|
|
#include "nsTextNode.h"
|
2013-08-09 03:51:34 +04:00
|
|
|
#include "nsJSUtils.h"
|
2018-08-25 06:51:49 +03:00
|
|
|
#include "js/CompilationAndEvaluation.h"
|
2018-11-09 05:42:48 +03:00
|
|
|
#include "js/SourceText.h"
|
2013-11-20 20:29:03 +04:00
|
|
|
#include "mozilla/dom/URL.h"
|
2014-09-21 20:37:08 +04:00
|
|
|
#include "nsIContentPolicy.h"
|
2016-02-08 16:51:00 +03:00
|
|
|
#include "mozAutoDocUpdate.h"
|
2016-05-28 03:26:56 +03:00
|
|
|
#include "xpcpublic.h"
|
2016-09-26 15:03:25 +03:00
|
|
|
#include "mozilla/StyleSheet.h"
|
|
|
|
#include "mozilla/StyleSheetInlines.h"
|
2018-04-12 21:56:55 +03:00
|
|
|
#include "nsIConsoleService.h"
|
2010-04-30 17:12:05 +04:00
|
|
|
|
2011-05-29 03:42:57 +04:00
|
|
|
using namespace mozilla;
|
2010-04-30 17:12:05 +04:00
|
|
|
using namespace mozilla::dom;
|
2000-05-26 03:48:45 +04:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// CIDs
|
|
|
|
//
|
1998-12-24 08:07:14 +03:00
|
|
|
|
2001-03-11 00:02:12 +03:00
|
|
|
static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
|
1999-02-23 06:31:26 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Statics
|
|
|
|
//
|
1999-09-03 11:02:25 +04:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
int32_t XULDocument::gRefCnt = 0;
|
1999-09-30 06:32:34 +04:00
|
|
|
|
2015-11-23 22:09:25 +03:00
|
|
|
LazyLogModule XULDocument::gXULLog("XULDocument");
|
2000-10-29 02:17:53 +04:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-01-12 22:41:06 +03:00
|
|
|
// ctors & dtors
|
1999-10-29 05:21:15 +04:00
|
|
|
//
|
1999-01-12 22:41:06 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
|
|
|
XULDocument::XULDocument(void)
|
2013-03-20 20:22:26 +04:00
|
|
|
: XMLDocument("application/vnd.mozilla.xul+xml"),
|
2017-01-24 19:10:39 +03:00
|
|
|
mNextSrcLoadWaiter(nullptr),
|
|
|
|
mIsWritingFastLoad(false),
|
|
|
|
mDocumentLoaded(false),
|
|
|
|
mStillWalking(false),
|
|
|
|
mPendingSheets(0),
|
|
|
|
mCurrentScriptProto(nullptr),
|
|
|
|
mOffThreadCompiling(false),
|
|
|
|
mOffThreadCompileStringBuf(nullptr),
|
|
|
|
mOffThreadCompileStringLength(0),
|
2018-10-19 04:22:46 +03:00
|
|
|
mInitialLayoutComplete(false) {
|
2003-03-26 10:41:30 +03:00
|
|
|
// Override the default in nsDocument
|
2017-06-18 14:37:50 +03:00
|
|
|
mCharacterSet = UTF_8_ENCODING;
|
2004-06-25 16:26:02 +04:00
|
|
|
|
|
|
|
mDefaultElementType = kNameSpaceID_XUL;
|
2014-05-24 23:28:48 +04:00
|
|
|
mType = eXUL;
|
2008-04-18 12:58:06 +04:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mDelayFrameLoaderInitialization = true;
|
2010-08-20 03:12:46 +04:00
|
|
|
|
|
|
|
mAllowXULXBL = eTriTrue;
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::~XULDocument() {
|
2012-07-30 18:20:58 +04:00
|
|
|
NS_ASSERTION(
|
|
|
|
mNextSrcLoadWaiter == nullptr,
|
1999-11-18 05:25:33 +03:00
|
|
|
"unreferenced document still waiting for script source to load?");
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
Preferences::UnregisterCallback(XULDocument::DirectionChanged,
|
2017-02-03 01:12:50 +03:00
|
|
|
"intl.uidirection", this);
|
2009-07-29 22:33:53 +04:00
|
|
|
|
2014-04-25 18:11:57 +04:00
|
|
|
if (mOffThreadCompileStringBuf) {
|
|
|
|
js_free(mOffThreadCompileStringBuf);
|
|
|
|
}
|
2003-03-26 10:41:30 +03:00
|
|
|
}
|
1999-02-16 22:30:04 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
2018-01-31 22:49:29 +03:00
|
|
|
nsresult NS_NewXULDocument(nsIDocument** result) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(result != nullptr, "null ptr");
|
1999-02-16 22:30:04 +03:00
|
|
|
if (!result) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<XULDocument> doc = new XULDocument();
|
1999-02-16 22:30:04 +03:00
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
if (NS_FAILED(rv = doc->Init())) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2015-09-25 20:43:21 +03:00
|
|
|
doc.forget(result);
|
1999-02-16 22:30:04 +03:00
|
|
|
return NS_OK;
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-01-12 22:41:06 +03:00
|
|
|
// nsISupports interface
|
1999-10-29 05:21:15 +04:00
|
|
|
//
|
1999-01-12 22:41:06 +03:00
|
|
|
|
2013-08-02 05:29:05 +04:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(XULDocument)
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XULDocument, XMLDocument)
|
2009-07-09 05:10:29 +04:00
|
|
|
NS_ASSERTION(
|
|
|
|
!nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration()),
|
2013-03-26 19:31:53 +04:00
|
|
|
"Shouldn't traverse XULDocument!");
|
2007-03-08 14:17:16 +03:00
|
|
|
// XXX tmp->mContextStack?
|
|
|
|
|
2012-11-15 11:32:40 +04:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentPrototype)
|
2015-11-23 01:38:57 +03:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrototypes)
|
2007-03-08 14:17:16 +03:00
|
|
|
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(XULDocument, XMLDocument)
|
2011-04-27 19:44:24 +04:00
|
|
|
// XXX We should probably unlink all the objects we traverse.
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
|
2017-09-01 02:29:22 +03:00
|
|
|
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(XULDocument, XMLDocument,
|
|
|
|
nsIStreamLoaderObserver,
|
|
|
|
nsICSSLoaderObserver,
|
|
|
|
nsIOffThreadScriptReceiver)
|
2008-02-21 23:39:20 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1998-12-24 08:07:14 +03:00
|
|
|
// nsIDocument interface
|
1999-10-29 05:21:15 +04:00
|
|
|
//
|
1998-12-24 08:07:14 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
void XULDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) {
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("Reset");
|
2001-03-12 09:39:27 +03:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
void XULDocument::ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
|
|
|
|
nsIPrincipal* aPrincipal) {
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("ResetToURI");
|
2001-11-16 05:03:19 +03:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
void XULDocument::SetContentType(const nsAString& aContentType) {
|
2004-05-23 02:15:22 +04:00
|
|
|
NS_ASSERTION(
|
|
|
|
aContentType.EqualsLiteral("application/vnd.mozilla.xul+xml"),
|
2003-01-09 18:45:45 +03:00
|
|
|
"xul-documents always has content-type application/vnd.mozilla.xul+xml");
|
|
|
|
// Don't do anything, xul always has the mimetype
|
|
|
|
// application/vnd.mozilla.xul+xml
|
|
|
|
}
|
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
// This is called when the master document begins loading, whether it's
|
2010-08-12 23:42:36 +04:00
|
|
|
// being cached or not.
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::StartDocumentLoad(const char* aCommand,
|
|
|
|
nsIChannel* aChannel,
|
|
|
|
nsILoadGroup* aLoadGroup,
|
|
|
|
nsISupports* aContainer,
|
|
|
|
nsIStreamListener** aDocListener,
|
|
|
|
bool aReset, nsIContentSink* aSink) {
|
2015-06-04 01:25:57 +03:00
|
|
|
if (MOZ_LOG_TEST(gXULLog, LogLevel::Warning)) {
|
2012-03-26 23:40:52 +04:00
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
nsresult rv = aChannel->GetOriginalURI(getter_AddRefs(uri));
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString urlspec;
|
2012-03-26 23:40:52 +04:00
|
|
|
rv = uri->GetSpec(urlspec);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2015-06-04 01:25:57 +03:00
|
|
|
MOZ_LOG(gXULLog, LogLevel::Warning,
|
2012-03-26 23:40:52 +04:00
|
|
|
("xul: load document '%s'", urlspec.get()));
|
|
|
|
}
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2006-04-21 05:24:44 +04:00
|
|
|
// NOTE: If this ever starts calling nsDocument::StartDocumentLoad
|
|
|
|
// we'll possibly need to reset our content type afterwards.
|
2011-10-17 18:59:28 +04:00
|
|
|
mStillWalking = true;
|
|
|
|
mMayStartLayout = false;
|
2003-07-25 23:06:59 +04:00
|
|
|
mDocumentLoadGroup = do_GetWeakReference(aLoadGroup);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2005-06-01 05:15:23 +04:00
|
|
|
mChannel = aChannel;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-05-04 19:21:50 +04:00
|
|
|
// Get the URI. Note that this should match nsDocShell::OnLoadingSite
|
2007-10-24 01:56:41 +04:00
|
|
|
nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI));
|
2006-05-04 19:21:50 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-04-03 23:49:16 +03:00
|
|
|
mOriginalURI = mDocumentURI;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-04-03 23:49:16 +03:00
|
|
|
// Get the document's principal
|
|
|
|
nsCOMPtr<nsIPrincipal> principal;
|
|
|
|
nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
|
2001-07-31 23:05:34 +04:00
|
|
|
mChannel, getter_AddRefs(principal));
|
2017-04-03 23:49:16 +03:00
|
|
|
principal = MaybeDowngradePrincipal(principal);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-04-03 23:49:16 +03:00
|
|
|
ResetStylesheetsToURI(mDocumentURI);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-04-03 23:49:16 +03:00
|
|
|
RetrieveRelevantHeaders(aChannel);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-04-03 23:49:16 +03:00
|
|
|
// Look in the chrome cache: we've got this puppy loaded
|
|
|
|
// already.
|
|
|
|
nsXULPrototypeDocument* proto =
|
2013-05-10 11:13:37 +04:00
|
|
|
IsChromeURI(mDocumentURI)
|
|
|
|
? nsXULPrototypeCache::GetInstance()->GetPrototype(mDocumentURI)
|
|
|
|
: nullptr;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2003-04-19 20:53:44 +04:00
|
|
|
// Same comment as nsChromeProtocolHandler::NewChannel and
|
2013-03-26 19:31:53 +04:00
|
|
|
// XULDocument::ResumeWalk
|
2002-05-03 07:04:34 +04:00
|
|
|
// - Ben Goodger
|
2018-11-30 13:46:48 +03:00
|
|
|
//
|
2003-04-19 20:53:44 +04:00
|
|
|
// We don't abort on failure here because there are too many valid
|
|
|
|
// cases that can return failure, and the null-ness of |proto| is enough
|
|
|
|
// to trigger the fail-safe parse-from-disk solution. Example failure cases
|
|
|
|
// (for reference) include:
|
2018-11-30 13:46:48 +03:00
|
|
|
//
|
2010-08-12 23:42:36 +04:00
|
|
|
// NS_ERROR_NOT_AVAILABLE: the URI cannot be found in the startup cache,
|
2002-05-03 07:04:34 +04:00
|
|
|
// parse from disk
|
2010-08-12 23:42:36 +04:00
|
|
|
// other: the startup cache file could not be found, probably
|
2002-05-03 07:04:34 +04:00
|
|
|
// due to being accessed before a profile has been selected (e.g.
|
2003-04-19 20:53:44 +04:00
|
|
|
// loading chrome for the profile manager itself). This must be
|
2003-03-26 10:41:30 +03:00
|
|
|
// parsed from disk.
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2002-05-03 07:04:34 +04:00
|
|
|
if (proto) {
|
2003-04-19 20:53:44 +04:00
|
|
|
// If we're racing with another document to load proto, wait till the
|
2001-07-31 23:05:34 +04:00
|
|
|
// load has finished loading before trying to add cloned style sheets.
|
2013-03-26 19:31:53 +04:00
|
|
|
// XULDocument::EndLoad will call proto->NotifyLoadDone, which will
|
2001-07-31 23:05:34 +04:00
|
|
|
// find all racing documents and notify them via OnPrototypeLoadDone,
|
2003-04-19 20:53:44 +04:00
|
|
|
// which will add style sheet clones to each document.
|
2011-09-29 10:19:26 +04:00
|
|
|
bool loaded;
|
2003-04-19 20:53:44 +04:00
|
|
|
rv = proto->AwaitLoadDone(this, &loaded);
|
2001-07-31 23:05:34 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2003-04-19 20:53:44 +04:00
|
|
|
|
2007-03-12 08:53:33 +03:00
|
|
|
mCurrentPrototype = proto;
|
2000-01-12 00:18:19 +03:00
|
|
|
|
2002-05-03 07:04:34 +04:00
|
|
|
// Set up the right principal on ourselves.
|
2006-11-22 21:27:54 +03:00
|
|
|
SetPrincipal(proto->DocumentPrincipal());
|
2001-07-31 23:05:34 +04:00
|
|
|
|
|
|
|
// We need a listener, even if proto is not yet loaded, in which
|
|
|
|
// event the listener's OnStopRequest method does nothing, and all
|
2013-03-26 19:31:53 +04:00
|
|
|
// the interesting work happens below XULDocument::EndLoad, from
|
2001-07-31 23:05:34 +04:00
|
|
|
// the call there to mCurrentPrototype->NotifyLoadDone().
|
|
|
|
*aDocListener = new CachedChromeStreamListener(this, loaded);
|
2018-11-30 13:46:48 +03:00
|
|
|
} else {
|
2011-09-29 10:19:26 +04:00
|
|
|
bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
|
|
|
|
bool fillXULCache = (useXULCache && IsChromeURI(mDocumentURI));
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2000-01-12 00:18:19 +03:00
|
|
|
// It's just a vanilla document load. Create a parser to deal
|
|
|
|
// with the stream n' stuff.
|
2002-05-03 07:04:34 +04:00
|
|
|
|
1999-12-04 10:45:57 +03:00
|
|
|
nsCOMPtr<nsIParser> parser;
|
2017-04-03 23:49:16 +03:00
|
|
|
rv = PrepareToLoadPrototype(mDocumentURI, aCommand, principal,
|
|
|
|
getter_AddRefs(parser));
|
1999-12-04 10:45:57 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
Reduce seeks outside the FastLoad file's underlying stream buffer (195010,
r=ben, sr=bryner).
- Pass null scope objects into nsIScriptContext::Compile{EventHandler,Script}
when precompiling for brutal sharing. The JS engine does not need a non-null
object parameter for static scope. That parameter can be non-null only if it
helps the compiler "pre-bind" functions to the same scope object that they'll
be parented by when executing, but with brutal sharing, functions are
precompiled once and executed against many different scope objects.
- A problem in XUL FastLoad was that it would serialize master .xul document
out-of-line scripts (those included via script src= from non-overlay, "master"
.xul docs) far from the place in the FastLoad file where XUL prototype script
info was serialized for the <script src=> tag itself. I fixed that so that,
unless the out-of-line script was previously serialized (by a different src=
reference from another .xul file), the OOL script data immediately follows the
proto-script info in the FastLoad file.
This required adding a SerializeOutOfLine method to nsXULPrototypeScript, which
restores symmetry by matching the existing DeserializeOutOfLine(Script) (note:
I dropped the redundant "Script" from the end of the latter method's name. We
need SerializeOutOfLine to handle overlay OOL scripts. They are serialized by
nsXULDocument::OnStreamComplete, because that code knows the difference between
an overlay and a master doc. This removes all trace of FastLoad writing from
nsXULPrototypeScript::Compile -- FastLoad stuff didn't belong there, not only
because we now want to write master OOL scripts later, when walking the master
XUL prototype doc's element tree, but also for modularity reasons. The caller
knows about FastLoad, nsXULPrototypeScript::Compile does just what its name
implies.
There are 132 seeks with the patch, only 49 of which dump the underlying file
stream's buffer, vs. 133 seeks without the patch, 87 of which dump the buffer.
- Nit-picked some comments to fit in 80 columns, and made other cosmetic fixes.
- Implicated the nsXULDocument::mIsWritingFastLoad flag from the useXULCache
"is the XUL cache enabled?" flag, so other places that test mIsWritingFastLoad
don't have to query whether the cache is enabled.
- Added METERING synchronous meter-dumping to /tmp/bufstats, only ifdef
DEBUG_brendan, in netwerk/base/src/nsBufferedStreams.cpp.
- Added the deferred seek optimization from the first patch in bug 195010 to
nsFastLoadFile.cpp.
- Fixed nsFastLoadFileReader so it overrides readSegments as well as read.
This catches up with the interface extension made to nsIInputStream to add
readSegments. The nsFastLoadFileReader extends nsBinaryInputStream, which is
a concrete class, and overrides Read in order to snoop on *all* bytes read.
It does this in order to demultiplex documents interleaved when the FastLoad
file was written.
But since the readSegments move into nsIInputStream.idl, certain primitives
in nsBinaryStream.cpp, e.g., nsBinaryInputStream::ReadCString, have used
ReadSegments, not Read, to consume parts of the underlying stream (to read
the C string's chars, in that example), and the FastLoad file implementation
has not accounted for those bytes.
- Added a new method to nsIFastLoadFileControl and its impls: hasMuxedDocument.
This is needed when serializing master XUL doc OOL scripts, because we must
not serialize twice, and any OOL script that other XUL docs can include via
script src= could already be in the FastLoad mux.
/be
2003-04-12 05:34:11 +04:00
|
|
|
// Predicate mIsWritingFastLoad on the XUL cache being enabled,
|
|
|
|
// so we don't have to re-check whether the cache is enabled all
|
|
|
|
// the time.
|
|
|
|
mIsWritingFastLoad = useXULCache;
|
2002-05-03 07:04:34 +04:00
|
|
|
|
1999-12-04 10:45:57 +03:00
|
|
|
nsCOMPtr<nsIStreamListener> listener = do_QueryInterface(parser, &rv);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "parser doesn't support nsIStreamListener");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
*aDocListener = listener;
|
|
|
|
|
2004-01-10 02:54:21 +03:00
|
|
|
parser->Parse(mDocumentURI);
|
2001-07-31 23:05:34 +04:00
|
|
|
|
|
|
|
// Put the current prototype, created under PrepareToLoad, into the
|
|
|
|
// XUL prototype cache now. We can't do this under PrepareToLoad or
|
|
|
|
// overlay loading will break; search for PutPrototype in ResumeWalk
|
|
|
|
// and see the comment there.
|
|
|
|
if (fillXULCache) {
|
2007-03-12 08:53:33 +03:00
|
|
|
nsXULPrototypeCache::GetInstance()->PutPrototype(mCurrentPrototype);
|
1999-12-04 10:45:57 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-12-04 10:45:57 +03:00
|
|
|
|
|
|
|
NS_IF_ADDREF(*aDocListener);
|
1999-10-29 05:21:15 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-04-23 20:48:33 +04:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
// This gets invoked after the prototype for this document is fully built in the
|
|
|
|
// content sink.
|
2013-03-26 19:31:53 +04:00
|
|
|
void XULDocument::EndLoad() {
|
2003-03-26 10:41:30 +03:00
|
|
|
nsresult rv;
|
2001-04-12 05:05:42 +04:00
|
|
|
|
2003-03-26 10:41:30 +03:00
|
|
|
// Whack the prototype document into the cache so that the next
|
|
|
|
// time somebody asks for it, they don't need to load it by hand.
|
2001-04-12 05:05:42 +04:00
|
|
|
|
2006-12-22 19:11:16 +03:00
|
|
|
nsCOMPtr<nsIURI> uri = mCurrentPrototype->GetURI();
|
2011-09-29 10:19:26 +04:00
|
|
|
bool isChrome = IsChromeURI(uri);
|
2004-01-14 21:03:25 +03:00
|
|
|
|
2003-03-26 10:41:30 +03:00
|
|
|
// Remember if the XUL cache is on
|
2011-09-29 10:19:26 +04:00
|
|
|
bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
|
1998-12-24 08:07:14 +03:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
if (isChrome && useXULCache) {
|
2018-06-07 01:15:25 +03:00
|
|
|
// If it's a chrome prototype document, then notify any
|
|
|
|
// documents that raced to load the prototype, and awaited
|
|
|
|
// its load completion via proto->AwaitLoadDone().
|
|
|
|
rv = mCurrentPrototype->NotifyLoadDone();
|
|
|
|
if (NS_FAILED(rv)) return;
|
2004-01-14 16:30:55 +03:00
|
|
|
}
|
2004-01-14 18:26:08 +03:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
OnPrototypeLoadDone(true);
|
2015-06-04 01:25:57 +03:00
|
|
|
if (MOZ_LOG_TEST(gXULLog, LogLevel::Warning)) {
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString urlspec;
|
2012-03-26 23:40:52 +04:00
|
|
|
rv = uri->GetSpec(urlspec);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2015-06-04 01:25:57 +03:00
|
|
|
MOZ_LOG(gXULLog, LogLevel::Warning,
|
2012-03-26 23:40:52 +04:00
|
|
|
("xul: Finished loading document '%s'", urlspec.get()));
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-02-23 06:31:26 +03:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::OnPrototypeLoadDone(bool aResumeWalk) {
|
2002-12-11 17:24:49 +03:00
|
|
|
nsresult rv;
|
|
|
|
|
2003-03-26 10:41:30 +03:00
|
|
|
rv = PrepareToWalk();
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to prepare for walk");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-03-27 03:58:42 +03:00
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
if (aResumeWalk) {
|
|
|
|
rv = ResumeWalk();
|
|
|
|
}
|
|
|
|
return rv;
|
1999-03-27 03:58:42 +03:00
|
|
|
}
|
1999-02-23 06:31:26 +03:00
|
|
|
|
2018-03-01 14:36:58 +03:00
|
|
|
void XULDocument::ContentAppended(nsIContent* aFirstNewContent) {
|
|
|
|
NS_ASSERTION(aFirstNewContent->OwnerDoc() == this, "unexpected doc");
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2010-07-21 19:33:32 +04:00
|
|
|
// Might not need this, but be safe for now.
|
|
|
|
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
|
|
|
|
2006-07-02 11:23:10 +04:00
|
|
|
// Update our element map
|
2018-10-29 17:01:51 +03:00
|
|
|
for (nsIContent* cur = aFirstNewContent; cur; cur = cur->GetNextSibling()) {
|
|
|
|
AddSubtreeToDocument(cur);
|
1999-08-30 06:45:54 +04:00
|
|
|
}
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
2018-03-01 14:36:58 +03:00
|
|
|
void XULDocument::ContentInserted(nsIContent* aChild) {
|
|
|
|
NS_ASSERTION(aChild->OwnerDoc() == this, "unexpected doc");
|
1999-08-30 06:45:54 +04:00
|
|
|
|
2010-07-21 19:33:32 +04:00
|
|
|
// Might not need this, but be safe for now.
|
|
|
|
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
|
|
|
|
2006-07-02 11:23:10 +04:00
|
|
|
AddSubtreeToDocument(aChild);
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
2018-03-01 14:36:58 +03:00
|
|
|
void XULDocument::ContentRemoved(nsIContent* aChild,
|
|
|
|
nsIContent* aPreviousSibling) {
|
2018-10-29 17:01:51 +03:00
|
|
|
// FIXME(emilio): Doesn't this need to remove the l10n links if they go
|
|
|
|
// away, or something?
|
1998-12-24 08:07:14 +03:00
|
|
|
}
|
|
|
|
|
2003-03-26 10:41:30 +03:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
2018-05-11 20:46:15 +03:00
|
|
|
// nsIDocument interface
|
2003-03-26 10:41:30 +03:00
|
|
|
//
|
1999-02-16 22:30:04 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
void XULDocument::AddElementToDocumentPost(Element* aElement) {
|
2017-12-11 12:48:42 +03:00
|
|
|
if (aElement == GetRootElement()) {
|
|
|
|
ResetDocumentDirection();
|
|
|
|
}
|
|
|
|
|
2018-09-20 11:42:07 +03:00
|
|
|
if (aElement->IsXULElement(nsGkAtoms::link)) {
|
2018-09-07 04:28:40 +03:00
|
|
|
LocalizationLinkAdded(aElement);
|
|
|
|
} else if (aElement->IsXULElement(nsGkAtoms::linkset)) {
|
|
|
|
OnL10nResourceContainerParsed();
|
2001-04-07 05:57:21 +04:00
|
|
|
}
|
2001-02-20 04:05:34 +03:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
void XULDocument::AddSubtreeToDocument(nsIContent* aContent) {
|
2018-10-29 16:26:09 +03:00
|
|
|
MOZ_ASSERT(aContent->GetComposedDoc() == this, "Element not in doc!");
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-10-29 16:26:09 +03:00
|
|
|
// If the content is not in the document, it must be in a shadow tree.
|
|
|
|
//
|
|
|
|
// The shadow root itself takes care of maintaining the ID tables and such,
|
|
|
|
// and there's no use case for localization links in shadow trees, or at
|
|
|
|
// least they don't work in regular HTML documents either as of today so...
|
|
|
|
if (MOZ_UNLIKELY(!aContent->IsInUncomposedDoc())) {
|
|
|
|
MOZ_ASSERT(aContent->IsInShadowTree());
|
2018-10-29 17:01:51 +03:00
|
|
|
return;
|
2018-10-29 16:26:09 +03:00
|
|
|
}
|
|
|
|
|
2005-09-24 22:43:15 +04:00
|
|
|
// From here on we only care about elements.
|
2018-05-30 17:56:24 +03:00
|
|
|
Element* aElement = Element::FromNode(aContent);
|
|
|
|
if (!aElement) {
|
2018-10-29 17:01:51 +03:00
|
|
|
return;
|
2005-09-24 22:43:15 +04:00
|
|
|
}
|
2001-02-20 04:05:34 +03:00
|
|
|
|
|
|
|
// Recurse to children
|
2011-09-27 11:54:58 +04:00
|
|
|
for (nsIContent* child = aElement->GetLastChild(); child;
|
|
|
|
child = child->GetPreviousSibling()) {
|
2018-10-29 17:01:51 +03:00
|
|
|
AddSubtreeToDocument(child);
|
1999-09-17 08:29:53 +04:00
|
|
|
}
|
|
|
|
|
2001-02-20 04:05:34 +03:00
|
|
|
// Do post-order addition magic
|
2018-10-29 17:01:51 +03:00
|
|
|
AddElementToDocumentPost(aElement);
|
1999-02-16 22:30:04 +03:00
|
|
|
}
|
|
|
|
|
2003-03-26 10:41:30 +03:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
2018-05-30 05:58:49 +03:00
|
|
|
// nsINode interface
|
2003-03-26 10:41:30 +03:00
|
|
|
//
|
2001-09-11 07:04:49 +04:00
|
|
|
|
2018-08-09 02:58:44 +03:00
|
|
|
nsresult XULDocument::Clone(mozilla::dom::NodeInfo* aNodeInfo,
|
|
|
|
nsINode** aResult) const {
|
2012-12-07 00:21:18 +04:00
|
|
|
// We don't allow cloning of a XUL document
|
|
|
|
*aResult = nullptr;
|
2003-03-26 10:41:30 +03:00
|
|
|
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
2001-09-11 07:04:49 +04:00
|
|
|
}
|
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-02-16 22:30:04 +03:00
|
|
|
// Implementation methods
|
1999-10-29 05:21:15 +04:00
|
|
|
//
|
1999-02-16 22:30:04 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::Init() {
|
2013-03-20 20:22:26 +04:00
|
|
|
nsresult rv = XMLDocument::Init();
|
2003-03-26 10:41:30 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-06 01:13:55 +04:00
|
|
|
if (gRefCnt++ == 0) {
|
2007-03-12 08:53:33 +03:00
|
|
|
// ensure that the XUL prototype cache is instantiated successfully,
|
|
|
|
// so that we can use nsXULPrototypeCache::GetInstance() without
|
|
|
|
// null-checks in the rest of the class.
|
|
|
|
nsXULPrototypeCache* cache = nsXULPrototypeCache::GetInstance();
|
|
|
|
if (!cache) {
|
|
|
|
NS_ERROR("Could not instantiate nsXULPrototypeCache");
|
|
|
|
return NS_ERROR_FAILURE;
|
1999-10-06 01:13:55 +04:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-10-06 01:13:55 +04:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
Preferences::RegisterCallback(XULDocument::DirectionChanged,
|
2017-02-03 01:12:50 +03:00
|
|
|
"intl.uidirection", this);
|
2009-07-29 22:33:53 +04:00
|
|
|
|
1999-02-02 01:34:51 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::StartLayout(void) {
|
2011-10-17 18:59:28 +04:00
|
|
|
mMayStartLayout = true;
|
2010-06-25 17:59:57 +04:00
|
|
|
nsCOMPtr<nsIPresShell> shell = GetShell();
|
2010-01-07 13:36:11 +03:00
|
|
|
if (shell) {
|
2003-03-26 10:41:30 +03:00
|
|
|
// Resize-reflow this time
|
2004-08-21 00:34:37 +04:00
|
|
|
nsPresContext* cx = shell->GetPresContext();
|
2012-07-30 18:20:58 +04:00
|
|
|
NS_ASSERTION(cx != nullptr, "no pres context");
|
2003-03-26 10:41:30 +03:00
|
|
|
if (!cx) return NS_ERROR_UNEXPECTED;
|
1999-02-02 01:34:51 +03:00
|
|
|
|
2013-11-20 23:18:25 +04:00
|
|
|
nsCOMPtr<nsIDocShell> docShell = cx->GetDocShell();
|
2012-07-30 18:20:58 +04:00
|
|
|
NS_ASSERTION(docShell != nullptr, "container is not a docshell");
|
2003-03-26 10:41:30 +03:00
|
|
|
if (!docShell) return NS_ERROR_UNEXPECTED;
|
|
|
|
|
2018-02-16 22:34:46 +03:00
|
|
|
nsresult rv = shell->Initialize();
|
2006-05-15 21:51:35 +04:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
1999-01-14 13:55:08 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::PrepareToLoadPrototype(nsIURI* aURI, const char* aCommand,
|
|
|
|
nsIPrincipal* aDocumentPrincipal,
|
|
|
|
nsIParser** aResult) {
|
1999-10-29 05:21:15 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
2001-07-31 23:05:34 +04:00
|
|
|
// Create a new prototype document.
|
2006-12-22 19:11:16 +03:00
|
|
|
rv = NS_NewXULPrototypeDocument(getter_AddRefs(mCurrentPrototype));
|
1999-10-29 05:21:15 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2006-11-22 21:27:54 +03:00
|
|
|
rv = mCurrentPrototype->InitPrincipal(aURI, aDocumentPrincipal);
|
|
|
|
if (NS_FAILED(rv)) {
|
2012-07-30 18:20:58 +04:00
|
|
|
mCurrentPrototype = nullptr;
|
2006-11-22 21:27:54 +03:00
|
|
|
return rv;
|
2017-07-06 15:00:35 +03:00
|
|
|
}
|
2006-11-22 21:27:54 +03:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
SetPrincipal(aDocumentPrincipal);
|
2006-02-02 23:02:34 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
// Create a XUL content sink, a parser, and kick off a load for
|
2018-03-29 04:20:04 +03:00
|
|
|
// the document.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<XULContentSinkImpl> sink = new XULContentSinkImpl();
|
1999-10-29 05:21:15 +04:00
|
|
|
|
|
|
|
rv = sink->Init(this, mCurrentPrototype);
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Unable to initialize datasource sink");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2002-12-11 17:24:49 +03:00
|
|
|
nsCOMPtr<nsIParser> parser = do_CreateInstance(kParserCID, &rv);
|
1999-10-29 05:21:15 +04:00
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create parser");
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
2000-04-12 03:48:37 +04:00
|
|
|
parser->SetCommand(nsCRT::strcmp(aCommand, "view-source") ? eViewNormal
|
2003-03-26 10:41:30 +03:00
|
|
|
: eViewSource);
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2017-06-18 14:37:50 +03:00
|
|
|
parser->SetDocumentCharset(UTF_8_ENCODING, kCharsetFromDocTypeDefault);
|
1999-10-29 05:21:15 +04:00
|
|
|
parser->SetContentSink(sink); // grabs a reference to the parser
|
|
|
|
|
2015-03-31 17:03:49 +03:00
|
|
|
parser.forget(aResult);
|
1999-10-29 05:21:15 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2017-11-14 20:10:30 +03:00
|
|
|
void XULDocument::TraceProtos(JSTracer* aTrc) {
|
2012-08-25 00:22:23 +04:00
|
|
|
uint32_t i, count = mPrototypes.Length();
|
|
|
|
for (i = 0; i < count; ++i) {
|
2017-11-14 20:10:30 +03:00
|
|
|
mPrototypes[i]->TraceProtos(aTrc);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2016-09-09 01:14:28 +03:00
|
|
|
if (mCurrentPrototype) {
|
2017-11-14 20:10:30 +03:00
|
|
|
mCurrentPrototype->TraceProtos(aTrc);
|
2016-09-09 01:14:28 +03:00
|
|
|
}
|
2012-08-25 00:22:23 +04:00
|
|
|
}
|
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
2013-03-26 19:31:53 +04:00
|
|
|
// XULDocument::ContextStack
|
1999-10-29 05:21:15 +04:00
|
|
|
//
|
1999-10-06 01:13:55 +04:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::ContextStack::ContextStack() : mTop(nullptr), mDepth(0) {}
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::ContextStack::~ContextStack() {
|
1999-10-29 05:21:15 +04:00
|
|
|
while (mTop) {
|
|
|
|
Entry* doomed = mTop;
|
|
|
|
mTop = mTop->mNext;
|
|
|
|
NS_IF_RELEASE(doomed->mElement);
|
|
|
|
delete doomed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::ContextStack::Push(nsXULPrototypeElement* aPrototype,
|
|
|
|
nsIContent* aElement) {
|
1999-10-29 05:21:15 +04:00
|
|
|
Entry* entry = new Entry;
|
|
|
|
entry->mPrototype = aPrototype;
|
|
|
|
entry->mElement = aElement;
|
|
|
|
NS_IF_ADDREF(entry->mElement);
|
|
|
|
entry->mIndex = 0;
|
|
|
|
|
|
|
|
entry->mNext = mTop;
|
|
|
|
mTop = entry;
|
|
|
|
|
|
|
|
++mDepth;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::ContextStack::Pop() {
|
1999-10-29 05:21:15 +04:00
|
|
|
if (mDepth == 0) return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
Entry* doomed = mTop;
|
|
|
|
mTop = mTop->mNext;
|
|
|
|
--mDepth;
|
|
|
|
|
|
|
|
NS_IF_RELEASE(doomed->mElement);
|
|
|
|
delete doomed;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::ContextStack::Peek(nsXULPrototypeElement** aPrototype,
|
|
|
|
nsIContent** aElement,
|
|
|
|
int32_t* aIndex) {
|
1999-10-29 05:21:15 +04:00
|
|
|
if (mDepth == 0) return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
*aPrototype = mTop->mPrototype;
|
|
|
|
*aElement = mTop->mElement;
|
|
|
|
NS_IF_ADDREF(*aElement);
|
|
|
|
*aIndex = mTop->mIndex;
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::ContextStack::SetTopIndex(int32_t aIndex) {
|
1999-10-29 05:21:15 +04:00
|
|
|
if (mDepth == 0) return NS_ERROR_UNEXPECTED;
|
|
|
|
|
|
|
|
mTop->mIndex = aIndex;
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Content model walking routines
|
|
|
|
//
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::PrepareToWalk() {
|
1999-10-29 05:21:15 +04:00
|
|
|
// Prepare to walk the mCurrentPrototype
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
// Keep an owning reference to the prototype document so that its
|
|
|
|
// elements aren't yanked from beneath us.
|
2006-12-22 19:11:16 +03:00
|
|
|
mPrototypes.AppendElement(mCurrentPrototype);
|
1999-10-29 05:21:15 +04:00
|
|
|
|
|
|
|
// Get the prototype's root element and initialize the context
|
|
|
|
// stack for the prototype walk.
|
2006-12-22 19:11:16 +03:00
|
|
|
nsXULPrototypeElement* proto = mCurrentPrototype->GetRootElement();
|
1999-11-18 05:25:33 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
if (!proto) {
|
2015-06-04 01:25:57 +03:00
|
|
|
if (MOZ_LOG_TEST(gXULLog, LogLevel::Error)) {
|
2006-12-22 19:11:16 +03:00
|
|
|
nsCOMPtr<nsIURI> url = mCurrentPrototype->GetURI();
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString urlspec;
|
2004-06-22 13:37:55 +04:00
|
|
|
rv = url->GetSpec(urlspec);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2015-06-04 01:25:57 +03:00
|
|
|
MOZ_LOG(gXULLog, LogLevel::Error,
|
1999-10-29 05:21:15 +04:00
|
|
|
("xul: error parsing '%s'", urlspec.get()));
|
|
|
|
}
|
|
|
|
|
2018-01-25 18:02:06 +03:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2006-11-12 01:27:00 +03:00
|
|
|
|
|
|
|
nsINode* nodeToInsertBefore = nsINode::GetFirstChild();
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
const nsTArray<RefPtr<nsXULPrototypePI> >& processingInstructions =
|
|
|
|
mCurrentPrototype->GetProcessingInstructions();
|
2006-11-12 01:27:00 +03:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
uint32_t total = processingInstructions.Length();
|
|
|
|
for (uint32_t i = 0; i < total; ++i) {
|
|
|
|
rv = CreateAndInsertPI(processingInstructions[i], this, nodeToInsertBefore);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
// Do one-time initialization.
|
|
|
|
RefPtr<Element> root;
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
// Add the root element
|
|
|
|
rv = CreateElementFromPrototype(proto, getter_AddRefs(root), true);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-04-20 23:55:51 +03:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
rv = AppendChildTo(root, false);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-11-18 05:25:33 +03:00
|
|
|
|
2000-10-29 20:58:21 +03:00
|
|
|
// Block onload until we've finished building the complete
|
2018-03-29 04:20:04 +03:00
|
|
|
// document content model.
|
2000-10-29 20:58:21 +03:00
|
|
|
BlockOnload();
|
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
nsContentUtils::AddScriptRunner(
|
|
|
|
new nsDocElementCreatedNotificationRunner(this));
|
|
|
|
|
2000-10-29 20:58:21 +03:00
|
|
|
// There'd better not be anything on the context stack at this
|
|
|
|
// point! This is the basis case for our "induction" in
|
|
|
|
// ResumeWalk(), below, which'll assume that there's always a
|
2018-03-29 04:20:04 +03:00
|
|
|
// content element on the context stack if we're in the document.
|
2000-10-29 20:58:21 +03:00
|
|
|
NS_ASSERTION(mContextStack.Depth() == 0,
|
|
|
|
"something's on the context stack already");
|
1999-10-29 05:21:15 +04:00
|
|
|
if (mContextStack.Depth() != 0) return NS_ERROR_UNEXPECTED;
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
rv = mContextStack.Push(proto, root);
|
2018-01-25 18:02:06 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2006-11-12 01:27:00 +03:00
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2006-11-12 01:27:00 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::CreateAndInsertPI(const nsXULPrototypePI* aProtoPI,
|
2018-01-25 18:02:06 +03:00
|
|
|
nsINode* aParent,
|
|
|
|
nsINode* aBeforeThis) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aProtoPI, "null ptr");
|
|
|
|
MOZ_ASSERT(aParent, "null ptr");
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<ProcessingInstruction> node = NS_NewXMLProcessingInstruction(
|
2013-04-04 16:01:11 +04:00
|
|
|
mNodeInfoManager, aProtoPI->mTarget, aProtoPI->mData);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2013-04-04 16:01:11 +04:00
|
|
|
nsresult rv;
|
2006-11-12 01:27:00 +03:00
|
|
|
if (aProtoPI->mTarget.EqualsLiteral("xml-stylesheet")) {
|
2018-01-25 18:02:06 +03:00
|
|
|
rv = InsertXMLStylesheetPI(aProtoPI, aParent, aBeforeThis, node);
|
2006-11-12 01:27:00 +03:00
|
|
|
} else {
|
|
|
|
// No special processing, just add the PI to the document.
|
2018-01-25 18:02:06 +03:00
|
|
|
rv = aParent->InsertChildBefore(
|
|
|
|
node->AsContent(), aBeforeThis ? aBeforeThis->AsContent() : nullptr,
|
|
|
|
false);
|
2006-11-12 01:27:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::InsertXMLStylesheetPI(const nsXULPrototypePI* aProtoPI,
|
|
|
|
nsINode* aParent,
|
2018-01-25 18:02:06 +03:00
|
|
|
nsINode* aBeforeThis,
|
2013-03-26 19:31:53 +04:00
|
|
|
nsIContent* aPINode) {
|
2006-11-12 01:27:00 +03:00
|
|
|
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(aPINode));
|
|
|
|
NS_ASSERTION(ssle,
|
|
|
|
"passed XML Stylesheet node does not "
|
|
|
|
"implement nsIStyleSheetLinkingElement!");
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
nsresult rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
ssle->InitStyleLinkElement(false);
|
2006-11-12 01:27:00 +03:00
|
|
|
// We want to be notified when the style sheet finishes loading, so
|
|
|
|
// disable style sheet loading for now.
|
2011-10-17 18:59:28 +04:00
|
|
|
ssle->SetEnableUpdates(false);
|
2006-12-22 19:11:16 +03:00
|
|
|
ssle->OverrideBaseURI(mCurrentPrototype->GetURI());
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-01-25 18:02:06 +03:00
|
|
|
rv = aParent->InsertChildBefore(
|
|
|
|
aPINode->AsContent(), aBeforeThis ? aBeforeThis->AsContent() : nullptr,
|
|
|
|
false);
|
2006-11-12 01:27:00 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
ssle->SetEnableUpdates(true);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
// load the stylesheet if necessary, passing ourselves as
|
|
|
|
// nsICSSObserver
|
2018-04-24 13:50:35 +03:00
|
|
|
auto result = ssle->UpdateStyleSheet(this);
|
|
|
|
if (result.isErr()) {
|
|
|
|
// Ignore errors from UpdateStyleSheet; we don't want failure to
|
|
|
|
// do that to break the XUL document load. But do propagate out
|
|
|
|
// NS_ERROR_OUT_OF_MEMORY.
|
|
|
|
if (result.unwrapErr() == NS_ERROR_OUT_OF_MEMORY) {
|
|
|
|
return result.unwrapErr();
|
2006-11-12 01:27:00 +03:00
|
|
|
}
|
2018-04-24 13:50:35 +03:00
|
|
|
return NS_OK;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2006-11-12 01:27:00 +03:00
|
|
|
|
2018-04-24 13:50:35 +03:00
|
|
|
auto update = result.unwrap();
|
|
|
|
if (update.ShouldBlock()) {
|
|
|
|
++mPendingSheets;
|
2007-04-21 03:43:28 +04:00
|
|
|
}
|
2017-07-06 15:00:35 +03:00
|
|
|
|
2007-04-21 03:43:28 +04:00
|
|
|
return NS_OK;
|
2006-11-12 01:27:00 +03:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::ResumeWalk() {
|
1999-10-29 05:21:15 +04:00
|
|
|
// Walk the prototype and build the delegate content model. The
|
|
|
|
// walk is performed in a top-down, left-to-right fashion. That
|
|
|
|
// is, a parent is built before any of its children; a node is
|
|
|
|
// only built after all of its siblings to the left are fully
|
|
|
|
// constructed.
|
|
|
|
//
|
|
|
|
// It is interruptable so that transcluded documents (e.g.,
|
|
|
|
// <html:script src="..." />) can be properly re-loaded if the
|
|
|
|
// cached copy of the document becomes stale.
|
|
|
|
nsresult rv;
|
2018-03-29 04:20:04 +03:00
|
|
|
nsCOMPtr<nsIURI> docURI =
|
2012-07-30 18:20:58 +04:00
|
|
|
mCurrentPrototype ? mCurrentPrototype->GetURI() : nullptr;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
while (1) {
|
2001-07-31 23:05:34 +04:00
|
|
|
// Begin (or resume) walking the current prototype.
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
while (mContextStack.Depth() > 0) {
|
2013-08-16 01:14:43 +04:00
|
|
|
// Look at the top of the stack to determine what we're
|
1999-10-29 05:21:15 +04:00
|
|
|
// currently working on.
|
|
|
|
// This will always be a node already constructed and
|
|
|
|
// inserted to the actual document.
|
|
|
|
nsXULPrototypeElement* proto;
|
2018-03-29 04:20:04 +03:00
|
|
|
nsCOMPtr<nsIContent> element;
|
1999-10-29 05:21:15 +04:00
|
|
|
int32_t indx; // all children of proto before indx (not
|
|
|
|
// inclusive) have already been constructed
|
|
|
|
rv = mContextStack.Peek(&proto, getter_AddRefs(element), &indx);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
if (indx >= (int32_t)proto->mChildren.Length()) {
|
2005-08-02 16:47:41 +04:00
|
|
|
if (element) {
|
1999-10-29 05:21:15 +04:00
|
|
|
// We've processed all of the prototype's children. If
|
|
|
|
// we're in the master prototype, do post-order
|
|
|
|
// document-level hookup.
|
2018-03-29 04:20:04 +03:00
|
|
|
AddElementToDocumentPost(element->AsElement());
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
if (element->NodeInfo()->Equals(nsGkAtoms::style,
|
|
|
|
kNameSpaceID_XHTML) ||
|
|
|
|
element->NodeInfo()->Equals(nsGkAtoms::style, kNameSpaceID_SVG)) {
|
1999-10-29 05:21:15 +04:00
|
|
|
// XXX sucks that we have to do this -
|
2018-03-29 04:20:04 +03:00
|
|
|
// see bug 370111
|
|
|
|
nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
|
|
|
|
do_QueryInterface(element);
|
|
|
|
NS_ASSERTION(ssle,
|
|
|
|
"<html:style> doesn't implement "
|
|
|
|
"nsIStyleSheetLinkingElement?");
|
1999-10-29 05:21:15 +04:00
|
|
|
Unused << ssle->UpdateStyleSheet(nullptr);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
}
|
1999-10-29 05:21:15 +04:00
|
|
|
// Now pop the context stack back up to the parent
|
|
|
|
// element and continue the prototype walk.
|
|
|
|
mContextStack.Pop();
|
|
|
|
continue;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
// Grab the next child, and advance the current context stack
|
|
|
|
// to the next sibling to our right.
|
1999-10-29 05:21:15 +04:00
|
|
|
nsXULPrototypeNode* childproto = proto->mChildren[indx];
|
|
|
|
mContextStack.SetTopIndex(++indx);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
NS_ASSERTION(element, "no element on context stack");
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
switch (childproto->mType) {
|
|
|
|
case nsXULPrototypeNode::eType_Element: {
|
2006-11-12 01:27:00 +03:00
|
|
|
// An 'element', which may contain more content.
|
1999-10-29 05:21:15 +04:00
|
|
|
nsXULPrototypeElement* protoele =
|
|
|
|
static_cast<nsXULPrototypeElement*>(childproto);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
RefPtr<Element> child;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
rv = CreateElementFromPrototype(protoele, getter_AddRefs(child),
|
2018-11-30 13:46:48 +03:00
|
|
|
false);
|
1999-10-29 05:21:15 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-03-29 04:20:04 +03:00
|
|
|
// ...and append it to the content model.
|
|
|
|
rv = element->AppendChildTo(child, false);
|
1999-10-29 05:21:15 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
// If it has children, push the element onto the context
|
|
|
|
// stack and begin to process them.
|
2008-10-08 15:41:52 +04:00
|
|
|
if (protoele->mChildren.Length() > 0) {
|
1999-10-29 05:21:15 +04:00
|
|
|
rv = mContextStack.Push(protoele, child);
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
} else {
|
2018-03-29 04:20:04 +03:00
|
|
|
// If there are no children, do post-order document hookup
|
|
|
|
// immediately.
|
|
|
|
AddElementToDocumentPost(child);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
case nsXULPrototypeNode::eType_Script: {
|
1999-11-18 05:25:33 +03:00
|
|
|
// A script reference. Execute the script immediately;
|
1999-10-29 05:21:15 +04:00
|
|
|
// this may have side effects in the content model.
|
|
|
|
nsXULPrototypeScript* scriptproto =
|
2007-07-08 11:08:04 +04:00
|
|
|
static_cast<nsXULPrototypeScript*>(childproto);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
if (scriptproto->mSrcURI) {
|
|
|
|
// A transcluded script reference; this may
|
|
|
|
// "block" our prototype walk if the script isn't
|
|
|
|
// cached, or the cached copy of the script is
|
|
|
|
// stale and must be reloaded.
|
2011-09-29 10:19:26 +04:00
|
|
|
bool blocked;
|
1999-11-18 05:25:33 +03:00
|
|
|
rv = LoadScript(scriptproto, &blocked);
|
2005-07-01 16:18:18 +04:00
|
|
|
// If the script cannot be loaded, just keep going!
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2005-07-01 16:18:18 +04:00
|
|
|
if (NS_SUCCEEDED(rv) && blocked) return NS_OK;
|
2016-10-14 11:45:28 +03:00
|
|
|
} else if (scriptproto->HasScriptObject()) {
|
(13163, r=alecf, scc, waterson, others; names available on request)
- Fix most of bug 13163 (see TODO for rest). This entails adding a version-string argument to nsIScriptContext::EvaluateString and passing it around lots of places in content sinks.
- Fix leaks and confusion about mSecurityManager and mNameSpaceManager in nsJSEnvironment.cpp. These still need to move from nsJSContext to nsGlobalWindow or thereabouts, jband and vidur are looking at that.
- Added comments and expanded tabs in nsJSEnvironment.cpp, esp. to EvaluateString. Also changed various nsresult vars to be named rv. Also restored brace/style conformity to nsJSProtocolHandler.cpp.
- Factored CompileFunction from AddScriptEventListener to pave the way for brutal sharing of compiled JS event handlers via JS_CloneFunctionObject.
- Lots of nsCOMPtr uses added. I'm using one for mNameSpaceManager. Hold mSecurityManager as a service explicitly, on the other hand (awaiting scc's fix to allow comptrs for services), and release in nsJSContext's dtor (fixing a leak). These two managers should be moved to the window object -- TODO item below.
- Hold JSRuntimeService along with JSRuntime for live of nsJSEnvironment, fix for shaver.
- Fix window.setTimeout etc. so the filename and line number of the timeout expr is propagated. This meant factoring nsJSUtils.cpp code.
- Fix all content sinks to use the same, and up-to-date JavaScript version parsing (whether for script type or for old language attribute); also fix SplitMimeType clones to strip whitespace.
- With waterson, fix bug in brutal-sharing version of XUL content sink: script src= should not evaluate the inline content of its tag.
1999-10-31 03:43:30 +03:00
|
|
|
// An inline script
|
2006-06-13 07:07:47 +04:00
|
|
|
rv = ExecuteScript(scriptproto);
|
1999-10-29 05:21:15 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
} break;
|
1999-10-29 05:21:15 +04:00
|
|
|
|
|
|
|
case nsXULPrototypeNode::eType_Text: {
|
1999-11-18 05:25:33 +03:00
|
|
|
// A simple text node.
|
2018-03-29 04:20:04 +03:00
|
|
|
RefPtr<nsTextNode> text = new nsTextNode(mNodeInfoManager);
|
1999-10-29 05:21:15 +04:00
|
|
|
|
|
|
|
nsXULPrototypeText* textproto =
|
|
|
|
static_cast<nsXULPrototypeText*>(childproto);
|
|
|
|
text->SetText(textproto->mValue, false);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
rv = element->AppendChildTo(text, false);
|
2018-03-29 04:20:04 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
1999-10-29 05:21:15 +04:00
|
|
|
} break;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
case nsXULPrototypeNode::eType_PI: {
|
2006-11-12 01:27:00 +03:00
|
|
|
nsXULPrototypePI* piProto =
|
1999-10-29 05:21:15 +04:00
|
|
|
static_cast<nsXULPrototypePI*>(childproto);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
// <?xml-stylesheet?> doesn't have an effect
|
|
|
|
// outside the prolog, like it used to. Issue a warning.
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
if (piProto->mTarget.EqualsLiteral("xml-stylesheet")) {
|
|
|
|
const char16_t* params[] = {piProto->mTarget.get()};
|
|
|
|
|
|
|
|
nsContentUtils::ReportToConsole(
|
|
|
|
nsIScriptError::warningFlag, NS_LITERAL_CSTRING("XUL Document"),
|
|
|
|
nullptr, nsContentUtils::eXUL_PROPERTIES, "PINotInProlog",
|
|
|
|
params, ArrayLength(params), docURI);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-11-23 04:44:51 +03:00
|
|
|
|
2018-11-07 00:45:20 +03:00
|
|
|
nsIContent* parent = element.get();
|
1999-11-23 04:44:51 +03:00
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
if (parent) {
|
|
|
|
// an inline script could have removed the root element
|
|
|
|
rv = CreateAndInsertPI(piProto, parent, nullptr);
|
2018-03-29 04:20:04 +03:00
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
} break;
|
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
default:
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Unexpected nsXULPrototypeNode::Type");
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2006-11-12 01:27:00 +03:00
|
|
|
}
|
|
|
|
|
2006-01-14 08:28:34 +03:00
|
|
|
// Once we get here, the context stack will have been
|
2018-09-07 04:28:40 +03:00
|
|
|
// depleted. That means that the entire prototype has been
|
|
|
|
// walked and content has been constructed.
|
|
|
|
break;
|
2006-07-25 04:20:33 +04:00
|
|
|
}
|
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
// If we get here, there is nothing left for us to walk. The content
|
2005-02-25 12:06:34 +03:00
|
|
|
// model is built and ready for layout.
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2005-02-25 12:06:34 +03:00
|
|
|
mXULPersist = new XULPersist(this);
|
2018-03-29 04:20:04 +03:00
|
|
|
mXULPersist->Init();
|
2005-02-25 12:06:34 +03:00
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
mStillWalking = false;
|
2008-04-18 12:58:06 +04:00
|
|
|
if (mPendingSheets == 0) {
|
2009-01-31 15:53:01 +03:00
|
|
|
rv = DoneWalking();
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-10-29 05:21:15 +04:00
|
|
|
return rv;
|
2008-04-18 12:58:06 +04:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::DoneWalking() {
|
2006-04-12 03:44:34 +04:00
|
|
|
MOZ_ASSERT(mPendingSheets == 0, "there are sheets to be loaded");
|
|
|
|
MOZ_ASSERT(!mStillWalking, "walk not done");
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-04-12 03:44:34 +04:00
|
|
|
// XXXldb This is where we should really be setting the chromehidden
|
2005-08-25 08:11:35 +04:00
|
|
|
// attribute.
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-04-12 03:44:34 +04:00
|
|
|
if (!mDocumentLoaded) {
|
2006-01-14 08:28:34 +03:00
|
|
|
// Make sure we don't reenter here from StartLayout(). Note that
|
2006-04-12 03:44:34 +04:00
|
|
|
// setting mDocumentLoaded to true here means that if StartLayout()
|
|
|
|
// causes ResumeWalk() to be reentered, we'll take the other branch of
|
2006-01-14 08:28:34 +03:00
|
|
|
// the |if (!mDocumentLoaded)| check above and since
|
|
|
|
// mInitialLayoutComplete will be false will follow the else branch
|
|
|
|
// there too. See the big comment there for how such reentry can
|
|
|
|
// happen.
|
2011-10-17 18:59:28 +04:00
|
|
|
mDocumentLoaded = true;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-04-12 03:44:34 +04:00
|
|
|
NotifyPossibleTitleChange(false);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-09-07 04:28:40 +03:00
|
|
|
// For performance reasons, we want to trigger the DocumentL10n's
|
|
|
|
// `TriggerInitialDocumentTranslation` within the same microtask that will
|
|
|
|
// be created for a `MozBeforeInitialXULLayout` event listener.
|
2006-04-12 03:44:34 +04:00
|
|
|
AddEventListener(NS_LITERAL_STRING("MozBeforeInitialXULLayout"),
|
2018-09-07 04:28:40 +03:00
|
|
|
mDocumentL10n, true, false);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-03-15 13:19:50 +03:00
|
|
|
nsContentUtils::DispatchTrustedEvent(
|
2018-12-26 05:32:55 +03:00
|
|
|
this, ToSupports(this), NS_LITERAL_STRING("MozBeforeInitialXULLayout"),
|
|
|
|
CanBubble::eYes, Cancelable::eNo);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-09-07 04:28:40 +03:00
|
|
|
RemoveEventListener(NS_LITERAL_STRING("MozBeforeInitialXULLayout"),
|
|
|
|
mDocumentL10n, true);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-07-25 04:20:33 +04:00
|
|
|
// Before starting layout, check whether we're a toplevel chrome
|
2018-03-15 13:19:50 +03:00
|
|
|
// window. If we are, setup some state so that we don't have to restyle
|
|
|
|
// the whole tree after StartLayout.
|
2006-04-12 03:44:34 +04:00
|
|
|
if (nsCOMPtr<nsIXULWindow> win = GetXULWindowIfToplevelChrome()) {
|
2018-03-10 04:42:13 +03:00
|
|
|
// We're the chrome document!
|
|
|
|
win->BeforeStartLayout();
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2018-03-10 04:42:13 +03:00
|
|
|
StartLayout();
|
2005-08-02 16:42:24 +04:00
|
|
|
|
2007-09-21 21:30:37 +04:00
|
|
|
if (mIsWritingFastLoad && IsChromeURI(mDocumentURI))
|
2005-08-02 16:42:24 +04:00
|
|
|
nsXULPrototypeCache::GetInstance()->WritePrototype(mCurrentPrototype);
|
|
|
|
|
2008-04-18 12:58:06 +04:00
|
|
|
NS_ASSERTION(mDelayFrameLoaderInitialization,
|
2011-10-17 18:59:28 +04:00
|
|
|
"mDelayFrameLoaderInitialization should be true!");
|
|
|
|
mDelayFrameLoaderInitialization = false;
|
2000-10-29 20:58:21 +03:00
|
|
|
NS_WARNING_ASSERTION(mUpdateNestLevel == 0,
|
2011-10-17 18:59:28 +04:00
|
|
|
"Constructing XUL document in middle of an update?");
|
2016-09-01 08:01:16 +03:00
|
|
|
if (mUpdateNestLevel == 0) {
|
2009-01-31 15:53:01 +03:00
|
|
|
MaybeInitializeFinalizeFrameLoaders();
|
1999-11-25 01:46:09 +03:00
|
|
|
}
|
2003-03-26 10:41:30 +03:00
|
|
|
|
2018-09-07 04:28:40 +03:00
|
|
|
NS_DOCUMENT_NOTIFY_OBSERVERS(EndLoad, (this));
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2007-09-21 21:30:37 +04:00
|
|
|
// DispatchContentLoadedEvents undoes the onload-blocking we
|
|
|
|
// did in PrepareToWalk().
|
2005-08-02 16:42:24 +04:00
|
|
|
DispatchContentLoadedEvents();
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-01-14 08:28:34 +03:00
|
|
|
mInitialLayoutComplete = true;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2016-09-26 15:03:25 +03:00
|
|
|
XULDocument::StyleSheetLoaded(StyleSheet* aSheet, bool aWasDeferred,
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult aStatus) {
|
2018-04-24 20:17:33 +03:00
|
|
|
if (!aWasDeferred) {
|
2006-11-12 01:27:00 +03:00
|
|
|
// Don't care about when alternate sheets finish loading
|
2018-04-24 20:17:33 +03:00
|
|
|
MOZ_ASSERT(mPendingSheets > 0, "Unexpected StyleSheetLoaded notification");
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
--mPendingSheets;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2006-11-12 01:27:00 +03:00
|
|
|
if (!mStillWalking && mPendingSheets == 0) {
|
|
|
|
return DoneWalking();
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2006-11-12 01:27:00 +03:00
|
|
|
|
|
|
|
return NS_OK;
|
1999-10-29 05:21:15 +04:00
|
|
|
}
|
|
|
|
|
2018-05-15 16:56:38 +03:00
|
|
|
void XULDocument::EndUpdate() { XMLDocument::EndUpdate(); }
|
2009-01-31 15:53:01 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::LoadScript(nsXULPrototypeScript* aScriptProto,
|
|
|
|
bool* aBlock) {
|
1999-10-29 05:21:15 +04:00
|
|
|
// Load a transcluded script
|
|
|
|
nsresult rv;
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool isChromeDoc = IsChromeURI(mDocumentURI);
|
2008-03-14 01:49:45 +03:00
|
|
|
|
2016-10-14 11:45:28 +03:00
|
|
|
if (isChromeDoc && aScriptProto->HasScriptObject()) {
|
2006-06-13 07:07:47 +04:00
|
|
|
rv = ExecuteScript(aScriptProto);
|
1999-10-29 05:21:15 +04:00
|
|
|
|
1999-11-18 05:25:33 +03:00
|
|
|
// Ignore return value from execution, and don't block
|
2011-10-17 18:59:28 +04:00
|
|
|
*aBlock = false;
|
2001-07-31 23:05:34 +04:00
|
|
|
return NS_OK;
|
1999-10-29 05:21:15 +04:00
|
|
|
}
|
2001-07-31 23:05:34 +04:00
|
|
|
|
|
|
|
// Try the XUL script cache, in case two XUL documents source the same
|
|
|
|
// .js file (e.g., strres.js from navigator.xul and utilityOverlay.xul).
|
|
|
|
// XXXbe the cache relies on aScriptProto's GC root!
|
2011-09-29 10:19:26 +04:00
|
|
|
bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2008-03-14 01:49:45 +03:00
|
|
|
if (isChromeDoc && useXULCache) {
|
2011-10-30 00:13:31 +04:00
|
|
|
JSScript* newScriptObject =
|
2011-10-30 00:13:55 +04:00
|
|
|
nsXULPrototypeCache::GetInstance()->GetScript(aScriptProto->mSrcURI);
|
2006-06-13 07:07:47 +04:00
|
|
|
if (newScriptObject) {
|
|
|
|
// The script language for a proto must remain constant - we
|
|
|
|
// can't just change it for this unexpected language.
|
2007-10-29 16:45:07 +03:00
|
|
|
aScriptProto->Set(newScriptObject);
|
2006-06-13 07:07:47 +04:00
|
|
|
}
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2016-10-14 11:45:28 +03:00
|
|
|
if (aScriptProto->HasScriptObject()) {
|
2006-06-13 07:07:47 +04:00
|
|
|
rv = ExecuteScript(aScriptProto);
|
2001-07-31 23:05:34 +04:00
|
|
|
|
|
|
|
// Ignore return value from execution, and don't block
|
2011-10-17 18:59:28 +04:00
|
|
|
*aBlock = false;
|
2001-07-31 23:05:34 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2010-10-19 09:15:32 +04:00
|
|
|
// Release script objects from FastLoad since we decided against using them
|
|
|
|
aScriptProto->UnlinkJSObjects();
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2001-07-31 23:05:34 +04:00
|
|
|
// Set the current script prototype so that OnStreamComplete can report
|
|
|
|
// the right file if there are errors in the script.
|
|
|
|
NS_ASSERTION(!mCurrentScriptProto,
|
|
|
|
"still loading a script when starting another load?");
|
|
|
|
mCurrentScriptProto = aScriptProto;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2015-11-03 04:31:08 +03:00
|
|
|
if (isChromeDoc && aScriptProto->mSrcLoading) {
|
2001-07-31 23:05:34 +04:00
|
|
|
// Another XULDocument load has started, which is still in progress.
|
|
|
|
// Remember to ResumeWalk this document when the load completes.
|
|
|
|
mNextSrcLoadWaiter = aScriptProto->mSrcLoadWaiters;
|
|
|
|
aScriptProto->mSrcLoadWaiters = this;
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
} else {
|
|
|
|
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2005-09-30 02:00:26 +04:00
|
|
|
// Note: the loader will keep itself alive while it's loading.
|
|
|
|
nsCOMPtr<nsIStreamLoader> loader;
|
2014-09-21 20:37:08 +04:00
|
|
|
rv = NS_NewStreamLoader(getter_AddRefs(loader), aScriptProto->mSrcURI,
|
|
|
|
this, // aObserver
|
|
|
|
this, // aRequestingContext
|
2015-11-03 04:31:08 +03:00
|
|
|
nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS,
|
|
|
|
nsIContentPolicy::TYPE_INTERNAL_SCRIPT, group);
|
2005-09-30 02:00:26 +04:00
|
|
|
|
2006-08-30 20:13:32 +04:00
|
|
|
if (NS_FAILED(rv)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
mCurrentScriptProto = nullptr;
|
2006-11-12 01:27:00 +03:00
|
|
|
return rv;
|
1999-10-29 05:21:15 +04:00
|
|
|
}
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2013-08-16 01:14:43 +04:00
|
|
|
aScriptProto->mSrcLoading = true;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2001-07-31 23:05:34 +04:00
|
|
|
// Block until OnStreamComplete resumes us.
|
2011-10-17 18:59:28 +04:00
|
|
|
*aBlock = true;
|
1999-10-29 05:21:15 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-30 07:50:42 +03:00
|
|
|
NS_IMETHODIMP
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* context,
|
|
|
|
nsresult aStatus, uint32_t stringLen,
|
|
|
|
const uint8_t* string) {
|
2005-06-12 16:32:05 +04:00
|
|
|
nsCOMPtr<nsIRequest> request;
|
|
|
|
aLoader->GetRequest(getter_AddRefs(request));
|
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
|
|
|
|
|
2003-04-23 01:57:25 +04:00
|
|
|
#ifdef DEBUG
|
2000-05-04 02:47:48 +04:00
|
|
|
// print a load error on bad status
|
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works
for me on optimized and debug gcc2.96, rh7.1.
- Better failure codes from nsXULPrototypeScript::Deserialize.
- Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize
failure, instead of just nulling the FastLoad service's output stream.
- Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from
nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for
good measure.
- The needless "Current" adjective in nsIFastLoadService attribute and method
names is no more.
- Add a do_GetFastLoadService() helper, to use CID instead of contractid, and
to let the compiler consolidate the static inline CID.
- Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without
the checksum verification step when reading a FastLoad file.
- Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad
service so we don't recompute it when re-opening the FastLoad file as mailnews
and other top-levels start up. Fill the checksum cache in EndFastLoad, when
the last pseudo-concurrent top-level finishes loading.
My hope to compute the checksum while writing the FastLoad file ran afoul of
misordered writes. The old code to checksum the in-memory nsFastLoadHeader
also was broken on little endian platforms. Now all checksumming is done via
a separate read pass over the complete file, save for the header's checksum
field, which is summed as if it contained zero.
- Track and check FastLoad file dependencies. This required groveling with a
bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it
and weep. Dependency checking, as well as checksum access and computation,
use better-factored nsIFastLoad{File,Read,Write}Control interfaces.
- nsBufferedStream::Seek wasn't flushing the buffer when seeking backward
within the buffer, but it must, because mCursor bounds the amount to write
if the buffer contains the end of file.
- Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we
don't have to screw around with the bufferying layer when checksumming. Also
implement nsIStreamBufferAccess in nsBufferedOutputStream.
- nsISeekableOutputStream was bogus, based on a bad state I had put the
nsBufferedOutputStream code in on its way from being completely broken when
you seek backwards outside of the buffer. Removing this interface required
using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful
ordering of Close calls (the Reader must close after the Writer or Updater,
so that the Reader's underlying, unbuffered input stream can be read by
nsFastLoadFileWriter::Close to compute the checksum.
- Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style,
nsnull vs. 0, useless variable elimination, tortured control flow,
AutoString instead of String, and gratuitous ; after nsISupportsUtils.h
macro call cleanups.
2001-08-22 00:51:34 +04:00
|
|
|
if (NS_FAILED(aStatus)) {
|
2001-07-31 23:05:34 +04:00
|
|
|
if (channel) {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
channel->GetURI(getter_AddRefs(uri));
|
|
|
|
if (uri) {
|
2016-08-26 09:02:31 +03:00
|
|
|
printf("Failed to load %s\n", uri->GetSpecOrDefault().get());
|
2000-05-04 02:47:48 +04:00
|
|
|
}
|
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2003-04-23 01:57:25 +04:00
|
|
|
#endif
|
2001-07-31 23:05:34 +04:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
// This is the completion routine that will be called when a
|
1999-11-18 05:25:33 +03:00
|
|
|
// transcluded script completes. Compile and execute the script
|
|
|
|
// if the load was successful, then continue building content
|
|
|
|
// from the prototype.
|
2013-09-03 18:59:11 +04:00
|
|
|
nsresult rv = aStatus;
|
1999-10-29 05:21:15 +04:00
|
|
|
|
1999-11-23 04:44:51 +03:00
|
|
|
NS_ASSERTION(mCurrentScriptProto && mCurrentScriptProto->mSrcLoading,
|
1999-11-18 05:25:33 +03:00
|
|
|
"script source not loading on unichar stream complete?");
|
2009-10-27 04:39:23 +03:00
|
|
|
if (!mCurrentScriptProto) {
|
|
|
|
// XXX Wallpaper for bug 270042
|
|
|
|
return NS_OK;
|
|
|
|
}
|
1999-11-02 04:14:07 +03:00
|
|
|
|
1999-11-18 05:25:33 +03:00
|
|
|
if (NS_SUCCEEDED(aStatus)) {
|
2001-07-31 23:05:34 +04:00
|
|
|
// If the including XUL document is a FastLoad document, and we're
|
|
|
|
// compiling an out-of-line script (one with src=...), then we must
|
|
|
|
// be writing a new FastLoad file. If we were reading this script
|
|
|
|
// from the FastLoad file, XULContentSinkImpl::OpenScript (over in
|
|
|
|
// nsXULContentSink.cpp) would have already deserialized a non-null
|
2006-06-13 07:07:47 +04:00
|
|
|
// script->mScriptObject, causing control flow at the top of LoadScript
|
2001-07-31 23:05:34 +04:00
|
|
|
// not to reach here.
|
2013-08-16 01:14:43 +04:00
|
|
|
nsCOMPtr<nsIURI> uri = mCurrentScriptProto->mSrcURI;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2005-06-12 16:32:05 +04:00
|
|
|
// XXX should also check nsIHttpChannel::requestSucceeded
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2014-04-25 18:11:57 +04:00
|
|
|
MOZ_ASSERT(!mOffThreadCompiling && (mOffThreadCompileStringLength == 0 &&
|
|
|
|
!mOffThreadCompileStringBuf),
|
2013-08-16 01:14:43 +04:00
|
|
|
"XULDocument can't load multiple scripts at once");
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2017-05-08 09:24:22 +03:00
|
|
|
rv = ScriptLoader::ConvertToUTF16(channel, string, stringLen, EmptyString(),
|
|
|
|
this, mOffThreadCompileStringBuf,
|
|
|
|
mOffThreadCompileStringLength);
|
2008-03-22 08:03:57 +03:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
2018-10-23 22:27:16 +03:00
|
|
|
// Pass ownership of the buffer, carefully emptying the existing
|
|
|
|
// fields in the process. Note that the |Compile| function called
|
|
|
|
// below always takes ownership of the buffer.
|
|
|
|
char16_t* units = nullptr;
|
|
|
|
size_t unitsLength = 0;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-10-23 22:27:16 +03:00
|
|
|
std::swap(units, mOffThreadCompileStringBuf);
|
|
|
|
std::swap(unitsLength, mOffThreadCompileStringLength);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2018-10-23 22:27:16 +03:00
|
|
|
rv = mCurrentScriptProto->Compile(units, unitsLength,
|
2018-11-09 05:42:48 +03:00
|
|
|
JS::SourceOwnership::TakeOwnership, uri,
|
2018-10-23 22:27:16 +03:00
|
|
|
1, this, this);
|
2016-10-14 11:45:28 +03:00
|
|
|
if (NS_SUCCEEDED(rv) && !mCurrentScriptProto->HasScriptObject()) {
|
2013-08-16 01:14:43 +04:00
|
|
|
mOffThreadCompiling = true;
|
|
|
|
BlockOnload();
|
|
|
|
return NS_OK;
|
2008-03-22 08:03:57 +03:00
|
|
|
}
|
2013-08-16 01:14:43 +04:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2013-08-16 01:14:43 +04:00
|
|
|
return OnScriptCompileComplete(mCurrentScriptProto->GetScriptObject(), rv);
|
|
|
|
}
|
2001-07-31 23:05:34 +04:00
|
|
|
|
2013-08-16 01:14:43 +04:00
|
|
|
NS_IMETHODIMP
|
|
|
|
XULDocument::OnScriptCompileComplete(JSScript* aScript, nsresult aStatus) {
|
2013-08-27 01:43:58 +04:00
|
|
|
// When compiling off thread the script will not have been attached to the
|
|
|
|
// script proto yet.
|
2016-10-14 11:45:28 +03:00
|
|
|
if (aScript && !mCurrentScriptProto->HasScriptObject())
|
2013-08-27 01:43:58 +04:00
|
|
|
mCurrentScriptProto->Set(aScript);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2013-08-16 01:14:43 +04:00
|
|
|
// Allow load events to be fired once off thread compilation finishes.
|
|
|
|
if (mOffThreadCompiling) {
|
|
|
|
mOffThreadCompiling = false;
|
|
|
|
UnblockOnload(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
// After compilation finishes the script's characters are no longer needed.
|
2014-04-25 18:11:57 +04:00
|
|
|
if (mOffThreadCompileStringBuf) {
|
|
|
|
js_free(mOffThreadCompileStringBuf);
|
|
|
|
mOffThreadCompileStringBuf = nullptr;
|
|
|
|
mOffThreadCompileStringLength = 0;
|
|
|
|
}
|
2013-08-16 01:14:43 +04:00
|
|
|
|
|
|
|
// Clear mCurrentScriptProto now, but save it first for use below in
|
|
|
|
// the execute code, and in the while loop that resumes walks of other
|
|
|
|
// documents that raced to load this script.
|
|
|
|
nsXULPrototypeScript* scriptProto = mCurrentScriptProto;
|
|
|
|
mCurrentScriptProto = nullptr;
|
|
|
|
|
|
|
|
// Clear the prototype's loading flag before executing the script or
|
|
|
|
// resuming document walks, in case any of those control flows starts a
|
|
|
|
// new script load.
|
|
|
|
scriptProto->mSrcLoading = false;
|
|
|
|
|
|
|
|
nsresult rv = aStatus;
|
2016-10-14 11:45:28 +03:00
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
rv = ExecuteScript(scriptProto);
|
1999-10-29 05:21:15 +04:00
|
|
|
|
1999-11-02 09:49:44 +03:00
|
|
|
// If the XUL cache is enabled, save the script object there in
|
2013-08-16 01:14:43 +04:00
|
|
|
// case different XUL documents source the same script.
|
2018-11-30 13:46:48 +03:00
|
|
|
//
|
1999-11-02 09:49:44 +03:00
|
|
|
// But don't save the script in the cache unless the master XUL
|
|
|
|
// document URL is a chrome: URL. It is valid for a URL such as
|
2013-08-16 01:14:43 +04:00
|
|
|
// about:config to translate into a master document URL, whose
|
|
|
|
// prototype document nodes -- including prototype scripts that
|
1999-11-02 09:49:44 +03:00
|
|
|
// hold GC roots protecting their mJSObject pointers -- are not
|
2013-08-16 01:14:43 +04:00
|
|
|
// cached in the XUL prototype cache. See StartDocumentLoad,
|
|
|
|
// the fillXULCache logic.
|
2018-11-30 13:46:48 +03:00
|
|
|
//
|
2013-08-16 01:14:43 +04:00
|
|
|
// A document such as about:config is free to load a script via
|
|
|
|
// a URL such as chrome://global/content/config.js, and we must
|
|
|
|
// not cache that script object without a prototype cache entry
|
|
|
|
// containing a companion nsXULPrototypeScript node that owns a
|
1999-11-02 09:49:44 +03:00
|
|
|
// GC root protecting the script object. Otherwise, the script
|
2013-08-16 01:14:43 +04:00
|
|
|
// cache entry will dangle once the uncached prototype document
|
|
|
|
// is released when its owning XULDocument is unloaded.
|
2018-11-30 13:46:48 +03:00
|
|
|
//
|
2013-08-16 01:14:43 +04:00
|
|
|
// (See http://bugzilla.mozilla.org/show_bug.cgi?id=98207 for
|
|
|
|
// the true crime story.)
|
1999-11-02 09:49:44 +03:00
|
|
|
bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
|
1999-11-18 05:25:33 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
if (useXULCache && IsChromeURI(mDocumentURI) &&
|
1999-11-23 04:44:51 +03:00
|
|
|
scriptProto->HasScriptObject()) {
|
2018-02-28 22:46:06 +03:00
|
|
|
JS::Rooted<JSScript*> script(RootingCx(), scriptProto->GetScriptObject());
|
|
|
|
nsXULPrototypeCache::GetInstance()->PutScript(scriptProto->mSrcURI,
|
2018-11-30 13:46:48 +03:00
|
|
|
script);
|
|
|
|
}
|
2018-02-28 22:46:06 +03:00
|
|
|
// ignore any evaluation errors
|
|
|
|
}
|
|
|
|
|
1999-11-23 04:44:51 +03:00
|
|
|
rv = ResumeWalk();
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-11-23 04:44:51 +03:00
|
|
|
// Load a pointer to the prototype-script's list of XULDocuments who
|
|
|
|
// raced to load the same script
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument** docp = &scriptProto->mSrcLoadWaiters;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-11-23 04:44:51 +03:00
|
|
|
// Resume walking other documents that waited for this one's load, first
|
|
|
|
// executing the script we just compiled, in each doc's script context
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument* doc;
|
1999-11-23 04:44:51 +03:00
|
|
|
while ((doc = *docp) != nullptr) {
|
|
|
|
NS_ASSERTION(doc->mCurrentScriptProto == scriptProto,
|
|
|
|
"waiting for wrong script to load?");
|
2012-07-30 18:20:58 +04:00
|
|
|
doc->mCurrentScriptProto = nullptr;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
1999-11-23 04:44:51 +03:00
|
|
|
// Unlink doc from scriptProto's list before executing and resuming
|
1999-11-18 05:25:33 +03:00
|
|
|
*docp = doc->mNextSrcLoadWaiter;
|
2012-07-30 18:20:58 +04:00
|
|
|
doc->mNextSrcLoadWaiter = nullptr;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2016-10-14 11:45:28 +03:00
|
|
|
if (aStatus == NS_BINDING_ABORTED && !scriptProto->HasScriptObject()) {
|
|
|
|
// If the previous doc load was aborted, we want to try loading
|
2018-02-28 22:46:06 +03:00
|
|
|
// again for the next doc. Otherwise, one abort would lead to all
|
2016-10-14 11:45:28 +03:00
|
|
|
// subsequent waiting docs to abort as well.
|
2018-02-28 22:46:06 +03:00
|
|
|
bool block = false;
|
2006-06-13 07:07:47 +04:00
|
|
|
doc->LoadScript(scriptProto, &block);
|
1999-11-18 05:25:33 +03:00
|
|
|
NS_RELEASE(doc);
|
2006-08-30 20:13:32 +04:00
|
|
|
return rv;
|
1999-11-18 05:25:33 +03:00
|
|
|
}
|
1999-11-23 04:44:51 +03:00
|
|
|
|
|
|
|
// Execute only if we loaded and compiled successfully, then resume
|
2016-10-14 11:45:28 +03:00
|
|
|
if (NS_SUCCEEDED(aStatus) && scriptProto->HasScriptObject()) {
|
2013-08-16 01:14:43 +04:00
|
|
|
doc->ExecuteScript(scriptProto);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-11-20 06:10:42 +03:00
|
|
|
doc->ResumeWalk();
|
2018-02-28 22:46:06 +03:00
|
|
|
NS_RELEASE(doc);
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2014-08-05 17:57:53 +04:00
|
|
|
nsresult XULDocument::ExecuteScript(nsXULPrototypeScript* aScript) {
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aScript != nullptr, "null ptr");
|
2014-08-05 17:57:53 +04:00
|
|
|
NS_ENSURE_TRUE(aScript, NS_ERROR_NULL_POINTER);
|
2006-07-18 04:36:35 +04:00
|
|
|
NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED);
|
|
|
|
|
2014-08-05 17:57:53 +04:00
|
|
|
nsresult rv;
|
|
|
|
rv = mScriptGlobalObject->EnsureScriptEnvironment();
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
2015-05-29 19:11:09 +03:00
|
|
|
// Execute the precompiled script with the given version
|
|
|
|
nsAutoMicroTask mt;
|
|
|
|
|
2014-08-05 17:57:53 +04:00
|
|
|
// We're about to run script via JS::CloneAndExecuteScript, so we need an
|
|
|
|
// AutoEntryScript. This is Gecko specific and not in any spec.
|
2015-04-09 04:23:48 +03:00
|
|
|
AutoEntryScript aes(mScriptGlobalObject, "precompiled XUL <script> element");
|
2014-08-05 17:57:53 +04:00
|
|
|
JSContext* cx = aes.cx();
|
2016-10-14 11:45:28 +03:00
|
|
|
|
|
|
|
JS::Rooted<JSScript*> scriptObject(cx, aScript->GetScriptObject());
|
|
|
|
NS_ENSURE_TRUE(scriptObject, NS_ERROR_UNEXPECTED);
|
|
|
|
|
2018-03-14 05:43:30 +03:00
|
|
|
JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
|
|
|
|
NS_ENSURE_TRUE(xpc::Scriptability::Get(global).Allowed(), NS_OK);
|
2014-06-21 22:55:15 +04:00
|
|
|
|
2013-11-13 04:43:34 +04:00
|
|
|
JS::ExposeObjectToActiveJS(global);
|
2018-07-31 09:37:07 +03:00
|
|
|
JSAutoRealm ar(cx, global);
|
2014-04-11 19:47:43 +04:00
|
|
|
|
|
|
|
// The script is in the compilation scope. Clone it into the target scope
|
2014-11-13 02:12:13 +03:00
|
|
|
// and execute it. On failure, ~AutoScriptEntry will handle exceptions, so
|
|
|
|
// there is no need to manually check the return value.
|
2016-06-01 06:34:40 +03:00
|
|
|
JS::RootedValue rval(cx);
|
|
|
|
JS::CloneAndExecuteScript(cx, scriptObject, &rval);
|
2006-06-13 07:07:47 +04:00
|
|
|
|
2014-08-05 17:57:53 +04:00
|
|
|
return NS_OK;
|
1999-10-29 05:21:15 +04:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::CreateElementFromPrototype(
|
2018-04-27 18:04:37 +03:00
|
|
|
nsXULPrototypeElement* aPrototype, Element** aResult, bool aIsRoot) {
|
1999-10-29 05:21:15 +04:00
|
|
|
// Create a content model element from a prototype element.
|
2018-04-28 22:50:58 +03:00
|
|
|
MOZ_ASSERT(aPrototype != nullptr, "null ptr");
|
1999-10-29 05:21:15 +04:00
|
|
|
if (!aPrototype) return NS_ERROR_NULL_POINTER;
|
|
|
|
|
2018-04-28 22:50:58 +03:00
|
|
|
*aResult = nullptr;
|
1999-10-29 05:21:15 +04:00
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
if (MOZ_LOG_TEST(gXULLog, LogLevel::Debug)) {
|
2018-11-30 13:46:48 +03:00
|
|
|
MOZ_LOG(
|
2012-07-30 18:20:58 +04:00
|
|
|
gXULLog, LogLevel::Debug,
|
2000-05-10 17:13:39 +04:00
|
|
|
("xul: creating <%s> from prototype",
|
|
|
|
NS_ConvertUTF16toUTF8(aPrototype->mNodeInfo->QualifiedName()).get()));
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2015-06-04 01:25:57 +03:00
|
|
|
RefPtr<Element> result;
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2002-09-25 13:56:09 +04:00
|
|
|
if (aPrototype->mNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
|
|
|
|
// If it's a XUL element, it'll be lightweight until somebody
|
|
|
|
// monkeys with it.
|
2018-04-27 18:04:37 +03:00
|
|
|
rv = nsXULElement::CreateFromPrototype(aPrototype, this, true, aIsRoot,
|
|
|
|
getter_AddRefs(result));
|
2002-09-25 13:56:09 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
} else {
|
2000-01-19 06:11:39 +03:00
|
|
|
// If it's not a XUL element, it's gonna be heavyweight no matter
|
|
|
|
// what. So we need to copy everything out of the prototype
|
2005-06-09 05:06:46 +04:00
|
|
|
// into the element. Get a nodeinfo from our nodeinfo manager
|
|
|
|
// for this node.
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<mozilla::dom::NodeInfo> newNodeInfo;
|
2008-09-13 02:32:18 +04:00
|
|
|
newNodeInfo = mNodeInfoManager->GetNodeInfo(
|
|
|
|
aPrototype->mNodeInfo->NameAtom(),
|
|
|
|
aPrototype->mNodeInfo->GetPrefixAtom(),
|
2011-06-14 11:56:49 +04:00
|
|
|
aPrototype->mNodeInfo->NamespaceID(), ELEMENT_NODE);
|
2008-09-26 02:46:52 +04:00
|
|
|
if (!newNodeInfo) return NS_ERROR_OUT_OF_MEMORY;
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<mozilla::dom::NodeInfo> xtfNi = newNodeInfo;
|
2018-12-11 00:19:35 +03:00
|
|
|
if (aPrototype->mIsAtom &&
|
|
|
|
newNodeInfo->NamespaceID() == kNameSpaceID_XHTML) {
|
|
|
|
rv = NS_NewHTMLElement(getter_AddRefs(result), newNodeInfo.forget(),
|
|
|
|
NOT_FROM_PARSER, aPrototype->mIsAtom);
|
|
|
|
} else {
|
|
|
|
rv = NS_NewElement(getter_AddRefs(result), newNodeInfo.forget(),
|
|
|
|
NOT_FROM_PARSER);
|
|
|
|
}
|
2002-09-25 13:56:09 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2018-04-27 18:04:37 +03:00
|
|
|
rv = AddAttributes(aPrototype, result);
|
2002-09-25 13:56:09 +04:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-01-19 06:11:39 +03:00
|
|
|
}
|
1999-10-29 05:21:15 +04:00
|
|
|
|
2016-07-21 01:19:00 +03:00
|
|
|
result.forget(aResult);
|
2004-06-25 16:26:02 +04:00
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
nsresult XULDocument::AddAttributes(nsXULPrototypeElement* aPrototype,
|
2017-12-05 20:05:51 +03:00
|
|
|
Element* aElement) {
|
1999-10-29 05:21:15 +04:00
|
|
|
nsresult rv;
|
|
|
|
|
2012-08-22 19:56:38 +04:00
|
|
|
for (uint32_t i = 0; i < aPrototype->mNumAttributes; ++i) {
|
1999-10-29 05:21:15 +04:00
|
|
|
nsXULPrototypeAttribute* protoattr = &(aPrototype->mAttributes[i]);
|
2000-09-15 10:52:17 +04:00
|
|
|
nsAutoString valueStr;
|
2004-02-10 12:08:06 +03:00
|
|
|
protoattr->mValue.ToString(valueStr);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2004-02-10 12:08:06 +03:00
|
|
|
rv = aElement->SetAttr(protoattr->mName.NamespaceID(),
|
|
|
|
protoattr->mName.LocalName(),
|
|
|
|
protoattr->mName.GetPrefix(), valueStr, false);
|
2000-01-19 06:11:39 +03:00
|
|
|
if (NS_FAILED(rv)) return rv;
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
1999-10-29 05:21:15 +04:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
1999-11-25 01:46:09 +03:00
|
|
|
//----------------------------------------------------------------------
|
|
|
|
//
|
1999-12-04 10:45:57 +03:00
|
|
|
// CachedChromeStreamListener
|
1999-11-25 01:46:09 +03:00
|
|
|
//
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::CachedChromeStreamListener::CachedChromeStreamListener(
|
|
|
|
XULDocument* aDocument, bool aProtoLoaded)
|
2001-07-31 23:05:34 +04:00
|
|
|
: mDocument(aDocument), mProtoLoaded(aProtoLoaded) {}
|
1999-11-25 01:46:09 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::CachedChromeStreamListener::~CachedChromeStreamListener() {}
|
1999-11-25 01:46:09 +03:00
|
|
|
|
2014-04-27 11:06:00 +04:00
|
|
|
NS_IMPL_ISUPPORTS(XULDocument::CachedChromeStreamListener, nsIRequestObserver,
|
|
|
|
nsIStreamListener)
|
1999-11-25 01:46:09 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::CachedChromeStreamListener::OnStartRequest(nsIRequest* request,
|
|
|
|
nsISupports* acontext) {
|
2009-02-16 14:27:22 +03:00
|
|
|
return NS_ERROR_PARSED_DATA_CACHED;
|
1999-11-25 01:46:09 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::CachedChromeStreamListener::OnStopRequest(nsIRequest* request,
|
|
|
|
nsISupports* aContext,
|
|
|
|
nsresult aStatus) {
|
2001-07-31 23:05:34 +04:00
|
|
|
if (!mProtoLoaded) return NS_OK;
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return mDocument->OnPrototypeLoadDone(true);
|
1999-12-04 10:45:57 +03:00
|
|
|
}
|
1999-11-25 01:46:09 +03:00
|
|
|
|
1999-12-04 10:45:57 +03:00
|
|
|
NS_IMETHODIMP
|
2013-03-26 19:31:53 +04:00
|
|
|
XULDocument::CachedChromeStreamListener::OnDataAvailable(nsIRequest* request,
|
|
|
|
nsISupports* aContext,
|
|
|
|
nsIInputStream* aInStr,
|
|
|
|
uint64_t aSourceOffset,
|
|
|
|
uint32_t aCount) {
|
2018-06-18 08:43:11 +03:00
|
|
|
MOZ_ASSERT_UNREACHABLE("CachedChromeStream doesn't receive data");
|
1999-12-04 10:45:57 +03:00
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-11-25 01:46:09 +03:00
|
|
|
}
|
2000-01-19 06:28:06 +03:00
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
bool XULDocument::IsDocumentRightToLeft() {
|
2010-03-17 20:10:57 +03:00
|
|
|
// setting the localedir attribute on the root element forces a
|
|
|
|
// specific direction for the document.
|
2010-04-30 17:12:05 +04:00
|
|
|
Element* element = GetRootElement();
|
|
|
|
if (element) {
|
2017-12-07 21:13:50 +03:00
|
|
|
static Element::AttrValuesArray strings[] = {nsGkAtoms::ltr, nsGkAtoms::rtl,
|
2018-04-03 06:21:06 +03:00
|
|
|
nullptr};
|
2010-04-30 17:12:05 +04:00
|
|
|
switch (element->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::localedir,
|
2010-03-17 20:10:57 +03:00
|
|
|
strings, eCaseMatters)) {
|
2011-10-17 18:59:28 +04:00
|
|
|
case 0:
|
|
|
|
return false;
|
2018-11-30 13:46:48 +03:00
|
|
|
case 1:
|
2012-09-02 06:35:17 +04:00
|
|
|
return true;
|
|
|
|
default:
|
2011-09-29 10:19:26 +04:00
|
|
|
break; // otherwise, not a valid value, so fall through
|
2010-03-17 20:10:57 +03:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
|
|
|
|
2010-03-17 20:10:57 +03:00
|
|
|
// otherwise, get the locale from the chrome registry and
|
|
|
|
// look up the intl.uidirection.<locale> preference
|
|
|
|
nsCOMPtr<nsIXULChromeRegistry> reg =
|
2010-05-14 13:24:41 +04:00
|
|
|
mozilla::services::GetXULChromeRegistryService();
|
2008-09-26 02:46:52 +04:00
|
|
|
if (!reg) return false;
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2012-09-02 06:35:17 +04:00
|
|
|
nsAutoCString package;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool isChrome;
|
2010-03-17 20:10:57 +03:00
|
|
|
if (NS_SUCCEEDED(mDocumentURI->SchemeIs("chrome", &isChrome)) && isChrome) {
|
|
|
|
mDocumentURI->GetHostPort(package);
|
|
|
|
} else {
|
|
|
|
// use the 'global' package for about and resource uris.
|
|
|
|
// otherwise, just default to left-to-right.
|
2011-09-29 10:19:26 +04:00
|
|
|
bool isAbout, isResource;
|
2010-03-17 20:10:57 +03:00
|
|
|
if (NS_SUCCEEDED(mDocumentURI->SchemeIs("about", &isAbout)) && isAbout) {
|
|
|
|
package.AssignLiteral("global");
|
|
|
|
} else if (NS_SUCCEEDED(mDocumentURI->SchemeIs("resource", &isResource)) &&
|
|
|
|
isResource) {
|
|
|
|
package.AssignLiteral("global");
|
|
|
|
} else {
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2009-07-29 22:33:53 +04:00
|
|
|
}
|
2018-11-30 13:46:48 +03:00
|
|
|
}
|
2009-07-29 22:33:53 +04:00
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool isRTL = false;
|
2010-03-17 20:10:57 +03:00
|
|
|
reg->IsLocaleRTL(package, &isRTL);
|
|
|
|
return isRTL;
|
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
void XULDocument::ResetDocumentDirection() {
|
2010-03-17 20:10:57 +03:00
|
|
|
DocumentStatesChanged(NS_DOCUMENT_STATE_RTL_LOCALE);
|
2009-07-29 22:33:53 +04:00
|
|
|
}
|
|
|
|
|
2018-07-06 22:24:41 +03:00
|
|
|
void XULDocument::DirectionChanged(const char* aPrefName, XULDocument* aDoc) {
|
2010-03-17 20:10:57 +03:00
|
|
|
// Reset the direction and restyle the document if necessary.
|
2018-07-06 22:24:41 +03:00
|
|
|
if (aDoc) {
|
|
|
|
aDoc->ResetDocumentDirection();
|
2009-07-29 22:33:53 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Bug 1117172 part 3. Change the wrappercached WrapObject methods to allow passing in aGivenProto. r=peterv
The only manual changes here are to BindingUtils.h, BindingUtils.cpp,
Codegen.py, Element.cpp, IDBFileRequest.cpp, IDBObjectStore.cpp,
dom/workers/Navigator.cpp, WorkerPrivate.cpp, DeviceStorageRequestChild.cpp,
Notification.cpp, nsGlobalWindow.cpp, MessagePort.cpp, nsJSEnvironment.cpp,
Sandbox.cpp, XPCConvert.cpp, ExportHelpers.cpp, and DataStoreService.cpp. The
rest of this diff was generated by running the following commands:
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObjectInternal\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapNode\((?:aCx|cx|aContext|aCtx|js))\)/\1, aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(WrapObject\(JSContext *\* *(?:aCx|cx|aContext|aCtx|js))\)/\1, JS::Handle<JSObject*> aGivenProto)/g'
find . -name "*.h" -o -name "*.cpp" | xargs perl -pi -e 'BEGIN { $/ = undef } s/(Binding(?:_workers)?::Wrap\((?:aCx|cx|aContext|aCtx|js), [^,)]+)\)/\1, aGivenProto)/g'
2015-03-19 17:13:33 +03:00
|
|
|
JSObject* XULDocument::WrapNode(JSContext* aCx,
|
|
|
|
JS::Handle<JSObject*> aGivenProto) {
|
2018-11-29 02:24:53 +03:00
|
|
|
return XULDocument_Binding::Wrap(aCx, this, aGivenProto);
|
2013-03-26 19:31:54 +04:00
|
|
|
}
|
|
|
|
|
2013-03-26 19:31:53 +04:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|