Merge inbound to m-c.

This commit is contained in:
Ryan VanderMeulen 2013-06-13 15:28:41 -04:00
commit f1d1348439
153 changed files with 2244 additions and 1251 deletions

View File

@ -63,6 +63,10 @@ a {
-moz-padding-end: 8px; -moz-padding-end: 8px;
} }
#searchLogoContainer[hidden] {
display: none;
}
#searchEngineLogo { #searchEngineLogo {
display: inline-block; display: inline-block;
height: 28px; height: 28px;

View File

@ -144,18 +144,22 @@ const DEFAULT_SNIPPETS_URLS = [
const SNIPPETS_UPDATE_INTERVAL_MS = 86400000; // 1 Day. const SNIPPETS_UPDATE_INTERVAL_MS = 86400000; // 1 Day.
// This global tracks if the page has been set up before, to prevent double inits
let gInitialized = false;
let gObserver = new MutationObserver(function (mutations) { let gObserver = new MutationObserver(function (mutations) {
for (let mutation of mutations) { for (let mutation of mutations) {
if (mutation.attributeName == "searchEngineURL") { if (mutation.attributeName == "searchEngineURL") {
gObserver.disconnect();
setupSearchEngine(); setupSearchEngine();
ensureSnippetsMapThen(loadSnippets); if (!gInitialized) {
ensureSnippetsMapThen(loadSnippets);
gInitialized = true;
}
return; return;
} }
} }
}); });
window.addEventListener("load", function () { window.addEventListener("pageshow", function () {
// Delay search engine setup, cause browser.js::BrowserOnAboutPageLoad runs // Delay search engine setup, cause browser.js::BrowserOnAboutPageLoad runs
// later and may use asynchronous getters. // later and may use asynchronous getters.
window.gObserver.observe(document.documentElement, { attributes: true }); window.gObserver.observe(document.documentElement, { attributes: true });
@ -163,6 +167,11 @@ window.addEventListener("load", function () {
window.addEventListener("resize", fitToWidth); window.addEventListener("resize", fitToWidth);
}); });
window.addEventListener("pagehide", function() {
window.gObserver.disconnect();
window.removeEventListener("resize", fitToWidth);
});
// This object has the same interface as Map and is used to store and retrieve // This object has the same interface as Map and is used to store and retrieve
// the snippets data. It is lazily initialized by ensureSnippetsMapThen(), so // the snippets data. It is lazily initialized by ensureSnippetsMapThen(), so
// be sure its callback returned before trying to use it. // be sure its callback returned before trying to use it.

View File

@ -2296,10 +2296,23 @@ function BrowserOnAboutPageLoad(doc) {
Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true); Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
} }
docElt.setAttribute("snippetsVersion", AboutHomeUtils.snippetsVersion); docElt.setAttribute("snippetsVersion", AboutHomeUtils.snippetsVersion);
docElt.setAttribute("searchEngineName",
AboutHomeUtils.defaultSearchEngine.name); function updateSearchEngine() {
docElt.setAttribute("searchEngineURL", let engine = AboutHomeUtils.defaultSearchEngine;
AboutHomeUtils.defaultSearchEngine.searchURL); docElt.setAttribute("searchEngineName", engine.name);
docElt.setAttribute("searchEngineURL", engine.searchURL);
}
updateSearchEngine();
// Listen for the event that's triggered when the user changes search engine.
// At this point we simply reload about:home to reflect the change.
Services.obs.addObserver(updateSearchEngine, "browser-search-engine-modified", false);
// Remove the observer when the page is reloaded or closed.
doc.defaultView.addEventListener("pagehide", function removeObserver() {
doc.defaultView.removeEventListener("pagehide", removeObserver);
Services.obs.removeObserver(updateSearchEngine, "browser-search-engine-modified");
}, false);
#ifdef MOZ_SERVICES_HEALTHREPORT #ifdef MOZ_SERVICES_HEALTHREPORT
doc.addEventListener("AboutHomeSearchEvent", function onSearch(e) { doc.addEventListener("AboutHomeSearchEvent", function onSearch(e) {
@ -4299,6 +4312,7 @@ var TabsProgressListener = {
aBrowser.addEventListener("pagehide", function onPageHide(event) { aBrowser.addEventListener("pagehide", function onPageHide(event) {
if (event.target.defaultView.frameElement) if (event.target.defaultView.frameElement)
return; return;
event.target.documentElement.removeAttribute("hasBrowserHandlers");
aBrowser.removeEventListener("click", BrowserOnClick, true); aBrowser.removeEventListener("click", BrowserOnClick, true);
aBrowser.removeEventListener("pagehide", onPageHide, true); aBrowser.removeEventListener("pagehide", onPageHide, true);
}, true); }, true);

View File

@ -243,6 +243,50 @@ let gTests = [
Services.prefs.clearUserPref("browser.rights.override"); Services.prefs.clearUserPref("browser.rights.override");
} }
},
{
desc: "Check that the search UI/ action is updated when the search engine is changed",
setup: function() {},
run: function()
{
let currEngine = Services.search.currentEngine;
let unusedEngines = [].concat(Services.search.getVisibleEngines()).filter(x => x != currEngine);
let searchbar = document.getElementById("searchbar");
function checkSearchUI(engine) {
let doc = gBrowser.selectedTab.linkedBrowser.contentDocument;
let searchText = doc.getElementById("searchText");
let logoElt = doc.getElementById("searchEngineLogo");
let engineName = doc.documentElement.getAttribute("searchEngineName");
is(engineName, engine.name, "Engine name should've been updated");
if (!logoElt.parentNode.hidden) {
is(logoElt.alt, engineName, "Alt text of logo image should match search engine name")
} else {
is(searchText.placeholder, engineName, "Placeholder text should match search engine name");
}
}
// Do a sanity check that all attributes are correctly set to begin with
checkSearchUI(currEngine);
let deferred = Promise.defer();
promiseBrowserAttributes(gBrowser.selectedTab).then(function() {
// Test if the update propagated
checkSearchUI(unusedEngines[0]);
deferred.resolve();
});
// The following cleanup function will set currentEngine back to the previous engine
registerCleanupFunction(function() {
searchbar.currentEngine = currEngine;
});
// Set the current search engine to an unused one
searchbar.currentEngine = unusedEngines[0];
searchbar.select();
return deferred.promise;
}
} }
]; ];

View File

@ -19,7 +19,6 @@ function test()
gPane = aPane; gPane = aPane;
gDebugger = gPane.panelWin; gDebugger = gPane.panelWin;
expectUncaughtException();
testNormalReturn(); testNormalReturn();
}); });
} }

View File

@ -18,10 +18,15 @@
return r; return r;
} }
function error(aArg) { function error(aArg) {
debugger; function inner(aArg) {
var r = 10; debugger;
throw "boom"; var r = 10;
return r; throw "boom";
return r;
}
try {
inner(aArg);
} catch (e) {}
} }
var button = document.getElementById("return"); var button = document.getElementById("return");
button.addEventListener("click", normal, false); button.addEventListener("click", normal, false);

View File

