Backed out changesets b242651c3c1b (bug 229827), b36eaac9ecf8, and 40f38a8aa660 (bug 663291) for mochitest-3/4 failures.

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2012-11-16 16:59:38 -05:00
parent 6c954363f7
commit 8a64b526bc
21 changed files with 440 additions and 672 deletions

View File

@ -2,3 +2,4 @@
<meta charset=utf-8>
<title>Non-UTF form target</title>
<body onload="parent.finish();">

View File

@ -1,7 +1,8 @@
<!doctype html>
<!DOCTYPE html>
<meta charset=windows-1252>
<title>Non-UTF form</title>
<body onload="document.forms[0].submit();">
<form action="file_bug708620-2.html">
<input name=foo value=bar>
</form>

View File

@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=513194
@ -6,22 +6,67 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=513194
<head>
<meta charset="utf-8">
<title>Test for Bug 513194</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<script type="text/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=631615"
>Mozilla Bug 513194</a>
<script>
// The use of document.write is deliberate. We are testing for the
// HTML parser to call the CSS parser once and only once when it
// encounters a new <style> element.
SimpleTest.runTestExpectingConsoleMessages(
function () { document.write("<style>qux { foo : bar; }<\/style>") },
[{ errorMessage: /Unknown property/ }]
);
<pre id="test">
<script class="testbody" type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
var consoleService =
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
var consoleListener = {
seenError: false,
observe: function(message) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
if (this.seenError) {
ok(false, "Seen too many errors!");
}
this.seenError = true;
ok(message.message.indexOf("Unknown property") > -1,
"Wrong message");
},
finish: function() {
ok(this.seenError , "Didn't get message.");
SimpleTest.finish();
},
QueryInterface: function(iid) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
if (iid.equals(Ci.nsIConsoleListener) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
}
};
consoleService.reset();
consoleService.registerListener(consoleListener);
SimpleTest.waitForExplicitFinish();
document.write("<style>qux { foo: bar; }<\/style>");
function done() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
consoleListener.finish();
consoleService.unregisterListener(consoleListener);
}
setTimeout(done, 0);
</script>
</pre>
</body>
</html>

View File

@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=631615
@ -6,21 +6,76 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=631615
<head>
<meta charset="utf-8">
<title>Test for Bug 631615</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<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=631615"
>Mozilla Bug 631615</a>
<pre id="monitor"></pre>
<script>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=631615">Mozilla Bug 631615</a>
<pre id="monitor">
</pre>
<script type="application/javascript">
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
var consoleService =
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
var messageCount = 0;
var monitor = document.getElementById("monitor");
var listener = {
observe: function(message) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
if (message.message === "sentinel") {
is(messageCount, 0, "should have been no console messages");
removeListener();
SimpleTest.finish();
} else {
messageCount++;
var err = "" + messageCount + ": " + message.message + "\n";
monitor.appendChild(document.createTextNode(err));
}
},
QueryInterface: function(iid) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
if (iid.equals(Ci.nsIConsoleListener) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
}
};
function addListener() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
consoleService.reset();
consoleService.registerListener(listener);
}
function removeListener() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
consoleService.unregisterListener(listener);
}
function postSentinel() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
consoleService.logStringMessage("sentinel");
}
SimpleTest.waitForExplicitFinish();
function doTest() {
var monitor = document.getElementById("monitor");
var html = document.documentElement;
var results;
var matches = html.matchesSelector || html.mozMatchesSelector;
addListener();
try {
results = "return: " +
matches.call(html, "[test!='']:sizzle") + "\n";
@ -30,9 +85,11 @@ function doTest() {
monitor.appendChild(document.createTextNode(results));
is(results.slice(0, 6), "throws", "looking for an exception");
}
SimpleTest.runTestExpectingConsoleMessages(doTest, []);
postSentinel();
}
doTest();
</script>
</body>
</html>

View File

@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=708620
@ -6,36 +6,61 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=708620
<head>
<meta charset="utf-8">
<title>Test for Bug 708620</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<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=708620"
>Mozilla Bug 708620</a>
<iframe></iframe>
<script>
<body onload="start();">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=708620">Mozilla Bug 708620</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 708620 **/
SimpleTest.waitForExplicitFinish();
SimpleTest.monitorConsole(SimpleTest.finish, [
{ errorMessage: "A form was submitted in the windows-1252 encoding "+
"which cannot encode all Unicode characters, so user "+
"input may get corrupted. To avoid this problem, the "+
"page should be changed so that the form is submitted "+
"in the UTF-8 encoding either by changing the encoding "+
"of the page itself to UTF-8 or by specifying "+
"accept-charset=utf-8 on the form element.",
isWarning: true }
]);
window.onload = function () {
document.getElementsByTagName("iframe")[0].src = "file_bug708620.html";
var tests = [
"file_bug708620.html"
];
function resolveURL(relative) {
var a = document.createElement('a');
a.href = relative;
return a.href;
}
var resolvedURL = resolveURL(tests[0]);
var expectedErrors = [
'[JavaScript Warning: "A form was submitted in the windows-1252 encoding which cannot encode all Unicode characters, so user input may get corrupted. To avoid this problem, the page should be changed so that the form is submitted in the UTF-8 encoding either by changing the encoding of the page itself to UTF-8 or by specifying accept-charset=utf-8 on the form element." {file: "' + resolvedURL + '" line: 1}]'
];
function consoleError(msg, fileName) {
// Ignore messages not generated by the test
if (fileName !== resolvedURL) {
return;
}
var expected = expectedErrors.shift();
is(msg, expected, "Not the right error message");
}
SpecialPowers.addErrorConsoleListener(consoleError);
function start() {
var url = tests.shift();
document.getElementsByTagName("iframe")[0].src = url;
}
function finish() {
SimpleTest.endMonitorConsole();
is(expectedErrors.length, 0, "The error supply was not exhausted");
SpecialPowers.removeErrorConsoleListener(consoleError);
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

View File

@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=489671
@ -6,20 +6,68 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=489671
<head>
<meta charset="utf-8">
<title>Test for Bug 489671</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<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=489671"
>Mozilla Bug 489671</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=489671">Mozilla Bug 489671</a>
<p id="display" onclick="throw 'Got click'"></p>
<script>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 489671 **/
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
var listener = {
observe: function(message) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
is(message.QueryInterface(Ci.nsIScriptError).errorMessage,
"uncaught exception: Got click");
SimpleTest.executeSoon(nextTest);
},
QueryInterface: function(iid) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
if (iid.equals(Ci.nsIConsoleListener) ||
iid.equals(Ci.nsISupports)) {
return this;
}
throw Cr.NS_NOINTERFACE;
}
};
function addListener() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var consoleService =
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
consoleService.reset();
consoleService.registerListener(listener);
}
function removeListener() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var consoleService =
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
consoleService.unregisterListener(listener);
}
SimpleTest.waitForExplicitFinish();
addListener();
// override window.onerror so it won't see our exceptions
window.onerror = function() {}
var testNum = 0;
function doTest() {
function nextTest() {
switch(testNum++) {
case 0:
var event = document.createEvent("MouseEvents");
@ -36,20 +84,15 @@ function doTest() {
window.setTimeout("throw 'Got click'", 0);
break;
case 3:
SimpleTest.endMonitorConsole();
return;
removeListener();
SimpleTest.finish();
break;
}
SimpleTest.executeSoon(doTest);
}
SimpleTest.waitForExplicitFinish();
SimpleTest.monitorConsole(SimpleTest.finish, [
{ errorMessage: "uncaught exception: Got click" },
{ errorMessage: "uncaught exception: Got click" },
{ errorMessage: "uncaught exception: Got click" }
]);
nextTest();
doTest();
</script>
</pre>
</body>
</html>

View File

@ -18,8 +18,8 @@
type: "window",
data: { message: message, filename: filename, lineno: lineno }
});
return true;
}
return false;
};
worker = new Worker("errorPropagation_worker.js");

