Bug 816410 - Part 1: Convert XMLSerializer and DOMParser to WebIDL bindings. r=bz

This commit is contained in:
Masatoshi Kimura 2012-12-03 20:26:16 -05:00
parent 7c943d7992
commit 4a261035a8
12 changed files with 549 additions and 22 deletions

View File

@ -28,10 +28,12 @@
#include "mozilla/AutoRestore.h" #include "mozilla/AutoRestore.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom;
nsDOMParser::nsDOMParser() nsDOMParser::nsDOMParser()
: mAttemptedInit(false) : mAttemptedInit(false)
{ {
SetIsDOMBinding();
} }
nsDOMParser::~nsDOMParser() nsDOMParser::~nsDOMParser()
@ -41,7 +43,8 @@ nsDOMParser::~nsDOMParser()
DOMCI_DATA(DOMParser, nsDOMParser) DOMCI_DATA(DOMParser, nsDOMParser)
// QueryInterface implementation for nsDOMParser // QueryInterface implementation for nsDOMParser
NS_INTERFACE_MAP_BEGIN(nsDOMParser) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMParser)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMParser) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMParser)
NS_INTERFACE_MAP_ENTRY(nsIDOMParser) NS_INTERFACE_MAP_ENTRY(nsIDOMParser)
NS_INTERFACE_MAP_ENTRY(nsIDOMParserJS) NS_INTERFACE_MAP_ENTRY(nsIDOMParserJS)
@ -50,9 +53,22 @@ NS_INTERFACE_MAP_BEGIN(nsDOMParser)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMParser) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMParser)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsDOMParser, mOwner)
NS_IMPL_ADDREF(nsDOMParser) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMParser)
NS_IMPL_RELEASE(nsDOMParser) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMParser)
already_AddRefed<nsIDocument>
nsDOMParser::ParseFromString(const nsAString& aStr, SupportedType aType,
ErrorResult& rv)
{
nsCOMPtr<nsIDOMDocument> domDocument;
rv = nsDOMParser::ParseFromString(PromiseFlatString(aStr).get(),
SupportedTypeValues::strings[aType].value,
getter_AddRefs(domDocument));
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
return document.forget();
}
NS_IMETHODIMP NS_IMETHODIMP
nsDOMParser::ParseFromString(const PRUnichar *str, nsDOMParser::ParseFromString(const PRUnichar *str,
@ -103,6 +119,38 @@ nsDOMParser::ParseFromString(const PRUnichar *str,
return ParseFromStream(stream, "UTF-8", data.Length(), contentType, aResult); return ParseFromStream(stream, "UTF-8", data.Length(), contentType, aResult);
} }
already_AddRefed<nsIDocument>
nsDOMParser::ParseFromBuffer(const Sequence<uint8_t>& aBuf, uint32_t aBufLen,
SupportedType aType, ErrorResult& rv)
{
if (aBufLen > aBuf.Length()) {
rv.Throw(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY);
return nullptr;
}
nsCOMPtr<nsIDOMDocument> domDocument;
rv = nsDOMParser::ParseFromBuffer(aBuf.Elements(), aBufLen,
SupportedTypeValues::strings[aType].value,
getter_AddRefs(domDocument));
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
return document.forget();
}
already_AddRefed<nsIDocument>
nsDOMParser::ParseFromBuffer(const Uint8Array& aBuf, uint32_t aBufLen,
SupportedType aType, ErrorResult& rv)
{
if (aBufLen > aBuf.Length()) {
rv.Throw(NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY);
return nullptr;
}
nsCOMPtr<nsIDOMDocument> domDocument;
rv = nsDOMParser::ParseFromBuffer(aBuf.Data(), aBufLen,
SupportedTypeValues::strings[aType].value,
getter_AddRefs(domDocument));
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
return document.forget();
}
NS_IMETHODIMP NS_IMETHODIMP
nsDOMParser::ParseFromBuffer(const uint8_t *buf, nsDOMParser::ParseFromBuffer(const uint8_t *buf,
uint32_t bufLen, uint32_t bufLen,
@ -124,6 +172,23 @@ nsDOMParser::ParseFromBuffer(const uint8_t *buf,
} }
already_AddRefed<nsIDocument>
nsDOMParser::ParseFromStream(nsIInputStream* aStream,
const nsAString& aCharset,
int32_t aContentLength,
SupportedType aType,
ErrorResult& rv)
{
nsCOMPtr<nsIDOMDocument> domDocument;
rv = nsDOMParser::ParseFromStream(aStream,
NS_ConvertUTF16toUTF8(aCharset).get(),
aContentLength,
SupportedTypeValues::strings[aType].value,
getter_AddRefs(domDocument));
nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
return document.forget();
}
NS_IMETHODIMP NS_IMETHODIMP
nsDOMParser::ParseFromStream(nsIInputStream *stream, nsDOMParser::ParseFromStream(nsIInputStream *stream,
const char *charset, const char *charset,
@ -363,11 +428,27 @@ GetInitArgs(JSContext *cx, uint32_t argc, jsval *argv,
return NS_OK; return NS_OK;
} }
/*static */already_AddRefed<nsDOMParser>
nsDOMParser::Constructor(nsISupports* aOwner, nsIPrincipal* aPrincipal,
nsIURI* aDocumentURI, nsIURI* aBaseURI,
ErrorResult& rv)
{
if (!nsContentUtils::IsCallerChrome()) {
rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return nullptr;
}
nsRefPtr<nsDOMParser> domParser = new nsDOMParser(aOwner);
rv = domParser->InitInternal(aOwner, aPrincipal, aDocumentURI, aBaseURI);
if (rv.Failed()) {
return nullptr;
}
return domParser.forget();
}
NS_IMETHODIMP NS_IMETHODIMP
nsDOMParser::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj, nsDOMParser::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
uint32_t argc, jsval *argv) uint32_t argc, jsval *argv)
{ {
AttemptedInitMarker marker(&mAttemptedInit);
nsCOMPtr<nsIPrincipal> prin; nsCOMPtr<nsIPrincipal> prin;
nsCOMPtr<nsIURI> documentURI; nsCOMPtr<nsIURI> documentURI;
nsCOMPtr<nsIURI> baseURI; nsCOMPtr<nsIURI> baseURI;
@ -388,8 +469,14 @@ nsDOMParser::Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED); NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED);
} }
NS_ASSERTION(prin, "Must have principal by now"); return InitInternal(aOwner, prin, documentURI, baseURI);
}
nsresult
nsDOMParser::InitInternal(nsISupports* aOwner, nsIPrincipal* prin,
nsIURI* documentURI, nsIURI* baseURI)
{
AttemptedInitMarker marker(&mAttemptedInit);
if (!documentURI) { if (!documentURI) {
// No explicit documentURI; grab document and base URIs off the window our // No explicit documentURI; grab document and base URIs off the window our
// constructor was called on. Error out if anything untoward happens. // constructor was called on. Error out if anything untoward happens.

View File

@ -3,8 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsDOMParser_h__ #ifndef nsDOMParser_h_
#define nsDOMParser_h__ #define nsDOMParser_h_
#include "nsIDOMParser.h" #include "nsIDOMParser.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -12,17 +12,26 @@
#include "nsWeakReference.h" #include "nsWeakReference.h"
#include "nsIJSNativeInitializer.h" #include "nsIJSNativeInitializer.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsWrapperCache.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/DOMParserBinding.h"
#include "mozilla/dom/TypedArray.h"
class nsDOMParser : public nsIDOMParser, class nsIInputStream;
public nsIDOMParserJS,
public nsIJSNativeInitializer, class nsDOMParser MOZ_FINAL : public nsIDOMParser,
public nsSupportsWeakReference public nsIDOMParserJS,
public nsIJSNativeInitializer,
public nsSupportsWeakReference,
public nsWrapperCache
{ {
public: public:
nsDOMParser(); nsDOMParser();
virtual ~nsDOMParser(); virtual ~nsDOMParser();
NS_DECL_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMParser,
nsIDOMParser)
// nsIDOMParser // nsIDOMParser
NS_DECL_NSIDOMPARSER NS_DECL_NSIDOMPARSER
@ -34,7 +43,70 @@ public:
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj, NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
uint32_t argc, jsval *argv); uint32_t argc, jsval *argv);
// WebIDL API
static already_AddRefed<nsDOMParser>
Constructor(nsISupports* aOwner, mozilla::ErrorResult& rv)
{
nsRefPtr<nsDOMParser> domParser = new nsDOMParser(aOwner);
rv = domParser->Initialize(aOwner, nullptr, nullptr, 0, nullptr);
if (rv.Failed()) {
return nullptr;
}
return domParser.forget();
}
static already_AddRefed<nsDOMParser>
Constructor(nsISupports* aOwner, nsIPrincipal* aPrincipal,
nsIURI* aDocumentURI, nsIURI* aBaseURI,
mozilla::ErrorResult& rv);
already_AddRefed<nsIDocument>
ParseFromString(const nsAString& aStr, mozilla::dom::SupportedType aType,
mozilla::ErrorResult& rv);
already_AddRefed<nsIDocument>
ParseFromBuffer(const mozilla::dom::Sequence<uint8_t>& aBuf,
uint32_t aBufLen, mozilla::dom::SupportedType aType,
mozilla::ErrorResult& rv);
already_AddRefed<nsIDocument>
ParseFromBuffer(const mozilla::dom::Uint8Array& aBuf, uint32_t aBufLen,
mozilla::dom::SupportedType aType,
mozilla::ErrorResult& rv);
already_AddRefed<nsIDocument>
ParseFromStream(nsIInputStream* aStream, const nsAString& aCharset,
int32_t aContentLength, mozilla::dom::SupportedType aType,
mozilla::ErrorResult& rv);
void Init(nsIPrincipal* aPrincipal, nsIURI* aDocumentURI,
nsIURI* aBaseURI, mozilla::ErrorResult& rv)
{
rv = Init(aPrincipal, aDocumentURI, aBaseURI);
}
nsISupports* GetParentObject() const
{
return mOwner;
}
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap) MOZ_OVERRIDE
{
return mozilla::dom::DOMParserBinding::Wrap(aCx, aScope, this,
aTriedToWrap);
}
private: private:
nsDOMParser(nsISupports* aOwner) : mOwner(aOwner), mAttemptedInit(false)
{
MOZ_ASSERT(aOwner);
SetIsDOMBinding();
}
nsresult InitInternal(nsISupports* aOwner, nsIPrincipal* prin,
nsIURI* documentURI, nsIURI* baseURI);
nsresult SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult); nsresult SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult);
class AttemptedInitMarker { class AttemptedInitMarker {
@ -50,7 +122,8 @@ private:
private: private:
bool* mAttemptedInit; bool* mAttemptedInit;
}; };
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIPrincipal> mPrincipal; nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIPrincipal> mOriginalPrincipal; nsCOMPtr<nsIPrincipal> mOriginalPrincipal;
nsCOMPtr<nsIURI> mDocumentURI; nsCOMPtr<nsIURI> mDocumentURI;