@ -206,9 +206,7 @@ BookmarksView.prototype = {
}, },
clearBookmarks: function bv_clearBookmarks() { clearBookmarks: function bv_clearBookmarks() {
while (this._set.itemCount > 0) this._set.clearAll();
this._set.removeItemAt(0, true);
this._set.arrangeItems();
}, },
addBookmark: function bv_addBookmark(aBookmarkId, aPos) { addBookmark: function bv_addBookmark(aBookmarkId, aPos) {

View File

@ -352,6 +352,7 @@ MenuPopup.prototype = {
window.addEventListener("keypress", this, true); window.addEventListener("keypress", this, true);
window.addEventListener("mousedown", this, true); window.addEventListener("mousedown", this, true);
Elements.stack.addEventListener("PopupChanged", this, false); Elements.stack.addEventListener("PopupChanged", this, false);
Elements.browsers.addEventListener("PanBegin", this, false);
this._panel.hidden = false; this._panel.hidden = false;
this._position(aPositionOptions || {}); this._position(aPositionOptions || {});
@ -382,6 +383,7 @@ MenuPopup.prototype = {
window.removeEventListener("keypress", this, true); window.removeEventListener("keypress", this, true);
window.removeEventListener("mousedown", this, true); window.removeEventListener("mousedown", this, true);
Elements.stack.removeEventListener("PopupChanged", this, false); Elements.stack.removeEventListener("PopupChanged", this, false);
Elements.browsers.removeEventListener("PanBegin", this, false);
let self = this; let self = this;
this._panel.addEventListener("transitionend", function () { this._panel.addEventListener("transitionend", function () {
@ -497,6 +499,9 @@ MenuPopup.prototype = {
this.hide(); this.hide();
} }
break; break;
case "PanBegin":
this.hide();
break;
} }
} }
}; };

View File

@ -319,6 +319,8 @@ gTests.push({
sendContextMenuClickToElement(window, item3, 10, 10); sendContextMenuClickToElement(window, item3, 10, 10);
yield promise; yield promise;
yield waitForCondition(() => !deleteButton.hidden);
ok(!deleteButton.hidden, "Delete button is visible."); ok(!deleteButton.hidden, "Delete button is visible.");
let promise = waitForCondition(() => !restoreButton.hidden); let promise = waitForCondition(() => !restoreButton.hidden);

View File

@ -352,12 +352,48 @@ gTests.push({
} }
}); });
var observeLogger = {
observe: function (aSubject, aTopic, aData) {
info("observeLogger: " + aTopic);
},
QueryInterface: function (aIID) {
if (!aIID.equals(Ci.nsIObserver) &&
!aIID.equals(Ci.nsISupportsWeakReference) &&
!aIID.equals(Ci.nsISupports)) {
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
},
init: function init() {
Services.obs.addObserver(observeLogger, "dl-start", true);
Services.obs.addObserver(observeLogger, "dl-done", true);
Services.obs.addObserver(observeLogger, "dl-failed", true);
Services.obs.addObserver(observeLogger, "dl-scanning", true);
Services.obs.addObserver(observeLogger, "dl-blocked", true);
Services.obs.addObserver(observeLogger, "dl-dirty", true);
Services.obs.addObserver(observeLogger, "dl-cancel", true);
},
shutdown: function shutdown() {
Services.obs.removeObserver(observeLogger, "dl-start");
Services.obs.removeObserver(observeLogger, "dl-done");
Services.obs.removeObserver(observeLogger, "dl-failed");
Services.obs.removeObserver(observeLogger, "dl-scanning");
Services.obs.removeObserver(observeLogger, "dl-blocked");
Services.obs.removeObserver(observeLogger, "dl-dirty");
Services.obs.removeObserver(observeLogger, "dl-cancel");
}
}
// Image context menu tests // Image context menu tests
gTests.push({ gTests.push({
desc: "image context menu", desc: "image context menu",
setUp: function() {
observeLogger.init();
},
tearDown: function() {
observeLogger.shutdown();
},
run: function test() { run: function test() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
info(chromeRoot + "browser_context_menu_tests_01.html"); info(chromeRoot + "browser_context_menu_tests_01.html");
yield addTab(chromeRoot + "browser_context_menu_tests_01.html"); yield addTab(chromeRoot + "browser_context_menu_tests_01.html");
@ -409,7 +445,9 @@ gTests.push({
ok(menuItem, "menu item exists"); ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible"); ok(!menuItem.hidden, "menu item visible");
let downloadPromise = waitForObserver("dl-done", 5000); // dl-start, dl-failed, dl-scanning, dl-blocked, dl-dirty, dl-cancel
let downloadPromise = waitForObserver("dl-done", 10000);
let popupPromise = waitForEvent(document, "popuphidden"); let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win); EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
yield popupPromise; yield popupPromise;

View File

@ -1128,3 +1128,5 @@ sys/thr.h
sys/user.h sys/user.h
kvm.h kvm.h
spawn.h spawn.h
err.h
xlocale.h

View File

@ -9127,6 +9127,18 @@ if test -n "$ARM_ARCH"; then
fi fi
fi fi
# Keep libcubeb and audio_device backends in sync
if test -n "$MOZ_ALSA"; then
EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D include_alsa_audio=1"
else
EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D include_alsa_audio=0"
fi
if test -n "$MOZ_PULSEAUDIO"; then
EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D include_pulse_audio=1"
else
EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D include_pulse_audio=0"
fi
# Don't try to compile ssse3/sse4.1 code if toolchain doesn't support # Don't try to compile ssse3/sse4.1 code if toolchain doesn't support
if test -z "$HAVE_TOOLCHAIN_SUPPORT_SSSE3" || test -z "$HAVE_TOOLCHAIN_SUPPORT_MSSE4_1"; then if test -z "$HAVE_TOOLCHAIN_SUPPORT_SSSE3" || test -z "$HAVE_TOOLCHAIN_SUPPORT_MSSE4_1"; then
EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D yuv_disable_asm=1" EXTRA_GYP_DEFINES="$EXTRA_GYP_DEFINES -D yuv_disable_asm=1"

View File

@ -21,7 +21,7 @@ interface nsIDOMBlob;
#include "jsapi.h" #include "jsapi.h"
%} %}
[scriptable, builtinclass, uuid(5bc978f2-41e5-4349-a12d-b018092271f7)] [scriptable, builtinclass, uuid(ac97e161-9f1d-4163-adc9-e9a59e18682c)]
interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget { interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
// event handler attributes // event handler attributes
[implicit_jscontext] attribute jsval onabort; [implicit_jscontext] attribute jsval onabort;
@ -133,7 +133,7 @@ interface nsIXMLHttpRequest : nsISupports
* The string representing the status of the response for * The string representing the status of the response for
* HTTP requests. * HTTP requests.
*/ */
readonly attribute DOMString statusText; readonly attribute ACString statusText;
/** /**
* If the request has been sent already, this method will * If the request has been sent already, this method will
@ -148,7 +148,7 @@ interface nsIXMLHttpRequest : nsISupports
* @returns A string containing all of the response headers. * @returns A string containing all of the response headers.
* The empty string if the response has not yet been received. * The empty string if the response has not yet been received.
*/ */
DOMString getAllResponseHeaders(); ACString getAllResponseHeaders();
/** /**
* Returns the text of the header with the specified name for * Returns the text of the header with the specified name for
@ -159,7 +159,7 @@ interface nsIXMLHttpRequest : nsISupports
* NULL if the response has not yet been received or the * NULL if the response has not yet been received or the
* header does not exist in the response. * header does not exist in the response.
*/ */
ACString getResponseHeader(in AUTF8String header); ACString getResponseHeader(in ACString header);
%{C++ %{C++
// note this is NOT virtual so this won't muck with the vtable! // note this is NOT virtual so this won't muck with the vtable!
@ -189,7 +189,7 @@ interface nsIXMLHttpRequest : nsISupports
* @param password (optional) A password for authentication if necessary. * @param password (optional) A password for authentication if necessary.
* The default value is the empty string * The default value is the empty string
*/ */
[optional_argc] void open(in AUTF8String method, in AUTF8String url, [optional_argc] void open(in ACString method, in AUTF8String url,
[optional] in boolean async, [optional] in boolean async,
[optional,Undefined(Empty)] in DOMString user, [optional,Undefined(Empty)] in DOMString user,
[optional,Undefined(Empty)] in DOMString password); [optional,Undefined(Empty)] in DOMString password);
@ -237,7 +237,7 @@ interface nsIXMLHttpRequest : nsISupports
* @param header The name of the header to set in the request. * @param header The name of the header to set in the request.
* @param value The body of the header. * @param value The body of the header.
*/ */
void setRequestHeader(in AUTF8String header, in AUTF8String value); void setRequestHeader(in ACString header, in ACString value);
/** /**
* The amount of milliseconds a request can take before being terminated. * The amount of milliseconds a request can take before being terminated.

View File

@ -139,11 +139,11 @@ using namespace mozilla::dom;
#define NS_PROGRESS_EVENT_INTERVAL 50 #define NS_PROGRESS_EVENT_INTERVAL 50
#define IMPL_STRING_GETTER(_name) \ #define IMPL_CSTRING_GETTER(_name) \
NS_IMETHODIMP \ NS_IMETHODIMP \
nsXMLHttpRequest::_name(nsAString& aOut) \ nsXMLHttpRequest::_name(nsACString& aOut) \
{ \ { \
nsString tmp; \ nsCString tmp; \
_name(tmp); \ _name(tmp); \
aOut = tmp; \ aOut = tmp; \
return NS_OK; \ return NS_OK; \
@ -1128,9 +1128,9 @@ nsXMLHttpRequest::Status()
return status; return status;
} }
IMPL_STRING_GETTER(GetStatusText) IMPL_CSTRING_GETTER(GetStatusText)
void void
nsXMLHttpRequest::GetStatusText(nsString& aStatusText) nsXMLHttpRequest::GetStatusText(nsCString& aStatusText)
{ {
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel(); nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
@ -1152,17 +1152,8 @@ nsXMLHttpRequest::GetStatusText(nsString& aStatusText)
} }
} }
nsCString statusText; httpChannel->GetResponseStatusText(aStatusText);
httpChannel->GetResponseStatusText(statusText);
if (statusText.IsVoid()) {
aStatusText.SetIsVoid(true);
} else {
// We use UTF8ToNewUnicode here because it truncates after invalid UTF-8
// characters, CopyUTF8toUTF16 just doesn't copy in that case.
uint32_t length;
PRUnichar* chars = UTF8ToNewUnicode(statusText, &length);
aStatusText.Adopt(chars, length);
}
} }
void void
@ -1286,10 +1277,10 @@ nsXMLHttpRequest::IsSafeHeader(const nsACString& header, nsIHttpChannel* httpCha
return isSafe; return isSafe;
} }
/* DOMString getAllResponseHeaders(); */ /* ByteString getAllResponseHeaders(); */
IMPL_STRING_GETTER(GetAllResponseHeaders) IMPL_CSTRING_GETTER(GetAllResponseHeaders)
void void
nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders) nsXMLHttpRequest::GetAllResponseHeaders(nsCString& aResponseHeaders)
{ {
aResponseHeaders.Truncate(); aResponseHeaders.Truncate();
@ -1303,7 +1294,7 @@ nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders)
if (nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel()) { if (nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel()) {
nsRefPtr<nsHeaderVisitor> visitor = new nsHeaderVisitor(this, httpChannel); nsRefPtr<nsHeaderVisitor> visitor = new nsHeaderVisitor(this, httpChannel);
if (NS_SUCCEEDED(httpChannel->VisitResponseHeaders(visitor))) { if (NS_SUCCEEDED(httpChannel->VisitResponseHeaders(visitor))) {
CopyASCIItoUTF16(visitor->Headers(), aResponseHeaders); aResponseHeaders = visitor->Headers();
} }
return; return;
} }
@ -1316,10 +1307,10 @@ nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders)
nsAutoCString value; nsAutoCString value;
if (NS_SUCCEEDED(mChannel->GetContentType(value))) { if (NS_SUCCEEDED(mChannel->GetContentType(value))) {
aResponseHeaders.AppendLiteral("Content-Type: "); aResponseHeaders.AppendLiteral("Content-Type: ");
AppendASCIItoUTF16(value, aResponseHeaders); aResponseHeaders.Append(value);
if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) && !value.IsEmpty()) { if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) && !value.IsEmpty()) {
aResponseHeaders.AppendLiteral(";charset="); aResponseHeaders.AppendLiteral(";charset=");
AppendASCIItoUTF16(value, aResponseHeaders); aResponseHeaders.Append(value);
} }
aResponseHeaders.AppendLiteral("\r\n"); aResponseHeaders.AppendLiteral("\r\n");
} }
@ -2950,7 +2941,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
return rv; return rv;
} }
/* void setRequestHeader (in AUTF8String header, in AUTF8String value); */ /* void setRequestHeader (in ByteString header, in ByteString value); */
// http://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-setrequestheader // http://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html#dom-xmlhttprequest-setrequestheader
NS_IMETHODIMP NS_IMETHODIMP
nsXMLHttpRequest::SetRequestHeader(const nsACString& header, nsXMLHttpRequest::SetRequestHeader(const nsACString& header,

View File

@ -242,19 +242,18 @@ public:
uint16_t ReadyState(); uint16_t ReadyState();
// request // request
void Open(const nsAString& aMethod, const nsAString& aUrl, bool aAsync, void Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
const mozilla::dom::Optional<nsAString>& aUser, const mozilla::dom::Optional<nsAString>& aUser,
const mozilla::dom::Optional<nsAString>& aPassword, const mozilla::dom::Optional<nsAString>& aPassword,
ErrorResult& aRv) ErrorResult& aRv)
{ {
aRv = Open(NS_ConvertUTF16toUTF8(aMethod), NS_ConvertUTF16toUTF8(aUrl), aRv = Open(aMethod, NS_ConvertUTF16toUTF8(aUrl),
aAsync, aUser, aPassword); aAsync, aUser, aPassword);
} }
void SetRequestHeader(const nsAString& aHeader, const nsAString& aValue, void SetRequestHeader(const nsACString& aHeader, const nsACString& aValue,
ErrorResult& aRv) ErrorResult& aRv)
{ {
aRv = SetRequestHeader(NS_ConvertUTF16toUTF8(aHeader), aRv = SetRequestHeader(aHeader, aValue);
NS_ConvertUTF16toUTF8(aValue));
} }
uint32_t Timeout() uint32_t Timeout()
{ {
@ -400,7 +399,7 @@ public:
// response // response
uint32_t Status(); uint32_t Status();
void GetStatusText(nsString& aStatusText); void GetStatusText(nsCString& aStatusText);
void GetResponseHeader(const nsACString& aHeader, nsACString& aResult, void GetResponseHeader(const nsACString& aHeader, nsACString& aResult,
ErrorResult& aRv); ErrorResult& aRv);
void GetResponseHeader(const nsAString& aHeader, nsString& aResult, void GetResponseHeader(const nsAString& aHeader, nsString& aResult,
@ -416,7 +415,7 @@ public:
CopyASCIItoUTF16(result, aResult); CopyASCIItoUTF16(result, aResult);
} }
} }
void GetAllResponseHeaders(nsString& aResponseHeaders); void GetAllResponseHeaders(nsCString& aResponseHeaders);
bool IsSafeHeader(const nsACString& aHeaderName, nsIHttpChannel* aHttpChannel); bool IsSafeHeader(const nsACString& aHeaderName, nsIHttpChannel* aHttpChannel);
void OverrideMimeType(const nsAString& aMimeType) void OverrideMimeType(const nsAString& aMimeType)
{ {

View File

@ -2,6 +2,7 @@
<html> <html>
<!-- <!--
https://bugzilla.mozilla.org/show_bug.cgi?id=638112 https://bugzilla.mozilla.org/show_bug.cgi?id=638112
https://bugzilla.mozilla.org/show_bug.cgi?id=796850
--> -->
<head> <head>
<title>Test for Bug 638112</title> <title>Test for Bug 638112</title>
@ -10,15 +11,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=638112
</head> </head>
<body> <body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=638112">Mozilla Bug 638112</a> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=638112">Mozilla Bug 638112</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=796850">Mozilla Bug 796850</a>
<p id="display"></p> <p id="display"></p>
<div id="content" style="display: none"> <div id="content" style="display: none">
</div> </div>
<pre id="test"> <pre id="test">
<script type="text/javascript"> <script type="text/javascript">
SimpleTest.expectAssertions(1); /** Test for Bug 638112, revised for Bug 796850 **/
/** Test for Bug 638112 **/ /* Bug 796850 changed the type of statusText to ByteString. As a result it is
* now considered to be raw 8 bit encoded rather than UTF8.
*/
function run_test() { function run_test() {
var req = new XMLHttpRequest(); var req = new XMLHttpRequest();
@ -26,7 +30,7 @@ function run_test() {
req.send(null); req.send(null);
var statusText = req.statusText; var statusText = req.statusText;
is(statusText, "Information Sans-Autorit", ""); is(statusText, "Information Sans-Autorit\u00E9", "");
SimpleTest.finish(); SimpleTest.finish();
} }

View File

@ -114,7 +114,8 @@ HTMLTrackElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aScope)
bool bool
HTMLTrackElement::IsWebVTTEnabled() HTMLTrackElement::IsWebVTTEnabled()
{ {
return HTMLTrackElementBinding::PrefEnabled(); // Our callee does not use its arguments.
return HTMLTrackElementBinding::ConstructorEnabled(nullptr, JS::NullPtr());
} }
TextTrack* TextTrack*

View File

@ -24,10 +24,5 @@ DISABLED_EXTRA_COMPONENTS = \
Activities.manifest \ Activities.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
ActivitiesService.jsm \
ActivitiesServiceFilter.jsm \
$(NULL)
include $(topsrcdir)/config/config.mk include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -21,3 +21,8 @@ EXTRA_COMPONENTS += [
'ActivityRequestHandler.js', 'ActivityRequestHandler.js',
'ActivityWrapper.js', 'ActivityWrapper.js',
] ]
EXTRA_JS_MODULES += [
'ActivitiesService.jsm',
'ActivitiesServiceFilter.jsm',
]

View File

@ -21,11 +21,6 @@ DISABLED_EXTRA_COMPONENTS = \
AlarmsManager.manifest \ AlarmsManager.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
AlarmDB.jsm \
AlarmService.jsm \
$(NULL)
include $(topsrcdir)/config/config.mk include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -31,3 +31,8 @@ EXTRA_COMPONENTS += [
'AlarmsManager.js', 'AlarmsManager.js',
'AlarmsManager.manifest', 'AlarmsManager.manifest',
] ]
EXTRA_JS_MODULES += [
'AlarmDB.jsm',
'AlarmService.jsm',
]

View File

@ -24,13 +24,4 @@ EXTRA_PP_JS_MODULES += \
AppsUtils.jsm \ AppsUtils.jsm \
$(NULL) $(NULL)
EXTRA_JS_MODULES += \
AppsServiceChild.jsm \
OfflineCacheInstaller.jsm \
PermissionsInstaller.jsm \
PermissionsTable.jsm \
FreeSpaceWatcher.jsm \
AppDownloadManager.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -9,3 +9,12 @@ EXTRA_COMPONENTS += [
'AppsService.manifest', 'AppsService.manifest',
'Webapps.manifest', 'Webapps.manifest',
] ]
EXTRA_JS_MODULES += [
'AppDownloadManager.jsm',
'AppsServiceChild.jsm',
'FreeSpaceWatcher.jsm',
'OfflineCacheInstaller.jsm',
'PermissionsInstaller.jsm',
'PermissionsTable.jsm',
]

View File

@ -22,15 +22,6 @@ DISABLED_EXTRA_COMPONENTS = \
ConsoleAPI.manifest \ ConsoleAPI.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = ConsoleAPIStorage.jsm \
$(NULL)
EXTRA_JS_MODULES += \
DOMRequestHelper.jsm \
IndexedDBHelper.jsm \
ObjectWrapper.jsm \
$(NULL)
include $(topsrcdir)/dom/dom-config.mk include $(topsrcdir)/dom/dom-config.mk
ifdef MOZ_JSDEBUGGER ifdef MOZ_JSDEBUGGER

View File

@ -103,3 +103,10 @@ EXTRA_COMPONENTS += [
'SiteSpecificUserAgent.js', 'SiteSpecificUserAgent.js',
'SiteSpecificUserAgent.manifest', 'SiteSpecificUserAgent.manifest',
] ]
EXTRA_JS_MODULES += [
'ConsoleAPIStorage.jsm',
'DOMRequestHelper.jsm',
'IndexedDBHelper.jsm',
'ObjectWrapper.jsm',
]

View File

@ -3934,7 +3934,8 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx,
} }
static bool static bool
ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin) OldBindingConstructorEnabled(const nsGlobalNameStruct *aStruct,
nsGlobalWindow *aWin)
{ {
MOZ_ASSERT(aStruct->mType == nsGlobalNameStruct::eTypeClassConstructor || MOZ_ASSERT(aStruct->mType == nsGlobalNameStruct::eTypeClassConstructor ||
aStruct->mType == nsGlobalNameStruct::eTypeExternalClassInfo); aStruct->mType == nsGlobalNameStruct::eTypeExternalClassInfo);
@ -3998,11 +3999,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
name_struct->mDefineDOMInterface; name_struct->mDefineDOMInterface;
if (define) { if (define) {
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor && if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor &&
!ConstructorEnabled(name_struct, aWin)) { !OldBindingConstructorEnabled(name_struct, aWin)) {
return NS_OK;
}
if (name_struct->mPrefEnabled && !(*name_struct->mPrefEnabled)()) {
return NS_OK; return NS_OK;
} }
@ -4019,6 +4016,14 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
global = obj; global = obj;
} }
// Check whether our constructor is enabled after we unwrap Xrays, since
// we don't want to define an interface on the Xray if it's disabled in
// the target global, even if it's enabled in the Xray's global.
if (name_struct->mConstructorEnabled &&
!(*name_struct->mConstructorEnabled)(cx, global)) {
return NS_OK;
}
bool enabled; bool enabled;
JS::Rooted<JSObject*> interfaceObject(cx, define(cx, global, id, &enabled)); JS::Rooted<JSObject*> interfaceObject(cx, define(cx, global, id, &enabled));
if (enabled) { if (enabled) {
@ -4081,7 +4086,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor || if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor ||
name_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) { name_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) {
if (!ConstructorEnabled(name_struct, aWin)) { if (!OldBindingConstructorEnabled(name_struct, aWin)) {
return NS_OK; return NS_OK;
} }
@ -4888,16 +4893,21 @@ nsNavigatorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
mozilla::dom::ConstructNavigatorProperty construct = name_struct->mConstructNavigatorProperty; mozilla::dom::ConstructNavigatorProperty construct = name_struct->mConstructNavigatorProperty;
MOZ_ASSERT(construct); MOZ_ASSERT(construct);
if (name_struct->mPrefEnabled && !(*name_struct->mPrefEnabled)()) {
return NS_OK;
}
JS::Rooted<JSObject*> naviObj(cx, js::CheckedUnwrap(obj, /* stopAtOuter = */ false)); JS::Rooted<JSObject*> naviObj(cx, js::CheckedUnwrap(obj, /* stopAtOuter = */ false));
NS_ENSURE_TRUE(naviObj, NS_ERROR_DOM_SECURITY_ERR); NS_ENSURE_TRUE(naviObj, NS_ERROR_DOM_SECURITY_ERR);
JS::Rooted<JSObject*> domObject(cx); JS::Rooted<JSObject*> domObject(cx);
{ {
JSAutoCompartment ac(cx, naviObj); JSAutoCompartment ac(cx, naviObj);
// Check whether our constructor is enabled after we unwrap Xrays, since
// we don't want to define an interface on the Xray if it's disabled in
// the target global, even if it's enabled in the Xray's global.
if (name_struct->mConstructorEnabled &&
!(*name_struct->mConstructorEnabled)(cx, naviObj)) {
return NS_OK;
}
domObject = construct(cx, naviObj); domObject = construct(cx, naviObj);
if (!domObject) { if (!domObject) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

View File

@ -825,7 +825,7 @@ nsScriptNameSpaceManager::Observe(nsISupports* aSubject, const char* aTopic,
void void
nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName, nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName,
mozilla::dom::DefineInterface aDefineDOMInterface, mozilla::dom::DefineInterface aDefineDOMInterface,
mozilla::dom::PrefEnabled aPrefEnabled) mozilla::dom::ConstructorEnabled* aConstructorEnabled)
{ {
nsGlobalNameStruct *s = AddToHash(&mGlobalNames, &aName); nsGlobalNameStruct *s = AddToHash(&mGlobalNames, &aName);
if (s) { if (s) {
@ -833,7 +833,7 @@ nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName,
s->mType = nsGlobalNameStruct::eTypeNewDOMBinding; s->mType = nsGlobalNameStruct::eTypeNewDOMBinding;
} }
s->mDefineDOMInterface = aDefineDOMInterface; s->mDefineDOMInterface = aDefineDOMInterface;
s->mPrefEnabled = aPrefEnabled; s->mConstructorEnabled = aConstructorEnabled;
} }
} }
@ -841,7 +841,7 @@ void
nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor( nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor(
const nsAFlatString& aName, const nsAFlatString& aName,
mozilla::dom::ConstructNavigatorProperty aNavConstructor, mozilla::dom::ConstructNavigatorProperty aNavConstructor,
mozilla::dom::PrefEnabled aPrefEnabled) mozilla::dom::ConstructorEnabled* aConstructorEnabled)
{ {
nsGlobalNameStruct *s = AddToHash(&mNavigatorNames, &aName); nsGlobalNameStruct *s = AddToHash(&mNavigatorNames, &aName);
if (s) { if (s) {
@ -849,7 +849,7 @@ nsScriptNameSpaceManager::RegisterNavigatorDOMConstructor(
s->mType = nsGlobalNameStruct::eTypeNewDOMBinding; s->mType = nsGlobalNameStruct::eTypeNewDOMBinding;
} }
s->mConstructNavigatorProperty = aNavConstructor; s->mConstructNavigatorProperty = aNavConstructor;
s->mPrefEnabled = aPrefEnabled; s->mConstructorEnabled = aConstructorEnabled;
} }
} }

View File

@ -55,6 +55,9 @@ struct nsGlobalNameStruct
eTypeExternalConstructorAlias eTypeExternalConstructorAlias
} mType; } mType;
// mChromeOnly is only used for structs that define non-WebIDL things
// (possibly in addition to WebIDL ones). In particular, it's not even
// initialized for eTypeNewDOMBinding structs.
bool mChromeOnly; bool mChromeOnly;
bool mDisabled; bool mDisabled;
@ -71,7 +74,8 @@ struct nsGlobalNameStruct
mozilla::dom::DefineInterface mDefineDOMInterface; // for window mozilla::dom::DefineInterface mDefineDOMInterface; // for window
mozilla::dom::ConstructNavigatorProperty mConstructNavigatorProperty; // for navigator mozilla::dom::ConstructNavigatorProperty mConstructNavigatorProperty; // for navigator
}; };
mozilla::dom::PrefEnabled mPrefEnabled; // May be null if not pref controlled // May be null if enabled unconditionally
mozilla::dom::ConstructorEnabled* mConstructorEnabled;
}; };
@ -140,11 +144,11 @@ public:
void RegisterDefineDOMInterface(const nsAFlatString& aName, void RegisterDefineDOMInterface(const nsAFlatString& aName,
mozilla::dom::DefineInterface aDefineDOMInterface, mozilla::dom::DefineInterface aDefineDOMInterface,
mozilla::dom::PrefEnabled aPrefEnabled); mozilla::dom::ConstructorEnabled* aConstructorEnabled);
void RegisterNavigatorDOMConstructor(const nsAFlatString& aName, void RegisterNavigatorDOMConstructor(const nsAFlatString& aName,
mozilla::dom::ConstructNavigatorProperty aNavConstructor, mozilla::dom::ConstructNavigatorProperty aNavConstructor,
mozilla::dom::PrefEnabled aPrefEnabled); mozilla::dom::ConstructorEnabled* aConstructorEnabled);
typedef PLDHashOperator typedef PLDHashOperator
(* GlobalNameEnumerator)(const nsAString& aGlobalName, void* aClosure); (* GlobalNameEnumerator)(const nsAString& aGlobalName, void* aClosure);