View File

@ -36,10 +36,6 @@
}
else if (event.type == "window") {
windowErrorCount++;
workerFrame.stop();
// do this via executeSoon to give the workers a chance to
// be cleaned up
SimpleTest.executeSoon(SimpleTest.endMonitorConsole);
}
else {
ok(false, "Bad event type: " + event.type);
@ -49,27 +45,17 @@
is(event.data.filename, errorFilename,
"Correct message event.filename");
is(event.data.lineno, errorLineno, "Correct message event.lineno");
}
function finish() {
is(scopeErrorCount, workerCount, "Good number of scope errors");
is(workerErrorCount, workerCount, "Good number of worker errors");
is(windowErrorCount, 1, "Good number of window errors");
SimpleTest.finish();
if (windowErrorCount == 1) {
is(scopeErrorCount, workerCount, "Good number of scope errors");
is(workerErrorCount, workerCount, "Good number of worker errors");
workerFrame.stop();
SimpleTest.finish();
}
}
function workerFrameLoaded() {
workerFrame = document.getElementById("workerFrame").contentWindow;
SimpleTest.monitorConsole(finish, [
{ 'isScriptError': true,
'isWarning': false,
'isException': false,
'sourceName': errorFilename,
'lineNumber': errorLineno,
'errorMessage': errorMessage }
]);
workerFrame.start(workerCount, messageListener);
}

View File

@ -17,7 +17,6 @@
#include "nsIScriptError.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsStyleUtil.h"
#include "nsThreadUtils.h"
#ifdef CSS_REPORT_PARSE_ERRORS
@ -253,10 +252,7 @@ ErrorReporter::ReportUnexpected(const char *aMessage,
{
if (!ShouldReportErrors()) return;
nsAutoString qparam;
nsStyleUtil::AppendEscapedCSSIdent(aParam, qparam);
const PRUnichar *params[1] = { qparam.get() };
const PRUnichar *params[1] = { aParam.get() };
nsAutoString str;
sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
params, ArrayLength(params),

View File

@ -9,7 +9,6 @@
#include <math.h> // must be first due to symbol conflicts
#include "nsCSSScanner.h"
#include "nsStyleUtil.h"
#include "mozilla/css/ErrorReporter.h"
#include "mozilla/Likely.h"
#include "mozilla/Util.h"
@ -145,85 +144,64 @@ void
nsCSSToken::AppendToString(nsString& aBuffer) const
{
switch (mType) {
case eCSSToken_Ident:
nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer);
break;
case eCSSToken_AtKeyword:
aBuffer.Append('@');
nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer);
break;
case eCSSToken_ID:
case eCSSToken_Ref:
aBuffer.Append('#');
nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer);
break;
aBuffer.Append(PRUnichar('@')); // fall through intentional
case eCSSToken_Ident:
case eCSSToken_WhiteSpace:
case eCSSToken_Function:
nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer);
aBuffer.Append('(');
case eCSSToken_HTMLComment:
case eCSSToken_URange:
aBuffer.Append(mIdent);
if (mType == eCSSToken_Function)
aBuffer.Append(PRUnichar('('));
break;
case eCSSToken_URL:
case eCSSToken_Bad_URL:
aBuffer.AppendLiteral("url(");
if (mSymbol != PRUnichar(0)) {
nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol);
} else {
aBuffer.Append(mIdent);
aBuffer.Append(mSymbol);
}
aBuffer.Append(mIdent);
if (mSymbol != PRUnichar(0)) {
aBuffer.Append(mSymbol);
}
if (mType == eCSSToken_URL) {
aBuffer.Append(PRUnichar(')'));
}
break;
case eCSSToken_Number:
if (mIntegerValid) {
aBuffer.AppendInt(mInteger, 10);
} else {
}
else {
aBuffer.AppendFloat(mNumber);
}
break;
case eCSSToken_Percentage:
NS_ASSERTION(!mIntegerValid, "How did a percentage token get this set?");
aBuffer.AppendFloat(mNumber * 100.0f);
aBuffer.Append(PRUnichar('%'));
break;
case eCSSToken_Dimension:
if (mIntegerValid) {
aBuffer.AppendInt(mInteger, 10);
} else {
}
else {
aBuffer.AppendFloat(mNumber);
}
nsStyleUtil::AppendEscapedCSSIdent(mIdent, aBuffer);
aBuffer.Append(mIdent);
break;
case eCSSToken_Bad_String:
nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol);
// remove the trailing quote character
aBuffer.Truncate(aBuffer.Length() - 1);
break;
case eCSSToken_String:
nsStyleUtil::AppendEscapedCSSString(mIdent, aBuffer, mSymbol);
break;
aBuffer.Append(mSymbol);
aBuffer.Append(mIdent); // fall through intentional
case eCSSToken_Symbol:
aBuffer.Append(mSymbol);
break;
case eCSSToken_WhiteSpace:
aBuffer.Append(' ');
break;
case eCSSToken_HTMLComment:
case eCSSToken_URange:
case eCSSToken_ID:
case eCSSToken_Ref:
aBuffer.Append(PRUnichar('#'));
aBuffer.Append(mIdent);
break;
case eCSSToken_Includes:
aBuffer.AppendLiteral("~=");
break;
@ -239,7 +217,10 @@ nsCSSToken::AppendToString(nsString& aBuffer) const
case eCSSToken_Containsmatch:
aBuffer.AppendLiteral("*=");
break;
case eCSSToken_Bad_String:
aBuffer.Append(mSymbol);
aBuffer.Append(mIdent);
break;
default:
NS_ERROR("invalid token type");
break;

