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;
}
#searchLogoContainer[hidden] {
display: none;
}
#searchEngineLogo {
display: inline-block;
height: 28px;

View File

@ -144,18 +144,22 @@ const DEFAULT_SNIPPETS_URLS = [
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) {
for (let mutation of mutations) {
if (mutation.attributeName == "searchEngineURL") {
gObserver.disconnect();
setupSearchEngine();
if (!gInitialized) {
ensureSnippetsMapThen(loadSnippets);
gInitialized = true;
}
return;
}
}
});
window.addEventListener("load", function () {
window.addEventListener("pageshow", function () {
// Delay search engine setup, cause browser.js::BrowserOnAboutPageLoad runs
// later and may use asynchronous getters.
window.gObserver.observe(document.documentElement, { attributes: true });
@ -163,6 +167,11 @@ window.addEventListener("load", function () {
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
// the snippets data. It is lazily initialized by ensureSnippetsMapThen(), so
// 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);
}
docElt.setAttribute("snippetsVersion", AboutHomeUtils.snippetsVersion);
docElt.setAttribute("searchEngineName",
AboutHomeUtils.defaultSearchEngine.name);
docElt.setAttribute("searchEngineURL",
AboutHomeUtils.defaultSearchEngine.searchURL);
function updateSearchEngine() {
let engine = AboutHomeUtils.defaultSearchEngine;
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
doc.addEventListener("AboutHomeSearchEvent", function onSearch(e) {
@ -4299,6 +4312,7 @@ var TabsProgressListener = {
aBrowser.addEventListener("pagehide", function onPageHide(event) {
if (event.target.defaultView.frameElement)
return;
event.target.documentElement.removeAttribute("hasBrowserHandlers");
aBrowser.removeEventListener("click", BrowserOnClick, true);
aBrowser.removeEventListener("pagehide", onPageHide, true);
}, true);

View File

@ -243,6 +243,50 @@ let gTests = [
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;
gDebugger = gPane.panelWin;
expectUncaughtException();
testNormalReturn();
});
}

View File

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

View File

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

View File

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

View File

@ -319,6 +319,8 @@ gTests.push({
sendContextMenuClickToElement(window, item3, 10, 10);
yield promise;
yield waitForCondition(() => !deleteButton.hidden);
ok(!deleteButton.hidden, "Delete button is visible.");
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
gTests.push({
desc: "image context menu",
setUp: function() {
observeLogger.init();
},
tearDown: function() {
observeLogger.shutdown();
},
run: function test() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
info(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.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");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, win);
yield popupPromise;

View File

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

View File

@ -9127,6 +9127,18 @@ if test -n "$ARM_ARCH"; then
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
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"

View File

@ -21,7 +21,7 @@ interface nsIDOMBlob;
#include "jsapi.h"
%}
[scriptable, builtinclass, uuid(5bc978f2-41e5-4349-a12d-b018092271f7)]
[scriptable, builtinclass, uuid(ac97e161-9f1d-4163-adc9-e9a59e18682c)]
interface nsIXMLHttpRequestEventTarget : nsIDOMEventTarget {
// event handler attributes
[implicit_jscontext] attribute jsval onabort;
@ -133,7 +133,7 @@ interface nsIXMLHttpRequest : nsISupports
* The string representing the status of the response for
* HTTP requests.
*/
readonly attribute DOMString statusText;
readonly attribute ACString statusText;
/**
* 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.
* 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
@ -159,7 +159,7 @@ interface nsIXMLHttpRequest : nsISupports
* NULL if the response has not yet been received or the
* header does not exist in the response.
*/
ACString getResponseHeader(in AUTF8String header);
ACString getResponseHeader(in ACString header);
%{C++
// 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.
* 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,Undefined(Empty)] in DOMString user,
[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 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.

View File

@ -139,11 +139,11 @@ using namespace mozilla::dom;
#define NS_PROGRESS_EVENT_INTERVAL 50
#define IMPL_STRING_GETTER(_name) \
#define IMPL_CSTRING_GETTER(_name) \
NS_IMETHODIMP \
nsXMLHttpRequest::_name(nsAString& aOut) \
nsXMLHttpRequest::_name(nsACString& aOut) \
{ \
nsString tmp; \
nsCString tmp; \
_name(tmp); \
aOut = tmp; \
return NS_OK; \
@ -1128,9 +1128,9 @@ nsXMLHttpRequest::Status()
return status;
}
IMPL_STRING_GETTER(GetStatusText)
IMPL_CSTRING_GETTER(GetStatusText)
void
nsXMLHttpRequest::GetStatusText(nsString& aStatusText)
nsXMLHttpRequest::GetStatusText(nsCString& aStatusText)
{
nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel();
@ -1152,17 +1152,8 @@ nsXMLHttpRequest::GetStatusText(nsString& aStatusText)
}
}
nsCString statusText;
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);
}
httpChannel->GetResponseStatusText(aStatusText);
}
void
@ -1286,10 +1277,10 @@ nsXMLHttpRequest::IsSafeHeader(const nsACString& header, nsIHttpChannel* httpCha
return isSafe;
}
/* DOMString getAllResponseHeaders(); */
IMPL_STRING_GETTER(GetAllResponseHeaders)
/* ByteString getAllResponseHeaders(); */
IMPL_CSTRING_GETTER(GetAllResponseHeaders)
void
nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders)
nsXMLHttpRequest::GetAllResponseHeaders(nsCString& aResponseHeaders)
{
aResponseHeaders.Truncate();
@ -1303,7 +1294,7 @@ nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders)
if (nsCOMPtr<nsIHttpChannel> httpChannel = GetCurrentHttpChannel()) {
nsRefPtr<nsHeaderVisitor> visitor = new nsHeaderVisitor(this, httpChannel);
if (NS_SUCCEEDED(httpChannel->VisitResponseHeaders(visitor))) {
CopyASCIItoUTF16(visitor->Headers(), aResponseHeaders);
aResponseHeaders = visitor->Headers();
}
return;
}
@ -1316,10 +1307,10 @@ nsXMLHttpRequest::GetAllResponseHeaders(nsString& aResponseHeaders)
nsAutoCString value;
if (NS_SUCCEEDED(mChannel->GetContentType(value))) {
aResponseHeaders.AppendLiteral("Content-Type: ");
AppendASCIItoUTF16(value, aResponseHeaders);
aResponseHeaders.Append(value);
if (NS_SUCCEEDED(mChannel->GetContentCharset(value)) && !value.IsEmpty()) {
aResponseHeaders.AppendLiteral(";charset=");
AppendASCIItoUTF16(value, aResponseHeaders);
aResponseHeaders.Append(value);
}
aResponseHeaders.AppendLiteral("\r\n");
}
@ -2950,7 +2941,7 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
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
NS_IMETHODIMP
nsXMLHttpRequest::SetRequestHeader(const nsACString& header,

View File

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

View File

@ -2,6 +2,7 @@
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=638112
https://bugzilla.mozilla.org/show_bug.cgi?id=796850
-->
<head>
<title>Test for Bug 638112</title>
@ -10,15 +11,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=638112
</head>
<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=796850">Mozilla Bug 796850</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<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() {
var req = new XMLHttpRequest();
@ -26,7 +30,7 @@ function run_test() {
req.send(null);
var statusText = req.statusText;
is(statusText, "Information Sans-Autorit", "");
is(statusText, "Information Sans-Autorit\u00E9", "");
SimpleTest.finish();
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,3 +9,12 @@ EXTRA_COMPONENTS += [
'AppsService.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 \
$(NULL)
EXTRA_JS_MODULES = ConsoleAPIStorage.jsm \
$(NULL)
EXTRA_JS_MODULES += \
DOMRequestHelper.jsm \
IndexedDBHelper.jsm \
ObjectWrapper.jsm \
$(NULL)
include $(topsrcdir)/dom/dom-config.mk
ifdef MOZ_JSDEBUGGER

View File

@ -103,3 +103,10 @@ EXTRA_COMPONENTS += [
'SiteSpecificUserAgent.js',
'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
ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin)
OldBindingConstructorEnabled(const nsGlobalNameStruct *aStruct,
nsGlobalWindow *aWin)
{
MOZ_ASSERT(aStruct->mType == nsGlobalNameStruct::eTypeClassConstructor ||
aStruct->mType == nsGlobalNameStruct::eTypeExternalClassInfo);
@ -3998,11 +3999,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
name_struct->mDefineDOMInterface;
if (define) {
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor &&
!ConstructorEnabled(name_struct, aWin)) {
return NS_OK;
}
if (name_struct->mPrefEnabled && !(*name_struct->mPrefEnabled)()) {
!OldBindingConstructorEnabled(name_struct, aWin)) {
return NS_OK;
}
@ -4019,6 +4016,14 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
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;
JS::Rooted<JSObject*> interfaceObject(cx, define(cx, global, id, &enabled));
if (enabled) {
@ -4081,7 +4086,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor ||
name_struct->mType == nsGlobalNameStruct::eTypeExternalClassInfo) {
if (!ConstructorEnabled(name_struct, aWin)) {
if (!OldBindingConstructorEnabled(name_struct, aWin)) {
return NS_OK;
}
@ -4888,16 +4893,21 @@ nsNavigatorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
mozilla::dom::ConstructNavigatorProperty construct = name_struct->mConstructNavigatorProperty;
MOZ_ASSERT(construct);
if (name_struct->mPrefEnabled && !(*name_struct->mPrefEnabled)()) {
return NS_OK;
}
JS::Rooted<JSObject*> naviObj(cx, js::CheckedUnwrap(obj, /* stopAtOuter = */ false));
NS_ENSURE_TRUE(naviObj, NS_ERROR_DOM_SECURITY_ERR);
JS::Rooted<JSObject*> domObject(cx);
{
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);
if (!domObject) {
return NS_ERROR_FAILURE;

View File

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

View File

@ -55,6 +55,9 @@ struct nsGlobalNameStruct
eTypeExternalConstructorAlias
} 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 mDisabled;
@ -71,7 +74,8 @@ struct nsGlobalNameStruct
mozilla::dom::DefineInterface mDefineDOMInterface; // for window
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,
mozilla::dom::DefineInterface aDefineDOMInterface,
mozilla::dom::PrefEnabled aPrefEnabled);
mozilla::dom::ConstructorEnabled* aConstructorEnabled);
void RegisterNavigatorDOMConstructor(const nsAFlatString& aName,
mozilla::dom::ConstructNavigatorProperty aNavConstructor,
mozilla::dom::PrefEnabled aPrefEnabled);
mozilla::dom::ConstructorEnabled* aConstructorEnabled);
typedef PLDHashOperator
(* GlobalNameEnumerator)(const nsAString& aGlobalName, void* aClosure);

View File

@ -7,8 +7,10 @@
#include <algorithm>
#include <stdarg.h>
#include "prprf.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/Assertions.h"
#include "BindingUtils.h"
@ -1899,5 +1901,83 @@ ConstructJSImplementation(JSContext* aCx, const char* aContractId,
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 mozilla

View File

@ -1582,6 +1582,11 @@ ConvertJSValueToString(JSContext* cx, JS::Handle<JS::Value> v,
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
// to keep track of which of its UnionMembers has been constructed.
template<class T>
@ -2057,6 +2062,24 @@ bool
RegisterForDeferredFinalization(DeferredFinalizeStartFunction start,
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 mozilla

View File

@ -1978,7 +1978,11 @@ class CGPrefEnabledNative(CGAbstractMethod):
if the method returns true.
"""
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):
return " return %s::PrefEnabled();" % self.descriptor.nativeType
@ -1991,13 +1995,33 @@ class CGPrefEnabled(CGAbstractMethod):
on the global if the pref is true.
"""
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):
pref = self.descriptor.interface.getExtendedAttribute("Pref")
assert isinstance(pref, list) and len(pref) == 1
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):
def __init__(self, descriptor):
args = [Argument('JSObject*', 'obj')]
@ -3189,7 +3213,7 @@ for (uint32_t i = 0; i < length; ++i) {
declType=CGGeneric(declType),
holderType=holderType)
if type.isString():
if type.isDOMString():
assert not isEnforceRange and not isClamp
treatAs = {
@ -3255,6 +3279,24 @@ for (uint32_t i = 0; i < length; ++i) {
declType=CGGeneric(declType),
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():
assert not isEnforceRange and not isClamp
@ -3958,12 +4000,18 @@ if (!returnArray) {
wrappingCode += wrapAndSetPtr(wrap, failed)
return (wrappingCode, False)
if type.isString():
if type.isDOMString():
if type.nullable():
return (wrapAndSetPtr("xpc::StringToJsval(cx, %s, ${jsvalRef}.address())" % result), False)
else:
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.nullable():
resultLoc = "%s.Value()" % result
@ -4179,10 +4227,12 @@ def getRetvalDeclarationForType(returnType, descriptorProvider,
if returnType.nullable():
result = CGTemplatedType("Nullable", result)
return result, False, None, None
if returnType.isString():
if returnType.isDOMString():
if isMember:
return CGGeneric("nsString"), True, None, None
return CGGeneric("DOMString"), True, None, None
if returnType.isByteString():
return CGGeneric("nsCString"), True, None, None
if returnType.isEnum():
result = CGGeneric(returnType.unroll().inner.identifier.name)
if returnType.nullable():
@ -5655,9 +5705,12 @@ def getUnionAccessorSignatureType(type, descriptorProvider):
typeName = CGWrapper(typeName, post="&")
return typeName
if type.isString():
if type.isDOMString():
return CGGeneric("const nsAString&")
if type.isByteString():
return CGGeneric("const nsCString&")
if type.isEnum():
if type.nullable():
raise TypeError("We don't support nullable enumerated arguments or "
@ -7510,10 +7563,20 @@ class CGDescriptor(CGThing):
not descriptor.interface.isExternal() and
# Workers stuff is never pref-controlled
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))
elif descriptor.interface.getExtendedAttribute("Pref") is not None:
elif havePref is not None:
cgThings.append(CGPrefEnabled(descriptor))
elif haveChromeOnly is not None:
cgThings.append(CGConstructorEnabledChromeOnly(descriptor))
if descriptor.concrete:
if descriptor.proxy:
@ -8027,12 +8090,12 @@ class CGRegisterProtos(CGAbstractMethod):
def _defineMacro(self):
return """
#define REGISTER_PROTO(_dom_class, _pref_check) \\
aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _pref_check);
#define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _pref_check) \\
aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _pref_check);
#define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _pref_check) \\
aNameSpaceManager->RegisterNavigatorDOMConstructor(NS_LITERAL_STRING(_prop), _dom_class##Binding::ConstructNavigatorObject, _pref_check);
#define REGISTER_PROTO(_dom_class, _ctor_check) \\
aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_class), _dom_class##Binding::DefineDOMInterface, _ctor_check);
#define REGISTER_CONSTRUCTOR(_dom_constructor, _dom_class, _ctor_check) \\
aNameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING(#_dom_constructor), _dom_class##Binding::DefineDOMInterface, _ctor_check);
#define REGISTER_NAVIGATOR_CONSTRUCTOR(_prop, _dom_class, _ctor_check) \\
aNameSpaceManager->RegisterNavigatorDOMConstructor(NS_LITERAL_STRING(_prop), _dom_class##Binding::ConstructNavigatorObject, _ctor_check);
"""
def _undefineMacro(self):
@ -8041,23 +8104,24 @@ class CGRegisterProtos(CGAbstractMethod):
#undef REGISTER_PROTO
#undef REGISTER_NAVIGATOR_CONSTRUCTOR"""
def _registerProtos(self):
def getPrefCheck(desc):
def getCheck(desc):
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 "%sBinding::PrefEnabled" % desc.name
return "%sBinding::ConstructorEnabled" % desc.name
lines = []
for desc in self.config.getDescriptors(hasInterfaceObject=True,
isExternal=False,
workers=False,
register=True):
lines.append("REGISTER_PROTO(%s, %s);" % (desc.name, getPrefCheck(desc)))
lines.extend("REGISTER_CONSTRUCTOR(%s, %s, %s);" % (n.identifier.name, 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, getCheck(desc))
for n in desc.interface.namedConstructors)
for desc in self.config.getDescriptors(isNavigatorProperty=True, register=True):
propName = desc.interface.getNavigatorProperty()
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'
def definition_body(self):
return self._defineMacro() + self._registerProtos() + self._undefineMacro()
@ -8448,12 +8512,18 @@ class CGNativeMember(ClassMethod):
return (result.define(),
"%s(%s)" % (result.define(), defaultReturnArg),
"return ${declName};")
if type.isString():
if type.isDOMString():
if isMember:
# No need for a third element in the isMember case
return "nsString", None, None
# Outparam
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():
enumName = type.unroll().inner.identifier.name
if type.nullable():
@ -8532,8 +8602,10 @@ class CGNativeMember(ClassMethod):
def getArgs(self, returnType, argList):
args = [self.getArg(arg) for arg in argList]
# Now the outparams
if returnType.isString():
if returnType.isDOMString():
args.append(Argument("nsString&", "retval"))
if returnType.isByteString():
args.append(Argument("nsCString&", "retval"))
elif returnType.isSequence():
nullable = returnType.nullable()
if nullable:
@ -8627,13 +8699,17 @@ class CGNativeMember(ClassMethod):
typeDecl = typeDecl % type.name
return typeDecl, False, False
if type.isString():
if type.isDOMString():
if isMember:
declType = "nsString"
else:
declType = "nsAString"
return declType, True, False
if type.isByteString():
declType = "nsCString"
return declType, True, False
if type.isEnum():
return type.unroll().inner.identifier.name, False, True
@ -9500,7 +9576,7 @@ class CallbackMember(CGNativeMember):
jsvalIndex = "%d" % i
if arg.optional and not arg.defaultValue:
argval += ".Value()"
if arg.type.isString():
if arg.type.isDOMString():
# XPConnect string-to-JS conversion wants to mutate the string. So
# let's give it a string it can mutate
# 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_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_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.")

View File

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

View File

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

View File

@ -137,6 +137,10 @@ public:
already_AddRefed<TestInterface> Test(const GlobalObject&, const nsAString&,
ErrorResult&);
static
already_AddRefed<TestInterface> Test(const GlobalObject&, const nsACString&,
ErrorResult&);
static
already_AddRefed<TestInterface> Test2(const GlobalObject&,
JSContext*,
const DictForConstructor&,
@ -370,6 +374,9 @@ public:
void ReceiveStringSequence(nsTArray<nsString>&);
void PassStringSequence(const Sequence<nsString>&);
void ReceiveByteStringSequence(nsTArray<nsCString>&);
void PassByteStringSequence(const Sequence<nsCString>&);
void ReceiveAnySequence(JSContext*, nsTArray<JS::Value>&);
void ReceiveNullableAnySequence(JSContext*, Nullable<nsTArray<JS::Value> >&);
void ReceiveAnySequenceSequence(JSContext*, nsTArray<nsTArray<JS::Value> >&);
@ -398,7 +405,7 @@ public:
void PassFloat64Array(Float64Array&);
JSObject* ReceiveUint8Array(JSContext*);
// String types
// DOMString types
void PassString(const nsAString&);
void PassNullableString(const nsAString&);
void PassOptionalString(const Optional<nsAString>&);
@ -409,6 +416,13 @@ public:
void PassOptionalNullableStringWithDefaultValue(const nsAString&);
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
void PassEnum(TestEnum);
void PassNullableEnum(const Nullable<TestEnum>&);
@ -753,6 +767,13 @@ private:
void PassOptionalNullableStringWithDefaultValue(nsAString&) 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
void PassDictionary(JSContext*, Dict&) MOZ_DELETE;
void PassOtherDictionary(GrandparentDict&) MOZ_DELETE;

View File

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

View File

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

View File

@ -252,6 +252,7 @@ interface TestJSImplInterface {
void passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg);
sequence<DOMString> receiveStringSequence();
sequence<ByteString> receiveByteStringSequence();
// Callback interface problem. See bug 843261.
//void passStringSequence(sequence<DOMString> arg);
sequence<any> receiveAnySequence();
@ -287,7 +288,7 @@ interface TestJSImplInterface {
//void passFloat64Array(Float64Array arg);
//Uint8Array receiveUint8Array();
// String types
// DOMString types
void passString(DOMString arg);
void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg);
@ -298,6 +299,13 @@ interface TestJSImplInterface {
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
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
void passEnum(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 \
$(NULL)
EXTRA_JS_MODULES = \
BrowserElementPromptService.jsm \
BrowserElementParent.jsm \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -14,7 +14,14 @@ EXPORTS.mozilla.dom.mobilemessage += [
'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 += [
'MmsService.h',
'MobileMessageDatabaseService.h',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,3 +5,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
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 \
$(NULL)
EXTRA_JS_MODULES = \
PushService.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

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

View File

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

View File

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

View File

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

View File

@ -66,3 +66,11 @@ if CONFIG['ENABLE_TESTS']:
CPP_SOURCES += [
'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
EXTRA_COMPONENTS = \
$(NULL)
EXTRA_JS_MODULES = \
gonk/WbxmlPduHelper.jsm \
gonk/SiPduHelper.jsm \
gonk/SlPduHelper.jsm \
gonk/WapPushManager.js \
$(NULL)
endif
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
# 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
[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);
[Throws]
void setRequestHeader(DOMString header, DOMString value);
void setRequestHeader(ByteString header, ByteString value);
[SetterThrows]
attribute unsigned long timeout;
@ -109,12 +109,12 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
[Throws=Workers]
readonly attribute unsigned short status;
readonly attribute DOMString statusText;
readonly attribute ByteString statusText;
[Throws]
DOMString? getResponseHeader(DOMString header);
ByteString? getResponseHeader(ByteString header);
[Throws=Workers]
DOMString getAllResponseHeaders();
ByteString getAllResponseHeaders();
[Throws=Workers]
void overrideMimeType(DOMString mime);

View File

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

View File

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

View File

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

View File

@ -690,29 +690,50 @@ VectorImage::Draw(gfxContext* aContext,
AutoSVGRenderingState autoSVGState(aSVGContext,
time,
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();
// 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
gfxRect sourceRect = aUserSpaceToImageSpace.Transform(aFill);
gfxRect imageRect(0, 0, aViewportSize.width, aViewportSize.height);
gfxRect subimage(aSubimage.x, aSubimage.y, aSubimage.width, aSubimage.height);
gfxRect sourceRect = unscaledTransform.Transform(aFill);
gfxRect imageRect(0, 0, scaledViewport.width, scaledViewport.height);
gfxRect subimage(scaledSubimage.x, scaledSubimage.y,
scaledSubimage.width, scaledSubimage.height);
nsRefPtr<gfxDrawingCallback> cb =
new SVGDrawingCallback(mSVGDocumentWrapper,
nsIntRect(nsIntPoint(0, 0), aViewportSize),
nsIntRect(nsIntPoint(0, 0), scaledViewport),
aFlags);
nsRefPtr<gfxDrawable> drawable = new gfxCallbackDrawable(cb, imageSizeGfx);
nsRefPtr<gfxDrawable> drawable = new gfxCallbackDrawable(cb, scaledViewportGfx);
gfxUtils::DrawPixelSnapped(aContext, drawable,
aUserSpaceToImageSpace,
unscaledTransform,
subimage, sourceRect, imageRect, aFill,
gfxASurface::ImageFormatARGB32, aFilter,
aFlags);

View File

@ -7,3 +7,8 @@
CSRCS += [
'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
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
DISABLE_SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
LIBS = \
$(XPCOM_STATICRUNTIME_GLUE_LDOPTS) \

View File

@ -12,3 +12,8 @@ CPP_SOURCES += [
'NormalizationTest.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
kvm.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 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());
}
@ -4025,7 +4025,7 @@ CheckComparison(FunctionCompiler &f, ParseNode *comp, MDefinition **def, Type *t
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());
}

View File

@ -1995,17 +1995,23 @@ BaselineCompiler::emitInitPropGetterSetter()
JS_ASSERT(JSOp(*pc) == JSOP_INITPROP_GETTER ||
JSOp(*pc) == JSOP_INITPROP_SETTER);
// Load value in R0, keep object on the stack.
frame.popRegsAndSync(1);
// Load value in R0 but keep it on the stack for the decompiler.
frame.syncStack(0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0);
prepareVMCall();
pushArg(R0);
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(ImmWord(pc));
return callVM(InitPropGetterSetterInfo);
if (!callVM(InitPropGetterSetterInfo))
return false;
frame.pop();
return true;
}
bool
@ -2031,17 +2037,25 @@ BaselineCompiler::emitInitElemGetterSetter()
JS_ASSERT(JSOp(*pc) == JSOP_INITELEM_GETTER ||
JSOp(*pc) == JSOP_INITELEM_SETTER);
// Load index and value in R0 and R1, keep object on the stack.
frame.popRegsAndSync(2);
// Load index and value in R0 and R1, but keep values on the stack for the
// decompiler.
frame.syncStack(0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-2)), R0);
masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R1);
prepareVMCall();
pushArg(R1);
pushArg(R0);
masm.extractObject(frame.addressOfStackValue(frame.peek(-1)), R0.scratchReg());
masm.extractObject(frame.addressOfStackValue(frame.peek(-3)), R0.scratchReg());
pushArg(R0.scratchReg());
pushArg(ImmWord(pc));
return callVM(InitElemGetterSetterInfo);
if (!callVM(InitElemGetterSetterInfo))
return false;
frame.popn(2);
return true;
}
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");
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) {
var resultArray = new Array(w * h);
for (var x = 0; x < w; x++) {
for (var y = 0; y < h; y++) {
resultArray[x*h + y] = (Math.abs(x%100-y%100) < 10) ? 32 : 0;
for (var x = 0; x < w; x++) {
resultArray[y*w + x] = (Math.abs(x%100-y%100) < 10) ? 32 : 0;
}
}
return resultArray;
}
function edges1dArraySequentially(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 edgesSequentially(data, width, height) {
var data1 = new Array(width * height);
for (var y = 0; y < height; y++) {
for (var x = 0; x < width; x++) {
// process pixel
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 = 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;
var total = compute(x, y);
data1[y*width + x] = total | 0;
}
}
return data1;
}
/* Compute edges using a flat JS array as input */
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) {
function compute(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 = data[pointIndex];
totalX += e * sobelX[offY + 1][offX + 1];
totalY += e * sobelY[offY + 1][offX + 1];
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];
}
}
}
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 edges1dParallelArrayInParallel(pa, 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) {
function edgesParallel(data) {
var pa = new ParallelArray([Height, Width], function (y, x) {
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(pointIndex);
totalX += e * sobelX[offY + 1][offX + 1];
totalY += e * sobelY[offY + 1][offX + 1];
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.get(y + offY, 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);
}
/* 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);
return (Math.abs(totalX) + Math.abs(totalY))/8.0 | 0;
});
return pa.flatten();
}
var Width = 1024;
var Height = 768;
var ArrInput = stripedImage(1024, 768);
var ParArrInput1D = new ParallelArray(ArrInput);
var ParArrInput2D = new ParallelArray([1024, 768],
function (x, y) ArrInput[x*Height + y]);
var ArrInput = stripedImage(Width, Height);
var ParArrInput2D = new ParallelArray([Height, Width],
function (y, x) ArrInput[y*Width + x]);
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"
shift
for T in "$@"; do
echo "$S" -e "'"'var libdir="'$D'/"; var MODE="'$MODE'";'"'" "$T"
"$S" -e 'var libdir="'$D'/"; var MODE="'$MODE'";' "$T"
echo "$S" --ion-parallel-compile=on -e "'"'var libdir="'$D'/"; var MODE="'$MODE'";'"'" "$T"
"$S" --ion-parallel-compile=on -e 'var libdir="'$D'/"; var MODE="'$MODE'";' "$T"
done

View File

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

View File

@ -479,8 +479,14 @@ typedef JSObject*
typedef JSObject*
(*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
(*PrefEnabled)();
(ConstructorEnabled)(JSContext* cx, JS::Handle<JSObject*> obj);
extern bool
DefineStaticJSVals(JSContext *cx);

View File

@ -2,17 +2,10 @@
== tall--contain--width.html ref-tall-empty.html
== wide--contain--height.html ref-wide-empty.html
== wide--contain--width.html ref-wide-empty.html
# We don't really care about the failures for this
# extreme edge case (the test exists more to test for safety against division by
# zero), so there is no bug has been filed to fix it, although a patch would
# 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
== tall--cover--height.html ref-tall-lime.html
== tall--cover--width.html ref-tall-lime.html
== wide--cover--height.html ref-wide-lime.html
== wide--cover--width.html ref-wide-lime.html
== zero-height-ratio-contain.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-percent-height.html ref-tall-lime256x384-aqua256x384.html
== tall--contain--percent-width-percent-height-viewbox.html ref-tall-lime48x384-aqua48x384.html
# We smear the background image when scaling it in these two tests...
# 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.html ref-tall-lime256x512-aqua256x256.html
== tall--cover--nonpercent-width-nonpercent-height-viewbox.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-omitted-height.html ref-tall-lime256x384-aqua256x384.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

View File

@ -154,4 +154,4 @@ HTTP == svg-stylesheet-external-1.html blue100x100.svg
# XXXseth: The underlying problems also apply to media fragments,
# but the test case would be much simpler. This should be switched
# 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