View File

@ -7,8 +7,10 @@
#include <algorithm> #include <algorithm>
#include <stdarg.h> #include <stdarg.h>
#include "prprf.h"
#include "mozilla/DebugOnly.h" #include "mozilla/DebugOnly.h"
#include "mozilla/FloatingPoint.h" #include "mozilla/FloatingPoint.h"
#include "mozilla/Assertions.h"
#include "BindingUtils.h" #include "BindingUtils.h"
@ -1899,5 +1901,83 @@ ConstructJSImplementation(JSContext* aCx, const char* aContractId,
return window.forget(); return window.forget();
} }
bool
NonVoidByteStringToJsval(JSContext *cx, const nsACString &str,
JS::MutableHandle<JS::Value> rval)
{
if (str.IsEmpty()) {
rval.set(JS_GetEmptyStringValue(cx));
return true;
}
// ByteStrings are not UTF-8 encoded.
JSString* jsStr = JS_NewStringCopyN(cx, str.Data(), str.Length());
if (!jsStr)
return false;
rval.setString(jsStr);
return true;
}
bool
ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
JS::MutableHandle<JS::Value> pval, bool nullable,
nsACString& result)
{
JSString *s;
if (v.isString()) {
s = v.toString();
} else {
if (nullable && v.isNullOrUndefined()) {
result.SetIsVoid(true);
return true;
}
s = JS_ValueToString(cx, v);
if (!s) {
return false;
}
pval.set(JS::StringValue(s)); // Root the new string.
}
size_t length;
const jschar *chars = JS_GetStringCharsZAndLength(cx, s, &length);
if (!chars) {
return false;
}
// Conversion from Javascript string to ByteString is only valid if all
// characters < 256.
for (size_t i = 0; i < length; i++) {
if (chars[i] > 255) {
// The largest unsigned 64 bit number (18,446,744,073,709,551,615) has
// 20 digits, plus one more for the null terminator.
char index[21];
MOZ_STATIC_ASSERT(sizeof(size_t) <= 8, "index array too small");
PR_snprintf(index, sizeof(index), "%d", i);
// A jschar is 16 bits long. The biggest unsigned 16 bit
// number (65,535) has 5 digits, plus one more for the null
// terminator.
char badChar[6];
MOZ_STATIC_ASSERT(sizeof(jschar) <= 2, "badChar array too small");
PR_snprintf(badChar, sizeof(badChar), "%d", chars[i]);
ThrowErrorMessage(cx, MSG_INVALID_BYTESTRING, index, badChar);
return false;
}
}
if (length >= UINT32_MAX) {
return false;
}
result.SetCapacity(length+1);
JS_EncodeStringToBuffer(cx, s, result.BeginWriting(), length);
result.BeginWriting()[length] = '\0';
result.SetLength(length);
return true;
}
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

View File

@ -1582,6 +1582,11 @@ ConvertJSValueToString(JSContext* cx, JS::Handle<JS::Value> v,
return true; return true;
} }
bool
ConvertJSValueToByteString(JSContext* cx, JS::Handle<JS::Value> v,
JS::MutableHandle<JS::Value> pval, bool nullable,
nsACString& result);
// Class for holding the type of members of a union. The union type has an enum // Class for holding the type of members of a union. The union type has an enum
// to keep track of which of its UnionMembers has been constructed. // to keep track of which of its UnionMembers has been constructed.
template<class T> template<class T>
@ -2057,6 +2062,24 @@ bool
RegisterForDeferredFinalization(DeferredFinalizeStartFunction start, RegisterForDeferredFinalization(DeferredFinalizeStartFunction start,
DeferredFinalizeFunction run); DeferredFinalizeFunction run);
/**
* Convert an nsCString to jsval, returning true on success.
* These functions are intended for ByteString implementations.
* As such, the string is not UTF-8 encoded. Any UTF8 strings passed to these
* methods will be mangled.
*/
bool NonVoidByteStringToJsval(JSContext *cx, const nsACString &str,
JS::MutableHandle<JS::Value> rval);
inline bool ByteStringToJsval(JSContext *cx, const nsACString &str,
JS::MutableHandle<JS::Value> rval)
{
if (str.IsVoid()) {
rval.setNull();
return true;
}
return NonVoidByteStringToJsval(cx, str, rval);
}
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

View File

@ -1978,7 +1978,11 @@ class CGPrefEnabledNative(CGAbstractMethod):
if the method returns true. if the method returns true.
""" """
def __init__(self, descriptor): def __init__(self, descriptor):
CGAbstractMethod.__init__(self, descriptor, 'PrefEnabled', 'bool', []) CGAbstractMethod.__init__(self, descriptor,
'ConstructorEnabled', 'bool',
[Argument("JSContext*", "/* unused */"),
Argument("JS::Handle<JSObject*>",
"/* unused */")])
def definition_body(self): def definition_body(self):
return " return %s::PrefEnabled();" % self.descriptor.nativeType return " return %s::PrefEnabled();" % self.descriptor.nativeType
@ -1991,13 +1995,33 @@ class CGPrefEnabled(CGAbstractMethod):
on the global if the pref is true. on the global if the pref is true.
""" """
def __init__(self, descriptor): def __init__(self, descriptor):
CGAbstractMethod.__init__(self, descriptor, 'PrefEnabled', 'bool', []) CGAbstractMethod.__init__(self, descriptor,
'ConstructorEnabled', 'bool',
[Argument("JSContext*", "/* unused */"),
Argument("JS::Handle<JSObject*>",
"/* unused */")])
def definition_body(self): def definition_body(self):
pref = self.descriptor.interface.getExtendedAttribute("Pref") pref = self.descriptor.interface.getExtendedAttribute("Pref")
assert isinstance(pref, list) and len(pref) == 1 assert isinstance(pref, list) and len(pref) == 1
return " return Preferences::GetBool(\"%s\");" % pref[0] return " return Preferences::GetBool(\"%s\");" % pref[0]
class CGConstructorEnabledChromeOnly(CGAbstractMethod):
"""
A method for testing whether the object we're going to be defined
on is chrome so we can decide whether our constructor should be
enabled.
"""
def __init__(self, descriptor):
assert descriptor.interface.getExtendedAttribute("ChromeOnly")
CGAbstractMethod.__init__(self, descriptor,
'ConstructorEnabled', 'bool',
[Argument("JSContext*", "aCx"),
Argument("JS::Handle<JSObject*>", "aObj")])
def definition_body(self):
return " return %s;" % GetAccessCheck(self.descriptor, "aObj")
class CGIsMethod(CGAbstractMethod): class CGIsMethod(CGAbstractMethod):
def __init__(self, descriptor): def __init__(self, descriptor):
args = [Argument('JSObject*', 'obj')] args = [Argument('JSObject*', 'obj')]
@ -3189,7 +3213,7 @@ for (uint32_t i = 0; i < length; ++i) {
declType=CGGeneric(declType), declType=CGGeneric(declType),
holderType=holderType) holderType=holderType)
if type.isString(): if type.isDOMString():
assert not isEnforceRange and not isClamp assert not isEnforceRange and not isClamp
treatAs = { treatAs = {
@ -3255,6 +3279,24 @@ for (uint32_t i = 0; i < length; ++i) {
declType=CGGeneric(declType), declType=CGGeneric(declType),
holderType=CGGeneric("FakeDependentString")) holderType=CGGeneric("FakeDependentString"))
if type.isByteString():
assert not isEnforceRange and not isClamp
nullable = toStringBool(type.nullable())
conversionCode = (
"if (!ConvertJSValueToByteString(cx, ${val}, ${mutableVal},"
" %s, ${declName})) {\n"
"%s\n"
"}" % (nullable, exceptionCodeIndented.define()))
# ByteString arguments cannot have a default value.
assert defaultValue is None
return JSToNativeConversionInfo(
conversionCode,
declType=CGGeneric("nsCString"),
dealWithOptional=isOptional)
if type.isEnum(): if type.isEnum():
assert not isEnforceRange and not isClamp assert not isEnforceRange and not isClamp
@ -3958,12 +4000,18 @@ if (!returnArray) {
wrappingCode += wrapAndSetPtr(wrap, failed) wrappingCode += wrapAndSetPtr(wrap, failed)
return (wrappingCode, False) return (wrappingCode, False)
if type.isString(): if type.isDOMString():
if type.nullable(): if type.nullable():
return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalRef}.address())" % result), False) return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalRef}.address())" % result), False)
else: else:
return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalRef}.address())" % result), False) return (wrapAndSetPtr("xpc::NonVoidStringToJsval(cx, %s, ${jsvalRef}.address())" % result), False)
if type.isByteString():
if type.nullable():
return (wrapAndSetPtr("ByteStringToJsval(cx, %s, ${jsvalHandle})" % result), False)
else:
return (wrapAndSetPtr("NonVoidByteStringToJsval(cx, %s, ${jsvalHandle})" % result), False)
if type.isEnum(): if type.isEnum():
if type.nullable(): if type.nullable():
resultLoc = "%s.Value()" % result resultLoc = "%s.Value()" % result
@ -4179,10 +4227,12 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
if returnType.nullable(): if returnType.nullable():
result = CGTemplatedType("Nullable", result) result = CGTemplatedType("Nullable", result)
return result, False, None, None return result, False, None, None
if returnType.isString(): if returnType.isDOMString():
if isMember: if isMember:
return CGGeneric("nsString"), True, None, None return CGGeneric("nsString"), True, None, None
return CGGeneric("DOMString"), True, None, None return CGGeneric("DOMString"), True, None, None
if returnType.isByteString():
return CGGeneric("nsCString"), True, None, None
if returnType.isEnum(): if returnType.isEnum():
result = CGGeneric(returnType.unroll().inner.identifier.name) result = CGGeneric(returnType.unroll().inner.identifier.name)
if returnType.nullable(): if returnType.nullable():
@ -5655,9 +5705,12 @@ def getUnionAccessorSignatureType(type, descriptorProvider):
typeName = CGWrapper(typeName, post="&") typeName = CGWrapper(typeName, post="&")
return typeName return typeName
if type.isString(): if type.isDOMString():
return CGGeneric("const nsAString&") return CGGeneric("const nsAString&")
if type.isByteString():
return CGGeneric("const nsCString&")
if type.isEnum(): if type.isEnum():
if type.nullable(): if type.nullable():
raise TypeError("We don't support nullable enumerated arguments or " raise TypeError("We don't support nullable enumerated arguments or "
@ -7510,10 +7563,20 @@ class CGDescriptor(CGThing):
not descriptor.interface.isExternal() and not descriptor.interface.isExternal() and
# Workers stuff is never pref-controlled # Workers stuff is never pref-controlled
not descriptor.workers): not descriptor.workers):
if descriptor.interface.getExtendedAttribute("PrefControlled") is not None: prefControlled = descriptor.interface.getExtendedAttribute("PrefControlled")
havePref = descriptor.interface.getExtendedAttribute("Pref")
haveChromeOnly = descriptor.interface.getExtendedAttribute("ChromeOnly")
# Make sure at most one of those is set
if bool(prefControlled) + bool(havePref) + bool(haveChromeOnly) > 1:
raise TypeError("Interface %s has more than one of "
"'PrefControlled', 'Pref', and 'ChomeOnly' "
"specified", descriptor.name)
if prefControlled is not None:
cgThings.append(CGPrefEnabledNative(descriptor)) cgThings.append(CGPrefEnabledNative(descriptor))
elif descriptor.interface.getExtendedAttribute("Pref") is not None: elif havePref is not None:
cgThings.append(CGPrefEnabled(descriptor)) cgThings.append(CGPrefEnabled(descriptor))
elif haveChromeOnly is not None:
cgThings.append(CGConstructorEnabledChromeOnly(descriptor))
if descriptor.concrete: if descriptor.concrete:
if descriptor.proxy: if descriptor.proxy:
@ -8027,12 +8090,12 @@ class CGRegisterProtos(CGAbstractMethod):
def _defineMacro(self): def _defineMacro(self):
return """ return """
#define REGISTER_PROTO(_dom_class, _pref_check) \\ #define REGISTER_PROTO(_dom_class, _ctor_check) \\
aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _pref_check); aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _ctor_check);
#define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _pref_check) \\ #define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _ctor_check) \\
aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _pref_check); aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _ctor_check);
#define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _pref_check) \\ #define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _ctor_check) \\
aNameSpaceManager->RegisterNavigatorDOMConstructor(NS_LITERAL_STRING(_prop), _dom_class##Binding::ConstructNavigatorObject, _pref_check); aNameSpaceManager->RegisterNavigatorDOMConstructor(NS_LITERAL_STRING(_prop), _dom_class##Binding::ConstructNavigatorObject, _ctor_check);
""" """
def _undefineMacro(self): def _undefineMacro(self):
@ -8041,23 +8104,24 @@ class CGRegisterProtos(CGAbstractMethod):
#undef REGISTER_PROTO #undef REGISTER_PROTO
#undef REGISTER_NAVIGATOR_CONSTRUCTOR""" #undef REGISTER_NAVIGATOR_CONSTRUCTOR"""
def _registerProtos(self): def _registerProtos(self):
def getPrefCheck(desc): def getCheck(desc):
if (desc.interface.getExtendedAttribute("PrefControlled") is None and if (desc.interface.getExtendedAttribute("PrefControlled") is None and
desc.interface.getExtendedAttribute("Pref") is None): desc.interface.getExtendedAttribute("Pref") is None and
desc.interface.getExtendedAttribute("ChromeOnly") is None):
return "nullptr" return "nullptr"
return "%sBinding::PrefEnabled" % desc.name return "%sBinding::ConstructorEnabled" % desc.name
lines = [] lines = []
for desc in self.config.getDescriptors(hasInterfaceObject=True, for desc in self.config.getDescriptors(hasInterfaceObject=True,
isExternal=False, isExternal=False,
workers=False, workers=False,
register=True): register=True):
lines.append("REGISTER_PROTO(%s, %s);" % (desc.name, getPrefCheck(desc))) lines.append("REGISTER_PROTO(%s, %s);" % (desc.name, getCheck(desc)))
lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);" % (n.identifier.name, desc.name, getPrefCheck(desc)) lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);" % (n.identifier.name, desc.name, getCheck(desc))
for n in desc.interface.namedConstructors) for n in desc.interface.namedConstructors)
for desc in self.config.getDescriptors(isNavigatorProperty=True, register=True): for desc in self.config.getDescriptors(isNavigatorProperty=True, register=True):
propName = desc.interface.getNavigatorProperty() propName = desc.interface.getNavigatorProperty()
assert propName assert propName
lines.append('REGISTER_NAVIGATOR_CONSTRUCTOR("%s", %s, %s);' % (propName, desc.name, getPrefCheck(desc))) lines.append('REGISTER_NAVIGATOR_CONSTRUCTOR("%s", %s, %s);' % (propName, desc.name, getCheck(desc)))
return '\n'.join(lines) + '\n' return '\n'.join(lines) + '\n'
def definition_body(self): def definition_body(self):
return self._defineMacro() + self._registerProtos() + self._undefineMacro() return self._defineMacro() + self._registerProtos() + self._undefineMacro()
@ -8448,12 +8512,18 @@ class CGNativeMember(ClassMethod):
return (result.define(), return (result.define(),
"%s(%s)" % (result.define(), defaultReturnArg), "%s(%s)" % (result.define(), defaultReturnArg),
"return ${declName};") "return ${declName};")
if type.isString(): if type.isDOMString():
if isMember: if isMember:
# No need for a third element in the isMember case # No need for a third element in the isMember case
return "nsString", None, None return "nsString", None, None
# Outparam # Outparam
return "void", "", "retval = ${declName};" return "void", "", "retval = ${declName};"
if type.isByteString():
if isMember:
# No need for a third element in the isMember case
return "nsCString", None, None
# Outparam
return "void", "", "retval = ${declName};"
if type.isEnum(): if type.isEnum():
enumName = type.unroll().inner.identifier.name enumName = type.unroll().inner.identifier.name
if type.nullable(): if type.nullable():
@ -8532,8 +8602,10 @@ class CGNativeMember(ClassMethod):
def getArgs(self, returnType, argList): def getArgs(self, returnType, argList):
args = [self.getArg(arg) for arg in argList] args = [self.getArg(arg) for arg in argList]
# Now the outparams # Now the outparams
if returnType.isString(): if returnType.isDOMString():
args.append(Argument("nsString&", "retval")) args.append(Argument("nsString&", "retval"))
if returnType.isByteString():
args.append(Argument("nsCString&", "retval"))
elif returnType.isSequence(): elif returnType.isSequence():
nullable = returnType.nullable() nullable = returnType.nullable()
if nullable: if nullable:
@ -8627,13 +8699,17 @@ class CGNativeMember(ClassMethod):
typeDecl = typeDecl % type.name typeDecl = typeDecl % type.name
return typeDecl, False, False return typeDecl, False, False
if type.isString(): if type.isDOMString():
if isMember: if isMember:
declType = "nsString" declType = "nsString"
else: else:
declType = "nsAString" declType = "nsAString"
return declType, True, False return declType, True, False
if type.isByteString():
declType = "nsCString"
return declType, True, False
if type.isEnum(): if type.isEnum():
return type.unroll().inner.identifier.name, False, True return type.unroll().inner.identifier.name, False, True
@ -9500,7 +9576,7 @@ class CallbackMember(CGNativeMember):
jsvalIndex = "%d" % i jsvalIndex = "%d" % i
if arg.optional and not arg.defaultValue: if arg.optional and not arg.defaultValue:
argval += ".Value()" argval += ".Value()"
if arg.type.isString(): if arg.type.isDOMString():
# XPConnect string-to-JS conversion wants to mutate the string. So # XPConnect string-to-JS conversion wants to mutate the string. So
# let's give it a string it can mutate # let's give it a string it can mutate
# XXXbz if we try to do a sequence of strings, this will kinda fail. # XXXbz if we try to do a sequence of strings, this will kinda fail.