View File

@ -372,9 +372,8 @@ static nscoord CalcLengthWith(const nsCSSValue& aValue,
}
switch (aValue.GetUnit()) {
case eCSSUnit_EM: {
// CSS2.1 specifies that this unit scales to the computed font
// size, not the em-width in the font metrics, despite the name.
return ScaleCoord(aValue, float(aFontSize));
// XXX scale against font metrics height instead?
}
case eCSSUnit_XHeight: {
nsRefPtr<nsFontMetrics> fm =

View File

@ -55,37 +55,45 @@ bool nsStyleUtil::DashMatchCompare(const nsAString& aAttributeValue,
return result;
}
void nsStyleUtil::AppendEscapedCSSString(const nsAString& aString,
nsAString& aReturn,
PRUnichar quoteChar)
void nsStyleUtil::AppendEscapedCSSString(const nsString& aString,
nsAString& aReturn)
{
NS_PRECONDITION(quoteChar == '\'' || quoteChar == '"',
"CSS strings must be quoted with ' or \"");
aReturn.Append(quoteChar);
aReturn.Append(PRUnichar('"'));
const PRUnichar* in = aString.BeginReading();
const PRUnichar* const end = aString.EndReading();
for (; in != end; in++) {
if (*in < 0x20 || (*in >= 0x7F && *in < 0xA0)) {
// Escape U+0000 through U+001F and U+007F through U+009F numerically.
aReturn.AppendPrintf("\\%hX ", *in);
} else {
if (*in == '"' || *in == '\'' || *in == '\\') {
// Escape backslash and quote characters symbolically.
// It's not technically necessary to escape the quote
// character that isn't being used to delimit the string,
// but we do it anyway because that makes testing simpler.
aReturn.Append(PRUnichar('\\'));
}
aReturn.Append(*in);
const nsString::char_type* in = aString.get();
const nsString::char_type* const end = in + aString.Length();
for (; in != end; in++)
{
if (*in < 0x20)
{
// Escape all characters below 0x20 numerically.
/*
This is the buffer into which snprintf should write. As the hex. value is,
for numbers below 0x20, max. 2 characters long, we don't need more than 5
characters ("\XX "+NUL).
*/
PRUnichar buf[5];
nsTextFormatter::snprintf(buf, ArrayLength(buf), NS_LITERAL_STRING("\\%hX ").get(), *in);
aReturn.Append(buf);
} else switch (*in) {
// Special characters which should be escaped: Quotes and backslash
case '\\':
case '\"':
case '\'':
aReturn.Append(PRUnichar('\\'));
// And now, after the eventual escaping character, the actual one.
default:
aReturn.Append(PRUnichar(*in));
}
}
aReturn.Append(quoteChar);
aReturn.Append(PRUnichar('"'));
}
/* static */ void
nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
nsStyleUtil::AppendEscapedCSSIdent(const nsString& aIdent, nsAString& aReturn)
{
// The relevant parts of the CSS grammar are:
// ident [-]?{nmstart}{nmchar}*
@ -96,48 +104,44 @@ nsStyleUtil::AppendEscapedCSSIdent(const nsAString& aIdent, nsAString& aReturn)
// unicode \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
// from http://www.w3.org/TR/CSS21/syndata.html#tokenization
const PRUnichar* in = aIdent.BeginReading();
const PRUnichar* const end = aIdent.EndReading();
const nsString::char_type* in = aIdent.get();
const nsString::char_type* const end = in + aIdent.Length();
if (in == end)
return;
// A leading dash does not need to be escaped as long as it is not the
// *only* character in the identifier.
if (in + 1 != end && *in == '-') {
// Deal with the leading dash separately so we don't need to
// unnecessarily escape digits.
if (in != end && *in == '-') {
aReturn.Append(PRUnichar('-'));
++in;
}
// Escape a digit at the start (including after a dash),
// numerically. If we didn't escape it numerically, it would get
// interpreted as a numeric escape for the wrong character.
// A second dash immediately after a leading dash must also be
// escaped, but this may be done symbolically.
if (in != end && (*in == '-' ||
('0' <= *in && *in <= '9'))) {
if (*in == '-') {
aReturn.Append(PRUnichar('\\'));
aReturn.Append(PRUnichar('-'));
} else {
aReturn.AppendPrintf("\\%hX ", *in);
}
++in;
}
bool first = true;
for (; in != end; ++in, first = false)
{
if (*in < 0x20 || (first && '0' <= *in && *in <= '9'))
{
// Escape all characters below 0x20, and digits at the start
// (including after a dash), numerically. If we didn't escape
// digits numerically, they'd get interpreted as a numeric escape
// for the wrong character.
for (; in != end; ++in) {
PRUnichar ch = *in;
if (ch < 0x20 || (0x7F <= ch && ch < 0xA0)) {
// Escape U+0000 through U+001F and U+007F through U+009F numerically.
aReturn.AppendPrintf("\\%hX ", *in);
/*
This is the buffer into which snprintf should write. As the hex.
value is, for numbers below 0x7F, max. 2 characters long, we
don't need more than 5 characters ("\XX "+NUL).
*/
PRUnichar buf[5];
nsTextFormatter::snprintf(buf, ArrayLength(buf),
NS_LITERAL_STRING("\\%hX ").get(), *in);
aReturn.Append(buf);
} else {
// Escape ASCII non-identifier printables as a backslash plus
// the character.
if (ch < 0x7F &&
ch != '_' && ch != '-' &&
(ch < '0' || '9' < ch) &&
(ch < 'A' || 'Z' < ch) &&
(ch < 'a' || 'z' < ch)) {
PRUnichar ch = *in;
if (!((ch == PRUnichar('_')) ||
(PRUnichar('A') <= ch && ch <= PRUnichar('Z')) ||
(PRUnichar('a') <= ch && ch <= PRUnichar('z')) ||
PRUnichar(0x80) <= ch ||
(!first && ch == PRUnichar('-')) ||
(PRUnichar('0') <= ch && ch <= PRUnichar('9')))) {
// Character needs to be escaped
aReturn.Append(PRUnichar('\\'));
}
aReturn.Append(ch);

View File

@ -25,17 +25,14 @@ public:
static bool DashMatchCompare(const nsAString& aAttributeValue,
const nsAString& aSelectorValue,
const nsStringComparator& aComparator);
// Append a quoted (with 'quoteChar') and escaped version of aString
// to aResult. 'quoteChar' must be ' or ".
static void AppendEscapedCSSString(const nsAString& aString,
nsAString& aResult,
PRUnichar quoteChar = '"');
// Append a quoted (with "") and escaped version of aString to aResult.
static void AppendEscapedCSSString(const nsString& aString,
nsAString& aResult);
// Append the identifier given by |aIdent| to |aResult|, with
// appropriate escaping so that it can be reparsed to the same
// identifier.
static void AppendEscapedCSSIdent(const nsAString& aIdent,
static void AppendEscapedCSSIdent(const nsString& aIdent,
nsAString& aResult);
// Append a bitmask-valued property's value(s) (space-separated) to aResult.

View File

@ -118,7 +118,6 @@ MOCHITEST_FILES = test_acid3_test46.html \
test_parse_ident.html \
test_parse_rule.html \
test_parse_url.html \
test_parser_diagnostics_unprintables.html \
test_pixel_lengths.html \
test_pointer-events.html \
test_property_database.html \

View File

@ -2315,7 +2315,7 @@ var gCSSProperties = {
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "foo 1", "bar", "foo 3 bar baz 2", "\\32 1", "-\\32 1", "-c 1", "\\32 1", "-\\32 1", "\\2 1", "-\\2 1", "-c 1", "\\2 1", "-\\2 1", "-\\7f \\9e 1" ],
other_values: [ "foo 1", "bar", "foo 3 bar baz 2", "\\32 1", "-\\32 1", "-c 1", "\\32 1", "-\\32 1", "\\2 1", "-\\2 1", "-c 1", "\\2 1", "-\\2 1" ],
invalid_values: []
},
"counter-reset": {
@ -2323,7 +2323,7 @@ var gCSSProperties = {
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "none" ],
other_values: [ "foo 1", "bar", "foo 3 bar baz 2", "\\32 1", "-\\32 1", "-c 1", "\\32 1", "-\\32 1", "\\2 1", "-\\2 1", "-c 1", "\\2 1", "-\\2 1", "-\\7f \\9e 1" ],
other_values: [ "foo 1", "bar", "foo 3 bar baz 2", "\\32 1", "-\\32 1", "-c 1", "\\32 1", "-\\32 1", "\\2 1", "-\\2 1", "-c 1", "\\2 1", "-\\2 1" ],
invalid_values: []
},
"cursor": {

View File

@ -1,219 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test for CSS parser diagnostics escaping unprintable
characters correctly</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=229827"
>Mozilla Bug 229827</a>
<style id="testbench"></style>
<script type="application/javascript;version=1.8">
// This test has intimate knowledge of how to get the CSS parser to
// emit diagnostics that contain text under control of the user.
// That's not the point of the test, though; the point is only that
// *that text* is properly escaped.
// There is one "pattern" for each code path through the error reporter
// that might need to escape some kind of user-supplied text.
// Each "pattern" is tested once with each of the "substitution"s below:
// <t>, <i>, and <s> are replaced by the t:, i:, and s: fields of
// each substitution object in turn.
const patterns = [
// REPORT_UNEXPECTED_P (only ever used in contexts where identifier-like
// escaping is appropriate)
{ i: "<t>|x{}", o: "prefix '<i>'" },
// REPORT_UNEXPECTED_TOKEN with:
// _Ident
{ i: "@namespace fnord <t>;", o: "within @namespace: '<i>'" },
// _Ref
{ i: "@namespace fnord #<t>;", o: "within @namespace: '#<i>'" },
// _Function
{ i: "@namespace fnord <t>();", o: "within @namespace: '<i>('" },
// _Dimension
{ i: "@namespace fnord 14<t>;", o: "within @namespace: '14<i>'" },
// _AtKeyword
{ i: "x{@<t>: }", o: "declaration but found '@<i>'." },
// _String
{ i: "x{ '<t>'}" , o: "declaration but found ''<s>''." },
// _Bad_String
{ i: "x{ '<t>\n}", o: "declaration but found ''<s>'." },
// _URL
{ i: "x{ url('<t>')}", o: "declaration but found 'url('<s>')'." },
// _Bad_URL
{ i: "x{ url('<t>'.)}" , o: "declaration but found 'url('<s>''." }
];
// Blocks of characters to test, and how they should be escaped when
// they appear in identifiers and string constants.
const substitutions = [
// ASCII printables that _can_ normally appear in identifiers,
// so should of course _not_ be escaped.
{ t: "-_0123456789", i: "-_0123456789",
s: "-_0123456789" },
{ t: "abcdefghijklmnopqrstuvwxyz", i: "abcdefghijklmnopqrstuvwxyz",
s: "abcdefghijklmnopqrstuvwxyz" },
{ t: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", i: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
s: "ABCDEFGHIJKLMNOPQRSTUVWXYZ" },
// ASCII printables that are not normally valid as the first character
// of an identifier, or the character immediately after a leading dash,
// but can be forced into that position with escapes.
{ t: "\\-", i: "\\-", s: "-" },
{ t: "\\30 ", i: "\\30 ", s: "0" },
{ t: "\\31 ", i: "\\31 ", s: "1" },
{ t: "\\32 ", i: "\\32 ", s: "2" },
{ t: "\\33 ", i: "\\33 ", s: "3" },
{ t: "\\34 ", i: "\\34 ", s: "4" },
{ t: "\\35 ", i: "\\35 ", s: "5" },
{ t: "\\36 ", i: "\\36 ", s: "6" },
{ t: "\\37 ", i: "\\37 ", s: "7" },
{ t: "\\38 ", i: "\\38 ", s: "8" },
{ t: "\\39 ", i: "\\39 ", s: "9" },
{ t: "-\\-", i: "-\\-", s: "--" },
{ t: "-\\30 ", i: "-\\30 ", s: "-0" },
{ t: "-\\31 ", i: "-\\31 ", s: "-1" },
{ t: "-\\32 ", i: "-\\32 ", s: "-2" },
{ t: "-\\33 ", i: "-\\33 ", s: "-3" },
{ t: "-\\34 ", i: "-\\34 ", s: "-4" },
{ t: "-\\35 ", i: "-\\35 ", s: "-5" },
{ t: "-\\36 ", i: "-\\36 ", s: "-6" },
{ t: "-\\37 ", i: "-\\37 ", s: "-7" },
{ t: "-\\38 ", i: "-\\38 ", s: "-8" },
{ t: "-\\39 ", i: "-\\39 ", s: "-9" },
// ASCII printables that must be escaped in identifiers.
// Most of these should not be escaped in strings.
{ t: "\\!\\\"\\#\\$", i: "\\!\\\"\\#\\$", s: "!\\\"#$" },
{ t: "\\%\\&\\'\\(", i: "\\%\\&\\'\\(", s: "%&\\'(" },
{ t: "\\)\\*\\+\\,", i: "\\)\\*\\+\\,", s: ")*+," },
{ t: "\\.\\/\\:\\;", i: "\\.\\/\\:\\;", s: "./:;" },
{ t: "\\<\\=\\>\\?", i: "\\<\\=\\>\\?", s: "<=>?", },
{ t: "\\@\\[\\\\\\]", i: "\\@\\[\\\\\\]", s: "@[\\\\]" },
{ t: "\\^\\`\\{\\}\\~", i: "\\^\\`\\{\\}\\~", s: "^`{}~" },
// U+0000 - U+0020 (C0 controls, space)
// U+000A LINE FEED, U+000C FORM FEED, and U+000D CARRIAGE RETURN
// cannot be put into a CSS token as escaped literal characters, so
// we do them with hex escapes instead.
{ t: "\\\x00\\\x01\\\x02\\\x03", i: "\\0 \\1 \\2 \\3 ",
s: "\\0 \\1 \\2 \\3 " },
{ t: "\\\x04\\\x05\\\x06\\\x07", i: "\\4 \\5 \\6 \\7 ",
s: "\\4 \\5 \\6 \\7 " },
{ t: "\\\x08\\\x09\\000A\\\x0B", i: "\\8 \\9 \\A \\B ",
s: "\\8 \\9 \\A \\B " },
{ t: "\\000C\\000D\\\x0E\\\x0F", i: "\\C \\D \\E \\F ",
s: "\\C \\D \\E \\F " },
{ t: "\\\x10\\\x11\\\x12\\\x13", i: "\\10 \\11 \\12 \\13 ",
s: "\\10 \\11 \\12 \\13 " },
{ t: "\\\x14\\\x15\\\x16\\\x17", i: "\\14 \\15 \\16 \\17 ",
s: "\\14 \\15 \\16 \\17 " },
{ t: "\\\x18\\\x19\\\x1A\\\x1B", i: "\\18 \\19 \\1A \\1B ",
s: "\\18 \\19 \\1A \\1B " },
{ t: "\\\x1C\\\x1D\\\x1E\\\x1F\\ ", i: "\\1C \\1D \\1E \\1F \\ ",
s: "\\1C \\1D \\1E \\1F " },
// U+007F (DELETE) and U+0080 - U+009F (C1 controls)
{ t: "\\\x7f\\\x80\\\x81\\\x82", i: "\\7F \\80 \\81 \\82 ",
s: "\\7F \\80 \\81 \\82 " },
{ t: "\\\x83\\\x84\\\x85\\\x86", i: "\\83 \\84 \\85 \\86 ",
s: "\\83 \\84 \\85 \\86 " },
{ t: "\\\x87\\\x88\\\x89\\\x8A", i: "\\87 \\88 \\89 \\8A ",
s: "\\87 \\88 \\89 \\8A " },
{ t: "\\\x8B\\\x8C\\\x8D\\\x8E", i: "\\8B \\8C \\8D \\8E ",
s: "\\8B \\8C \\8D \\8E " },
{ t: "\\\x8F\\\x90\\\x91\\\x92", i: "\\8F \\90 \\91 \\92 ",
s: "\\8F \\90 \\91 \\92 " },
{ t: "\\\x93\\\x94\\\x95\\\x96", i: "\\93 \\94 \\95 \\96 ",
s: "\\93 \\94 \\95 \\96 " },
{ t: "\\\x97\\\x98\\\x99\\\x9A", i: "\\97 \\98 \\99 \\9A ",
s: "\\97 \\98 \\99 \\9A " },
{ t: "\\\x9B\\\x9C\\\x9D\\\x9E\\\x9F", i: "\\9B \\9C \\9D \\9E \\9F ",
s: "\\9B \\9C \\9D \\9E \\9F " },
// CSS doesn't bother with the full Unicode rules for identifiers,
// instead declaring that any code point greater than or equal to
// U+00A0 is a valid identifier character. Test a small handful
// of both basic and astral plane characters.
// Arabic (caution to editors: there is a possibly-invisible U+200E
// LEFT-TO-RIGHT MARK in each string, just before the close quote)
{ t: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎",
i: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎",
s: "أبجدهوزحطيكلمنسعفصقرشتثخذضظغ‎" },
// Box drawing
{ t: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷",
i: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷",
s: "─│┌┐└┘├┤┬┴┼╭╮╯╰╴╵╶╷" },
// CJK Unified Ideographs
{ t: "一丁丂七丄丅丆万丈三上下丌不与丏",
i: "一丁丂七丄丅丆万丈三上下丌不与丏",
s: "一丁丂七丄丅丆万丈三上下丌不与丏" },
// CJK Unified Ideographs Extension B (astral)
{ t: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏",
i: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏",
s: "𠀀𠀁𠀂𠀃𠀄𠀅𠀆𠀇𠀈𠀉𠀊𠀋𠀌𠀍𠀎𠀏" },
// Devanagari
{ t: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह",
i: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह",
s: "कखगघङचछजझञटठडढणतथदधनपफबभमयरलळवशषसह" },
// Emoticons (astral)
{ t: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐",
i: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐",
s: "😁😂😃😄😅😆😇😈😉😊😋😌😍😎😏😐" },
// Greek
{ t: "αβγδεζηθικλμνξοπρςστυφχψω",
i: "αβγδεζηθικλμνξοπρςστυφχψω",
s: "αβγδεζηθικλμνξοπρςστυφχψω" }
];
const npatterns = patterns.length;
const nsubstitutions = substitutions.length;
function quotemeta(str) {
return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
}
function subst(str, sub) {
return str.replace("<t>", sub.t)
.replace("<i>", sub.i)
.replace("<s>", sub.s);
}
var curpat = 0;
var cursubst = -1;
var testbench = document.getElementById("testbench");
function nextTest() {
cursubst++;
if (cursubst == nsubstitutions) {
curpat++;
cursubst = 0;
}
if (curpat == npatterns) {
SimpleTest.finish();
return;
}
let css = subst(patterns[curpat].i, substitutions[cursubst]);
let msg = quotemeta(subst(patterns[curpat].o, substitutions[cursubst]));
SimpleTest.expectConsoleMessages(function () { testbench.innerHTML = css },
[{ errorMessage: new RegExp(msg) }],
nextTest);
}
SimpleTest.waitForExplicitFinish();
nextTest();
</script>
</body>
</html>

View File

@ -63,7 +63,6 @@ MOCHITEST_FILES = parser_datreader.js \
test_bug655682.html \
file_bug655682.sjs \
test_bug667533.html \
test_bug672453.html \
file_bug672453_not_declared.html \
file_bug672453_late_meta.html \
file_bug672453_meta_restart.html \
@ -104,4 +103,7 @@ endif
# Disable test due to frequent orange on Mac
# test_bug534293.html \
# Disabled due to frequent orange (bug 739354)
# test_bug672453.html \
include $(topsrcdir)/config/rules.mk

View File

@ -1,4 +1,4 @@
<!doctype html>
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=672453
@ -6,17 +6,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=672453
<head>
<meta charset="utf-8">
<title>Test for Bug 672453</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<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=672453"
>Mozilla Bug 672453</a>
<iframe></iframe>
<script>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=672453">Mozilla Bug 672453</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe onload="runNextTest();"></iframe>
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 672453 **/
SimpleTest.waitForExplicitFinish();
var tests = [
"file_bug672453_not_declared.html",
"file_bug672453_late_meta.html",
@ -29,66 +34,35 @@ var tests = [
];
var expectedErrors = [
{ errorMessage: "The character encoding of a framed document was not declared. The document may appear different if viewed without the document framing it.",
sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html",
lineNumber: 0,
isWarning: true,
isException: false },
{ errorMessage: "The character encoding declaration of the framed HTML document was not found when prescanning the first 1024 bytes of the file. When viewed without the document framing it, the page will reload automatically. The encoding declaration needs to be moved to be within the first 1024 bytes of the file.",
sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html",
lineNumber: 1028,
isWarning: true,
isException: false },
{ errorMessage: "The page was reloaded, because the character encoding declaration of the HTML document was not found when prescanning the first 1024 bytes of the file. The encoding declaration needs to be moved to be within the first 1024 bytes of the file.",
sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html",
lineNumber: 1028,
isWarning: true,
isException: false },
{ errorMessage: "An unsupported character encoding was declared for the HTML document using a meta tag. The declaration was ignored.",
sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html",
lineNumber: 1,
isWarning: false,
isException: false },
{ errorMessage: "An unsupported character encoding was declared on the transfer protocol level. The declaration was ignored.",
sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html",
lineNumber: 0,
isWarning: false,
isException: false },
{ errorMessage: "Detected UTF-16-encoded Basic Latin-only text without a byte order mark and without a transfer protocol-level declaration. Encoding this content in UTF-16 is inefficient and the character encoding should have been declared in any case.",
sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_bomless_utf16.html",
lineNumber: 0,
isWarning: false,
isException: false },
{ errorMessage: "A meta tag was used to declare the character encoding as UTF-16. This was interpreted as an UTF-8 declaration instead.",
sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html",
lineNumber: 1,
isWarning: false,
isException: false },
{ errorMessage: "A meta tag was used to declare a character encoding the does not encode the Basic Latin range roughly like US-ASCII. The declaration was ignored.",
sourceName: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html",
lineNumber: 1,
isWarning: false,
isException: false }
'[JavaScript Warning: "The character encoding of a framed document was not declared. The document may appear different if viewed without the document framing it." {file: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_not_declared.html" line: 0}]',
'[JavaScript Warning: "The character encoding declaration of the framed HTML document was not found when prescanning the first 1024 bytes of the file. When viewed without the document framing it, the page will reload automatically. The encoding declaration needs to be moved to be within the first 1024 bytes of the file." {file: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_late_meta.html" line: 1028}]',
'[JavaScript Warning: "The page was reloaded, because the character encoding declaration of the HTML document was not found when prescanning the first 1024 bytes of the file. The encoding declaration needs to be moved to be within the first 1024 bytes of the file." {file: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_restart.html" line: 1028}]',
'[JavaScript Error: "An unsupported character encoding was declared for the HTML document using a meta tag. The declaration was ignored." {file: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_unsupported.html" line: 1}]',
'[JavaScript Error: "An unsupported character encoding was declared on the transfer protocol level. The declaration was ignored." {file: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_http_unsupported.html" line: 0}]',
'[JavaScript Error: "Detected UTF-16-encoded Basic Latin-only text without a byte order mark and without a transfer protocol-level declaration. Encoding this content in UTF-16 is inefficient and the character encoding should have been declared in any case." {file: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_bomless_utf16.html" line: 0}]',
'[JavaScript Error: "A meta tag was used to declare the character encoding as UTF-16. This was interpreted as an UTF-8 declaration instead." {file: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_utf16.html" line: 1}]',
'[JavaScript Error: "A meta tag was used to declare a character encoding the does not encode the Basic Latin range roughly like US-ASCII. The declaration was ignored." {file: "http://mochi.test:8888/tests/parser/htmlparser/tests/mochitest/file_bug672453_meta_non_superset.html" line: 1}]'
];
SimpleTest.waitForExplicitFinish();
window.onload = function() {
var iframe = document.getElementsByTagName("iframe")[0];
function runNextTest() {
var url = tests.shift();
if (!url) {
SimpleTest.endMonitorConsole();
return;
}
iframe.src = url;
}
iframe.onload = runNextTest;
SimpleTest.monitorConsole(SimpleTest.finish, expectedErrors);
runNextTest();
function consoleError(msg) {
var expected = expectedErrors.shift();
is(msg, expected, "Not the right error message");
}
SpecialPowers.addErrorConsoleListener(consoleError);
function runNextTest() {
var url = tests.shift();
if (!url) {
is(expectedErrors.length, 0, "The error supply was not exhausted");
SpecialPowers.removeErrorConsoleListener(consoleError);
SimpleTest.finish();
return;
}
document.getElementsByTagName("iframe")[0].src = url;
}
</script>
</pre>
</body>
</html>

View File

@ -693,89 +693,6 @@ SimpleTest.finish = function () {
}
};
/**
* Monitor console output from now until endMonitorConsole is called.
*
* Expect to receive as many console messages as there are elements of
* |msgs|, an array; each element is an object which may have any
* number of the following properties:
* message, errorMessage, sourceName, sourceLine, category:
* string or regexp
* lineNumber, columnNumber: number
* isScriptError, isWarning, isException, isStrict: boolean
* Strings, numbers, and booleans must compare equal to the named
* property of the Nth console message. Regexps must match. Any
* fields present in the message but not in the pattern object are ignored.
*
* After endMonitorConsole is called, |continuation| will be called
* asynchronously. (Normally, you will want to pass |SimpleTest.finish| here.)
*
* It is incorrect to use this function in a test which has not called
* SimpleTest.waitForExplicitFinish.
*/
SimpleTest.monitorConsole = function (continuation, msgs) {
if (SimpleTest._stopOnLoad) {
ok(false, "Console monitoring requires use of waitForExplicitFinish.");
}
var counter = 0;
function listener(msg) {
if (msg.message === "SENTINEL" && !msg.isScriptError) {
is(counter, msgs.length, "monitorConsole | number of messages");
SimpleTest.executeSoon(continuation);
} else if (counter >= msgs.length) {
ok(false, "monitorConsole | extra message | " + JSON.stringify(msg));
} else {
var pat = msgs[counter];
for (k in pat) {
ok(k in msg, "monitorConsole | [" + counter + "]." + k + " present");
if (k in msg) {
if (pat[k] instanceof RegExp && typeof(msg[k]) === 'string') {
ok(pat[k].test(msg[k]),
"monitorConsole | [" + counter + "]." + k + " value - " +
msg[k].quote() + " contains /" + pat[k].source + "/");
} else {
ise(msg[k], pat[k],
"monitorConsole | [" + counter + "]." + k + " value");
}
}
}
counter++;
}
}
SpecialPowers.registerConsoleListener(listener);
};
/**
* Stop monitoring console output.
*/
SimpleTest.endMonitorConsole = function () {
SpecialPowers.postConsoleSentinel();
};
/**
* Run |testfn| synchronously, and monitor its console output.
*
* |msgs| is handled as described above for monitorConsole.
*
* After |testfn| returns, console monitoring will stop, and
* |continuation| will be called asynchronously.
*/
SimpleTest.expectConsoleMessages = function (testfn, msgs, continuation) {
SimpleTest.monitorConsole(continuation, msgs);
testfn();
SimpleTest.executeSoon(SimpleTest.endMonitorConsole);
};
/**
* Wrapper around |expectConsoleMessages| for the case where the test has
* only one |testfn| to run.
*/
SimpleTest.runTestExpectingConsoleMessages = function(testfn, msgs) {
SimpleTest.waitForExplicitFinish();
SimpleTest.expectConsoleMessages(testfn, msgs, SimpleTest.finish);
};
/**
* Indicates to the test framework that the current test expects one or
* more crashes (from plugins or IPC documents), and that the minidumps from

View File

@ -11,23 +11,22 @@ function SpecialPowers(window) {
this._unexpectedCrashDumpFiles = { };
this._crashDumpDir = null;
this.DOMWindowUtils = bindDOMWindowUtils(window);
Object.defineProperty(this, 'Components', {
configurable: true, enumerable: true, get: function() {
var win = this.window.get();
if (!win)
return null;
return getRawComponents(win);
}});
Object.defineProperty(this, 'Components', { configurable: true, enumerable: true,
get: function() { var win = this.window.get();
if (!win)
return null;
return getRawComponents(win); } });
this._pongHandlers = [];
this._messageListener = this._messageReceived.bind(this);
addMessageListener("SPPingService", this._messageListener);
this._consoleListeners = [];
}
SpecialPowers.prototype = new SpecialPowersAPI();
SpecialPowers.prototype.toString = function() { return "[SpecialPowers]"; };
SpecialPowers.prototype.sanityCheck = function() { return "foo"; };
// This gets filled in in the constructor.
SpecialPowers.prototype.DOMWindowUtils = undefined;
SpecialPowers.prototype.Components = undefined;

View File

@ -9,13 +9,12 @@ var Ci = Components.interfaces;
var Cc = Components.classes;
var Cu = Components.utils;
Cu.import("resource://specialpowers/MockFilePicker.jsm");
Cu.import("resource://specialpowers/MockPermissionPrompt.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://specialpowers/MockFilePicker.jsm");
Components.utils.import("resource://specialpowers/MockPermissionPrompt.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
function SpecialPowersAPI() {
function SpecialPowersAPI() {
this._consoleListeners = [];
this._encounteredCrashDumpFiles = [];
this._unexpectedCrashDumpFiles = { };
@ -380,58 +379,6 @@ SpecialPowersHandler.prototype.enumerate = function() {
return this.getPropertyNames().filter(filt);
};
// SPConsoleListener reflects nsIConsoleMessage objects into JS in a
// tidy, XPCOM-hiding way. Messages that are nsIScriptError objects
// have their properties exposed in detail. It also auto-unregisters
// itself when it receives a "sentinel" message.
function SPConsoleListener(callback) {
this.callback = callback;
}
SPConsoleListener.prototype = {
observe: function(msg) {
let m = { message: msg.message,
errorMessage: null,
sourceName: null,
sourceLine: null,
lineNumber: null,
columnNumber: null,
category: null,
windowID: null,
isScriptError: false,
isWarning: false,
isException: false,
isStrict: false };
if (msg instanceof Ci.nsIScriptError) {
m.errorMessage = msg.errorMessage;
m.sourceName = msg.sourceName;
m.sourceLine = msg.sourceLine;
m.lineNumber = msg.lineNumber;
m.columnNumber = msg.columnNumber;
m.category = msg.category;
m.windowID = msg.outerWindowID;
m.isScriptError = true;
m.isWarning = ((msg.flags & Ci.nsIScriptError.warningFlag) === 1);
m.isException = ((msg.flags & Ci.nsIScriptError.exceptionFlag) === 1);
m.isStrict = ((msg.flags & Ci.nsIScriptError.strictFlag) === 1);
}
// expose all props of 'm' as read-only
let expose = {};
for (let prop in m)
expose[prop] = 'r';
m.__exposedProps__ = expose;
Object.freeze(m);
this.callback.call(undefined, m);
if (!m.isScriptError && m.message === "SENTINEL")
Services.console.unregisterListener(this);
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener])
};
SpecialPowersAPI.prototype = {
/*
@ -802,15 +749,6 @@ SpecialPowersAPI.prototype = {
return(this._sendSyncMessage('SPPrefService', msg)[0]);
},
_getDocShell: function(window) {
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
},
_getMUDV: function(window) {
return this._getDocShell(window).contentViewer
.QueryInterface(Ci.nsIMarkupDocumentViewer);
},
//XXX: these APIs really ought to be removed, they're not e10s-safe.
// (also they're pretty Firefox-specific)
_getTopChromeWindow: function(window) {
@ -822,6 +760,15 @@ SpecialPowersAPI.prototype = {
.getInterface(Ci.nsIDOMWindow)
.QueryInterface(Ci.nsIDOMChromeWindow);
},
_getDocShell: function(window) {
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
},
_getMUDV: function(window) {
return this._getDocShell(window).contentViewer
.QueryInterface(Ci.nsIMarkupDocumentViewer);
},
_getAutoCompletePopup: function(window) {
return this._getTopChromeWindow(window).document
.getElementById("PopupAutoComplete");
@ -853,7 +800,6 @@ SpecialPowersAPI.prototype = {
.getElementById("Browser:Back")
.hasAttribute("disabled");
},
//XXX end of problematic APIs
addChromeEventListener: function(type, listener, capture, allowUntrusted) {
addEventListener(type, listener, capture, allowUntrusted);
@ -862,21 +808,36 @@ SpecialPowersAPI.prototype = {
removeEventListener(type, listener, capture);
},
// Note: each call to registerConsoleListener MUST be paired with a
// call to postConsoleSentinel; when the callback receives the
// sentinel it will unregister itself (_after_ calling the
// callback). SimpleTest.expectConsoleMessages does this for you.
// If you register more than one console listener, a call to
// postConsoleSentinel will zap all of them.
registerConsoleListener: function(callback) {
let listener = new SPConsoleListener(callback);
Services.console.registerListener(listener);
addErrorConsoleListener: function(listener) {
var consoleListener = {
userListener: listener,
observe: function(consoleMessage) {
var fileName;
try {
fileName = consoleMessage.QueryInterface(Ci.nsIScriptError)
.sourceName;
} catch (e) {
}
this.userListener(consoleMessage.message, fileName);
}
};
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
.registerListener(consoleListener);
this._consoleListeners.push(consoleListener);
},
postConsoleSentinel: function() {
Services.console.logStringMessage("SENTINEL");
},
resetConsole: function() {
Services.console.reset();
removeErrorConsoleListener: function(listener) {
for (var index in this._consoleListeners) {
var consoleListener = this._consoleListeners[index];
if (consoleListener.userListener == listener) {
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
.unregisterListener(consoleListener);
this._consoleListeners = this._consoleListeners.splice(index, 1);
break;
}
}
},
getMaxLineBoxWidth: function(window) {
@ -938,11 +899,11 @@ SpecialPowersAPI.prototype = {
},
forceGC: function() {
Cu.forceGC();
Components.utils.forceGC();
},
forceCC: function() {
Cu.forceCC();
Components.utils.forceCC();
},
exactGC: function(win, callback) {
@ -960,14 +921,14 @@ SpecialPowersAPI.prototype = {
}
}
Cu.schedulePreciseGC(scheduledGCCallback);
Components.utils.schedulePreciseGC(scheduledGCCallback);
}
doPreciseGCandCC();
},
setGCZeal: function(zeal) {
Cu.setGCZeal(zeal);
Components.utils.setGCZeal(zeal);
},
isMainProcess: function() {
@ -1241,7 +1202,7 @@ SpecialPowersAPI.prototype = {
} else if (arg.manifestURL) {
// It's a thing representing an app.
let tmp = {};
Cu.import("resource://gre/modules/Webapps.jsm", tmp);
Components.utils.import("resource://gre/modules/Webapps.jsm", tmp);
let app = tmp.DOMApplicationRegistry.getAppByManifestURL(arg.manifestURL);
if (!app) {