View File

@ -15,6 +15,8 @@
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsError.h" #include "nsError.h"
using namespace mozilla;
nsDOMSerializer::nsDOMSerializer() nsDOMSerializer::nsDOMSerializer()
{ {
} }
@ -26,15 +28,17 @@ nsDOMSerializer::~nsDOMSerializer()
DOMCI_DATA(XMLSerializer, nsDOMSerializer) DOMCI_DATA(XMLSerializer, nsDOMSerializer)
// QueryInterface implementation for nsDOMSerializer // QueryInterface implementation for nsDOMSerializer
NS_INTERFACE_MAP_BEGIN(nsDOMSerializer) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMSerializer)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIDOMSerializer) NS_INTERFACE_MAP_ENTRY(nsIDOMSerializer)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XMLSerializer) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(XMLSerializer)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsDOMSerializer, mOwner)
NS_IMPL_ADDREF(nsDOMSerializer) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMSerializer)
NS_IMPL_RELEASE(nsDOMSerializer) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMSerializer)
static nsresult static nsresult
@ -90,6 +94,13 @@ SetUpEncoder(nsIDOMNode *aRoot, const nsACString& aCharset,
return rv; return rv;
} }
void
nsDOMSerializer::SerializeToString(nsINode& aRoot, nsAString& aStr,
ErrorResult& rv)
{
rv = nsDOMSerializer::SerializeToString(aRoot.AsDOMNode(), aStr);
}
NS_IMETHODIMP NS_IMETHODIMP
nsDOMSerializer::SerializeToString(nsIDOMNode *aRoot, nsAString& _retval) nsDOMSerializer::SerializeToString(nsIDOMNode *aRoot, nsAString& _retval)
{ {
@ -109,6 +120,14 @@ nsDOMSerializer::SerializeToString(nsIDOMNode *aRoot, nsAString& _retval)
return encoder->EncodeToString(_retval); return encoder->EncodeToString(_retval);
} }
void
nsDOMSerializer::SerializeToStream(nsINode& aRoot, nsIOutputStream* aStream,
const nsAString& aCharset, ErrorResult& rv)
{
rv = nsDOMSerializer::SerializeToStream(aRoot.AsDOMNode(), aStream,
NS_ConvertUTF16toUTF8(aCharset));
}
NS_IMETHODIMP NS_IMETHODIMP
nsDOMSerializer::SerializeToStream(nsIDOMNode *aRoot, nsDOMSerializer::SerializeToStream(nsIDOMNode *aRoot,
nsIOutputStream *aStream, nsIOutputStream *aStream,

View File

@ -3,21 +3,66 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsDOMSerializer_h__ #ifndef nsDOMSerializer_h_
#define nsDOMSerializer_h__ #define nsDOMSerializer_h_
#include "nsIDOMSerializer.h" #include "nsIDOMSerializer.h"
#include "nsWrapperCache.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/XMLSerializerBinding.h"
class nsDOMSerializer : public nsIDOMSerializer class nsINode;
class nsIOutputStream;
class nsDOMSerializer MOZ_FINAL : public nsIDOMSerializer,
public nsWrapperCache
{ {
public: public:
nsDOMSerializer(); nsDOMSerializer();
virtual ~nsDOMSerializer(); virtual ~nsDOMSerializer();
NS_DECL_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMSerializer)
// nsIDOMSerializer // nsIDOMSerializer
NS_DECL_NSIDOMSERIALIZER NS_DECL_NSIDOMSERIALIZER
// WebIDL API
static already_AddRefed<nsDOMSerializer>
Constructor(nsISupports* aOwner, mozilla::ErrorResult& rv)
{
nsRefPtr<nsDOMSerializer> domSerializer = new nsDOMSerializer(aOwner);
return domSerializer.forget();
}
void
SerializeToString(nsINode& aRoot, nsAString& aStr,
mozilla::ErrorResult& rv);
void
SerializeToStream(nsINode& aRoot, nsIOutputStream* aStream,
const nsAString& aCharset, mozilla::ErrorResult& rv);
nsISupports* GetParentObject() const
{
return mOwner;
}
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap) MOZ_OVERRIDE
{
return mozilla::dom::XMLSerializerBinding::Wrap(aCx, aScope, this,
aTriedToWrap);
}
private:
nsDOMSerializer(nsISupports* aOwner) : mOwner(aOwner)
{
MOZ_ASSERT(aOwner);
SetIsDOMBinding();
}
nsCOMPtr<nsISupports> mOwner;
}; };