View File

@ -37,4 +37,6 @@ MSG_DEF(MSG_ENCODING_NOT_SUPPORTED, 1, "The given encoding '{0}' is not supporte
MSG_DEF(MSG_DOM_ENCODING_NOT_UTF, 0, "The encoding must be utf-8, utf-16, or utf-16be.") MSG_DEF(MSG_DOM_ENCODING_NOT_UTF, 0, "The encoding must be utf-8, utf-16, or utf-16be.")
MSG_DEF(MSG_NOT_FINITE, 0, "Floating-point value is not finite.") MSG_DEF(MSG_NOT_FINITE, 0, "Floating-point value is not finite.")
MSG_DEF(MSG_INVALID_VERSION, 0, "0 (Zero) is not a valid database version.") MSG_DEF(MSG_INVALID_VERSION, 0, "0 (Zero) is not a valid database version.")
MSG_DEF(MSG_INVALID_BYTESTRING, 2, "Cannot convert string to ByteString because the character"
" at index {0} has value {1} which is greater than 255.")
MSG_DEF(MSG_NOT_DATE, 0, "Value is not a date.") MSG_DEF(MSG_NOT_DATE, 0, "Value is not a date.")

View File

@ -384,7 +384,7 @@ class IDLObjectWithIdentifier(IDLObject):
identifier = attr.identifier() identifier = attr.identifier()
value = attr.value() value = attr.value()
if identifier == "TreatNullAs": if identifier == "TreatNullAs":
if not self.type.isString() or self.type.nullable(): if not self.type.isDOMString() or self.type.nullable():
raise WebIDLError("[TreatNullAs] is only allowed on " raise WebIDLError("[TreatNullAs] is only allowed on "
"arguments or attributes whose type is " "arguments or attributes whose type is "
"DOMString", "DOMString",
@ -407,7 +407,7 @@ class IDLObjectWithIdentifier(IDLObject):
"allowed on optional arguments", "allowed on optional arguments",
[self.location]) [self.location])
elif value == 'Null': elif value == 'Null':
if not self.type.isString(): if not self.type.isDOMString():
raise WebIDLError("[TreatUndefinedAs=Null] is only " raise WebIDLError("[TreatUndefinedAs=Null] is only "
"allowed on arguments or " "allowed on arguments or "
"attributes whose type is " "attributes whose type is "
@ -418,7 +418,7 @@ class IDLObjectWithIdentifier(IDLObject):
"allowed on arguments whose type " "allowed on arguments whose type "
"is DOMString?", [self.location]) "is DOMString?", [self.location])
elif value == 'EmptyString': elif value == 'EmptyString':
if not self.type.isString(): if not self.type.isDOMString():
raise WebIDLError("[TreatUndefinedAs=EmptyString] " raise WebIDLError("[TreatUndefinedAs=EmptyString] "
"is only allowed on arguments or " "is only allowed on arguments or "
"attributes whose type is " "attributes whose type is "
@ -508,7 +508,10 @@ class IDLInterface(IDLObjectWithScope):
self._callback = False self._callback = False
self._finished = False self._finished = False
self.members = [] self.members = []
self.namedConstructors = set() # namedConstructors needs deterministic ordering because bindings code
# outputs the constructs in the order that namedConstructors enumerates
# them.
self.namedConstructors = list()
self.implementedInterfaces = set() self.implementedInterfaces = set()
self._consequential = False self._consequential = False
self._isPartial = True self._isPartial = True
@ -903,7 +906,7 @@ class IDLInterface(IDLObjectWithScope):
# NamedConstructors. # NamedConstructors.
newMethod = self.parentScope.lookupIdentifier(method.identifier) newMethod = self.parentScope.lookupIdentifier(method.identifier)
if newMethod == method: if newMethod == method:
self.namedConstructors.add(method) self.namedConstructors.append(method)
elif not newMethod in self.namedConstructors: elif not newMethod in self.namedConstructors:
raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface", raise WebIDLError("NamedConstructor conflicts with a NamedConstructor of a different interface",
[method.location, newMethod.location]) [method.location, newMethod.location])
@ -913,7 +916,8 @@ class IDLInterface(IDLObjectWithScope):
identifier == "JSImplementation" or identifier == "JSImplementation" or
identifier == "HeaderFile" or identifier == "HeaderFile" or
identifier == "NavigatorProperty" or identifier == "NavigatorProperty" or
identifier == "OverrideBuiltins"): identifier == "OverrideBuiltins" or
identifier == "ChromeOnly"):
# Known attributes that we don't need to do anything with here # Known attributes that we don't need to do anything with here
pass pass
else: else:
@ -1213,6 +1217,7 @@ class IDLType(IDLObject):
# Other types # Other types
'any', 'any',
'domstring', 'domstring',
'bytestring',
'object', 'object',
'date', 'date',
'void', 'void',
@ -1252,6 +1257,12 @@ class IDLType(IDLObject):
def isString(self): def isString(self):
return False return False
def isByteString(self):
return False
def isDOMString(self):
return False
def isVoid(self): def isVoid(self):
return self.name == "Void" return self.name == "Void"
@ -1400,6 +1411,12 @@ class IDLNullableType(IDLType):
def isString(self): def isString(self):
return self.inner.isString() return self.inner.isString()
def isByteString(self):
return self.inner.isByteString()
def isDOMString(self):
return self.inner.isDOMString()
def isFloat(self): def isFloat(self):
return self.inner.isFloat() return self.inner.isFloat()
@ -1509,6 +1526,12 @@ class IDLSequenceType(IDLType):
def isString(self): def isString(self):
return False; return False;
def isByteString(self):
return False
def isDOMString(self):
return False
def isVoid(self): def isVoid(self):
return False return False
@ -1693,6 +1716,12 @@ class IDLArrayType(IDLType):
def isString(self): def isString(self):
return False return False
def isByteString(self):
return False
def isDOMString(self):
return False
def isVoid(self): def isVoid(self):
return False return False
@ -1776,6 +1805,12 @@ class IDLTypedefType(IDLType, IDLObjectWithIdentifier):
def isString(self): def isString(self):
return self.inner.isString() return self.inner.isString()
def isByteString(self):
return self.inner.isByteString()
def isDOMString(self):
return self.inner.isDOMString()
def isVoid(self): def isVoid(self):
return self.inner.isVoid() return self.inner.isVoid()
@ -1863,6 +1898,12 @@ class IDLWrapperType(IDLType):
def isString(self): def isString(self):
return False return False
def isByteString(self):
return False
def isDOMString(self):
return False
def isVoid(self): def isVoid(self):
return False return False
@ -1981,6 +2022,7 @@ class IDLBuiltinType(IDLType):
# Other types # Other types
'any', 'any',
'domstring', 'domstring',
'bytestring',
'object', 'object',
'date', 'date',
'void', 'void',
@ -2014,6 +2056,7 @@ class IDLBuiltinType(IDLType):
Types.double: IDLType.Tags.double, Types.double: IDLType.Tags.double,
Types.any: IDLType.Tags.any, Types.any: IDLType.Tags.any,
Types.domstring: IDLType.Tags.domstring, Types.domstring: IDLType.Tags.domstring,
Types.bytestring: IDLType.Tags.bytestring,
Types.object: IDLType.Tags.object, Types.object: IDLType.Tags.object,
Types.date: IDLType.Tags.date, Types.date: IDLType.Tags.date,
Types.void: IDLType.Tags.void, Types.void: IDLType.Tags.void,
@ -2039,6 +2082,13 @@ class IDLBuiltinType(IDLType):
return self._typeTag <= IDLBuiltinType.Types.double return self._typeTag <= IDLBuiltinType.Types.double
def isString(self): def isString(self):
return self._typeTag == IDLBuiltinType.Types.domstring or \
self._typeTag == IDLBuiltinType.Types.bytestring
def isByteString(self):
return self._typeTag == IDLBuiltinType.Types.bytestring
def isDOMString(self):
return self._typeTag == IDLBuiltinType.Types.domstring return self._typeTag == IDLBuiltinType.Types.domstring
def isInteger(self): def isInteger(self):
@ -2173,6 +2223,9 @@ BuiltinTypes = {
IDLBuiltinType.Types.domstring: IDLBuiltinType.Types.domstring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "String", IDLBuiltinType(BuiltinLocation("<builtin type>"), "String",
IDLBuiltinType.Types.domstring), IDLBuiltinType.Types.domstring),
IDLBuiltinType.Types.bytestring:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "ByteString",
IDLBuiltinType.Types.bytestring),
IDLBuiltinType.Types.object: IDLBuiltinType.Types.object:
IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object", IDLBuiltinType(BuiltinLocation("<builtin type>"), "Object",
IDLBuiltinType.Types.object), IDLBuiltinType.Types.object),
@ -3256,6 +3309,7 @@ class Tokenizer(object):
"::": "SCOPE", "::": "SCOPE",
"Date": "DATE", "Date": "DATE",
"DOMString": "DOMSTRING", "DOMString": "DOMSTRING",
"ByteString": "BYTESTRING",
"any": "ANY", "any": "ANY",
"boolean": "BOOLEAN", "boolean": "BOOLEAN",
"byte": "BYTE", "byte": "BYTE",
@ -3813,8 +3867,8 @@ class Parser(Tokenizer):
if len(arguments) != 0: if len(arguments) != 0:
raise WebIDLError("stringifier has wrong number of arguments", raise WebIDLError("stringifier has wrong number of arguments",
[self.getLocation(p, 2)]) [self.getLocation(p, 2)])
if not returnType.isString(): if not returnType.isDOMString():
raise WebIDLError("stringifier must have string return type", raise WebIDLError("stringifier must have DOMString return type",
[self.getLocation(p, 2)]) [self.getLocation(p, 2)])
inOptionalArguments = False inOptionalArguments = False
@ -4123,6 +4177,7 @@ class Parser(Tokenizer):
| QUESTIONMARK | QUESTIONMARK
| DATE | DATE
| DOMSTRING | DOMSTRING
| BYTESTRING
| ANY | ANY
| ATTRIBUTE | ATTRIBUTE
| BOOLEAN | BOOLEAN
@ -4358,6 +4413,12 @@ class Parser(Tokenizer):
""" """
p[0] = IDLBuiltinType.Types.domstring p[0] = IDLBuiltinType.Types.domstring
def p_PrimitiveOrStringTypeBytestring(self, p):
"""
PrimitiveOrStringType : BYTESTRING
"""
p[0] = IDLBuiltinType.Types.bytestring
def p_UnsignedIntegerTypeUnsigned(self, p): def p_UnsignedIntegerTypeUnsigned(self, p):
""" """
UnsignedIntegerType : UNSIGNED IntegerType UnsignedIntegerType : UNSIGNED IntegerType

View File

@ -0,0 +1,72 @@
# -*- coding: UTF-8 -*-
import WebIDL
def WebIDLTest(parser, harness):
parser.parse("""
interface TestByteString {
attribute ByteString bs;
attribute DOMString ds;
};
""")
results = parser.finish();
harness.ok(True, "TestByteString interface parsed without error.")
harness.check(len(results), 1, "Should be one production")
harness.ok(isinstance(results[0], WebIDL.IDLInterface),
"Should be an IDLInterface")
iface = results[0]
harness.check(iface.identifier.QName(), "::TestByteString", "Interface has the right QName")
harness.check(iface.identifier.name, "TestByteString", "Interface has the right name")
harness.check(iface.parent, None, "Interface has no parent")
members = iface.members
harness.check(len(members), 2, "Should be two productions")
attr = members[0]
harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
harness.check(attr.identifier.QName(), "::TestByteString::bs", "Attr has correct QName")
harness.check(attr.identifier.name, "bs", "Attr has correct name")
harness.check(str(attr.type), "ByteString", "Attr type is the correct name")
harness.ok(attr.type.isByteString(), "Should be ByteString type")
harness.ok(attr.type.isString(), "Should be String collective type")
harness.ok(not attr.type.isDOMString(), "Should be not be DOMString type")
# now check we haven't broken DOMStrings in the process.
attr = members[1]
harness.ok(isinstance(attr, WebIDL.IDLAttribute), "Should be an IDLAttribute")
harness.check(attr.identifier.QName(), "::TestByteString::ds", "Attr has correct QName")
harness.check(attr.identifier.name, "ds", "Attr has correct name")
harness.check(str(attr.type), "String", "Attr type is the correct name")
harness.ok(attr.type.isDOMString(), "Should be DOMString type")
harness.ok(attr.type.isString(), "Should be String collective type")
harness.ok(not attr.type.isByteString(), "Should be not be ByteString type")
# Cannot represent constant ByteString in IDL.
threw = False
try:
parser.parse("""
interface ConstByteString {
const ByteString foo = "hello"
};
""")
except WebIDL.WebIDLError:
threw = True
harness.ok(threw, "Should have thrown a WebIDL error")
# Cannot have optional ByteStrings with default values
threw = False
try:
parser.parse("""
interface OptionalByteString {
void passByteString(optional ByteString arg = "hello");
};
""")
results2 = parser.finish();
except WebIDL.WebIDLError:
threw = True
harness.ok(threw, "Should have thrown a WebIDL error")

View File

@ -62,6 +62,7 @@ def WebIDLTest(parser, harness):
"byte", "byte",
"octet", "octet",
"DOMString", "DOMString",
"ByteString",
#"sequence<float>", #"sequence<float>",
"object", "object",
"ArrayBuffer", "ArrayBuffer",

View File

@ -74,6 +74,7 @@ MOCHITEST_FILES := \
test_bug862092.html \ test_bug862092.html \
test_bug560072.html \ test_bug560072.html \
test_lenientThis.html \ test_lenientThis.html \
test_ByteString.html \
$(NULL) $(NULL)
MOCHITEST_CHROME_FILES = \ MOCHITEST_CHROME_FILES = \

View File

@ -137,6 +137,10 @@ public:
already_AddRefed<TestInterface> Test(const GlobalObject&, const nsAString&, already_AddRefed<TestInterface> Test(const GlobalObject&, const nsAString&,
ErrorResult&); ErrorResult&);
static static
already_AddRefed<TestInterface> Test(const GlobalObject&, const nsACString&,
ErrorResult&);
static
already_AddRefed<TestInterface> Test2(const GlobalObject&, already_AddRefed<TestInterface> Test2(const GlobalObject&,
JSContext*, JSContext*,
const DictForConstructor&, const DictForConstructor&,
@ -370,6 +374,9 @@ public:
void ReceiveStringSequence(nsTArray<nsString>&); void ReceiveStringSequence(nsTArray<nsString>&);
void PassStringSequence(const Sequence<nsString>&); void PassStringSequence(const Sequence<nsString>&);
void ReceiveByteStringSequence(nsTArray<nsCString>&);
void PassByteStringSequence(const Sequence<nsCString>&);
void ReceiveAnySequence(JSContext*, nsTArray<JS::Value>&); void ReceiveAnySequence(JSContext*, nsTArray<JS::Value>&);
void ReceiveNullableAnySequence(JSContext*, Nullable<nsTArray<JS::Value> >&); void ReceiveNullableAnySequence(JSContext*, Nullable<nsTArray<JS::Value> >&);
void ReceiveAnySequenceSequence(JSContext*, nsTArray<nsTArray<JS::Value> >&); void ReceiveAnySequenceSequence(JSContext*, nsTArray<nsTArray<JS::Value> >&);
@ -398,7 +405,7 @@ public:
void PassFloat64Array(Float64Array&); void PassFloat64Array(Float64Array&);
JSObject* ReceiveUint8Array(JSContext*); JSObject* ReceiveUint8Array(JSContext*);
// String types // DOMString types
void PassString(const nsAString&); void PassString(const nsAString&);
void PassNullableString(const nsAString&); void PassNullableString(const nsAString&);
void PassOptionalString(const Optional<nsAString>&); void PassOptionalString(const Optional<nsAString>&);
@ -409,6 +416,13 @@ public:
void PassOptionalNullableStringWithDefaultValue(const nsAString&); void PassOptionalNullableStringWithDefaultValue(const nsAString&);
void PassVariadicString(const Sequence<nsString>&); void PassVariadicString(const Sequence<nsString>&);
// ByteString types
void PassByteString(const nsCString&);
void PassNullableByteString(const nsCString&);
void PassOptionalByteString(const Optional<nsCString>&);
void PassOptionalNullableByteString(const Optional<nsCString>&);
void PassVariadicByteString(const Sequence<nsCString>&);
// Enumerated types // Enumerated types
void PassEnum(TestEnum); void PassEnum(TestEnum);
void PassNullableEnum(const Nullable<TestEnum>&); void PassNullableEnum(const Nullable<TestEnum>&);
@ -753,6 +767,13 @@ private:
void PassOptionalNullableStringWithDefaultValue(nsAString&) MOZ_DELETE; void PassOptionalNullableStringWithDefaultValue(nsAString&) MOZ_DELETE;
void PassVariadicString(Sequence<nsString>&) MOZ_DELETE; void PassVariadicString(Sequence<nsString>&) MOZ_DELETE;
// cstrings should be const as well
void PassByteString(nsCString&) MOZ_DELETE;
void PassNullableByteString(nsCString&) MOZ_DELETE;
void PassOptionalByteString(Optional<nsCString>&) MOZ_DELETE;
void PassOptionalNullableByteString(Optional<nsCString>&) MOZ_DELETE;
void PassVariadicByteString(Sequence<nsCString>&) MOZ_DELETE;
// Make sure dictionary arguments are always const // Make sure dictionary arguments are always const
void PassDictionary(JSContext*, Dict&) MOZ_DELETE; void PassDictionary(JSContext*, Dict&) MOZ_DELETE;
void PassOtherDictionary(GrandparentDict&) MOZ_DELETE; void PassOtherDictionary(GrandparentDict&) MOZ_DELETE;

View File

@ -338,6 +338,9 @@ interface TestInterface {
sequence<DOMString> receiveStringSequence(); sequence<DOMString> receiveStringSequence();
void passStringSequence(sequence<DOMString> arg); void passStringSequence(sequence<DOMString> arg);
sequence<ByteString> receiveByteStringSequence();
void passByteStringSequence(sequence<ByteString> arg);
sequence<any> receiveAnySequence(); sequence<any> receiveAnySequence();
sequence<any>? receiveNullableAnySequence(); sequence<any>? receiveNullableAnySequence();
sequence<sequence<any>> receiveAnySequenceSequence(); sequence<sequence<any>> receiveAnySequenceSequence();
@ -366,7 +369,7 @@ interface TestInterface {
void passFloat64Array(Float64Array arg); void passFloat64Array(Float64Array arg);
Uint8Array receiveUint8Array(); Uint8Array receiveUint8Array();
// String types // DOMString types
void passString(DOMString arg); void passString(DOMString arg);
void passNullableString(DOMString? arg); void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg); void passOptionalString(optional DOMString arg);
@ -377,6 +380,13 @@ interface TestInterface {
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null); void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg); void passVariadicString(DOMString... arg);
// ByteString types
void passByteString(ByteString arg);
void passNullableByteString(ByteString? arg);
void passOptionalByteString(optional ByteString arg);
void passOptionalNullableByteString(optional ByteString? arg);
void passVariadicByteString(ByteString... arg);
// Enumerated types // Enumerated types
void passEnum(TestEnum arg); void passEnum(TestEnum arg);
void passNullableEnum(TestEnum? arg); void passNullableEnum(TestEnum? arg);

View File

@ -234,6 +234,9 @@ interface TestExampleInterface {
sequence<DOMString> receiveStringSequence(); sequence<DOMString> receiveStringSequence();
void passStringSequence(sequence<DOMString> arg); void passStringSequence(sequence<DOMString> arg);
sequence<ByteString> receiveByteStringSequence();
void passByteStringSequence(sequence<ByteString> arg);
sequence<any> receiveAnySequence(); sequence<any> receiveAnySequence();
sequence<any>? receiveNullableAnySequence(); sequence<any>? receiveNullableAnySequence();
//XXXbz No support for sequence of sequence return values yet. //XXXbz No support for sequence of sequence return values yet.
@ -264,7 +267,7 @@ interface TestExampleInterface {
void passFloat64Array(Float64Array arg); void passFloat64Array(Float64Array arg);
Uint8Array receiveUint8Array(); Uint8Array receiveUint8Array();
// String types // DOMString types
void passString(DOMString arg); void passString(DOMString arg);
void passNullableString(DOMString? arg); void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg); void passOptionalString(optional DOMString arg);
@ -275,6 +278,13 @@ interface TestExampleInterface {
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null); void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg); void passVariadicString(DOMString... arg);
// ByteString types
void passByteString(ByteString arg);
void passNullableByteString(ByteString? arg);
void passOptionalByteString(optional ByteString arg);
void passOptionalNullableByteString(optional ByteString? arg);
void passVariadicByteString(ByteString... arg);
// Enumerated types // Enumerated types
void passEnum(TestEnum arg); void passEnum(TestEnum arg);
void passNullableEnum(TestEnum? arg); void passNullableEnum(TestEnum? arg);

View File

@ -252,6 +252,7 @@ interface TestJSImplInterface {
void passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg); void passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg);
sequence<DOMString> receiveStringSequence(); sequence<DOMString> receiveStringSequence();
sequence<ByteString> receiveByteStringSequence();
// Callback interface problem. See bug 843261. // Callback interface problem. See bug 843261.
//void passStringSequence(sequence<DOMString> arg); //void passStringSequence(sequence<DOMString> arg);
sequence<any> receiveAnySequence(); sequence<any> receiveAnySequence();
@ -287,7 +288,7 @@ interface TestJSImplInterface {
//void passFloat64Array(Float64Array arg); //void passFloat64Array(Float64Array arg);
//Uint8Array receiveUint8Array(); //Uint8Array receiveUint8Array();
// String types // DOMString types
void passString(DOMString arg); void passString(DOMString arg);
void passNullableString(DOMString? arg); void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg); void passOptionalString(optional DOMString arg);
@ -298,6 +299,13 @@ interface TestJSImplInterface {
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null); void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg); void passVariadicString(DOMString... arg);
// ByteString types
void passByteString(ByteString arg);
void passNullableByteString(ByteString? arg);
void passOptionalByteString(optional ByteString arg);
void passOptionalNullableByteString(optional ByteString? arg);
void passVariadicByteString(ByteString... arg);
// Enumerated types // Enumerated types
void passEnum(MyTestEnum arg); void passEnum(MyTestEnum arg);
void passNullableEnum(MyTestEnum? arg); void passNullableEnum(MyTestEnum? arg);

View File

@ -0,0 +1,32 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=796850
-->
<head>
<meta charset="utf-8">
<title>Test for ByteString support</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=796850">Mozilla Bug 796850</a>
<p id="display"></p>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 796850 **/
var xhr = new XMLHttpRequest();
caught = false;
try {
xhr.open("\u5427", "about:mozilla", true);
}
catch (TypeError) {
caught = true;
}
ok(caught, "Character values > 255 not rejected for ByteString");
</script>
</pre>
</body>
</html>

View File

@ -21,11 +21,6 @@ DISABLED_EXTRA_COMPONENTS = \
BrowserElementParent.manifest \ BrowserElementParent.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
BrowserElementPromptService.jsm \
BrowserElementParent.jsm \
$(NULL)
include $(topsrcdir)/config/config.mk include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -34,3 +34,8 @@ EXTRA_COMPONENTS += [
'BrowserElementParent.js', 'BrowserElementParent.js',
'BrowserElementParent.manifest', 'BrowserElementParent.manifest',
] ]
EXTRA_JS_MODULES += [
'BrowserElementParent.jsm',
'BrowserElementPromptService.jsm',
]

View File

@ -16,9 +16,4 @@ DISABLED_EXTRA_COMPONENTS = \
ContactManager.manifest \ ContactManager.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
ContactService.jsm \
ContactDB.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -10,3 +10,8 @@ EXTRA_COMPONENTS += [
'ContactManager.js', 'ContactManager.js',
'ContactManager.manifest', 'ContactManager.manifest',
] ]
EXTRA_JS_MODULES += [
'ContactDB.jsm',
'ContactService.jsm',
]

View File

@ -20,10 +20,6 @@ EXTRA_COMPONENTS = \
DOMFMRadio.manifest \ DOMFMRadio.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
DOMFMRadioParent.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk

View File

@ -22,3 +22,7 @@ CPP_SOURCES += [
'nsFMRadioSettings.cpp', 'nsFMRadioSettings.cpp',
] ]
EXTRA_JS_MODULES += [
'DOMFMRadioParent.jsm',
]

View File

@ -21,7 +21,4 @@ EXTRA_PP_JS_MODULES = \
DOMIdentity.jsm \ DOMIdentity.jsm \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -17,8 +17,4 @@ DISABLED_EXTRA_COMPONENTS = \
SystemMessageManager.manifest \ SystemMessageManager.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES += \
SystemMessagePermissionsChecker.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -11,3 +11,7 @@ EXTRA_COMPONENTS += [
'SystemMessageManager.js', 'SystemMessageManager.js',
'SystemMessageManager.manifest', 'SystemMessageManager.manifest',
] ]
EXTRA_JS_MODULES += [
'SystemMessagePermissionsChecker.jsm',
]

View File

@ -49,13 +49,6 @@ EXTRA_COMPONENTS = \
ril/MobileMessageDatabaseService.js \ ril/MobileMessageDatabaseService.js \
ril/MobileMessageDatabaseService.manifest \ ril/MobileMessageDatabaseService.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
ril/mms_consts.js \
ril/MmsPduHelper.jsm \
ril/wap_consts.js \
ril/WspPduHelper.jsm \
$(NULL)
endif endif
include $(topsrcdir)/config/config.mk include $(topsrcdir)/config/config.mk

View File