View File

@ -252,6 +252,7 @@ MOCHITEST_FILES_A = \
file_XHRDocURI.text \ file_XHRDocURI.text \
file_XHRDocURI.text^headers^ \ file_XHRDocURI.text^headers^ \
test_DOMException.html \ test_DOMException.html \
test_domparsing.html \
test_meta_viewport0.html \ test_meta_viewport0.html \
test_meta_viewport1.html \ test_meta_viewport1.html \
test_meta_viewport2.html \ test_meta_viewport2.html \

View File

@ -49,6 +49,7 @@ MOCHITEST_CHROME_FILES = \
test_csp_bug768029.html \ test_csp_bug768029.html \
test_bug800386.xul \ test_bug800386.xul \
test_csp_bug773891.html \ test_csp_bug773891.html \
test_domparsing.xul \
$(NULL) $(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,139 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Test for the Mozilla extesion of the DOM Parsing and Serialization API"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=816410"
target="_blank">Mozilla Bug 816410</a>
</body>
<!-- test code goes here -->
<script type="application/javascript;version=1.7"><![CDATA[
"use strict";
/** Test for Bug 816410 **/
const Cc = Components.classes;
const Ci = Components.interfaces;
function throws(a, type, message) {
for (let fn of Array.isArray(a) ? a : [a]) {
try {
fn();
ok(false, message);
} catch (e) {
if (type) {
is(e.name, type, message);
} else {
ok(true, message);
}
}
}
}
// DOMParser constructor should not throw for null arguments
new DOMParser(undefined);
new DOMParser(null);
throws([
function() { new DOMParser(false); },
function() { new DOMParser(0); },
function() { new DOMParser(""); },
function() { new DOMParser({}); },
], "TypeError", "DOMParser constructor should throw for extra arguments");
{
let parser = new DOMParser();
throws(function() {
parser.init();
}, "NS_ERROR_UNEXPECTED", "init method should throw when DOMParser is created by constructor");
}
// XMLSerializer constructor should not throw for extra arguments
new XMLSerializer(undefined);
new XMLSerializer(null);
new XMLSerializer(false);
new XMLSerializer(0);
new XMLSerializer("");
new XMLSerializer({});
runTest(new DOMParser(), new XMLSerializer());
{
let parser = Cc["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Ci.nsIDOMParser);
parser.init();
throws(function() {
parser.init();
}, "NS_ERROR_UNEXPECTED", "init method should throw when called twice");
}
runTest(Cc["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Ci.nsIDOMParser),
Cc["@mozilla.org/xmlextras/xmlserializer;1"]
.createInstance(Ci.nsIDOMSerializer));
function runTest(parser, serializer) {
is(typeof parser.parseFromString, "function", "parseFromString should exist");
is(typeof parser.parseFromBuffer, "function", "parseFromBuffer should exist");
is(typeof parser.parseFromStream, "function", "parseFromStream should exist");
is(typeof parser.init, "function", "init should exist");
is(typeof serializer.serializeToString, "function", "serializeToString should exist");
is(typeof serializer.serializeToStream, "function", "serializeToStream should exist");
let tests = [
{input: "<html></html>", type: "text/html",
expected: '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body></body></html>'},
{input: "<xml></xml>", type: "text/xml", expected: "<xml/>"},
{input: "<xml></xml>", type: "application/xml", expected: "<xml/>"},
{input: "<html></html>", type: "application/xhtml+xml", expected: "<html/>"},
{input: "<svg></svg>", type: "image/svg+xml", expected: "<svg/>"},
];
for (let t of tests) {
is(serializer.serializeToString(parser.parseFromString(t.input, t.type)), t.expected,
"parseFromString test for " + t.type);
let ostream = {
data: "",
write: function(buf, count) { this.data += buf; return count; }
};
serializer.serializeToStream(parser.parseFromString(t.input, t.type), ostream, "UTF-8");
is(ostream.data, t.expected, "serializeToStream test for " + t.type);
if (t.type === "text/html") {
// parseFromBuffer and parseFromStream don't support "text/html".
continue;
}
let array = Array.map(t.input, function(c) { return c.charCodeAt(c); });
let inputs = [
{array: array, name: "parseFromBuffer (array)"},
{array: new Uint8Array(array), name: "parseFromBuffer (Uint8Array)"},
];
for (let input of inputs) {
let a = input.array;
is(serializer.serializeToString(parser.parseFromBuffer(a, a.length, t.type)), t.expected,
input.name + " test for " + t.type);
throws(function() {
parser.parseFromBuffer(a, a.length + 1, t.type);
}, "NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY",
input.name + " should throw if bufLen parameter is greater than actual length"
);
}
let istream = Cc["@mozilla.org/io/string-input-stream;1"].
createInstance(Ci.nsIStringInputStream);
istream.setData(t.input, -1);
is(serializer.serializeToString(parser.parseFromStream(istream, null, array.length, t.type)),
t.expected, "parseFromStream test for " + t.type);
}
throws(function() {
parser.parseFromString("<xml></xml>", "foo/bar");
}, "TypeError", "parseFromString should throw for the unknown type");
}
]]></script>
</window>

View File

@ -0,0 +1,84 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset=utf-8>
<title>Test for the DOM Parsing and Serialization Standard</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=816410">Mozilla Bug 816410</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
"use strict";
/** Test for Bug 816410 **/
function throws(fn, type, message) {
try {
fn();
ok(false, message);
} catch (e) {
if (type) {
is(e.name, type, message);
} else {
ok(true, message);
}
}
}
let parser = new DOMParser();
is(typeof parser.parseFromString, "function", "parseFromString should exist");
is(typeof parser.parseFromBuffer, "undefined", "parseFromBuffer should NOT be visible from unprivileged callers");
is(typeof parser.parseFromStream, "undefined", "parseFromStream should NOT be visible from unprivileged callers");
is(typeof parser.init, "undefined", "init should NOT be visible from unprivileged callers");
// The three-arguments constructor should not be visible from
// unprivileged callers for interoperability with other browsers.
// But we have no way to do that right now.
try {
new DOMParser(undefined);
new DOMParser(null);
new DOMParser(false);
new DOMParser(0);
new DOMParser("");
new DOMParser({});
} catch (e) {
todo(false, "DOMParser constructor should not throw for extra arguments");
}
let serializer = new XMLSerializer();
is(typeof serializer.serializeToString, "function", "serializeToString should exist");
is(typeof serializer.serializeToStream, "undefined", "serializeToStream should NOT be visible from unprivileged callers");
// XMLSerializer constructor should not throw for extra arguments
new XMLSerializer(undefined);
new XMLSerializer(null);
new XMLSerializer(false);
new XMLSerializer(0);
new XMLSerializer("");
new XMLSerializer({});
let tests = [
{input: "<html></html>", type: "text/html",
expected: '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body></body></html>'},
{input: "<xml></xml>", type: "text/xml", expected: "<xml/>"},
{input: "<xml></xml>", type: "application/xml", expected: "<xml/>"},
{input: "<html></html>", type: "application/xhtml+xml", expected: "<html/>"},
{input: "<svg></svg>", type: "image/svg+xml", expected: "<svg/>"},
];
for (let t of tests) {
is(serializer.serializeToString(parser.parseFromString(t.input, t.type)), t.expected,
"parseFromString test for " + t.type);
}
throws(function() {
parser.parseFromString("<xml></xml>", "foo/bar");
}, "TypeError", "parseFromString should throw for the unknown type");
</script>
</pre>
</body>
</html>

View File

@ -167,6 +167,10 @@ DOMInterfaces = {
'skipGen': True 'skipGen': True
}], }],
'DOMParser': {
'nativeType': 'nsDOMParser',
},
'DOMSettableTokenList': { 'DOMSettableTokenList': {
'nativeType': 'nsDOMSettableTokenList', 'nativeType': 'nsDOMSettableTokenList',
'binaryNames': { 'binaryNames': {
@ -535,6 +539,10 @@ DOMInterfaces = {
'workers': True, 'workers': True,
}], }],
'XMLSerializer': {
'nativeType': 'nsDOMSerializer',
},
#################################### ####################################
# Test Interfaces of various sorts # # Test Interfaces of various sorts #
#################################### ####################################
@ -739,6 +747,8 @@ addExternalIface('HTMLElement')
addExternalIface('LockedFile') addExternalIface('LockedFile')
addExternalIface('MediaStream') addExternalIface('MediaStream')
addExternalIface('NamedNodeMap') addExternalIface('NamedNodeMap')
addExternalIface('OutputStream', nativeType='nsIOutputStream',
notflattened=True)
addExternalIface('PaintRequest') addExternalIface('PaintRequest')
addExternalIface('Principal', nativeType='nsIPrincipal', addExternalIface('Principal', nativeType='nsIPrincipal',
headerFile='nsIPrincipal.h', notflattened=True) headerFile='nsIPrincipal.h', notflattened=True)

View File

@ -0,0 +1,46 @@
/* 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/.
*
* The origin of this IDL file is
* http://domparsing.spec.whatwg.org/#the-domparser-interface
*/
interface Principal;
interface URI;
interface InputStream;
enum SupportedType {
"text/html",
"text/xml",
"application/xml",
"application/xhtml+xml",
"image/svg+xml"
};
// the latter is Mozilla-specific
[Constructor,
Constructor(Principal? prin, optional URI? documentURI = null,
optional URI? baseURI = null)]
interface DOMParser {
[Creator, Throws]
Document parseFromString(DOMString str, SupportedType type);
// Mozilla-specific stuff
// Throws if the passed-in length is greater than the actual sequence length
[Creator, Throws, ChromeOnly]
Document parseFromBuffer(sequence<octet> buf, unsigned long bufLen,
SupportedType type);
// Throws if the passed-in length is greater than the actual typed array length
[Creator, Throws, ChromeOnly]
Document parseFromBuffer(Uint8Array buf, unsigned long bufLen,
SupportedType type);
[Creator, Throws, ChromeOnly]
Document parseFromStream(InputStream stream, DOMString charset,
long contentLength, SupportedType type);
[Throws, ChromeOnly]
void init(optional Principal? principal = null,
optional URI? documentURI = null,
optional URI? baseURI = null);
};

View File

@ -24,9 +24,10 @@ webidl_files = \
CSSStyleDeclaration.webidl \ CSSStyleDeclaration.webidl \
DelayNode.webidl \ DelayNode.webidl \
DOMImplementation.webidl \ DOMImplementation.webidl \
DOMTokenList.webidl \ DOMParser.webidl \
DOMSettableTokenList.webidl \ DOMSettableTokenList.webidl \
DOMStringMap.webidl \ DOMStringMap.webidl \
DOMTokenList.webidl \
DynamicsCompressorNode.webidl \ DynamicsCompressorNode.webidl \
Element.webidl \ Element.webidl \
EventHandler.webidl \ EventHandler.webidl \
@ -61,6 +62,7 @@ webidl_files = \
XMLHttpRequest.webidl \ XMLHttpRequest.webidl \
XMLHttpRequestEventTarget.webidl \ XMLHttpRequestEventTarget.webidl \
XMLHttpRequestUpload.webidl \ XMLHttpRequestUpload.webidl \
XMLSerializer.webidl \
$(NULL) $(NULL)
ifdef MOZ_WEBGL ifdef MOZ_WEBGL

View File

@ -0,0 +1,20 @@
/* 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/.
*
* The origin of this IDL file is
* http://domparsing.spec.whatwg.org/#the-xmlserializer-interface
*/
interface OutputStream;
[Constructor]
interface XMLSerializer {
[Throws]
DOMString serializeToString(Node root);
// Mozilla-specific stuff
[Throws, ChromeOnly]
void serializeToStream(Node root, OutputStream stream, DOMString charset);
};