@ -14,7 +14,14 @@ EXPORTS.mozilla.dom.mobilemessage += [
'Types.h', 'Types.h',
] ]
if not CONFIG['MOZ_B2G_RIL']: if CONFIG['MOZ_B2G_RIL']:
EXTRA_JS_MODULES = [
'ril/MmsPduHelper.jsm',
'ril/WspPduHelper.jsm',
'ril/mms_consts.js',
'ril/wap_consts.js',
]
else:
EXPORTS.mozilla.dom.mobilemessage += [ EXPORTS.mozilla.dom.mobilemessage += [
'MmsService.h', 'MmsService.h',
'MobileMessageDatabaseService.h', 'MobileMessageDatabaseService.h',

View File

@ -25,11 +25,6 @@ DISABLED_EXTRA_COMPONENTS += \
NetworkStatsManager.manifest \ NetworkStatsManager.manifest \
NetworkStatsManager.js \ NetworkStatsManager.js \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
NetworkStatsService.jsm \
NetworkStatsDB.jsm \
$(NULL)
endif endif
include $(topsrcdir)/dom/dom-config.mk include $(topsrcdir)/dom/dom-config.mk

View File

@ -23,6 +23,10 @@ if CONFIG['MOZ_B2G_RIL']:
CPP_SOURCES += [ CPP_SOURCES += [
'MobileConnection.cpp', 'MobileConnection.cpp',
] ]
EXTRA_JS_MODULES = [
'NetworkStatsDB.jsm',
'NetworkStatsService.jsm',
]
EXTRA_COMPONENTS += [ EXTRA_COMPONENTS += [
'TCPSocket.js', 'TCPSocket.js',

View File

@ -16,9 +16,5 @@ EXTRA_COMPONENTS = \
Payment.manifest \ Payment.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES += \
Payment.jsm \
$(NULL)
include $(topsrcdir)/config/config.mk include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -8,3 +8,7 @@ PARALLEL_DIRS += ['interfaces']
TEST_DIRS += ['tests'] TEST_DIRS += ['tests']
EXTRA_JS_MODULES += [
'Payment.jsm',
]

View File

@ -16,9 +16,4 @@ DISABLED_EXTRA_COMPONENTS = \
PermissionPromptService.manifest \ PermissionPromptService.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
PermissionPromptHelper.jsm \
PermissionSettings.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -12,3 +12,8 @@ EXTRA_COMPONENTS += [
'PermissionSettings.js', 'PermissionSettings.js',
'PermissionSettings.manifest', 'PermissionSettings.manifest',
] ]
EXTRA_JS_MODULES += [
'PermissionPromptHelper.jsm',
'PermissionSettings.jsm',
]

View File

@ -9,12 +9,6 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk include $(DEPTH)/config/autoconf.mk
EXTRA_JS_MODULES = \
PhoneNumber.jsm \
PhoneNumberMetaData.jsm \
mcc_iso3166_table.jsm \
$(NULL)
EXTRA_PP_JS_MODULES = \ EXTRA_PP_JS_MODULES = \
PhoneNumberUtils.jsm \ PhoneNumberUtils.jsm \
$(NULL) $(NULL)

View File

@ -5,3 +5,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_DIRS += ['tests'] TEST_DIRS += ['tests']
EXTRA_JS_MODULES += [
'PhoneNumber.jsm',
'PhoneNumberMetaData.jsm',
'mcc_iso3166_table.jsm',
]

View File

@ -14,9 +14,5 @@ DISABLED_EXTRA_COMPONENTS = \
Push.manifest \ Push.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
PushService.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -9,3 +9,7 @@ EXTRA_COMPONENTS += [
'Push.manifest', 'Push.manifest',
'PushServiceLauncher.js', 'PushServiceLauncher.js',
] ]
EXTRA_JS_MODULES += [
'PushService.jsm',
]

View File

@ -16,10 +16,4 @@ DISABLED_EXTRA_COMPONENTS = \
SettingsService.manifest \ SettingsService.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
SettingsQueue.jsm \
SettingsDB.jsm \
SettingsChangeNotifier.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -12,3 +12,9 @@ EXTRA_COMPONENTS += [
'SettingsService.js', 'SettingsService.js',
'SettingsService.manifest', 'SettingsService.manifest',
] ]
EXTRA_JS_MODULES += [
'SettingsChangeNotifier.jsm',
'SettingsDB.jsm',
'SettingsQueue.jsm',
]

View File

@ -47,13 +47,6 @@ EXTRA_COMPONENTS = \
NetworkInterfaceListService.js \ NetworkInterfaceListService.js \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
net_worker.js \
ril_consts.js \
ril_worker.js \
systemlibs.js \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk include $(topsrcdir)/ipc/chromium/chromium-config.mk

View File

@ -66,3 +66,11 @@ if CONFIG['ENABLE_TESTS']:
CPP_SOURCES += [ CPP_SOURCES += [
'SystemWorkerManager.cpp', 'SystemWorkerManager.cpp',
] ]
EXTRA_JS_MODULES += [
'net_worker.js',
'ril_consts.js',
'ril_worker.js',
'systemlibs.js',
]

View File

@ -14,13 +14,6 @@ include $(DEPTH)/config/autoconf.mk
ifdef MOZ_B2G_RIL ifdef MOZ_B2G_RIL
EXTRA_COMPONENTS = \ EXTRA_COMPONENTS = \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
gonk/WbxmlPduHelper.jsm \
gonk/SiPduHelper.jsm \
gonk/SlPduHelper.jsm \
gonk/WapPushManager.js \
$(NULL)
endif endif
include $(topsrcdir)/config/config.mk include $(topsrcdir)/config/config.mk

View File

@ -3,3 +3,10 @@
# 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/.
if CONFIG['MOZ_B2G_RIL']:
EXTRA_JS_MODULES = [
'gonk/SiPduHelper.jsm',
'gonk/SlPduHelper.jsm',
'gonk/WapPushManager.js',
'gonk/WbxmlPduHelper.jsm',
]

View File

@ -71,10 +71,10 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
// request // request
[Throws] [Throws]
void open(DOMString method, DOMString url, optional boolean async = true, void open(ByteString method, DOMString url, optional boolean async = true,
optional DOMString? user, optional DOMString? password); optional DOMString? user, optional DOMString? password);
[Throws] [Throws]
void setRequestHeader(DOMString header, DOMString value); void setRequestHeader(ByteString header, ByteString value);
[SetterThrows] [SetterThrows]
attribute unsigned long timeout; attribute unsigned long timeout;
@ -109,12 +109,12 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
[Throws=Workers] [Throws=Workers]
readonly attribute unsigned short status; readonly attribute unsigned short status;
readonly attribute DOMString statusText; readonly attribute ByteString statusText;
[Throws] [Throws]
DOMString? getResponseHeader(DOMString header); ByteString? getResponseHeader(ByteString header);
[Throws=Workers] [Throws=Workers]
DOMString getAllResponseHeaders(); ByteString getAllResponseHeaders();
[Throws=Workers] [Throws=Workers]
void overrideMimeType(DOMString mime); void overrideMimeType(DOMString mime);

View File

@ -22,11 +22,6 @@ EXTRA_COMPONENTS = \
DOMWifiManager.manifest \ DOMWifiManager.manifest \
$(NULL) $(NULL)
EXTRA_JS_MODULES = \
libhardware_legacy.js \
wifi_worker.js \
$(NULL)
include $(topsrcdir)/config/rules.mk include $(topsrcdir)/config/rules.mk

View File

@ -21,3 +21,8 @@ XPIDL_FLAGS += [
MODULE = 'dom' MODULE = 'dom'
EXTRA_JS_MODULES += [
'libhardware_legacy.js',
'wifi_worker.js',
]

View File

@ -523,7 +523,7 @@ class EventRunnable : public MainThreadProxyRunnable
nsTArray<nsCOMPtr<nsISupports> > mClonedObjects; nsTArray<nsCOMPtr<nsISupports> > mClonedObjects;
jsval mResponse; jsval mResponse;
nsString mResponseText; nsString mResponseText;
nsString mStatusText; nsCString mStatusText;
uint64_t mLoaded; uint64_t mLoaded;
uint64_t mTotal; uint64_t mTotal;
uint32_t mEventStreamId; uint32_t mEventStreamId;
@ -970,11 +970,11 @@ public:
class GetAllResponseHeadersRunnable : public WorkerThreadProxySyncRunnable class GetAllResponseHeadersRunnable : public WorkerThreadProxySyncRunnable
{ {
nsString& mResponseHeaders; nsCString& mResponseHeaders;
public: public:
GetAllResponseHeadersRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, GetAllResponseHeadersRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
nsString& aResponseHeaders) nsCString& aResponseHeaders)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy),
mResponseHeaders(aResponseHeaders) mResponseHeaders(aResponseHeaders)
{ } { }
@ -994,7 +994,7 @@ class GetResponseHeaderRunnable : public WorkerThreadProxySyncRunnable
public: public:
GetResponseHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, GetResponseHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
const nsCString& aHeader, nsCString& aValue) const nsACString& aHeader, nsCString& aValue)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader), : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader),
mValue(aValue) mValue(aValue)
{ } { }
@ -1008,7 +1008,7 @@ public:
class OpenRunnable : public WorkerThreadProxySyncRunnable class OpenRunnable : public WorkerThreadProxySyncRunnable
{ {
nsString mMethod; nsCString mMethod;
nsString mURL; nsString mURL;
Optional<nsAString> mUser; Optional<nsAString> mUser;
nsString mUserStr; nsString mUserStr;
@ -1020,7 +1020,7 @@ class OpenRunnable : public WorkerThreadProxySyncRunnable
public: public:
OpenRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, OpenRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
const nsAString& aMethod, const nsAString& aURL, const nsACString& aMethod, const nsAString& aURL,
const Optional<nsAString>& aUser, const Optional<nsAString>& aUser,
const Optional<nsAString>& aPassword, const Optional<nsAString>& aPassword,
bool aBackgroundRequest, bool aWithCredentials, bool aBackgroundRequest, bool aWithCredentials,
@ -1201,7 +1201,7 @@ class SetRequestHeaderRunnable : public WorkerThreadProxySyncRunnable
public: public:
SetRequestHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy, SetRequestHeaderRunnable(WorkerPrivate* aWorkerPrivate, Proxy* aProxy,
const nsCString& aHeader, const nsCString& aValue) const nsACString& aHeader, const nsACString& aValue)
: WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader), : WorkerThreadProxySyncRunnable(aWorkerPrivate, aProxy), mHeader(aHeader),
mValue(aValue) mValue(aValue)
{ } { }
@ -1716,7 +1716,7 @@ XMLHttpRequest::Notify(JSContext* aCx, Status aStatus)
} }
void void
XMLHttpRequest::Open(const nsAString& aMethod, const nsAString& aUrl, XMLHttpRequest::Open(const nsACString& aMethod, const nsAString& aUrl,
bool aAsync, const Optional<nsAString>& aUser, bool aAsync, const Optional<nsAString>& aUser,
const Optional<nsAString>& aPassword, ErrorResult& aRv) const Optional<nsAString>& aPassword, ErrorResult& aRv)
{ {
@ -1754,8 +1754,8 @@ XMLHttpRequest::Open(const nsAString& aMethod, const nsAString& aUrl,
} }
void void
XMLHttpRequest::SetRequestHeader(const nsAString& aHeader, XMLHttpRequest::SetRequestHeader(const nsACString& aHeader,
const nsAString& aValue, ErrorResult& aRv) const nsACString& aValue, ErrorResult& aRv)
{ {
mWorkerPrivate->AssertIsOnWorkerThread(); mWorkerPrivate->AssertIsOnWorkerThread();
@ -1770,9 +1770,7 @@ XMLHttpRequest::SetRequestHeader(const nsAString& aHeader,
} }
nsRefPtr<SetRequestHeaderRunnable> runnable = nsRefPtr<SetRequestHeaderRunnable> runnable =
new SetRequestHeaderRunnable(mWorkerPrivate, mProxy, new SetRequestHeaderRunnable(mWorkerPrivate, mProxy, aHeader, aValue);
NS_ConvertUTF16toUTF8(aHeader),
NS_ConvertUTF16toUTF8(aValue));
if (!runnable->Dispatch(GetJSContext())) { if (!runnable->Dispatch(GetJSContext())) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return; return;
@ -2012,8 +2010,8 @@ XMLHttpRequest::Abort(ErrorResult& aRv)
} }
void void
XMLHttpRequest::GetResponseHeader(const nsAString& aHeader, XMLHttpRequest::GetResponseHeader(const nsACString& aHeader,
nsAString& aResponseHeader, ErrorResult& aRv) nsACString& aResponseHeader, ErrorResult& aRv)
{ {
mWorkerPrivate->AssertIsOnWorkerThread(); mWorkerPrivate->AssertIsOnWorkerThread();
@ -2027,20 +2025,19 @@ XMLHttpRequest::GetResponseHeader(const nsAString& aHeader,
return; return;
} }
nsCString value; nsCString responseHeader;
nsRefPtr<GetResponseHeaderRunnable> runnable = nsRefPtr<GetResponseHeaderRunnable> runnable =
new GetResponseHeaderRunnable(mWorkerPrivate, mProxy, new GetResponseHeaderRunnable(mWorkerPrivate, mProxy, aHeader,
NS_ConvertUTF16toUTF8(aHeader), value); responseHeader);
if (!runnable->Dispatch(GetJSContext())) { if (!runnable->Dispatch(GetJSContext())) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return; return;
} }
aResponseHeader = responseHeader;
aResponseHeader = NS_ConvertUTF8toUTF16(value);
} }
void void
XMLHttpRequest::GetAllResponseHeaders(nsAString& aResponseHeaders, XMLHttpRequest::GetAllResponseHeaders(nsACString& aResponseHeaders,
ErrorResult& aRv) ErrorResult& aRv)
{ {
mWorkerPrivate->AssertIsOnWorkerThread(); mWorkerPrivate->AssertIsOnWorkerThread();
@ -2055,7 +2052,7 @@ XMLHttpRequest::GetAllResponseHeaders(nsAString& aResponseHeaders,
return; return;
} }
nsString responseHeaders; nsCString responseHeaders;
nsRefPtr<GetAllResponseHeadersRunnable> runnable = nsRefPtr<GetAllResponseHeadersRunnable> runnable =
new GetAllResponseHeadersRunnable(mWorkerPrivate, mProxy, responseHeaders); new GetAllResponseHeadersRunnable(mWorkerPrivate, mProxy, responseHeaders);
if (!runnable->Dispatch(GetJSContext())) { if (!runnable->Dispatch(GetJSContext())) {

View File

@ -29,7 +29,7 @@ public:
{ {
nsString mResponseText; nsString mResponseText;
uint32_t mStatus; uint32_t mStatus;
nsString mStatusText; nsCString mStatusText;
uint16_t mReadyState; uint16_t mReadyState;
jsval mResponse; jsval mResponse;
nsresult mResponseTextResult; nsresult mResponseTextResult;
@ -122,12 +122,12 @@ public:
} }
void void
Open(const nsAString& aMethod, const nsAString& aUrl, bool aAsync, Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
const Optional<nsAString>& aUser, const Optional<nsAString>& aPassword, const Optional<nsAString>& aUser, const Optional<nsAString>& aPassword,
ErrorResult& aRv); ErrorResult& aRv);
void void
SetRequestHeader(const nsAString& aHeader, const nsAString& aValue, SetRequestHeader(const nsACString& aHeader, const nsACString& aValue,
ErrorResult& aRv); ErrorResult& aRv);
uint32_t uint32_t
@ -199,17 +199,17 @@ public:
} }
void void
GetStatusText(nsAString& aStatusText) const GetStatusText(nsACString& aStatusText) const
{ {
aStatusText = mStateData.mStatusText; aStatusText = mStateData.mStatusText;
} }
void void
GetResponseHeader(const nsAString& aHeader, nsAString& aResponseHeader, GetResponseHeader(const nsACString& aHeader, nsACString& aResponseHeader,
ErrorResult& aRv); ErrorResult& aRv);
void void
GetAllResponseHeaders(nsAString& aResponseHeaders, ErrorResult& aRv); GetAllResponseHeaders(nsACString& aResponseHeaders, ErrorResult& aRv);
void void
OverrideMimeType(const nsAString& aMimeType, ErrorResult& aRv); OverrideMimeType(const nsAString& aMimeType, ErrorResult& aRv);

View File

@ -690,29 +690,50 @@ VectorImage::Draw(gfxContext* aContext,
AutoSVGRenderingState autoSVGState(aSVGContext, AutoSVGRenderingState autoSVGState(aSVGContext,
time, time,
mSVGDocumentWrapper->GetRootSVGElem()); mSVGDocumentWrapper->GetRootSVGElem());
mSVGDocumentWrapper->UpdateViewportBounds(aViewportSize);
// gfxUtils::DrawPixelSnapped may rasterize this image to a temporary surface
// if we hit the tiling path. Unfortunately, the temporary surface isn't
// created at the size at which we'll ultimately draw, causing fuzzy output.
// To fix this we pre-apply the transform's scaling to the drawing parameters
// and then remove the scaling from the transform, so the fact that temporary
// surfaces won't take the scaling into account doesn't matter. (Bug 600207.)
gfxSize scale(aUserSpaceToImageSpace.ScaleFactors(true));
gfxPoint translation(aUserSpaceToImageSpace.GetTranslation());
// Rescale everything.
nsIntSize scaledViewport(aViewportSize.width / scale.width,
aViewportSize.height / scale.height);
gfxIntSize scaledViewportGfx(scaledViewport.width, scaledViewport.height);
nsIntRect scaledSubimage(aSubimage);
scaledSubimage.ScaleRoundOut(1.0 / scale.width, 1.0 / scale.height);
// Remove the scaling from the transform.
gfxMatrix unscale;
unscale.Translate(gfxPoint(translation.x / scale.width,
translation.y / scale.height));
unscale.Scale(1.0 / scale.width, 1.0 / scale.height);
unscale.Translate(-translation);
gfxMatrix unscaledTransform(aUserSpaceToImageSpace * unscale);
mSVGDocumentWrapper->UpdateViewportBounds(scaledViewport);
mSVGDocumentWrapper->FlushImageTransformInvalidation(); mSVGDocumentWrapper->FlushImageTransformInvalidation();
// XXXdholbert Do we need to convert image size from
// CSS pixels to dev pixels here? (is gfxCallbackDrawable's 2nd arg in dev
// pixels?)
gfxIntSize imageSizeGfx(aViewportSize.width, aViewportSize.height);
// Based on imgFrame::Draw // Based on imgFrame::Draw
gfxRect sourceRect = aUserSpaceToImageSpace.Transform(aFill); gfxRect sourceRect = unscaledTransform.Transform(aFill);
gfxRect imageRect(0, 0, aViewportSize.width, aViewportSize.height); gfxRect imageRect(0, 0, scaledViewport.width, scaledViewport.height);
gfxRect subimage(aSubimage.x, aSubimage.y, aSubimage.width, aSubimage.height); gfxRect subimage(scaledSubimage.x, scaledSubimage.y,
scaledSubimage.width, scaledSubimage.height);
nsRefPtr<gfxDrawingCallback> cb = nsRefPtr<gfxDrawingCallback> cb =
new SVGDrawingCallback(mSVGDocumentWrapper, new SVGDrawingCallback(mSVGDocumentWrapper,
nsIntRect(nsIntPoint(0, 0), aViewportSize), nsIntRect(nsIntPoint(0, 0), scaledViewport),
aFlags); aFlags);
nsRefPtr<gfxDrawable> drawable = new gfxCallbackDrawable(cb, imageSizeGfx); nsRefPtr<gfxDrawable> drawable = new gfxCallbackDrawable(cb, scaledViewportGfx);
gfxUtils::DrawPixelSnapped(aContext, drawable, gfxUtils::DrawPixelSnapped(aContext, drawable,
aUserSpaceToImageSpace, unscaledTransform,
subimage, sourceRect, imageRect, aFill, subimage, sourceRect, imageRect, aFill,
gfxASurface::ImageFormatARGB32, aFilter, gfxASurface::ImageFormatARGB32, aFilter,
aFlags); aFlags);

View File

@ -7,3 +7,8 @@
CSRCS += [ CSRCS += [
'umaptable.c', 'umaptable.c',
] ]
bin_suffix = CONFIG['BIN_SUFFIX']
SIMPLE_PROGRAMS += [
"%s%s" % (fyl[0:-2], bin_suffix) for fyl in CSRCS
]

View File

@ -13,7 +13,7 @@ include $(DEPTH)/config/autoconf.mk
USE_STATIC_LIBS = 1 USE_STATIC_LIBS = 1
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX)) DISABLE_SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
LIBS = \ LIBS = \
$(XPCOM_STATICRUNTIME_GLUE_LDOPTS) \ $(XPCOM_STATICRUNTIME_GLUE_LDOPTS) \

View File

@ -12,3 +12,8 @@ CPP_SOURCES += [
'NormalizationTest.cpp', 'NormalizationTest.cpp',
'UnicharSelfTest.cpp', 'UnicharSelfTest.cpp',
] ]
bin_suffix = CONFIG['BIN_SUFFIX']
SIMPLE_PROGRAMS += [
"%s%s" % (fyl[0:-4], bin_suffix) for fyl in CPP_SOURCES
]

View File

@ -1128,3 +1128,5 @@ sys/thr.h
sys/user.h sys/user.h
kvm.h kvm.h
spawn.h spawn.h
err.h
xlocale.h

View File

@ -3991,7 +3991,7 @@ CheckDivOrMod(FunctionCompiler &f, ParseNode *expr, MDefinition **def, Type *typ
return true; return true;
} }
return f.failf(expr, "arguments to / or &% must both be double, signed, or unsigned, " return f.failf(expr, "arguments to / or %% must both be double, signed, or unsigned; "
"%s and %s are given", lhsType.toChars(), rhsType.toChars()); "%s and %s are given", lhsType.toChars(), rhsType.toChars());
} }
@ -4025,7 +4025,7 @@ CheckComparison(FunctionCompiler &f, ParseNode *comp, MDefinition **def, Type *t
return true; return true;
} }
return f.failf(comp, "arguments to a comparison must both be signed, unsigned or doubles, " return f.failf(comp, "arguments to a comparison must both be signed, unsigned or doubles; "
"%s and %s are given", lhsType.toChars(), rhsType.toChars()); "%s and %s are given", lhsType.toChars(), rhsType.toChars());
} }

View File

@ -1995,17 +1995,23 @@ BaselineCompiler::emitInitPropGetterSetter()
JS_ASSERT(JSOp(*pc) == JSOP_INITPROP_GETTER || JS_ASSERT(JSOp(*pc) == JSOP_INITPROP_GETTER ||
JSOp(*pc) == JSOP_INITPROP_SETTER); JSOp(*pc) == JSOP_INITPROP_SETTER);
// Load value in R0, keep object on the stack. // Load value in R0 but keep it on the stack for the decompiler.
frame.popRegsAndSync(1); frame.syncStack(0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
prepareVMCall(); prepareVMCall();
pushArg(R0); pushArg(R0);
pushArg(ImmGCPtr(script->getName(pc))); pushArg(ImmGCPtr(script->getName(pc)));
masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg()); masm.extractObject(frame.addressOfStackValue(frame.peek(-2)), R0.scratchReg());
pushArg(R0.scratchReg()); pushArg(R0.scratchReg());
pushArg(ImmWord(pc)); pushArg(ImmWord(pc));
return callVM(InitPropGetterSetterInfo); if (!callVM(InitPropGetterSetterInfo))
return false;
frame.pop();
return true;
} }
bool bool
@ -2031,17 +2037,25 @@ BaselineCompiler::emitInitElemGetterSetter()
JS_ASSERT(JSOp(*pc) == JSOP_INITELEM_GETTER || JS_ASSERT(JSOp(*pc) == JSOP_INITELEM_GETTER ||
JSOp(*pc) == JSOP_INITELEM_SETTER); JSOp(*pc) == JSOP_INITELEM_SETTER);
// Load index and value in R0 and R1, keep object on the stack. // Load index and value in R0 and R1, but keep values on the stack for the
frame.popRegsAndSync(2); // decompiler.
frame.syncStack(0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R1);
prepareVMCall(); prepareVMCall();
pushArg(R1); pushArg(R1);
pushArg(R0); pushArg(R0);
masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg()); masm.extractObject(frame.addressOfStackValue(frame.peek(-3)), R0.scratchReg());
pushArg(R0.scratchReg()); pushArg(R0.scratchReg());
pushArg(ImmWord(pc)); pushArg(ImmWord(pc));
return callVM(InitElemGetterSetterInfo); if (!callVM(InitElemGetterSetterInfo))
return false;
frame.popn(2);
return true;
} }
bool bool

View File

@ -0,0 +1,3 @@
// |jit-test| error: TypeError
z = Proxy.create({}, (function(){}));
({__proto__: z, set c(a) {}});

View File

@ -1,152 +1,82 @@
load(libdir + "util.js"); load(libdir + "util.js");
var SobelX = [[-1.0, 0.0, 1.0],
[-2.0, 0.0, 2.0],
[-1.0, 0.0, 1.0]];
var SobelY = [[ 1.0, 2.0, 1.0],
[ 0.0, 0.0, 0.0],
[-1.0, -2.0, -1.0]];
function stripedImage(w, h) { function stripedImage(w, h) {
var resultArray = new Array(w * h); var resultArray = new Array(w * h);
for (var x = 0; x < w; x++) { for (var y = 0; y < h; y++) {
for (var y = 0; y < h; y++) { for (var x = 0; x < w; x++) {
resultArray[x*h + y] = (Math.abs(x%100-y%100) < 10) ? 32 : 0; resultArray[y*w + x] = (Math.abs(x%100-y%100) < 10) ? 32 : 0;
} }
} }
return resultArray; return resultArray;
} }
function edges1dArraySequentially(data, width, height) { function edgesSequentially(data, width, height) {
var sobelX = [[-1.0, 0.0, 1.0],
[-2.0, 0.0, 2.0],
[-1.0, 0.0, 1.0]];
var sobelY = [[1.0, 2.0, 1.0],
[0.0, 0.0, 0.0],
[-1.0, -2.0, -1.0]];
var data1 = new Array(width * height); var data1 = new Array(width * height);
for (var y = 0; y < height; y++) { for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) { for (var x = 0; x < width; x++) {
// process pixel var total = compute(x, y);
var totalX = 0; data1[y*width + x] = total | 0;
var totalY = 0;
for (var offY = -1; offY <= 1; offY++) {
var newY = y + offY;
for (var offX = -1; offX <= 1; offX++) {
var newX = x + offX;
if ((newX >= 0) && (newX < width) && (newY >= 0) && (newY < height)) {
var pointIndex = (x + offX) * height + (y + offY);
var e = data[pointIndex];
totalX += e * sobelX[offY + 1][offX + 1];
totalY += e * sobelY[offY + 1][offX + 1];
}
}
}
var total = ((Math.abs(totalX) + Math.abs(totalY))/8.0)|0;
var index = y*width+x;
data1[index] = total | 0;
} }
} }
return data1; return data1;
}
/* Compute edges using a flat JS array as input */ function compute(x, y) {
function edges1dArrayInParallel(data, width, height) {
var sobelX = [[-1.0, 0.0, 1.0],
[-2.0, 0.0, 2.0],
[-1.0, 0.0, 1.0]];
var sobelY = [[1.0, 2.0, 1.0],
[0.0, 0.0, 0.0],
[-1.0, -2.0, -1.0]];
function computePixel(x, y) {
var totalX = 0; var totalX = 0;
var totalY = 0; var totalY = 0;
for (var offY = -1; offY <= 1; offY++) {
var newY = y + offY; var offYMin = (y == 0 ? 0 : -1);
for (var offX = -1; offX <= 1; offX++) { var offYMax = (y == height - 1 ? 0 : 1);
var newX = x + offX; var offXMin = (x == 0 ? 0 : -1);
if ((newX >= 0) && (newX < width) && (newY >= 0) && (newY < height)) { var offXMax = (x == width - 1 ? 0 : 1);
var pointIndex = (x + offX) * height + (y + offY);
var e = data[pointIndex]; for (var offY = offYMin; offY <= offYMax; offY++) {
totalX += e * sobelX[offY + 1][offX + 1]; for (var offX = offXMin; offX <= offXMax; offX++) {
totalY += e * sobelY[offY + 1][offX + 1]; var e = data[(y + offY) * width + x + offX];
} totalX += e * SobelX[offY + 1][offX + 1];
totalY += e * SobelY[offY + 1][offX + 1];
} }
} }
var total = (Math.abs(totalX) + Math.abs(totalY))/8.0 | 0;
return total;
}
return new ParallelArray([width, height], computePixel); return (Math.abs(totalX) + Math.abs(totalY))/8.0 | 0;
}
} }
/* Compute edges using a flat JS array as input */ function edgesParallel(data) {
function edges1dParallelArrayInParallel(pa, width, height) { var pa = new ParallelArray([Height, Width], function (y, x) {
var sobelX = [[-1.0, 0.0, 1.0], var totalX = 0;
[-2.0, 0.0, 2.0], var totalY = 0;
[-1.0, 0.0, 1.0]];
var sobelY = [[1.0, 2.0, 1.0],
[0.0, 0.0, 0.0],
[-1.0, -2.0, -1.0]];
function computePixel(x, y) { var offYMin = (y == 0 ? 0 : -1);
var totalX = 0; var offYMax = (y == Height - 1 ? 0 : 1);
var totalY = 0; var offXMin = (x == 0 ? 0 : -1);
for (var offY = -1; offY <= 1; offY++) { var offXMax = (x == Width - 1 ? 0 : 1);
var newY = y + offY;
for (var offX = -1; offX <= 1; offX++) { for (var offY = offYMin; offY <= offYMax; offY++) {
var newX = x + offX; for (var offX = offXMin; offX <= offXMax; offX++) {
if ((newX >= 0) && (newX < width) && (newY >= 0) && (newY < height)) { var e = data.get(y + offY, x + offX);
var pointIndex = (x + offX) * height + (y + offY); totalX += e * SobelX[offY + 1][offX + 1];
// var e = pa.buffer[pointIndex]; totalY += e * SobelY[offY + 1][offX + 1];
var e = pa.get(pointIndex);
totalX += e * sobelX[offY + 1][offX + 1];
totalY += e * sobelY[offY + 1][offX + 1];
}
}
} }
var total = (Math.abs(totalX) + Math.abs(totalY))/8.0 | 0; }
return total;
}
return new ParallelArray([width, height], computePixel); return (Math.abs(totalX) + Math.abs(totalY))/8.0 | 0;
} });
return pa.flatten();
/* Compute edges using 2D parallel array as input */
function edges2dParallelArrayInParallel(pa) {
var sobelX = [[-1.0, 0.0, 1.0],
[-2.0, 0.0, 2.0],
[-1.0, 0.0, 1.0]];
var sobelY = [[1.0, 2.0, 1.0],
[0.0, 0.0, 0.0],
[-1.0, -2.0, -1.0]];
var width = pa.shape[0];
var height = pa.shape[1];
function computePixel(x, y) {
var totalX = 0;
var totalY = 0;
for (var offY = -1; offY <= 1; offY++) {
var newY = y + offY;
for (var offX = -1; offX <= 1; offX++) {
var newX = x + offX;
if ((newX >= 0) && (newX < width) && (newY >= 0) && (newY < height)) {
var pointIndex = (x + offX) * height + (y + offY);
// var e = pa.buffer[pointIndex];
var e = pa.get(x + offX, y + offY);
totalX += e * sobelX[offY + 1][offX + 1];
totalY += e * sobelY[offY + 1][offX + 1];
}
}
}
var total = (Math.abs(totalX) + Math.abs(totalY))/8.0 | 0;
return total;
}
return new ParallelArray([width, height], computePixel);
} }
var Width = 1024; var Width = 1024;
var Height = 768; var Height = 768;
var ArrInput = stripedImage(1024, 768); var ArrInput = stripedImage(Width, Height);
var ParArrInput1D = new ParallelArray(ArrInput); var ParArrInput2D = new ParallelArray([Height, Width],
var ParArrInput2D = new ParallelArray([1024, 768], function (y, x) ArrInput[y*Width + x]);
function (x, y) ArrInput[x*Height + y]);
benchmark("EDGES", 2, DEFAULT_MEASURE * 20,
function() edgesSequentially(ArrInput, Width, Height),
function() edgesParallel(ParArrInput2D));

View File

@ -1,6 +0,0 @@
load(libdir + "edges.js");
benchmark("EDGES-ARRAY-1D", 1, DEFAULT_MEASURE,
function() {edges1dArraySequentially(ArrInput, Width, Height)},
function() {edges1dArrayInParallel(ArrInput, Width, Height)});

View File

@ -1,6 +0,0 @@
load(libdir + "edges.js");
benchmark("EDGES-PARALLEL-ARRAY-1D", 1, DEFAULT_MEASURE,
function() {edges1dArraySequentially(ArrInput, Width, Height)},
function() {edges1dParallelArrayInParallel(ParArrInput1D, Width, Height)});

View File

@ -1,5 +0,0 @@
load(libdir + "edges.js");
benchmark("EDGES-PARALLEL-ARRAY-2D", 1, DEFAULT_MEASURE,
function() {edges1dArraySequentially(ArrInput, Width, Height)},
function() {edges2dParallelArrayInParallel(ParArrInput2D)});

View File

@ -0,0 +1,454 @@
// -*- mode: js2; indent-tabs-mode: nil; -*-
// Adapted from
//
// https://github.com/RiverTrail/RiverTrail/blob/master/examples/liquid-resize/resize-compute-dp.js
//
// which in turn is based on an algorithm from the paper below (which
// also appeared in ACM SIGGRAPH 2007):
// Shai Avidan and Ariel Shamir. 2007. Seam carving for content-aware image resizing.
// ACM Trans. Graph. 26, 3, Article 10 (July 2007).
// DOI=10.1145/1276377.1276390 http://doi.acm.org/10.1145/1276377.1276390
///////////////////////////////////////////////////////////////////////////
// Inputs
function buildArray(width, height, func) {
var length = width * height;
var array = new Array(length);
var index = 0;
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
array[index++] = func(y, x);
}
}
return array;
}
function parImage(seqImage, width, height) {
return new ParallelArray([height, width], function (y, x) {
return seqImage[y*width + x];
});
}
var tinyImage =
buildArray(20, 5, function(y, x) {
var ret;
if (6 <= x && x < 8 && 0 <= y && y < 4)
ret = ".";
else if ((x-15)*(x-15)+(y-1)*(y-1) < 2)
ret = "^";
else if ((x-20)*(x-20)+(y-3)*(y-3) < 2)
ret = "%";
else if ((x-1)*(x-1)+(y-3)*(y-3) < 2)
ret = "@";
else
ret = " ";
return ret.charCodeAt(0) - 32;
});
var SmallImageWidth = 60;
var SmallImageHeight = 15;
var SmallImage =
buildArray(SmallImageWidth, SmallImageHeight, function(y, x) {
var ret;
if (6 <= x && x < 8 && 0 <= y && y < 7)
ret = ".";
else if ((x-15)*(x-15)+(y-1)*(y-1) < 2)
ret = "^";
else if ((x-40)*(x-40)+(y-6)*(y-6) < 6)
ret = "%";
else if ((x-1)*(x-1)+(y-12)*(y-12) < 2)
ret = "@";
else
ret = " ";
return ret.charCodeAt(0) - 32;
});
var SmallImagePar = parImage(SmallImage,
SmallImageWidth,
SmallImageHeight);
var bigImage =
buildArray(200, 70, function(y, x) {
var ret;
if (4 <= x && x < 7 && 10 <= y && y < 40)
ret = ".";
else if ((x-150)*(x-150)+(y-13)*(y-13) < 70)
ret = "^";
else if ((x-201)*(x-201)+(y-33)*(y-33) < 200)
ret = "%";
else if ((x-15)*(x-15)+(y-3)*(y-3) < 7)
ret = "@";
else
ret = " ";
return ret.charCodeAt(0) - 32;
});
// randomImage: Nat Nat Nat Nat -> RectArray
function randomImage(w, h, sparsity, variety) {
return buildArray(w, h, function (x,y) {
if (Math.random() > 1/sparsity)
return 0;
else
return 1+Math.random()*variety|0;
});
}
// stripedImage: Nat Nat -> RectArray
function stripedImage(w, h) {
return buildArray(w, h, function (y, x) {
return (Math.abs(x%100-y%100) < 10) ? 32 : 0;
});
}
var massiveImage =
buildArray(70, 10000, function(y, x) (Math.abs(x%100-y%100) < 10) ? 32 : 0);
function printImage(array, width, height) {
print("Width", width, "Height", height);
for (var y = 0; y < height; y++) {
var line = "";
for (var x = 0; x < width; x++) {
var c = array[y*width + x];
line += String.fromCharCode(c + 32);
}
print(line);
}
}
///////////////////////////////////////////////////////////////////////////
// Common
var SobelX = [[-1.0, 0.0, 1.0],
[-2.0, 0.0, 2.0],
[-1.0, 0.0, 1.0]];
var SobelY = [[ 1.0, 2.0, 1.0],
[ 0.0, 0.0, 0.0],
[-1.0, -2.0, -1.0]];
// computeEnergy: Array -> RectArray
//
// (The return type is forced upon us, for now at least, until we add
// appropriate API to ParallelArray; there's a dependency from each
// row upon its predecessor, but the contents of each row could be
// computed in parallel.)
function computeEnergy(source, width, height) {
var energy = new Array(width * height);
energy[0] = 0;
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var e = source[y*width + x];
if (y >= 1) {
var p = energy[(y-1)*width + x];
if (x > 0) {
p = Math.min(p, energy[(y-1)*width + x-1]);
}
if (x < (width - 1)) {
p = Math.min(p, energy[(y-1)*width + x+1]);
}
e += p;
}
energy[y*width + x] = e;
}
}
return energy;
}
// findPath: RectArray -> Array
// (This is inherently sequential.)
function findPath(energy, width, height)
{
var path = new Array(height);
var y = height - 1;
var minPos = 0;
var minEnergy = energy[y*width + minPos];
for (var x = 1; x < width; x++) {
if (energy[y+width + x] < minEnergy) {
minEnergy = energy[y*width + x];
minPos = x;
}
}
path[y] = minPos;
for (y = height - 2; y >= 0; y--) {
minEnergy = energy[y*width + minPos];
// var line = energy[y]
var p = minPos;
if (p >= 1 && energy[y*width + p-1] < minEnergy) {
minPos = p-1; minEnergy = energy[y*width + p-1];
}
if (p < width - 1 && energy[y*width + p+1] < minEnergy) {
minPos = p+1; minEnergy = energy[y*width + p+1];
}
path[y] = minPos;
}
return path;
}
///////////////////////////////////////////////////////////////////////////
// Sequential
function transposeSeq(array, width, height) {
return buildArray(height, width, function(y, x) {
return array[x*width + y];
});
}
// detectEdgesSeq: Array Nat Nat -> Array
function detectEdgesSeq(data, width, height) {
var data1 = new Array(width * height);
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
var total = compute(y, x);
data1[y*width + x] = total | 0;
}
}
return data1;
function compute(y, x) {
var totalX = 0;
var totalY = 0;
var offYMin = (y == 0 ? 0 : -1);
var offYMax = (y == height - 1 ? 0 : 1);
var offXMin = (x == 0 ? 0 : -1);
var offXMax = (x == width - 1 ? 0 : 1);
for (var offY = offYMin; offY <= offYMax; offY++) {
for (var offX = offXMin; offX <= offXMax; offX++) {
var e = data[(y + offY) * width + x + offX];
totalX += e * SobelX[offY + 1][offX + 1];
totalY += e * SobelY[offY + 1][offX + 1];
}
}
return (Math.abs(totalX) + Math.abs(totalY))/8.0 | 0;
}
}
function cutPathHorizontallyBWSeq(array, width, height, path) {
return buildArray(width-1, height, function (y, x) {
if (x < path[y]-1)
return array[y*width + x];
if (x == path[y]-1)
return (array[y*width + x] + array[y*width + x+1]) / 2 | 0;
else
return array[y*width + x+1];
});
}
function cutPathVerticallyBWSeq(array, width, height, path) {
return buildArray(width, height-1, function (y, x) {
if (y < path[x]-1)
return array[y*width + x];
if (y == path[x]-1)
return (array[y*width + x] + array[(y+1)*width + x]) / 2 | 0;
else
return array[(y+1)*width + x];
});
}
function cutHorizontalSeamBWSeq(array, width, height)
{
var edges = detectEdgesSeq(array, width, height);
var energy = computeEnergy(edges, width, height);
var path = findPath(energy, width, height);
edges = null; // no longer live
return cutPathHorizontallyBWSeq(array, width, height, path);
}
function cutVerticalSeamBWSeq(array, width, height)
{
var arrayT = transposeSeq(array, width, height);
var edges = detectEdgesSeq(arrayT, height, width);
var energy = computeEnergy(edges, height, width);
var path = findPath(energy, height, width);
edges = null; // no longer live
return cutPathVerticallyBWSeq(array, width, height, path);
}
function reduceImageBWSeq(image,
width, height,
newWidth, newHeight,
intermediateFunc,
finalFunc) {
while (width > newWidth || height > newHeight) {
intermediateFunc(image, width, height);
if (width > newWidth) {
image = cutHorizontalSeamBWSeq(image, width, height);
width -= 1;
}
if (height > newHeight) {
image = cutVerticalSeamBWSeq(image, width, height);
height -= 1;
}
}
finalFunc(image, width, height);
return image;
}
///////////////////////////////////////////////////////////////////////////
// Parallel
function transposePar(image) {
var height = image.shape[0];
var width = image.shape[1];
return new ParallelArray([width, height], function (y, x) {
return image.get(x, y);
});
}
// detectEdgesSeq: Array Nat Nat -> Array
function detectEdgesPar(image) {
var height = image.shape[0];
var width = image.shape[1];
return new ParallelArray([height, width], function (y, x) {
var totalX = 0;
var totalY = 0;
var offYMin = (y == 0 ? 0 : -1);
var offYMax = (y == height - 1 ? 0 : 1);
var offXMin = (x == 0 ? 0 : -1);
var offXMax = (x == width - 1 ? 0 : 1);
for (var offY = offYMin; offY <= offYMax; offY++) {
for (var offX = offXMin; offX <= offXMax; offX++) {
var e = image.get(y + offY, x + offX);
totalX += e * SobelX[offY + 1][offX + 1];
totalY += e * SobelY[offY + 1][offX + 1];
}
}
var result = (Math.abs(totalX) + Math.abs(totalY))/8.0 | 0;
return result;
});
}
function cutPathHorizontallyBWPar(image, path) {
var height = image.shape[0];
var width = image.shape[1];
return new ParallelArray([height, width-1], function (y, x) {
if (x < path[y]-1)
return image.get(y, x);
if (x == path[y]-1)
return (image.get(y, x) + image.get(y, x+1)) / 2 | 0;
else
return image.get(y, x+1);
});
}
function cutPathVerticallyBWPar(image, path) {
var height = image.shape[0];
var width = image.shape[1];
return new ParallelArray([height-1, width], function (y, x) {
if (y < path[x]-1)
return image.get(y, x);
if (y == path[x]-1)
return (image.get(y, x) + image.get(y+1, x)) / 2 | 0;
else
return image.get(y+1, x);
});
}
function cutHorizontalSeamBWPar(image)
{
var height = image.shape[0];
var width = image.shape[1];
var edges = detectEdgesPar(image);
var energy = computeEnergy(edges.buffer, width, height);
var path = findPath(energy, width, height);
edges = null; // no longer live
return cutPathHorizontallyBWPar(image, path);
}
function cutVerticalSeamBWPar(image) {
var height = image.shape[0];
var width = image.shape[1];
var imageT = transposePar(image);
var edges = detectEdgesPar(imageT);
var energy = computeEnergy(edges.buffer, height, width);
var path = findPath(energy, height, width);
edges = null; // no longer live
return cutPathVerticallyBWPar(image, path);
}
function reduceImageBWPar(image,
newWidth, newHeight,
intermediateFunc,
finalFunc) {
var height = image.shape[0];
var width = image.shape[1];
while (width > newWidth || height > newHeight) {
intermediateFunc(image.buffer, width, height);
if (width > newWidth) {
image = cutHorizontalSeamBWPar(image);
width -= 1;
}
if (height > newHeight) {
image = cutVerticalSeamBWPar(image);
height -= 1;
}
}
finalFunc(image.buffer, width, height);
return image.buffer;
}
///////////////////////////////////////////////////////////////////////////
// Benchmarking via run.sh
var BenchmarkImageWidth = 512;
var BenchmarkImageHeight = 256;
var BenchmarkImage = stripedImage(BenchmarkImageWidth,
BenchmarkImageHeight);
var BenchmarkImagePar = parImage(BenchmarkImage,
BenchmarkImageWidth,
BenchmarkImageHeight);
var benchmarking = (typeof(MODE) != "undefined");
if (benchmarking) {
load(libdir + "util.js");
benchmark("LIQUID-RESIZE", 1, DEFAULT_MEASURE,
function() {
return reduceImageBWSeq(
BenchmarkImage,
BenchmarkImageWidth, BenchmarkImageHeight,
BenchmarkImageWidth/2, BenchmarkImageHeight/2,
function() {},
function() {});
},
function() {
return reduceImageBWPar(
BenchmarkImagePar,
BenchmarkImageWidth/2, BenchmarkImageHeight/2,
function() {},
function() {});
});
}
///////////////////////////////////////////////////////////////////////////
// Running (sanity check)
if (!benchmarking) {
var seqData =
reduceImageBWSeq(SmallImage, SmallImageWidth, SmallImageHeight,
SmallImageWidth - 15, SmallImageHeight - 10,
function() {},
printImage);
var parData =
reduceImageBWPar(SmallImagePar,
SmallImageWidth - 15, SmallImageHeight - 10,
function() {},
printImage);
assertEq(seqData, parData);
}

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,6 @@ D="$(dirname $0)"
S="$1" S="$1"
shift shift
for T in "$@"; do for T in "$@"; do
echo "$S" -e "'"'var libdir="'$D'/"; var MODE="'$MODE'";'"'" "$T" echo "$S" --ion-parallel-compile=on -e "'"'var libdir="'$D'/"; var MODE="'$MODE'";'"'" "$T"
"$S" -e 'var libdir="'$D'/"; var MODE="'$MODE'";' "$T" "$S" --ion-parallel-compile=on -e 'var libdir="'$D'/"; var MODE="'$MODE'";' "$T"
done done

View File

@ -31,6 +31,9 @@ function benchmark(label, w, m, seq, par) {
} }
if (mode(PAR)) { if (mode(PAR)) {
print("Warming up parallel runs");
warmup(w, par);
print("Measuring parallel runs"); print("Measuring parallel runs");
var [parTimes, parResult] = measureN(m, par); var [parTimes, parResult] = measureN(m, par);
} }

View File

@ -479,8 +479,14 @@ typedef JSObject*
typedef JSObject* typedef JSObject*
(*ConstructNavigatorProperty)(JSContext *cx, JS::Handle<JSObject*> naviObj); (*ConstructNavigatorProperty)(JSContext *cx, JS::Handle<JSObject*> naviObj);
// Check whether a constructor should be enabled for the given object.
// Note that the object should NOT be an Xray, since Xrays will end up
// defining constructors on the underlying object.
// This is a typedef for the function type itself, not the function
// pointer, so it's more obvious that pointers to a ConstructorEnabled
// can be null.
typedef bool typedef bool
(*PrefEnabled)(); (ConstructorEnabled)(JSContext* cx, JS::Handle<JSObject*> obj);
extern bool extern bool
DefineStaticJSVals(JSContext *cx); DefineStaticJSVals(JSContext *cx);

View File

@ -2,17 +2,10 @@
== tall--contain--width.html ref-tall-empty.html == tall--contain--width.html ref-tall-empty.html
== wide--contain--height.html ref-wide-empty.html == wide--contain--height.html ref-wide-empty.html
== wide--contain--width.html ref-wide-empty.html == wide--contain--width.html ref-wide-empty.html
== tall--cover--height.html ref-tall-lime.html
# We don't really care about the failures for this == tall--cover--width.html ref-tall-lime.html
# extreme edge case (the test exists more to test for safety against division by == wide--cover--height.html ref-wide-lime.html
# zero), so there is no bug has been filed to fix it, although a patch would == wide--cover--width.html ref-wide-lime.html
# probably be accepted.
# They're still marked as failing though, rather than 'load', since
# we want to know if they start working when we upgrade to Azure.
fails == tall--cover--height.html ref-tall-lime.html
fails == tall--cover--width.html ref-tall-lime.html
fails == wide--cover--height.html ref-wide-lime.html
fails == wide--cover--width.html ref-wide-lime.html
== zero-height-ratio-contain.html ref-tall-empty.html == zero-height-ratio-contain.html ref-tall-empty.html
== zero-height-ratio-cover.html ref-tall-empty.html == zero-height-ratio-cover.html ref-tall-empty.html

View File

@ -84,16 +84,10 @@ skip-if(B2G) == tall--contain--nonpercent-width-omitted-height-viewbox.html ref-
== tall--contain--percent-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html == tall--contain--percent-width-omitted-height-viewbox.html ref-tall-lime48x384-aqua48x384.html
== tall--contain--percent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html == tall--contain--percent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html
== tall--contain--percent-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html == tall--contain--percent-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html
== tall--cover--nonpercent-width-nonpercent-height.html ref-tall-lime256x512-aqua256x256.html
# We smear the background image when scaling it in these two tests... == tall--cover--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime256x512-aqua256x256.html
# Android uses FILTER_NEAREST for background images so the smear doesn't occur
fails-if(!(Android||B2G)) == tall--cover--nonpercent-width-nonpercent-height.html ref-tall-lime256x512-aqua256x256.html
fails-if(!(Android||B2G)) == tall--cover--nonpercent-width-nonpercent-height-viewbox.html ref-tall-lime256x512-aqua256x256.html
# ...but we don't in identical tests with image-rendering: -moz-crisp-edges.
== tall--cover--nonpercent-width-nonpercent-height--crisp.html ref-tall-lime256x512-aqua256x256.html == tall--cover--nonpercent-width-nonpercent-height--crisp.html ref-tall-lime256x512-aqua256x256.html
== tall--cover--nonpercent-width-nonpercent-height-viewbox--crisp.html ref-tall-lime256x512-aqua256x256.html == tall--cover--nonpercent-width-nonpercent-height-viewbox--crisp.html ref-tall-lime256x512-aqua256x256.html
== tall--cover--nonpercent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html == tall--cover--nonpercent-width-omitted-height.html ref-tall-lime256x384-aqua256x384.html
== tall--cover--nonpercent-width-omitted-height-viewbox.html ref-tall-lime256x768.html == tall--cover--nonpercent-width-omitted-height-viewbox.html ref-tall-lime256x768.html
== tall--cover--nonpercent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html == tall--cover--nonpercent-width-percent-height.html ref-tall-lime256x384-aqua256x384.html

View File

@ -154,4 +154,4 @@ HTTP == svg-stylesheet-external-1.html blue100x100.svg
# XXXseth: The underlying problems also apply to media fragments, # XXXseth: The underlying problems also apply to media fragments,
# but the test case would be much simpler. This should be switched # but the test case would be much simpler. This should be switched
# over to use media fragments once bug 790640 lands. # over to use media fragments once bug 790640 lands.
skip-if(B2G) == svg-border-image-repaint-1.html svg-border-image-repaint-1-ref.html skip-if(B2G) fuzzy(2,1) == svg-border-image-repaint-1.html svg-border-image-repaint-1-ref.html

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="80" height="80">
<circle cx="40" cy="40" r="40" style="fill: green"/>
</svg>

After

Width:  |  Height:  |  Size: 141 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="20" height="20">
<circle cx="10" cy="10" r="10" style="fill: green"/>
</svg>

After

Width:  |  Height:  |  Size: 141 B

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
border: 0px;
}
div {
background: url('circle-small.svg');
background-size: 40px 40px;
background-repeat: repeat;
margin: 0px;
padding: 0px;
border: 0px;
width: 80px;
height: 80px;
transform: scale(2.0);
transform-origin: 0 0;
}
</style>
</head>
<body>
<div></div>
</body>
</html>

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
border: 0px;
}
div {
background: url('circle-large.svg');
background-size: 40px 40px;
background-repeat: repeat;
margin: 0px;
padding: 0px;
border: 0px;
width: 80px;
height: 80px;
transform: scale(0.5);
transform-origin: 0 0;
}
</style>
</head>
<body>
<div></div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
border: 0px;
}
div {
background: url('circle-large.svg');
background-size: 80px 80px;
background-repeat: repeat;
margin: 0px;
padding: 0px;
border: 0px;
width: 160px;
height: 160px;
}
</style>
</head>
<body>
<div></div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html reftest-zoom="2.0">
<head>
<style>
body {
margin: 0px;
padding: 0px;
border: 0px;
}
div {
background: url('circle-small.svg');
background-size: 40px 40px;
background-repeat: repeat;
margin: 0px;
padding: 0px;
border: 0px;
width: 80px;
height: 80px;
}
</style>
</head>
<body>
<div></div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<!-- Any copyright is dedicated to the Public Domain.
- http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
border: 0px;
}
div {
background: url('circle-small.svg');
background-size: 20px 20px;
background-repeat: repeat;
margin: 0px;
padding: 0px;
border: 0px;
width: 40px;
height: 40px;
}
</style>
</head>
<body>
<div></div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More