mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
be3c66b5a5
@ -9,7 +9,12 @@
|
||||
<?xml-stylesheet href="chrome://browser/content/downloads/downloads.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/downloads/downloads.css"?>
|
||||
|
||||
<!DOCTYPE overlay SYSTEM "chrome://browser/locale/downloads/downloads.dtd">
|
||||
<!DOCTYPE overlay [
|
||||
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
|
||||
%browserDTD;
|
||||
<!ENTITY % downloadsDTD SYSTEM "chrome://browser/locale/downloads/downloads.dtd" >
|
||||
%downloadsDTD;
|
||||
]>
|
||||
|
||||
<overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
@ -23,7 +28,7 @@
|
||||
toolbar handling code could remove it from the document. -->
|
||||
<toolbarbutton id="downloads-indicator"
|
||||
class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
tooltiptext="&indicator.tooltiptext;"
|
||||
tooltiptext="&downloads.tooltip;"
|
||||
collapsed="true"
|
||||
oncommand="DownloadsIndicatorView.onCommand(event);"
|
||||
ondrop="DownloadsIndicatorView.onDrop(event);"
|
||||
|
@ -14,6 +14,7 @@ include $(DEPTH)/config/autoconf.mk
|
||||
# browser_526613.js is disabled because of frequent failures (bug 534489)
|
||||
# browser_589246.js is disabled for leaking browser windows (bug 752467)
|
||||
# browser_580512.js is disabled for leaking browser windows (bug 752467)
|
||||
# browser_586068-reload.js is disabled due to generally being broken (bug 809123, 797263)
|
||||
|
||||
MOCHITEST_BROWSER_FILES = \
|
||||
head.js \
|
||||
@ -88,7 +89,6 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_586068-browser_state_interrupted.js \
|
||||
browser_586068-cascade.js \
|
||||
browser_586068-multi_window.js \
|
||||
browser_586068-reload.js \
|
||||
browser_586068-select.js \
|
||||
browser_586068-window_state.js \
|
||||
browser_586068-window_state_override.js \
|
||||
|
@ -2,11 +2,6 @@
|
||||
- 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/. -->
|
||||
|
||||
<!-- LOCALIZATION NOTE (indicator.tooltiptext):
|
||||
Tooltip for the indicator that displays the progress of ongoing downloads.
|
||||
-->
|
||||
<!ENTITY indicator.tooltiptext "Downloads">
|
||||
|
||||
<!-- LOCALIZATION NOTE (downloads.title):
|
||||
Used by screen readers to describe the Downloads Panel.
|
||||
-->
|
||||
|
@ -160,37 +160,53 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
|
||||
|
||||
/*** Status and progress indicator ***/
|
||||
|
||||
#downloads-indicator {
|
||||
width: 35px;
|
||||
}
|
||||
|
||||
#downloads-indicator-anchor {
|
||||
min-width: 18px;
|
||||
min-height: 18px;
|
||||
/* Makes the outermost stack element positioned, so that its contents are
|
||||
rendered over the main browser window in the Z order. This is required by
|
||||
the animated event notification. */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
toolbar[iconsize="small"] #downloads-indicator-anchor {
|
||||
min-width: 16px;
|
||||
min-height: 16px;
|
||||
}
|
||||
|
||||
toolbar[iconsize="large"] #downloads-indicator-anchor {
|
||||
min-width: 24px;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
/*** Main indicator icon ***/
|
||||
|
||||
#downloads-indicator-icon {
|
||||
toolbar[iconsize="small"] #downloads-indicator-icon {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"),
|
||||
0, 16, 16, 0) center no-repeat;
|
||||
}
|
||||
|
||||
toolbar[iconsize="large"] #downloads-indicator-icon {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
|
||||
0, 24, 24, 0) center no-repeat;
|
||||
}
|
||||
|
||||
#downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
|
||||
16, 32, 32, 16) center no-repeat;
|
||||
}
|
||||
|
||||
#downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
toolbar[iconsize="small"] #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"),
|
||||
0, 16, 16, 0) center no-repeat;
|
||||
background-size: 12px;
|
||||
}
|
||||
|
||||
toolbar[iconsize="large"] #downloads-indicator:not([counter]) > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
|
||||
0, 24, 24, 0) center no-repeat;
|
||||
background-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
#downloads-indicator:not([counter])[attention] > #downloads-indicator-anchor > #downloads-indicator-progress-area > #downloads-indicator-counter {
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
|
||||
16, 32, 32, 16);
|
||||
|
@ -157,10 +157,6 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
|
||||
|
||||
/*** Status and progress indicator ***/
|
||||
|
||||
#downloads-indicator {
|
||||
width: 35px;
|
||||
}
|
||||
|
||||
#downloads-indicator-anchor {
|
||||
min-width: 20px;
|
||||
min-height: 20px;
|
||||
|
@ -159,13 +159,7 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
|
||||
|
||||
/*** Status and progress indicator ***/
|
||||
|
||||
#downloads-indicator {
|
||||
width: 35px;
|
||||
}
|
||||
|
||||
#downloads-indicator-anchor {
|
||||
min-width: 18px;
|
||||
min-height: 18px;
|
||||
/* Makes the outermost stack element positioned, so that its contents are
|
||||
rendered over the main browser window in the Z order. This is required by
|
||||
the animated event notification. */
|
||||
@ -177,6 +171,8 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
|
||||
#downloads-indicator-icon {
|
||||
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
|
||||
0, 108, 18, 90) center no-repeat;
|
||||
min-width: 18px;
|
||||
min-height: 18px;
|
||||
}
|
||||
|
||||
#downloads-indicator-icon:-moz-lwtheme-brighttext {
|
||||
|
@ -243,8 +243,17 @@ case "$target" in
|
||||
android_platform_tools="$android_sdk"/tools # SDK Tools < r8
|
||||
fi
|
||||
ANDROID_SDK="${android_sdk}"
|
||||
if test -e "${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar" ; then
|
||||
ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar"
|
||||
else
|
||||
ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/support/v4/android-support-v4.jar";
|
||||
fi
|
||||
ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
|
||||
AC_SUBST(ANDROID_SDK)
|
||||
AC_SUBST(ANDROID_COMPAT_LIB)
|
||||
if ! test -e $ANDROID_COMPAT_LIB ; then
|
||||
AC_MSG_ERROR([You must download the andrioid compatibility library when targeting Android. (found $ANDROID_COMPAT_LIB)])
|
||||
fi
|
||||
AC_SUBST(ANDROID_PLATFORM_TOOLS)
|
||||
;;
|
||||
esac
|
||||
|
@ -93,7 +93,7 @@ classes.dex: $(_JAVA_HARNESS)
|
||||
classes.dex: $(_JAVA_TESTS)
|
||||
$(NSINSTALL) -D classes
|
||||
$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(addprefix $(DEPTH)/mobile/android/base/tests/,$(_JAVA_TESTS))
|
||||
$(DX) --dex --output=$@ classes $(ROBOTIUM_PATH)
|
||||
$(DX) --dex --output=$@ classes $(ROBOTIUM_PATH) $(ANDROID_COMPT_LIB)
|
||||
|
||||
robocop.ap_: AndroidManifest.xml $(TESTPATH)/assets/*
|
||||
$(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./
|
||||
|
@ -4,12 +4,13 @@
|
||||
|
||||
package com.mozilla.SUTAgentAndroid.service;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Timer;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
|
||||
import com.mozilla.SUTAgentAndroid.R;
|
||||
@ -39,6 +40,7 @@ public class ASMozStub extends android.app.Service {
|
||||
RunDataThread runDataThrd = null;
|
||||
Thread monitor = null;
|
||||
Timer timer = null;
|
||||
boolean doZeroConfig = false;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final Class<?>[] mSetForegroundSignature = new Class[] {
|
||||
@ -178,14 +180,24 @@ public class ASMozStub extends android.app.Service {
|
||||
runDataThrd.start();
|
||||
doToast(String.format("Data channel port %d ...", DATA_PORT));
|
||||
|
||||
startZeroConf();
|
||||
DoCommand tmpdc = new DoCommand(getApplication());
|
||||
File dir = getFilesDir();
|
||||
File iniFile = new File(dir, "SUTAgent.ini");
|
||||
String sIniFile = iniFile.getAbsolutePath();
|
||||
String zeroconf = tmpdc.GetIniData("General", "ZeroConfig", sIniFile);
|
||||
if (zeroconf != "" && Integer.parseInt(zeroconf) == 1) {
|
||||
this.doZeroConfig = true;
|
||||
}
|
||||
|
||||
if (this.doZeroConfig) {
|
||||
startZeroConf();
|
||||
}
|
||||
|
||||
Notification notification = new Notification();
|
||||
startForegroundCompat(R.string.foreground_service_started, notification);
|
||||
}
|
||||
catch (Exception e) {
|
||||
doToast(e.toString());
|
||||
// Toast.makeText(getApplication().getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
return;
|
||||
@ -195,7 +207,9 @@ public class ASMozStub extends android.app.Service {
|
||||
{
|
||||
super.onDestroy();
|
||||
|
||||
stopZeroConf();
|
||||
if (this.doZeroConfig) {
|
||||
stopZeroConf();
|
||||
}
|
||||
|
||||
if (runCmdThrd.isAlive())
|
||||
{
|
||||
|
@ -8,11 +8,14 @@ import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
@ -46,6 +49,8 @@ import android.os.Environment;
|
||||
|
||||
public class WatcherService extends Service
|
||||
{
|
||||
private final String prgVersion = "Watcher Version 1.15";
|
||||
|
||||
String sErrorPrefix = "##Installer Error## ";
|
||||
String currentDir = "/";
|
||||
String sPingTarget = "";
|
||||
@ -53,6 +58,7 @@ public class WatcherService extends Service
|
||||
long lPeriod = 300000;
|
||||
int nMaxStrikes = 0; // maximum number of tries before we consider network unreachable (0 means don't check)
|
||||
boolean bStartSUTAgent = true;
|
||||
boolean bStartedTimer = false;
|
||||
|
||||
Process pProc;
|
||||
Context myContext = null;
|
||||
@ -217,9 +223,13 @@ public class WatcherService extends Service
|
||||
}
|
||||
else if (sCmd.equalsIgnoreCase("start"))
|
||||
{
|
||||
doToast("WatcherService started");
|
||||
myTimer = new Timer();
|
||||
myTimer.scheduleAtFixedRate(new MyTime(), lDelay, lPeriod);
|
||||
if (!this.bStartedTimer) {
|
||||
doToast("WatcherService started");
|
||||
myTimer = new Timer();
|
||||
Date startSchedule = new Date(System.currentTimeMillis() + lDelay);
|
||||
myTimer.schedule(new MyTime(), startSchedule, lPeriod);
|
||||
this.bStartedTimer = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -230,15 +240,33 @@ public class WatcherService extends Service
|
||||
doToast("WatcherService created");
|
||||
}
|
||||
|
||||
public void writeVersion() {
|
||||
PrintWriter pw = null;
|
||||
String appPath = getApplicationContext().getFilesDir().getAbsolutePath();
|
||||
String versionPath = appPath + "/version.txt";
|
||||
Log.i("Watcher", "writing version string to: " + versionPath);
|
||||
try {
|
||||
pw = new PrintWriter(new FileWriter(versionPath, true));
|
||||
pw.println(this.prgVersion);
|
||||
} catch (IOException ioe) {
|
||||
Log.e("Watcher", "Exception writing version: " + this.prgVersion + " to file: " + versionPath);
|
||||
} finally {
|
||||
if (pw != null) {
|
||||
pw.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(Intent intent, int startId) {
|
||||
writeVersion();
|
||||
handleCommand(intent);
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
writeVersion();
|
||||
handleCommand(intent);
|
||||
return START_STICKY;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ endif
|
||||
|
||||
# For Android, this defaults to $(ANDROID_SDK)/android.jar
|
||||
ifndef JAVA_BOOTCLASSPATH
|
||||
JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar
|
||||
JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar:$(ANDROID_COMPAT_LIB)
|
||||
endif
|
||||
|
||||
# For Android, we default to 1.5
|
||||
|
@ -42,7 +42,7 @@ nsReferencedElement.h \
|
||||
nsTreeSanitizer.h \
|
||||
nsXMLNameSpaceMap.h \
|
||||
nsIXFormsUtilityService.h \
|
||||
nsBlobProtocolHandler.h \
|
||||
nsHostObjectProtocolHandler.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla/dom mozilla
|
||||
|
@ -1,51 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsBlobProtocolHandler_h
|
||||
#define nsBlobProtocolHandler_h
|
||||
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define BLOBURI_SCHEME "blob"
|
||||
|
||||
class nsIDOMBlob;
|
||||
class nsIPrincipal;
|
||||
class nsIInputStream;
|
||||
|
||||
inline bool IsBlobURI(nsIURI* aUri)
|
||||
{
|
||||
bool isBlob;
|
||||
return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob;
|
||||
}
|
||||
|
||||
extern nsresult
|
||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
|
||||
|
||||
class nsBlobProtocolHandler : public nsIProtocolHandler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIProtocolHandler methods:
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
|
||||
// nsBlobProtocolHandler methods:
|
||||
nsBlobProtocolHandler() {}
|
||||
virtual ~nsBlobProtocolHandler() {}
|
||||
|
||||
// Methods for managing uri->file mapping
|
||||
static void AddFileDataEntry(nsACString& aUri,
|
||||
nsIDOMBlob* aFile,
|
||||
nsIPrincipal* aPrincipal);
|
||||
static void RemoveFileDataEntry(nsACString& aUri);
|
||||
static nsIPrincipal* GetFileDataEntryPrincipal(nsACString& aUri);
|
||||
};
|
||||
|
||||
#define NS_BLOBPROTOCOLHANDLER_CID \
|
||||
{ 0xb43964aa, 0xa078, 0x44b2, \
|
||||
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
|
||||
|
||||
#endif /* nsBlobProtocolHandler_h */
|
81
content/base/public/nsHostObjectProtocolHandler.h
Normal file
81
content/base/public/nsHostObjectProtocolHandler.h
Normal file
@ -0,0 +1,81 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsHostObjectProtocolHandler_h
|
||||
#define nsHostObjectProtocolHandler_h
|
||||
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#define BLOBURI_SCHEME "blob"
|
||||
#define MEDIASTREAMURI_SCHEME "mediastream"
|
||||
|
||||
class nsIDOMBlob;
|
||||
class nsIDOMMediaStream;
|
||||
class nsIPrincipal;
|
||||
class nsIInputStream;
|
||||
|
||||
class nsHostObjectProtocolHandler : public nsIProtocolHandler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIProtocolHandler methods, except for GetScheme which is only defined
|
||||
// in subclasses.
|
||||
NS_IMETHOD GetDefaultPort(int32_t *aDefaultPort);
|
||||
NS_IMETHOD GetProtocolFlags(uint32_t *aProtocolFlags);
|
||||
NS_IMETHOD NewURI(const nsACString & aSpec, const char * aOriginCharset, nsIURI *aBaseURI, nsIURI * *_retval);
|
||||
NS_IMETHOD NewChannel(nsIURI *aURI, nsIChannel * *_retval);
|
||||
NS_IMETHOD AllowPort(int32_t port, const char * scheme, bool *_retval);
|
||||
|
||||
// Methods for managing uri->object mapping
|
||||
// AddDataEntry creates the URI with the given scheme and returns it in aUri
|
||||
static nsresult AddDataEntry(const nsACString& aScheme,
|
||||
nsISupports* aObject,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri);
|
||||
static void RemoveDataEntry(const nsACString& aUri);
|
||||
static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri);
|
||||
};
|
||||
|
||||
class nsBlobProtocolHandler : public nsHostObjectProtocolHandler
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD GetScheme(nsACString &result);
|
||||
};
|
||||
|
||||
class nsMediaStreamProtocolHandler : public nsHostObjectProtocolHandler
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD GetScheme(nsACString &result);
|
||||
};
|
||||
|
||||
inline bool IsBlobURI(nsIURI* aUri)
|
||||
{
|
||||
bool isBlob;
|
||||
return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob;
|
||||
}
|
||||
|
||||
inline bool IsMediaStreamURI(nsIURI* aUri)
|
||||
{
|
||||
bool isStream;
|
||||
return NS_SUCCEEDED(aUri->SchemeIs(MEDIASTREAMURI_SCHEME, &isStream)) && isStream;
|
||||
}
|
||||
|
||||
extern nsresult
|
||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
|
||||
|
||||
extern nsresult
|
||||
NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream);
|
||||
|
||||
#define NS_BLOBPROTOCOLHANDLER_CID \
|
||||
{ 0xb43964aa, 0xa078, 0x44b2, \
|
||||
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
|
||||
|
||||
#define NS_MEDIASTREAMPROTOCOLHANDLER_CID \
|
||||
{ 0x27d1fa24, 0x2b73, 0x4db3, \
|
||||
{ 0xab, 0x48, 0xb9, 0x83, 0x83, 0x40, 0xe0, 0x81 } }
|
||||
|
||||
#endif /* nsHostObjectProtocolHandler_h */
|
@ -79,8 +79,8 @@ class Element;
|
||||
} // namespace mozilla
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x0e1324c9, 0xc997, 0x447e, \
|
||||
{ 0xbc, 0xd9, 0xa6, 0x57, 0x80, 0x29, 0x91, 0xe4 } }
|
||||
{ 0x20d19edb, 0xa74c, 0x4ce4, \
|
||||
{ 0xb2, 0x7c, 0x5b, 0xdd, 0x6f, 0xbd, 0x2b, 0x66 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -1557,13 +1557,13 @@ public:
|
||||
virtual nsISupports* GetCurrentContentSink() = 0;
|
||||
|
||||
/**
|
||||
* Register/Unregister a filedata uri as being "owned" by this document.
|
||||
* Register/Unregister a hostobject uri as being "owned" by this document.
|
||||
* I.e. that its lifetime is connected with this document. When the document
|
||||
* goes away it should "kill" the uri by calling
|
||||
* nsBlobProtocolHandler::RemoveFileDataEntry
|
||||
* nsHostObjectProtocolHandler::RemoveDataEntry
|
||||
*/
|
||||
virtual void RegisterFileDataUri(const nsACString& aUri) = 0;
|
||||
virtual void UnregisterFileDataUri(const nsACString& aUri) = 0;
|
||||
virtual void RegisterHostObjectUri(const nsACString& aUri) = 0;
|
||||
virtual void UnregisterHostObjectUri(const nsACString& aUri) = 0;
|
||||
|
||||
virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0;
|
||||
virtual void ScrollToRef() = 0;
|
||||
|
@ -127,8 +127,8 @@ CPPSRCS = \
|
||||
nsXMLNameSpaceMap.cpp \
|
||||
FragmentOrElement.cpp \
|
||||
Link.cpp \
|
||||
nsBlobProtocolHandler.cpp \
|
||||
nsBlobURI.cpp \
|
||||
nsHostObjectProtocolHandler.cpp \
|
||||
nsHostObjectURI.cpp \
|
||||
nsFrameMessageManager.cpp \
|
||||
nsInProcessTabChildGlobal.cpp \
|
||||
ThirdPartyUtil.cpp \
|
||||
|
@ -1,217 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsBlobProtocolHandler.h"
|
||||
#include "nsBlobURI.h"
|
||||
#include "nsError.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDOMFile.h"
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Hash table
|
||||
struct FileDataInfo
|
||||
{
|
||||
nsCOMPtr<nsIDOMBlob> mFile;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
static nsClassHashtable<nsCStringHashKey, FileDataInfo>* gFileDataTable;
|
||||
|
||||
void
|
||||
nsBlobProtocolHandler::AddFileDataEntry(nsACString& aUri,
|
||||
nsIDOMBlob* aFile,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
if (!gFileDataTable) {
|
||||
gFileDataTable = new nsClassHashtable<nsCStringHashKey, FileDataInfo>;
|
||||
gFileDataTable->Init();
|
||||
}
|
||||
|
||||
FileDataInfo* info = new FileDataInfo;
|
||||
|
||||
info->mFile = aFile;
|
||||
info->mPrincipal = aPrincipal;
|
||||
|
||||
gFileDataTable->Put(aUri, info);
|
||||
}
|
||||
|
||||
void
|
||||
nsBlobProtocolHandler::RemoveFileDataEntry(nsACString& aUri)
|
||||
{
|
||||
if (gFileDataTable) {
|
||||
gFileDataTable->Remove(aUri);
|
||||
if (gFileDataTable->Count() == 0) {
|
||||
delete gFileDataTable;
|
||||
gFileDataTable = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsBlobProtocolHandler::GetFileDataEntryPrincipal(nsACString& aUri)
|
||||
{
|
||||
if (!gFileDataTable) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileDataInfo* res;
|
||||
gFileDataTable->Get(aUri, &res);
|
||||
if (!res) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return res->mPrincipal;
|
||||
}
|
||||
|
||||
static FileDataInfo*
|
||||
GetFileDataInfo(const nsACString& aUri)
|
||||
{
|
||||
NS_ASSERTION(StringBeginsWith(aUri,
|
||||
NS_LITERAL_CSTRING(BLOBURI_SCHEME ":")),
|
||||
"Bad URI");
|
||||
|
||||
if (!gFileDataTable) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileDataInfo* res;
|
||||
gFileDataTable->Get(aUri, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Protocol handler
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsBlobProtocolHandler, nsIProtocolHandler)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobProtocolHandler::GetScheme(nsACString &result)
|
||||
{
|
||||
result.AssignLiteral(BLOBURI_SCHEME);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobProtocolHandler::GetDefaultPort(int32_t *result)
|
||||
{
|
||||
*result = -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobProtocolHandler::GetProtocolFlags(uint32_t *result)
|
||||
{
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS |
|
||||
URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
const char *aCharset,
|
||||
nsIURI *aBaseURI,
|
||||
nsIURI **aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
nsresult rv;
|
||||
|
||||
FileDataInfo* info =
|
||||
GetFileDataInfo(aSpec);
|
||||
|
||||
nsRefPtr<nsBlobURI> uri =
|
||||
new nsBlobURI(info ? info->mPrincipal.get() : nullptr);
|
||||
|
||||
rv = uri->SetSpec(aSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_TryToSetImmutable(uri);
|
||||
uri.forget(aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
||||
{
|
||||
*result = nullptr;
|
||||
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
|
||||
FileDataInfo* info =
|
||||
GetFileDataInfo(spec);
|
||||
|
||||
if (!info) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
NS_ASSERTION(info->mPrincipal == principal, "Wrong principal!");
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = info->mFile->GetInternalStream(getter_AddRefs(stream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
|
||||
uri,
|
||||
stream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
|
||||
|
||||
nsAutoString type;
|
||||
rv = info->mFile->GetType(type);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint64_t size;
|
||||
rv = info->mFile->GetSize(&size);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
channel->SetOwner(owner);
|
||||
channel->SetOriginalURI(uri);
|
||||
channel->SetContentType(NS_ConvertUTF16toUTF8(type));
|
||||
channel->SetContentLength(size);
|
||||
|
||||
channel.forget(result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobProtocolHandler::AllowPort(int32_t port, const char *scheme,
|
||||
bool *_retval)
|
||||
{
|
||||
// don't override anything.
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
|
||||
{
|
||||
NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs");
|
||||
|
||||
*aStream = nullptr;
|
||||
|
||||
nsCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
FileDataInfo* info =
|
||||
GetFileDataInfo(spec);
|
||||
|
||||
if (!info) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
return info->mFile->GetInternalStream(aStream);
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsBlobProtocolHandler.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsPrintfCString.h"
|
||||
@ -284,26 +284,15 @@ nsDOMFileBase::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
|
||||
{
|
||||
NS_ENSURE_STATE(aPrincipal);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsID id;
|
||||
rv = uuidgen->GenerateUUIDInPlace(&id);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
char chars[NSID_LENGTH];
|
||||
id.ToProvidedString(chars);
|
||||
|
||||
nsCString url = NS_LITERAL_CSTRING(BLOBURI_SCHEME ":") +
|
||||
Substring(chars + 1, chars + NSID_LENGTH - 2);
|
||||
|
||||
nsBlobProtocolHandler::AddFileDataEntry(url, this,
|
||||
aPrincipal);
|
||||
nsCString url;
|
||||
nsresult rv = nsBlobProtocolHandler::AddDataEntry(
|
||||
NS_LITERAL_CSTRING(BLOBURI_SCHEME),
|
||||
static_cast<nsIDOMBlob*>(this), aPrincipal, url);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
CopyASCIItoUTF16(url, aURL);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -859,6 +848,6 @@ nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() {
|
||||
if (!mUrl.IsEmpty()) {
|
||||
nsAutoCString narrowUrl;
|
||||
CopyUTF16toUTF8(mUrl, narrowUrl);
|
||||
nsBlobProtocolHandler::RemoveFileDataEntry(narrowUrl);
|
||||
nsBlobProtocolHandler::RemoveDataEntry(narrowUrl);
|
||||
}
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsLayoutStatics.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsBlobProtocolHandler.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/EncodingUtils.h"
|
||||
#include "xpcpublic.h"
|
||||
|
@ -107,7 +107,7 @@
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsBlobProtocolHandler.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
|
||||
#include "nsCharsetAlias.h"
|
||||
#include "nsCharsetSource.h"
|
||||
@ -1445,8 +1445,8 @@ nsDocument::~nsDocument()
|
||||
|
||||
mPendingTitleChangeEvent.Revoke();
|
||||
|
||||
for (uint32_t i = 0; i < mFileDataUris.Length(); ++i) {
|
||||
nsBlobProtocolHandler::RemoveFileDataEntry(mFileDataUris[i]);
|
||||
for (uint32_t i = 0; i < mHostObjectURIs.Length(); ++i) {
|
||||
nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[i]);
|
||||
}
|
||||
|
||||
// We don't want to leave residual locks on images. Make sure we're in an
|
||||
@ -7595,15 +7595,15 @@ nsDocument::GetCurrentContentSink()
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RegisterFileDataUri(const nsACString& aUri)
|
||||
nsDocument::RegisterHostObjectUri(const nsACString& aUri)
|
||||
{
|
||||
mFileDataUris.AppendElement(aUri);
|
||||
mHostObjectURIs.AppendElement(aUri);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::UnregisterFileDataUri(const nsACString& aUri)
|
||||
nsDocument::UnregisterHostObjectUri(const nsACString& aUri)
|
||||
{
|
||||
mFileDataUris.RemoveElement(aUri);
|
||||
mHostObjectURIs.RemoveElement(aUri);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -839,7 +839,7 @@ public:
|
||||
virtual NS_HIDDEN_(void)
|
||||
EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData);
|
||||
|
||||
nsTArray<nsCString> mFileDataUris;
|
||||
nsTArray<nsCString> mHostObjectURIs;
|
||||
|
||||
// Returns our (lazily-initialized) animation controller.
|
||||
// If HasAnimationController is true, this is guaranteed to return non-null.
|
||||
@ -891,8 +891,8 @@ public:
|
||||
|
||||
virtual nsEventStates GetDocumentState();
|
||||
|
||||
virtual void RegisterFileDataUri(const nsACString& aUri);
|
||||
virtual void UnregisterFileDataUri(const nsACString& aUri);
|
||||
virtual void RegisterHostObjectUri(const nsACString& aUri);
|
||||
virtual void UnregisterHostObjectUri(const nsACString& aUri);
|
||||
|
||||
// Only BlockOnload should call this!
|
||||
void AsyncBlockOnload();
|
||||
|
264
content/base/src/nsHostObjectProtocolHandler.cpp
Normal file
264
content/base/src/nsHostObjectProtocolHandler.cpp
Normal file
@ -0,0 +1,264 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsHostObjectURI.h"
|
||||
#include "nsError.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDOMMediaStream.h"
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Hash table
|
||||
struct DataInfo
|
||||
{
|
||||
// mObject must be an nsIDOMBlob or an nsIDOMMediaStream
|
||||
nsCOMPtr<nsISupports> mObject;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
|
||||
|
||||
nsresult
|
||||
nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
|
||||
nsISupports* aObject,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsACString& aUri)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsID id;
|
||||
rv = uuidgen->GenerateUUIDInPlace(&id);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
char chars[NSID_LENGTH];
|
||||
id.ToProvidedString(chars);
|
||||
|
||||
aUri += aScheme;
|
||||
aUri += NS_LITERAL_CSTRING(":");
|
||||
aUri += Substring(chars + 1, chars + NSID_LENGTH - 2);
|
||||
|
||||
if (!gDataTable) {
|
||||
gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
|
||||
gDataTable->Init();
|
||||
}
|
||||
|
||||
DataInfo* info = new DataInfo;
|
||||
|
||||
info->mObject = aObject;
|
||||
info->mPrincipal = aPrincipal;
|
||||
|
||||
gDataTable->Put(aUri, info);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri)
|
||||
{
|
||||
if (gDataTable) {
|
||||
gDataTable->Remove(aUri);
|
||||
if (gDataTable->Count() == 0) {
|
||||
delete gDataTable;
|
||||
gDataTable = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri)
|
||||
{
|
||||
if (!gDataTable) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DataInfo* res;
|
||||
gDataTable->Get(aUri, &res);
|
||||
if (!res) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return res->mPrincipal;
|
||||
}
|
||||
|
||||
static DataInfo*
|
||||
GetDataInfo(const nsACString& aUri)
|
||||
{
|
||||
if (!gDataTable) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DataInfo* res;
|
||||
gDataTable->Get(aUri, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static nsISupports*
|
||||
GetDataObject(nsIURI* aURI)
|
||||
{
|
||||
nsCString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
DataInfo* info = GetDataInfo(spec);
|
||||
return info ? info->mObject : nullptr;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Protocol handler
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsHostObjectProtocolHandler, nsIProtocolHandler)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHostObjectProtocolHandler::GetDefaultPort(int32_t *result)
|
||||
{
|
||||
*result = -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHostObjectProtocolHandler::GetProtocolFlags(uint32_t *result)
|
||||
{
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS |
|
||||
URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec,
|
||||
const char *aCharset,
|
||||
nsIURI *aBaseURI,
|
||||
nsIURI **aResult)
|
||||
{
|
||||
*aResult = nullptr;
|
||||
nsresult rv;
|
||||
|
||||
DataInfo* info = GetDataInfo(aSpec);
|
||||
|
||||
nsRefPtr<nsHostObjectURI> uri =
|
||||
new nsHostObjectURI(info ? info->mPrincipal.get() : nullptr);
|
||||
|
||||
rv = uri->SetSpec(aSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_TryToSetImmutable(uri);
|
||||
uri.forget(aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
||||
{
|
||||
*result = nullptr;
|
||||
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
|
||||
DataInfo* info = GetDataInfo(spec);
|
||||
|
||||
if (!info) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(info->mObject);
|
||||
if (!blob) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
NS_ASSERTION(info->mPrincipal == principal, "Wrong principal!");
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = blob->GetInternalStream(getter_AddRefs(stream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
|
||||
uri,
|
||||
stream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
|
||||
|
||||
nsAutoString type;
|
||||
rv = blob->GetType(type);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint64_t size;
|
||||
rv = blob->GetSize(&size);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
channel->SetOwner(owner);
|
||||
channel->SetOriginalURI(uri);
|
||||
channel->SetContentType(NS_ConvertUTF16toUTF8(type));
|
||||
channel->SetContentLength(size);
|
||||
|
||||
channel.forget(result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHostObjectProtocolHandler::AllowPort(int32_t port, const char *scheme,
|
||||
bool *_retval)
|
||||
{
|
||||
// don't override anything.
|
||||
*_retval = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobProtocolHandler::GetScheme(nsACString &result)
|
||||
{
|
||||
result.AssignLiteral(BLOBURI_SCHEME);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMediaStreamProtocolHandler::GetScheme(nsACString &result)
|
||||
{
|
||||
result.AssignLiteral(MEDIASTREAMURI_SCHEME);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
|
||||
{
|
||||
NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs");
|
||||
|
||||
*aStream = nullptr;
|
||||
|
||||
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(GetDataObject(aURI));
|
||||
if (!blob) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
return blob->GetInternalStream(aStream);
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream)
|
||||
{
|
||||
NS_ASSERTION(IsMediaStreamURI(aURI), "Only call this with mediastream URIs");
|
||||
|
||||
*aStream = nullptr;
|
||||
|
||||
nsCOMPtr<nsIDOMMediaStream> stream = do_QueryInterface(GetDataObject(aURI));
|
||||
if (!stream) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
*aStream = stream;
|
||||
NS_ADDREF(*aStream);
|
||||
return NS_OK;
|
||||
}
|
@ -2,24 +2,24 @@
|
||||
* 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/. */
|
||||
|
||||
#include "nsBlobURI.h"
|
||||
#include "nsHostObjectURI.h"
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
#include "nsIProgrammingLanguage.h"
|
||||
|
||||
static NS_DEFINE_CID(kBLOBURICID, NS_BLOBURI_CID);
|
||||
static NS_DEFINE_CID(kHOSTOBJECTURICID, NS_HOSTOBJECTURI_CID);
|
||||
|
||||
static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
|
||||
NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsBlobURI, nsSimpleURI)
|
||||
NS_IMPL_RELEASE_INHERITED(nsBlobURI, nsSimpleURI)
|
||||
NS_IMPL_ADDREF_INHERITED(nsHostObjectURI, nsSimpleURI)
|
||||
NS_IMPL_RELEASE_INHERITED(nsHostObjectURI, nsSimpleURI)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsBlobURI)
|
||||
NS_INTERFACE_MAP_BEGIN(nsHostObjectURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal)
|
||||
if (aIID.Equals(kBLOBURICID))
|
||||
if (aIID.Equals(kHOSTOBJECTURICID))
|
||||
foundInterface = static_cast<nsIURI*>(this);
|
||||
else if (aIID.Equals(kThisSimpleURIImplementationCID)) {
|
||||
// Need to return explicitly here, because if we just set foundInterface
|
||||
@ -34,7 +34,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsSimpleURI)
|
||||
// nsIURIWithPrincipal methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetPrincipal(nsIPrincipal** aPrincipal)
|
||||
nsHostObjectURI::GetPrincipal(nsIPrincipal** aPrincipal)
|
||||
{
|
||||
NS_IF_ADDREF(*aPrincipal = mPrincipal);
|
||||
|
||||
@ -42,7 +42,7 @@ nsBlobURI::GetPrincipal(nsIPrincipal** aPrincipal)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetPrincipalUri(nsIURI** aUri)
|
||||
nsHostObjectURI::GetPrincipalUri(nsIURI** aUri)
|
||||
{
|
||||
if (mPrincipal) {
|
||||
mPrincipal->GetURI(aUri);
|
||||
@ -57,7 +57,7 @@ nsBlobURI::GetPrincipalUri(nsIURI** aUri)
|
||||
// nsISerializable methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::Read(nsIObjectInputStream* aStream)
|
||||
nsHostObjectURI::Read(nsIObjectInputStream* aStream)
|
||||
{
|
||||
nsresult rv = nsSimpleURI::Read(aStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -66,7 +66,7 @@ nsBlobURI::Read(nsIObjectInputStream* aStream)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::Write(nsIObjectOutputStream* aStream)
|
||||
nsHostObjectURI::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
nsresult rv = nsSimpleURI::Write(aStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -78,8 +78,8 @@ nsBlobURI::Write(nsIObjectOutputStream* aStream)
|
||||
|
||||
// nsIURI methods:
|
||||
nsresult
|
||||
nsBlobURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
|
||||
nsIURI** aClone)
|
||||
nsHostObjectURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
|
||||
nsIURI** aClone)
|
||||
{
|
||||
nsCOMPtr<nsIURI> simpleClone;
|
||||
nsresult rv =
|
||||
@ -87,56 +87,56 @@ nsBlobURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#ifdef DEBUG
|
||||
nsRefPtr<nsBlobURI> uriCheck;
|
||||
rv = simpleClone->QueryInterface(kBLOBURICID, getter_AddRefs(uriCheck));
|
||||
nsRefPtr<nsHostObjectURI> uriCheck;
|
||||
rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck));
|
||||
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) && uriCheck,
|
||||
"Unexpected!");
|
||||
#endif
|
||||
|
||||
nsBlobURI* blobURI = static_cast<nsBlobURI*>(simpleClone.get());
|
||||
nsHostObjectURI* u = static_cast<nsHostObjectURI*>(simpleClone.get());
|
||||
|
||||
blobURI->mPrincipal = mPrincipal;
|
||||
u->mPrincipal = mPrincipal;
|
||||
|
||||
simpleClone.forget(aClone);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* virtual */ nsresult
|
||||
nsBlobURI::EqualsInternal(nsIURI* aOther,
|
||||
nsSimpleURI::RefHandlingEnum aRefHandlingMode,
|
||||
bool* aResult)
|
||||
nsHostObjectURI::EqualsInternal(nsIURI* aOther,
|
||||
nsSimpleURI::RefHandlingEnum aRefHandlingMode,
|
||||
bool* aResult)
|
||||
{
|
||||
if (!aOther) {
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsBlobURI> otherBlobUri;
|
||||
aOther->QueryInterface(kBLOBURICID, getter_AddRefs(otherBlobUri));
|
||||
if (!otherBlobUri) {
|
||||
nsRefPtr<nsHostObjectURI> otherUri;
|
||||
aOther->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(otherUri));
|
||||
if (!otherUri) {
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Compare the member data that our base class knows about.
|
||||
if (!nsSimpleURI::EqualsInternal(otherBlobUri, aRefHandlingMode)) {
|
||||
if (!nsSimpleURI::EqualsInternal(otherUri, aRefHandlingMode)) {
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Compare the piece of additional member data that we add to base class.
|
||||
if (mPrincipal && otherBlobUri->mPrincipal) {
|
||||
if (mPrincipal && otherUri->mPrincipal) {
|
||||
// Both of us have mPrincipals. Compare them.
|
||||
return mPrincipal->Equals(otherBlobUri->mPrincipal, aResult);
|
||||
return mPrincipal->Equals(otherUri->mPrincipal, aResult);
|
||||
}
|
||||
// else, at least one of us lacks a principal; only equal if *both* lack it.
|
||||
*aResult = (!mPrincipal && !otherBlobUri->mPrincipal);
|
||||
*aResult = (!mPrincipal && !otherUri->mPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIClassInfo methods:
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetInterfaces(uint32_t *count, nsIID * **array)
|
||||
nsHostObjectURI::GetInterfaces(uint32_t *count, nsIID * **array)
|
||||
{
|
||||
*count = 0;
|
||||
*array = nullptr;
|
||||
@ -144,14 +144,14 @@ nsBlobURI::GetInterfaces(uint32_t *count, nsIID * **array)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetHelperForLanguage(uint32_t language, nsISupports **_retval)
|
||||
nsHostObjectURI::GetHelperForLanguage(uint32_t language, nsISupports **_retval)
|
||||
{
|
||||
*_retval = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetContractID(char * *aContractID)
|
||||
nsHostObjectURI::GetContractID(char * *aContractID)
|
||||
{
|
||||
// Make sure to modify any subclasses as needed if this ever
|
||||
// changes.
|
||||
@ -160,14 +160,14 @@ nsBlobURI::GetContractID(char * *aContractID)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetClassDescription(char * *aClassDescription)
|
||||
nsHostObjectURI::GetClassDescription(char * *aClassDescription)
|
||||
{
|
||||
*aClassDescription = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetClassID(nsCID * *aClassID)
|
||||
nsHostObjectURI::GetClassID(nsCID * *aClassID)
|
||||
{
|
||||
// Make sure to modify any subclasses as needed if this ever
|
||||
// changes to not call the virtual GetClassIDNoAlloc.
|
||||
@ -178,22 +178,22 @@ nsBlobURI::GetClassID(nsCID * *aClassID)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetImplementationLanguage(uint32_t *aImplementationLanguage)
|
||||
nsHostObjectURI::GetImplementationLanguage(uint32_t *aImplementationLanguage)
|
||||
{
|
||||
*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetFlags(uint32_t *aFlags)
|
||||
nsHostObjectURI::GetFlags(uint32_t *aFlags)
|
||||
{
|
||||
*aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBlobURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
nsHostObjectURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
{
|
||||
*aClassIDNoAlloc = kBLOBURICID;
|
||||
*aClassIDNoAlloc = kHOSTOBJECTURICID;
|
||||
return NS_OK;
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
* 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/. */
|
||||
|
||||
#ifndef nsBlobURI_h
|
||||
#define nsBlobURI_h
|
||||
#ifndef nsHostObjectURI_h
|
||||
#define nsHostObjectURI_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIClassInfo.h"
|
||||
@ -12,17 +12,21 @@
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsSimpleURI.h"
|
||||
|
||||
class nsBlobURI : public nsSimpleURI,
|
||||
public nsIURIWithPrincipal
|
||||
/**
|
||||
* These URIs refer to host objects: Blobs, with scheme "blob", and
|
||||
* MediaStreams, with scheme "mediastream".
|
||||
*/
|
||||
class nsHostObjectURI : public nsSimpleURI,
|
||||
public nsIURIWithPrincipal
|
||||
{
|
||||
public:
|
||||
nsBlobURI(nsIPrincipal* aPrincipal) :
|
||||
nsHostObjectURI(nsIPrincipal* aPrincipal) :
|
||||
nsSimpleURI(), mPrincipal(aPrincipal)
|
||||
{}
|
||||
virtual ~nsBlobURI() {}
|
||||
virtual ~nsHostObjectURI() {}
|
||||
|
||||
// For use only from deserialization
|
||||
nsBlobURI() : nsSimpleURI() {}
|
||||
nsHostObjectURI() : nsSimpleURI() {}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIURIWITHPRINCIPAL
|
||||
@ -36,15 +40,15 @@ public:
|
||||
RefHandlingEnum aRefHandlingMode,
|
||||
bool* aResult);
|
||||
|
||||
// Override StartClone to hand back a nsBlobURI
|
||||
// Override StartClone to hand back a nsHostObjectURI
|
||||
virtual nsSimpleURI* StartClone(RefHandlingEnum /* unused */)
|
||||
{ return new nsBlobURI(); }
|
||||
{ return new nsHostObjectURI(); }
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
#define NS_BLOBURI_CID \
|
||||
#define NS_HOSTOBJECTURI_CID \
|
||||
{ 0xf5475c51, 0x59a7, 0x4757, \
|
||||
{ 0xb3, 0xd9, 0xe2, 0x11, 0xa9, 0x41, 0x08, 0x72 } }
|
||||
|
||||
#endif /* nsBlobURI_h */
|
||||
#endif /* nsHostObjectURI_h */
|
@ -429,9 +429,9 @@ protected:
|
||||
void SetPlayedOrSeeked(bool aValue);
|
||||
|
||||
/**
|
||||
* Initialize the media element for playback of mSrcAttrStream
|
||||
* Initialize the media element for playback of aStream
|
||||
*/
|
||||
void SetupSrcMediaStreamPlayback();
|
||||
void SetupSrcMediaStreamPlayback(nsDOMMediaStream* aStream);
|
||||
/**
|
||||
* Stop playback on mSrcStream.
|
||||
*/
|
||||
|
@ -64,6 +64,7 @@
|
||||
#include "MediaStreamGraph.h"
|
||||
#include "nsDOMMediaStream.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsIMediaList.h"
|
||||
@ -758,7 +759,7 @@ void nsHTMLMediaElement::SelectResource()
|
||||
// If we have a 'src' attribute, use that exclusively.
|
||||
nsAutoString src;
|
||||
if (mSrcAttrStream) {
|
||||
SetupSrcMediaStreamPlayback();
|
||||
SetupSrcMediaStreamPlayback(mSrcAttrStream);
|
||||
} else if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NewURIFromString(src, getter_AddRefs(uri));
|
||||
@ -766,6 +767,7 @@ void nsHTMLMediaElement::SelectResource()
|
||||
LOG(PR_LOG_DEBUG, ("%p Trying load from src=%s", this, NS_ConvertUTF16toUTF8(src).get()));
|
||||
NS_ASSERTION(!mIsLoadingFromSourceChildren,
|
||||
"Should think we're not loading from source children by default");
|
||||
|
||||
mLoadingSrc = uri;
|
||||
if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
|
||||
// preload:none media, suspend the load here before we make any
|
||||
@ -1035,7 +1037,7 @@ nsresult nsHTMLMediaElement::LoadResource()
|
||||
mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
|
||||
|
||||
nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
|
||||
if (other) {
|
||||
if (other && other->mDecoder) {
|
||||
// Clone it.
|
||||
nsresult rv = InitializeDecoderAsClone(other->mDecoder);
|
||||
// Get the mimetype from the element we clone, since we will not get it via
|
||||
@ -1062,6 +1064,21 @@ nsresult nsHTMLMediaElement::LoadResource()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (IsMediaStreamURI(mLoadingSrc)) {
|
||||
nsCOMPtr<nsIDOMMediaStream> stream;
|
||||
rv = NS_GetStreamForMediaStreamURI(mLoadingSrc, getter_AddRefs(stream));
|
||||
if (NS_FAILED(rv)) {
|
||||
nsCString specUTF8;
|
||||
mLoadingSrc->GetSpec(specUTF8);
|
||||
NS_ConvertUTF8toUTF16 spec(specUTF8);
|
||||
const PRUnichar* params[] = { spec.get() };
|
||||
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
|
||||
return rv;
|
||||
}
|
||||
SetupSrcMediaStreamPlayback(static_cast<nsDOMMediaStream*>(stream.get()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
|
||||
|
||||
// check for a Content Security Policy to pass down to the channel
|
||||
@ -2765,11 +2782,11 @@ private:
|
||||
bool mDidHaveCurrentData;
|
||||
};
|
||||
|
||||
void nsHTMLMediaElement::SetupSrcMediaStreamPlayback()
|
||||
void nsHTMLMediaElement::SetupSrcMediaStreamPlayback(nsDOMMediaStream* aStream)
|
||||
{
|
||||
NS_ASSERTION(!mSrcStream && !mSrcStreamListener, "Should have been ended already");
|
||||
|
||||
mSrcStream = mSrcAttrStream;
|
||||
mSrcStream = aStream;
|
||||
// XXX if we ever support capturing the output of a media element which is
|
||||
// playing a stream, we'll need to add a CombineWithPrincipal call here.
|
||||
mSrcStreamListener = new StreamListener(this);
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "mozilla/Util.h" // for DebugOnly
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsBlobProtocolHandler.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* gMediaResourceLog;
|
||||
|
@ -138,6 +138,7 @@ ifneq ($(OS_ARCH), WINNT)
|
||||
MOCHITEST_FILES += \
|
||||
test_streams_element_capture.html \
|
||||
test_streams_element_capture_reset.html \
|
||||
test_streams_element_capture_createObjectURL.html \
|
||||
test_timeupdate_small_files.html \
|
||||
$(NULL)
|
||||
else
|
||||
|
@ -0,0 +1,62 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test that a MediaStream captured from one element plays back in another</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
function checkDrawImage(vout) {
|
||||
var canvas = document.createElement("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.drawImage(vout, 0, 0);
|
||||
var imgData = ctx.getImageData(0, 0, 1, 1);
|
||||
is(imgData.data[3], 255, "Check video frame pixel has been drawn");
|
||||
}
|
||||
|
||||
function startTest(test, token) {
|
||||
manager.started(token);
|
||||
|
||||
var v = document.createElement('video');
|
||||
var vout = document.createElement('video');
|
||||
vout.token = token;
|
||||
|
||||
v.src = test.name;
|
||||
var stream = v.mozCaptureStreamUntilEnded();
|
||||
is(stream.currentTime, 0, test.name + " stream initial currentTime");
|
||||
vout.src = URL.createObjectURL(stream);
|
||||
|
||||
var checkEnded = function(test, vout, stream) { return function() {
|
||||
is(stream.currentTime, vout.currentTime, test.name + " stream final currentTime");
|
||||
if (test.duration) {
|
||||
ok(Math.abs(vout.currentTime - test.duration) < 0.1,
|
||||
test.name + " current time at end: " + vout.currentTime + " should be: " + test.duration);
|
||||
}
|
||||
is(vout.readyState, vout.HAVE_CURRENT_DATA, test.name + " checking readyState");
|
||||
ok(vout.ended, test.name + " checking playback has ended");
|
||||
if (test.type.match(/^video/)) {
|
||||
checkDrawImage(vout);
|
||||
}
|
||||
vout.parentNode.removeChild(vout);
|
||||
URL.revokeObjectURL(vout.src);
|
||||
manager.finished(vout.token);
|
||||
}}(test, vout, stream);
|
||||
vout.addEventListener("ended", checkEnded, false);
|
||||
|
||||
document.body.appendChild(vout);
|
||||
v.play();
|
||||
vout.play();
|
||||
}
|
||||
|
||||
manager.runTests([getPlayableVideo(gSmallTests)], startTest);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -17,6 +17,7 @@
|
||||
#include "PannerNode.h"
|
||||
#include "AudioListener.h"
|
||||
#include "DynamicsCompressorNode.h"
|
||||
#include "BiquadFilterNode.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -124,6 +125,14 @@ AudioContext::CreateDynamicsCompressor()
|
||||
return compressorNode.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<BiquadFilterNode>
|
||||
AudioContext::CreateBiquadFilter()
|
||||
{
|
||||
nsRefPtr<BiquadFilterNode> filterNode =
|
||||
new BiquadFilterNode(this);
|
||||
return filterNode.forget();
|
||||
}
|
||||
|
||||
AudioListener*
|
||||
AudioContext::Listener()
|
||||
{
|
||||
|
@ -27,6 +27,7 @@ class AudioBuffer;
|
||||
class AudioBufferSourceNode;
|
||||
class AudioDestinationNode;
|
||||
class AudioListener;
|
||||
class BiquadFilterNode;
|
||||
class DelayNode;
|
||||
class DynamicsCompressorNode;
|
||||
class GainNode;
|
||||
@ -80,6 +81,9 @@ public:
|
||||
already_AddRefed<DynamicsCompressorNode>
|
||||
CreateDynamicsCompressor();
|
||||
|
||||
already_AddRefed<BiquadFilterNode>
|
||||
CreateBiquadFilter();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDOMWindow> mWindow;
|
||||
nsRefPtr<AudioDestinationNode> mDestination;
|
||||
|
57
content/media/webaudio/BiquadFilterNode.cpp
Normal file
57
content/media/webaudio/BiquadFilterNode.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BiquadFilterNode.h"
|
||||
#include "mozilla/dom/BiquadFilterNodeBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(BiquadFilterNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BiquadFilterNode, AudioNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFrequency)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mQ)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGain)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BiquadFilterNode, AudioNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mFrequency, AudioParam, "frequency value")
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mQ, AudioParam, "Q value")
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mGain, AudioParam, "gain value")
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BiquadFilterNode)
|
||||
NS_INTERFACE_MAP_END_INHERITING(AudioNode)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(BiquadFilterNode, AudioNode)
|
||||
NS_IMPL_RELEASE_INHERITED(BiquadFilterNode, AudioNode)
|
||||
|
||||
static float
|
||||
Nyquist(AudioContext* aContext)
|
||||
{
|
||||
// TODO: Replace the hardcoded 44100 here with AudioContext::SampleRate()
|
||||
// when we implement that.
|
||||
return 0.5f * 44100;
|
||||
}
|
||||
|
||||
BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
|
||||
: AudioNode(aContext)
|
||||
, mType(BiquadTypeEnum::LOWPASS)
|
||||
, mFrequency(new AudioParam(aContext, 350.f, 10.f, Nyquist(aContext)))
|
||||
, mQ(new AudioParam(aContext, 1.f, 0.0001f, 1000.f))
|
||||
, mGain(new AudioParam(aContext, 0.f, -40.f, 40.f))
|
||||
{
|
||||
}
|
||||
|
||||
JSObject*
|
||||
BiquadFilterNode::WrapObject(JSContext* aCx, JSObject* aScope,
|
||||
bool* aTriedToWrap)
|
||||
{
|
||||
return BiquadFilterNodeBinding::Wrap(aCx, aScope, this, aTriedToWrap);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
92
content/media/webaudio/BiquadFilterNode.h
Normal file
92
content/media/webaudio/BiquadFilterNode.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BiquadFilterNode_h_
|
||||
#define BiquadFilterNode_h_
|
||||
|
||||
#include "AudioNode.h"
|
||||
#include "AudioParam.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class AudioContext;
|
||||
|
||||
MOZ_BEGIN_ENUM_CLASS(BiquadTypeEnum, uint16_t)
|
||||
LOWPASS = 0,
|
||||
HIGHPASS = 1,
|
||||
BANDPASS = 2,
|
||||
LOWSHELF = 3,
|
||||
HIGHSHELF = 4,
|
||||
PEAKING = 5,
|
||||
NOTCH = 6,
|
||||
ALLPASS = 7,
|
||||
Max = 7
|
||||
MOZ_END_ENUM_CLASS(BiquadTypeEnum)
|
||||
|
||||
class BiquadFilterNode : public AudioNode
|
||||
{
|
||||
public:
|
||||
explicit BiquadFilterNode(AudioContext* aContext);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BiquadFilterNode, AudioNode)
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
|
||||
bool* aTriedToWrap);
|
||||
|
||||
virtual uint32_t MaxNumberOfInputs() const MOZ_FINAL MOZ_OVERRIDE
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
virtual uint32_t MaxNumberOfOutputs() const MOZ_FINAL MOZ_OVERRIDE
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint16_t Type() const
|
||||
{
|
||||
return static_cast<uint16_t> (mType);
|
||||
}
|
||||
void SetType(uint16_t aType, ErrorResult& aRv)
|
||||
{
|
||||
BiquadTypeEnum type = static_cast<BiquadTypeEnum> (aType);
|
||||
if (type > BiquadTypeEnum::Max) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
} else {
|
||||
mType = type;
|
||||
}
|
||||
}
|
||||
|
||||
AudioParam* Frequency() const
|
||||
{
|
||||
return mFrequency;
|
||||
}
|
||||
|
||||
AudioParam* Q() const
|
||||
{
|
||||
return mQ;
|
||||
}
|
||||
|
||||
AudioParam* Gain() const
|
||||
{
|
||||
return mGain;
|
||||
}
|
||||
|
||||
private:
|
||||
BiquadTypeEnum mType;
|
||||
nsRefPtr<AudioParam> mFrequency;
|
||||
nsRefPtr<AudioParam> mQ;
|
||||
nsRefPtr<AudioParam> mGain;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -23,6 +23,7 @@ CPPSRCS := \
|
||||
AudioNode.cpp \
|
||||
AudioParam.cpp \
|
||||
AudioSourceNode.cpp \
|
||||
BiquadFilterNode.cpp \
|
||||
DelayNode.cpp \
|
||||
DynamicsCompressorNode.cpp \
|
||||
EnableWebAudioCheck.cpp \
|
||||
@ -39,6 +40,7 @@ EXPORTS_mozilla/dom := \
|
||||
AudioNode.h \
|
||||
AudioParam.h \
|
||||
AudioSourceNode.h \
|
||||
BiquadFilterNode.h \
|
||||
DelayNode.h \
|
||||
DynamicsCompressorNode.h \
|
||||
GainNode.h \
|
||||
|
@ -11,11 +11,13 @@ relativesrcdir := @relativesrcdir@
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOCHITEST_FILES := \
|
||||
webaudio.js \
|
||||
test_bug808374.html \
|
||||
test_AudioBuffer.html \
|
||||
test_AudioContext.html \
|
||||
test_AudioListener.html \
|
||||
test_badConnect.html \
|
||||
test_biquadFilterNode.html \
|
||||
test_delayNode.html \
|
||||
test_dynamicsCompressorNode.html \
|
||||
test_gainNode.html \
|
||||
|
@ -7,20 +7,9 @@
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="webaudio.js" type="text/javascript"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function expectException(func, exceptionCode) {
|
||||
var threw = false;
|
||||
try {
|
||||
func();
|
||||
} catch (ex) {
|
||||
threw = true;
|
||||
ok(ex instanceof DOMException, "Expect a DOM exception");
|
||||
ok(ex.code, exceptionCode, "Expect the correct exception code");
|
||||
}
|
||||
ok(threw, "The exception was thrown");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
|
||||
|
73
content/media/webaudio/test/test_biquadFilterNode.html
Normal file
73
content/media/webaudio/test/test_biquadFilterNode.html
Normal file
@ -0,0 +1,73 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test BiquadFilterNode</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="webaudio.js" type="text/javascript"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
function near(a, b, msg) {
|
||||
ok(Math.abs(a - b) < 1e-3, msg);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(function() {
|
||||
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
|
||||
|
||||
var context = new mozAudioContext();
|
||||
var buffer = context.createBuffer(1, 2048, 44100);
|
||||
for (var i = 0; i < 2048; ++i) {
|
||||
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / 44100);
|
||||
}
|
||||
|
||||
var destination = context.destination;
|
||||
|
||||
var source = context.createBufferSource();
|
||||
|
||||
var filter = context.createBiquadFilter();
|
||||
|
||||
source.buffer = buffer;
|
||||
|
||||
source.connect(filter);
|
||||
filter.connect(destination);
|
||||
|
||||
// Verify default values
|
||||
is(filter.type, 0, "Correct default value for type");
|
||||
near(filter.frequency.minValue, 10, "Correct min value for filter frequency");
|
||||
near(filter.frequency.maxValue, 22050, "Correct max value for filter frequency");
|
||||
near(filter.frequency.defaultValue, 350, "Correct default value for filter frequency");
|
||||
near(filter.Q.minValue, 0.001, "Correct min value for filter Q");
|
||||
near(filter.Q.maxValue, 1000, "Correct max value for filter Q");
|
||||
near(filter.Q.defaultValue, 1, "Correct default value for filter Q");
|
||||
near(filter.gain.minValue, -40, "Correct min value for filter gain");
|
||||
near(filter.gain.maxValue, 40, "Correct max value for filter gain");
|
||||
near(filter.gain.defaultValue, 0, "Correct default value for filter gain");
|
||||
|
||||
// Make sure that we can set all of the valid type values
|
||||
for (var i = 0; i <= 7; ++i) {
|
||||
filter.type = i;
|
||||
}
|
||||
|
||||
expectException(function() {
|
||||
filter.type = 8;
|
||||
}, DOMException.INDEX_SIZE_ERR);
|
||||
|
||||
source.start(0);
|
||||
SimpleTest.executeSoon(function() {
|
||||
source.stop(0);
|
||||
source.disconnect();
|
||||
filter.disconnect();
|
||||
|
||||
SpecialPowers.clearUserPref("media.webaudio.enabled");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
14
content/media/webaudio/test/webaudio.js
Normal file
14
content/media/webaudio/test/webaudio.js
Normal file
@ -0,0 +1,14 @@
|
||||
// Helpers for Web Audio tests
|
||||
|
||||
function expectException(func, exceptionCode) {
|
||||
var threw = false;
|
||||
try {
|
||||
func();
|
||||
} catch (ex) {
|
||||
threw = true;
|
||||
ok(ex instanceof DOMException, "Expect a DOM exception");
|
||||
ok(ex.code, exceptionCode, "Expect the correct exception code");
|
||||
}
|
||||
ok(threw, "The exception was thrown");
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ EXPORTS_mozilla/dom = \
|
||||
DOMRequest.h \
|
||||
StructuredCloneTags.h \
|
||||
ScreenOrientation.h \
|
||||
URL.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
@ -115,6 +116,7 @@ CPPSRCS = \
|
||||
DOMError.cpp \
|
||||
DOMRequest.cpp \
|
||||
Navigator.cpp \
|
||||
URL.cpp \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/dom/dom-config.mk
|
||||
|
101
dom/base/URL.cpp
Normal file
101
dom/base/URL.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "URL.h"
|
||||
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDOMMediaStream.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
void
|
||||
URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob,
|
||||
const objectURLOptions& aOptions,
|
||||
nsAString& aResult,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
CreateObjectURLInternal(aGlobal, aBlob, NS_LITERAL_CSTRING(BLOBURI_SCHEME),
|
||||
aOptions, aResult, aError);
|
||||
}
|
||||
|
||||
void
|
||||
URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMMediaStream* aStream,
|
||||
const mozilla::dom::objectURLOptions& aOptions,
|
||||
nsAString& aResult,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
CreateObjectURLInternal(aGlobal, aStream, NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME),
|
||||
aOptions, aResult, aError);
|
||||
}
|
||||
|
||||
void
|
||||
URL::CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
|
||||
const nsACString& aScheme,
|
||||
const mozilla::dom::objectURLOptions& aOptions,
|
||||
nsAString& aResult,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal);
|
||||
nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
|
||||
NS_PRECONDITION(!window || window->IsInnerWindow(),
|
||||
"Should be inner window");
|
||||
|
||||
if (!window || !window->GetExtantDoc()) {
|
||||
aError.Throw(NS_ERROR_INVALID_POINTER);
|
||||
return;
|
||||
}
|
||||
|
||||
nsIDocument* doc = window->GetExtantDoc();
|
||||
|
||||
nsCString url;
|
||||
nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
|
||||
doc->NodePrincipal(), url);
|
||||
if (NS_FAILED(rv)) {
|
||||
aError.Throw(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
doc->RegisterHostObjectUri(url);
|
||||
CopyASCIItoUTF16(url, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
URL::RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal);
|
||||
nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
|
||||
NS_PRECONDITION(!window || window->IsInnerWindow(),
|
||||
"Should be inner window");
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
NS_LossyConvertUTF16toASCII asciiurl(aURL);
|
||||
|
||||
nsIPrincipal* winPrincipal = window->GetPrincipal();
|
||||
if (!winPrincipal) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIPrincipal* principal =
|
||||
nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
|
||||
bool subsumes;
|
||||
if (principal && winPrincipal &&
|
||||
NS_SUCCEEDED(winPrincipal->Subsumes(principal, &subsumes)) &&
|
||||
subsumes) {
|
||||
if (window->GetExtantDoc()) {
|
||||
window->GetExtantDoc()->UnregisterHostObjectUri(asciiurl);
|
||||
}
|
||||
nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
42
dom/base/URL.h
Normal file
42
dom/base/URL.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef URL_h___
|
||||
#define URL_h___
|
||||
|
||||
#include "nscore.h"
|
||||
#include "mozilla/dom/URLBinding.h"
|
||||
|
||||
class nsIDOMBlob;
|
||||
class nsIDOMMediaStream;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class URL MOZ_FINAL
|
||||
{
|
||||
public:
|
||||
// WebIDL methods
|
||||
static void CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob,
|
||||
const objectURLOptions& aOptions,
|
||||
nsAString& aResult,
|
||||
ErrorResult& aError);
|
||||
static void CreateObjectURL(nsISupports* aGlobal, nsIDOMMediaStream* aStream,
|
||||
const mozilla::dom::objectURLOptions& aOptions,
|
||||
nsAString& aResult,
|
||||
mozilla::ErrorResult& aError);
|
||||
static void RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL);
|
||||
|
||||
private:
|
||||
static void CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
|
||||
const nsACString& aScheme,
|
||||
const mozilla::dom::objectURLOptions& aOptions,
|
||||
nsAString& aResult,
|
||||
mozilla::ErrorResult& aError);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* URL_h___ */
|
@ -1434,8 +1434,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(ArchiveRequest, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(MozURLProperty, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
|
||||
DEFAULT_SCRIPTABLE_FLAGS |
|
||||
@ -4008,10 +4006,6 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMRequest)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MozURLProperty, nsIDOMMozURLProperty)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozURLProperty)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(ModalContentWindow, nsIDOMWindow)
|
||||
DOM_CLASSINFO_WINDOW_MAP_ENTRIES(nsGlobalWindow::HasIndexedDBSupport())
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMModalContentWindow)
|
||||
@ -6683,6 +6677,14 @@ ConstructorEnabled(const nsGlobalNameStruct *aStruct, nsGlobalWindow *aWin)
|
||||
}
|
||||
}
|
||||
|
||||
// Don't expose ArchiveReader unless user has explicitly enabled it
|
||||
if (aStruct->mDOMClassInfoID == eDOMClassInfo_ArchiveReader_id ||
|
||||
aStruct->mDOMClassInfoID == eDOMClassInfo_ArchiveRequest_id) {
|
||||
if (!dom::file::ArchiveReader::PrefEnabled()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -366,7 +366,6 @@ DOMCI_CLASS(File)
|
||||
DOMCI_CLASS(FileReader)
|
||||
DOMCI_CLASS(ArchiveReader)
|
||||
DOMCI_CLASS(ArchiveRequest)
|
||||
DOMCI_CLASS(MozURLProperty)
|
||||
|
||||
// DOM modal content window class, almost identical to Window
|
||||
DOMCI_CLASS(ModalContentWindow)
|
||||
|
@ -148,7 +148,6 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCSSProps.h"
|
||||
#include "nsBlobProtocolHandler.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIDOMFileList.h"
|
||||
#include "nsIURIFixup.h"
|
||||
@ -422,85 +421,6 @@ static const char sPopStatePrefStr[] = "browser.history.allowPopState";
|
||||
#define NETWORK_UPLOAD_EVENT_NAME NS_LITERAL_STRING("moznetworkupload")
|
||||
#define NETWORK_DOWNLOAD_EVENT_NAME NS_LITERAL_STRING("moznetworkdownload")
|
||||
|
||||
/**
|
||||
* An object implementing the window.URL property.
|
||||
*/
|
||||
class nsDOMMozURLProperty MOZ_FINAL : public nsIDOMMozURLProperty
|
||||
{
|
||||
public:
|
||||
nsDOMMozURLProperty(nsGlobalWindow* aWindow)
|
||||
: mWindow(aWindow)
|
||||
{
|
||||
}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMMOZURLPROPERTY
|
||||
|
||||
void ClearWindowReference() {
|
||||
mWindow = nullptr;
|
||||
}
|
||||
private:
|
||||
nsGlobalWindow* mWindow;
|
||||
};
|
||||
|
||||
DOMCI_DATA(MozURLProperty, nsDOMMozURLProperty)
|
||||
NS_IMPL_ADDREF(nsDOMMozURLProperty)
|
||||
NS_IMPL_RELEASE(nsDOMMozURLProperty)
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMMozURLProperty)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMozURLProperty)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozURLProperty)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozURLProperty)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMozURLProperty::CreateObjectURL(nsIDOMBlob* aBlob, nsAString& aURL)
|
||||
{
|
||||
NS_PRECONDITION(!mWindow || mWindow->IsInnerWindow(),
|
||||
"Should be inner window");
|
||||
|
||||
NS_ENSURE_STATE(mWindow && mWindow->mDoc);
|
||||
NS_ENSURE_ARG_POINTER(aBlob);
|
||||
|
||||
nsIDocument* doc = mWindow->mDoc;
|
||||
|
||||
nsresult rv = aBlob->GetInternalUrl(doc->NodePrincipal(), aURL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
doc->RegisterFileDataUri(NS_LossyConvertUTF16toASCII(aURL));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMozURLProperty::RevokeObjectURL(const nsAString& aURL)
|
||||
{
|
||||
NS_PRECONDITION(!mWindow || mWindow->IsInnerWindow(),
|
||||
"Should be inner window");
|
||||
|
||||
NS_ENSURE_STATE(mWindow);
|
||||
|
||||
NS_LossyConvertUTF16toASCII asciiurl(aURL);
|
||||
|
||||
nsIPrincipal* winPrincipal = mWindow->GetPrincipal();
|
||||
if (!winPrincipal) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIPrincipal* principal =
|
||||
nsBlobProtocolHandler::GetFileDataEntryPrincipal(asciiurl);
|
||||
bool subsumes;
|
||||
if (principal && winPrincipal &&
|
||||
NS_SUCCEEDED(winPrincipal->Subsumes(principal, &subsumes)) &&
|
||||
subsumes) {
|
||||
if (mWindow->mDoc) {
|
||||
mWindow->mDoc->UnregisterFileDataUri(asciiurl);
|
||||
}
|
||||
nsBlobProtocolHandler::RemoveFileDataEntry(asciiurl);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* An indirect observer object that means we don't have to implement nsIObserver
|
||||
* on nsGlobalWindow, where any script could see it.
|
||||
@ -533,6 +453,14 @@ private:
|
||||
NS_IMPL_ISUPPORTS2(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor)
|
||||
|
||||
nsTimeout::nsTimeout()
|
||||
: mCleared(false),
|
||||
mRunning(false),
|
||||
mIsInterval(false),
|
||||
mPublicId(0),
|
||||
mInterval(0),
|
||||
mFiringDepth(0),
|
||||
mNestingLevel(0),
|
||||
mPopupState(openAllowed)
|
||||
{
|
||||
#ifdef DEBUG_jst
|
||||
{
|
||||
@ -542,8 +470,6 @@ nsTimeout::nsTimeout()
|
||||
}
|
||||
#endif
|
||||
|
||||
memset(this, 0, sizeof(*this));
|
||||
|
||||
MOZ_COUNT_CTOR(nsTimeout);
|
||||
}
|
||||
|
||||
@ -723,9 +649,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
// Initialize the PRCList (this).
|
||||
PR_INIT_CLIST(this);
|
||||
|
||||
// Initialize timeout storage
|
||||
PR_INIT_CLIST(&mTimeouts);
|
||||
|
||||
if (aOuterWindow) {
|
||||
// |this| is an inner window, add this inner window to the outer
|
||||
// window list of inners.
|
||||
@ -928,10 +851,6 @@ nsGlobalWindow::~nsGlobalWindow()
|
||||
nsCycleCollector_DEBUG_wasFreed(static_cast<nsIScriptGlobalObject*>(this));
|
||||
#endif
|
||||
|
||||
if (mURLProperty) {
|
||||
mURLProperty->ClearWindowReference();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
|
||||
if (ac)
|
||||
ac->RemoveWindowAsListener(this);
|
||||
@ -1319,9 +1238,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager,
|
||||
nsEventListenerManager)
|
||||
|
||||
for (nsTimeout* timeout = tmp->FirstTimeout();
|
||||
tmp->IsTimeout(timeout);
|
||||
timeout = timeout->Next()) {
|
||||
for (nsTimeout* timeout = tmp->mTimeouts.getFirst();
|
||||
timeout;
|
||||
timeout = timeout->getNext()) {
|
||||
cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout));
|
||||
}
|
||||
|
||||
@ -1426,9 +1345,9 @@ nsGlobalWindow::IsBlackForCC()
|
||||
void
|
||||
nsGlobalWindow::UnmarkGrayTimers()
|
||||
{
|
||||
for (nsTimeout* timeout = FirstTimeout();
|
||||
timeout && IsTimeout(timeout);
|
||||
timeout = timeout->Next()) {
|
||||
for (nsTimeout* timeout = mTimeouts.getFirst();
|
||||
timeout;
|
||||
timeout = timeout->getNext()) {
|
||||
if (timeout->mScriptHandler) {
|
||||
JSObject* o = timeout->mScriptHandler->GetScriptObject();
|
||||
xpc_UnmarkGrayObject(o);
|
||||
@ -2318,8 +2237,7 @@ nsGlobalWindow::DetachFromDocShell()
|
||||
// (mJSObject) so that it can be retrieved later (until it is
|
||||
// finalized by the JS GC).
|
||||
|
||||
NS_ASSERTION(PR_CLIST_IS_EMPTY(&mTimeouts),
|
||||
"Uh, outer window holds timeouts!");
|
||||
NS_ASSERTION(mTimeouts.isEmpty(), "Uh, outer window holds timeouts!");
|
||||
|
||||
// Call FreeInnerObjects on all inner windows, not just the current
|
||||
// one, since some could be held by WindowStateHolder objects that
|
||||
@ -9906,7 +9824,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
||||
// timeout events fire "early", so we need to test the timer as well
|
||||
// as the deadline.
|
||||
last_expired_timeout = nullptr;
|
||||
for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = timeout->Next()) {
|
||||
for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
|
||||
if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) &&
|
||||
(timeout->mFiringDepth == 0)) {
|
||||
// Mark any timeouts that are on the list to be fired with the
|
||||
@ -9940,7 +9858,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
||||
// list for any timeouts inserted as a result of running a timeout.
|
||||
dummy_timeout.mFiringDepth = firingDepth;
|
||||
dummy_timeout.mWhen = now;
|
||||
PR_INSERT_AFTER(&dummy_timeout, last_expired_timeout);
|
||||
last_expired_timeout->setNext(&dummy_timeout);
|
||||
|
||||
// Don't let ClearWindowTimeouts throw away our stack-allocated
|
||||
// dummy timeout.
|
||||
@ -9954,10 +9872,10 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
||||
|
||||
Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan;
|
||||
|
||||
for (timeout = FirstTimeout();
|
||||
for (timeout = mTimeouts.getFirst();
|
||||
timeout != &dummy_timeout && !IsFrozen();
|
||||
timeout = nextTimeout) {
|
||||
nextTimeout = timeout->Next();
|
||||
nextTimeout = timeout->getNext();
|
||||
|
||||
if (timeout->mFiringDepth != firingDepth) {
|
||||
// We skip the timeout since it's on the list to run at another
|
||||
@ -10021,9 +9939,9 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
||||
|
||||
// Running a timeout can cause another timeout to be deleted, so
|
||||
// we need to reset the pointer to the following timeout.
|
||||
nextTimeout = timeout->Next();
|
||||
nextTimeout = timeout->getNext();
|
||||
|
||||
PR_REMOVE_LINK(timeout);
|
||||
timeout->remove();
|
||||
|
||||
if (needsReinsertion) {
|
||||
// Insert interval timeout onto list sorted in deadline order.
|
||||
@ -10036,7 +9954,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
|
||||
}
|
||||
|
||||
// Take the dummy timeout off the head of the list
|
||||
PR_REMOVE_LINK(&dummy_timeout);
|
||||
dummy_timeout.remove();
|
||||
|
||||
mTimeoutInsertionPoint = last_insertion_point;
|
||||
}
|
||||
@ -10074,9 +9992,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
|
||||
uint32_t public_id = (uint32_t)aTimerID;
|
||||
nsTimeout *timeout;
|
||||
|
||||
for (timeout = FirstTimeout();
|
||||
IsTimeout(timeout);
|
||||
timeout = timeout->Next()) {
|
||||
for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
|
||||
if (timeout->mPublicId == public_id) {
|
||||
if (timeout->mRunning) {
|
||||
/* We're running from inside the timeout. Mark this
|
||||
@ -10086,7 +10002,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
|
||||
}
|
||||
else {
|
||||
/* Delete the timeout from the pending timeout list */
|
||||
PR_REMOVE_LINK(timeout);
|
||||
timeout->remove();
|
||||
|
||||
if (timeout->mTimer) {
|
||||
timeout->mTimer->Cancel();
|
||||
@ -10121,13 +10037,13 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
|
||||
// start at the timer after mTimeoutInsertionPoint, if there is one.
|
||||
// Otherwise, start at the beginning of the list.
|
||||
for (nsTimeout *timeout = mTimeoutInsertionPoint ?
|
||||
mTimeoutInsertionPoint->Next() : FirstTimeout();
|
||||
IsTimeout(timeout); ) {
|
||||
mTimeoutInsertionPoint->getNext() : mTimeouts.getFirst();
|
||||
timeout; ) {
|
||||
// It's important that this check be <= so that we guarantee that
|
||||
// taking NS_MAX with |now| won't make a quantity equal to
|
||||
// timeout->mWhen below.
|
||||
if (timeout->mWhen <= now) {
|
||||
timeout = timeout->Next();
|
||||
timeout = timeout->getNext();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -10164,14 +10080,14 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
|
||||
|
||||
// Get the pointer to the next timeout now, before we move the
|
||||
// current timeout in the list.
|
||||
nsTimeout* nextTimeout = timeout->Next();
|
||||
nsTimeout* nextTimeout = timeout->getNext();
|
||||
|
||||
// It is safe to remove and re-insert because mWhen is now
|
||||
// strictly smaller than it used to be, so we know we'll insert
|
||||
// |timeout| before nextTimeout.
|
||||
NS_ASSERTION(!IsTimeout(nextTimeout) ||
|
||||
NS_ASSERTION(!nextTimeout ||
|
||||
timeout->mWhen < nextTimeout->mWhen, "How did that happen?");
|
||||
PR_REMOVE_LINK(timeout);
|
||||
timeout->remove();
|
||||
// InsertTimeoutIntoList will addref |timeout| and reset
|
||||
// mFiringDepth. Make sure to undo that after calling it.
|
||||
uint32_t firingDepth = timeout->mFiringDepth;
|
||||
@ -10188,7 +10104,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
|
||||
|
||||
timeout = nextTimeout;
|
||||
} else {
|
||||
timeout = timeout->Next();
|
||||
timeout = timeout->getNext();
|
||||
}
|
||||
}
|
||||
|
||||
@ -10200,7 +10116,7 @@ nsGlobalWindow::ClearAllTimeouts()
|
||||
{
|
||||
nsTimeout *timeout, *nextTimeout;
|
||||
|
||||
for (timeout = FirstTimeout(); IsTimeout(timeout); timeout = nextTimeout) {
|
||||
for (timeout = mTimeouts.getFirst(); timeout; timeout = nextTimeout) {
|
||||
/* If RunTimeout() is higher up on the stack for this
|
||||
window, e.g. as a result of document.write from a timeout,
|
||||
then we need to reset the list insertion point for
|
||||
@ -10209,7 +10125,7 @@ nsGlobalWindow::ClearAllTimeouts()
|
||||
if (mRunningTimeout == timeout)
|
||||
mTimeoutInsertionPoint = nullptr;
|
||||
|
||||
nextTimeout = timeout->Next();
|
||||
nextTimeout = timeout->getNext();
|
||||
|
||||
if (timeout->mTimer) {
|
||||
timeout->mTimer->Cancel();
|
||||
@ -10229,7 +10145,7 @@ nsGlobalWindow::ClearAllTimeouts()
|
||||
}
|
||||
|
||||
// Clear out our list
|
||||
PR_INIT_CLIST(&mTimeouts);
|
||||
mTimeouts.clear();
|
||||
}
|
||||
|
||||
void
|
||||
@ -10242,19 +10158,23 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
|
||||
// mTimeoutInsertionPoint, though. This optimizes for the common case of
|
||||
// insertion at the end.
|
||||
nsTimeout* prevSibling;
|
||||
for (prevSibling = LastTimeout();
|
||||
IsTimeout(prevSibling) && prevSibling != mTimeoutInsertionPoint &&
|
||||
for (prevSibling = mTimeouts.getLast();
|
||||
prevSibling && prevSibling != mTimeoutInsertionPoint &&
|
||||
// This condition needs to match the one in SetTimeoutOrInterval that
|
||||
// determines whether to set mWhen or mTimeRemaining.
|
||||
((IsFrozen() || mTimeoutsSuspendDepth) ?
|
||||
prevSibling->mTimeRemaining > aTimeout->mTimeRemaining :
|
||||
prevSibling->mWhen > aTimeout->mWhen);
|
||||
prevSibling = prevSibling->Prev()) {
|
||||
prevSibling = prevSibling->getPrevious()) {
|
||||
/* Do nothing; just searching */
|
||||
}
|
||||
|
||||
// Now link in aTimeout after prevSibling.
|
||||
PR_INSERT_AFTER(aTimeout, prevSibling);
|
||||
if (prevSibling) {
|
||||
prevSibling->setNext(aTimeout);
|
||||
} else {
|
||||
mTimeouts.insertFront(aTimeout);
|
||||
}
|
||||
|
||||
aTimeout->mFiringDepth = 0;
|
||||
|
||||
@ -10546,7 +10466,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease,
|
||||
mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
|
||||
for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
|
||||
// Set mTimeRemaining to be the time remaining for this timer.
|
||||
if (t->mWhen > now)
|
||||
t->mTimeRemaining = t->mWhen - now;
|
||||
@ -10634,7 +10554,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
|
||||
bool _seenDummyTimeout = false;
|
||||
#endif
|
||||
|
||||
for (nsTimeout *t = FirstTimeout(); IsTimeout(t); t = t->Next()) {
|
||||
for (nsTimeout *t = mTimeouts.getFirst(); t; t = t->getNext()) {
|
||||
// There's a chance we're being called with RunTimeout on the stack in which
|
||||
// case we have a dummy timeout in the list that *must not* be resumed. It
|
||||
// can be identified by a null mWindow.
|
||||
@ -10770,20 +10690,6 @@ nsGlobalWindow::DisableDeviceSensor(uint32_t aType)
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetURL(nsIDOMMozURLProperty** aURL)
|
||||
{
|
||||
FORWARD_TO_INNER(GetURL, (aURL), NS_ERROR_UNEXPECTED);
|
||||
|
||||
if (!mURLProperty) {
|
||||
mURLProperty = new nsDOMMozURLProperty(this);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aURL = mURLProperty);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::EnableTimeChangeNotifications()
|
||||
{
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "nsIContent.h"
|
||||
#include "nsIIDBFactory.h"
|
||||
#include "nsFrameMessageManager.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsIDOMTouchEvent.h"
|
||||
#include "nsIInlineEventHandlers.h"
|
||||
@ -111,7 +112,6 @@ class PostMessageEvent;
|
||||
class nsRunnable;
|
||||
class nsDOMEventTargetHelper;
|
||||
class nsDOMOfflineResourceList;
|
||||
class nsDOMMozURLProperty;
|
||||
class nsDOMWindowUtils;
|
||||
class nsIIdleService;
|
||||
|
||||
@ -124,6 +124,7 @@ class nsWindowSizes;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Navigator;
|
||||
class URL;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@ -138,7 +139,7 @@ NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
|
||||
* timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which
|
||||
* abstracts the language specific cruft.
|
||||
*/
|
||||
struct nsTimeout : PRCList
|
||||
struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
|
||||
{
|
||||
nsTimeout();
|
||||
~nsTimeout();
|
||||
@ -148,16 +149,6 @@ struct nsTimeout : PRCList
|
||||
nsrefcnt Release();
|
||||
nsrefcnt AddRef();
|
||||
|
||||
nsTimeout* Next() {
|
||||
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
|
||||
return static_cast<nsTimeout*>(PR_NEXT_LINK(this));
|
||||
}
|
||||
|
||||
nsTimeout* Prev() {
|
||||
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
|
||||
return static_cast<nsTimeout*>(PR_PREV_LINK(this));
|
||||
}
|
||||
|
||||
nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) {
|
||||
return mTimer->InitWithFuncCallback(aFunc, this, delay,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
@ -282,8 +273,6 @@ class nsGlobalWindow : public nsPIDOMWindow,
|
||||
#endif // MOZ_B2G
|
||||
{
|
||||
public:
|
||||
friend class nsDOMMozURLProperty;
|
||||
|
||||
typedef mozilla::TimeStamp TimeStamp;
|
||||
typedef mozilla::TimeDuration TimeDuration;
|
||||
typedef mozilla::dom::Navigator Navigator;
|
||||
@ -886,20 +875,6 @@ protected:
|
||||
|
||||
bool IsInModalState();
|
||||
|
||||
nsTimeout* FirstTimeout() {
|
||||
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
|
||||
return static_cast<nsTimeout*>(PR_LIST_HEAD(&mTimeouts));
|
||||
}
|
||||
|
||||
nsTimeout* LastTimeout() {
|
||||
// Note: might not actually return an nsTimeout. Use IsTimeout to check.
|
||||
return static_cast<nsTimeout*>(PR_LIST_TAIL(&mTimeouts));
|
||||
}
|
||||
|
||||
bool IsTimeout(PRCList* aList) {
|
||||
return aList != &mTimeouts;
|
||||
}
|
||||
|
||||
// Convenience functions for the many methods that need to scale
|
||||
// from device to CSS pixels or vice versa. Note: if a presentation
|
||||
// context is not available, they will assume a 1:1 ratio.
|
||||
@ -1067,7 +1042,7 @@ protected:
|
||||
// non-null. In that case, the dummy timeout pointed to by
|
||||
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
|
||||
// that come after it.
|
||||
PRCList mTimeouts;
|
||||
mozilla::LinkedList<nsTimeout> mTimeouts;
|
||||
// If mTimeoutInsertionPoint is non-null, insertions should happen after it.
|
||||
// This is a dummy timeout at the moment; if that ever changes, the logic in
|
||||
// ResetTimersForNonBackgroundWindow needs to change.
|
||||
@ -1128,8 +1103,6 @@ protected:
|
||||
// destroying this window).
|
||||
bool mDialogsPermanentlyDisabled;
|
||||
|
||||
nsRefPtr<nsDOMMozURLProperty> mURLProperty;
|
||||
|
||||
nsTHashtable<nsPtrHashKey<nsDOMEventTargetHelper> > mEventTargetObjects;
|
||||
|
||||
nsTArray<uint32_t> mEnabledSensors;
|
||||
|
@ -108,31 +108,6 @@ nsLocation::GetDocShell()
|
||||
return docshell;
|
||||
}
|
||||
|
||||
// Try to get the the document corresponding to the given JSScript.
|
||||
static already_AddRefed<nsIDocument>
|
||||
GetScriptDocument(JSContext *cx, JSScript *script)
|
||||
{
|
||||
if (!cx || !script)
|
||||
return nullptr;
|
||||
|
||||
JSObject* scope = JS_GetGlobalFromScript(script);
|
||||
if (!scope)
|
||||
return nullptr;
|
||||
|
||||
JSAutoCompartment ac(cx, scope);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window =
|
||||
do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(cx, scope));
|
||||
if (!window)
|
||||
return nullptr;
|
||||
|
||||
// If it's a window, get its document.
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
window->GetDocument(getter_AddRefs(domDoc));
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
|
||||
return doc.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
|
||||
{
|
||||
@ -166,13 +141,12 @@ nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
|
||||
// current URI as the referrer. If they don't match, use the principal's
|
||||
// URI.
|
||||
|
||||
JSScript* script = nullptr;
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
nsCOMPtr<nsIURI> docOriginalURI, docCurrentURI, principalURI;
|
||||
// NB: A false return value from JS_DescribeScriptedCaller means no caller
|
||||
// was found. It does not signal that an exception was thrown.
|
||||
if (JS_DescribeScriptedCaller(cx, &script, nullptr)) {
|
||||
doc = GetScriptDocument(cx, script);
|
||||
nsCOMPtr<nsPIDOMWindow> entryPoint =
|
||||
do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
|
||||
if (entryPoint) {
|
||||
doc = entryPoint->GetDoc();
|
||||
}
|
||||
if (doc) {
|
||||
docOriginalURI = doc->GetOriginalURI();
|
||||
|
@ -48,8 +48,8 @@ class nsIArray;
|
||||
class nsPIWindowRoot;
|
||||
|
||||
#define NS_PIDOMWINDOW_IID \
|
||||
{ 0x54fd92bd, 0xda33, 0x4451, \
|
||||
{ 0x8f, 0xb5, 0x11, 0x20, 0x5c, 0x03, 0xce, 0xaa } }
|
||||
{ 0x7b18e421, 0x2179, 0x4e24, \
|
||||
{ 0x96, 0x58, 0x26, 0x75, 0xa4, 0x37, 0xf3, 0x8f } }
|
||||
|
||||
class nsPIDOMWindow : public nsIDOMWindowInternal
|
||||
{
|
||||
|
@ -114,6 +114,10 @@ DOMInterfaces = {
|
||||
'concrete': False,
|
||||
},
|
||||
|
||||
'BiquadFilterNode': {
|
||||
'resultNotAddRefed': [ 'frequency', 'q', 'gain' ],
|
||||
},
|
||||
|
||||
'Blob': [
|
||||
{
|
||||
'headerFile': 'nsIDOMFile.h',
|
||||
@ -365,6 +369,10 @@ DOMInterfaces = {
|
||||
'implicitJSContext': [ 'encode' ],
|
||||
},
|
||||
|
||||
'URL' : {
|
||||
'concrete': False,
|
||||
},
|
||||
|
||||
'WebGLActiveInfo': {
|
||||
'nativeType': 'mozilla::WebGLActiveInfo',
|
||||
'headerFile': 'WebGLContext.h',
|
||||
|
@ -1095,7 +1095,9 @@ class MethodDefiner(PropertyDefiner):
|
||||
"flags": "JSPROP_ENUMERATE",
|
||||
"pref": None })
|
||||
|
||||
if not descriptor.interface.parent and not static and descriptor.nativeOwnership == 'nsisupports':
|
||||
if (not descriptor.interface.parent and not static and
|
||||
descriptor.nativeOwnership == 'nsisupports' and
|
||||
descriptor.interface.hasInterfacePrototypeObject()):
|
||||
self.chrome.append({"name": 'QueryInterface',
|
||||
"methodInfo": False,
|
||||
"length": 1,
|
||||
@ -5634,50 +5636,53 @@ class CGDescriptor(CGThing):
|
||||
assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
|
||||
|
||||
cgThings = []
|
||||
if descriptor.interface.hasInterfacePrototypeObject():
|
||||
# These are set to true if at least one non-static
|
||||
# method/getter/setter exist on the interface.
|
||||
(hasMethod, hasGetter, hasLenientGetter,
|
||||
hasSetter, hasLenientSetter) = False, False, False, False, False
|
||||
for m in descriptor.interface.members:
|
||||
if (m.isMethod() and
|
||||
(not m.isIdentifierLess() or m == descriptor.operations['Stringifier'])):
|
||||
if m.isStatic():
|
||||
cgThings.append(CGStaticMethod(descriptor, m))
|
||||
# These are set to true if at least one non-static
|
||||
# method/getter/setter exist on the interface.
|
||||
(hasMethod, hasGetter, hasLenientGetter,
|
||||
hasSetter, hasLenientSetter) = False, False, False, False, False
|
||||
for m in descriptor.interface.members:
|
||||
if (m.isMethod() and
|
||||
(not m.isIdentifierLess() or m == descriptor.operations['Stringifier'])):
|
||||
if m.isStatic():
|
||||
assert descriptor.interface.hasInterfaceObject
|
||||
cgThings.append(CGStaticMethod(descriptor, m))
|
||||
elif descriptor.interface.hasInterfacePrototypeObject():
|
||||
cgThings.append(CGSpecializedMethod(descriptor, m))
|
||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||
hasMethod = True
|
||||
elif m.isAttr():
|
||||
if m.isStatic():
|
||||
assert descriptor.interface.hasInterfaceObject
|
||||
cgThings.append(CGStaticGetter(descriptor, m))
|
||||
elif descriptor.interface.hasInterfacePrototypeObject():
|
||||
cgThings.append(CGSpecializedGetter(descriptor, m))
|
||||
if m.hasLenientThis():
|
||||
hasLenientGetter = True
|
||||
else:
|
||||
cgThings.append(CGSpecializedMethod(descriptor, m))
|
||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||
hasMethod = True
|
||||
elif m.isAttr():
|
||||
hasGetter = True
|
||||
if not m.readonly:
|
||||
if m.isStatic():
|
||||
cgThings.append(CGStaticGetter(descriptor, m))
|
||||
else:
|
||||
cgThings.append(CGSpecializedGetter(descriptor, m))
|
||||
assert descriptor.interface.hasInterfaceObject
|
||||
cgThings.append(CGStaticSetter(descriptor, m))
|
||||
elif descriptor.interface.hasInterfacePrototypeObject():
|
||||
cgThings.append(CGSpecializedSetter(descriptor, m))
|
||||
if m.hasLenientThis():
|
||||
hasLenientGetter = True
|
||||
hasLenientSetter = True
|
||||
else:
|
||||
hasGetter = True
|
||||
if not m.readonly:
|
||||
if m.isStatic():
|
||||
cgThings.append(CGStaticSetter(descriptor, m))
|
||||
else:
|
||||
cgThings.append(CGSpecializedSetter(descriptor, m))
|
||||
if m.hasLenientThis():
|
||||
hasLenientSetter = True
|
||||
else:
|
||||
hasSetter = True
|
||||
elif m.getExtendedAttribute("PutForwards"):
|
||||
cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
|
||||
hasSetter = True
|
||||
if not m.isStatic():
|
||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||
if hasMethod: cgThings.append(CGGenericMethod(descriptor))
|
||||
if hasGetter: cgThings.append(CGGenericGetter(descriptor))
|
||||
if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor,
|
||||
lenientThis=True))
|
||||
if hasSetter: cgThings.append(CGGenericSetter(descriptor))
|
||||
if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor,
|
||||
lenientThis=True))
|
||||
hasSetter = True
|
||||
elif m.getExtendedAttribute("PutForwards"):
|
||||
cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
|
||||
hasSetter = True
|
||||
if (not m.isStatic() and
|
||||
descriptor.interface.hasInterfacePrototypeObject()):
|
||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||
if hasMethod: cgThings.append(CGGenericMethod(descriptor))
|
||||
if hasGetter: cgThings.append(CGGenericGetter(descriptor))
|
||||
if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor,
|
||||
lenientThis=True))
|
||||
if hasSetter: cgThings.append(CGGenericSetter(descriptor))
|
||||
if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor,
|
||||
lenientThis=True))
|
||||
|
||||
if descriptor.concrete:
|
||||
if descriptor.nativeOwnership == 'owned' or descriptor.nativeOwnership == 'refcounted':
|
||||
@ -5805,9 +5810,10 @@ class CGNamespacedEnum(CGThing):
|
||||
|
||||
class CGDictionary(CGThing):
|
||||
def __init__(self, dictionary, descriptorProvider):
|
||||
self.dictionary = dictionary;
|
||||
self.dictionary = dictionary
|
||||
self.descriptorProvider = descriptorProvider
|
||||
self.workers = descriptorProvider.workers
|
||||
self.needToInitIds = not self.workers and len(dictionary.members) > 0
|
||||
if all(CGDictionary(d, descriptorProvider).generatable for
|
||||
d in CGDictionary.getDictionaryDependencies(dictionary)):
|
||||
self.generatable = True
|
||||
@ -5869,7 +5875,7 @@ class CGDictionary(CGThing):
|
||||
" ${selfName}(const ${selfName}&) MOZ_DELETE;\n" +
|
||||
# NOTE: jsids are per-runtime, so don't use them in workers
|
||||
(" static bool InitIds(JSContext* cx);\n"
|
||||
" static bool initedIds;\n" if not self.workers else "") +
|
||||
" static bool initedIds;\n" if self.needToInitIds else "") +
|
||||
"\n".join(" static jsid " +
|
||||
self.makeIdName(m.identifier.name) + ";" for
|
||||
m in d.members) + "\n"
|
||||
@ -5934,7 +5940,7 @@ class CGDictionary(CGThing):
|
||||
" initedIds = true;\n"
|
||||
" return true;\n"
|
||||
"}\n"
|
||||
"\n" if not self.workers else "") +
|
||||
"\n" if self.needToInitIds else "") +
|
||||
"bool\n"
|
||||
"${selfName}::Init(JSContext* cx, const JS::Value& val)\n"
|
||||
"{\n"
|
||||
@ -5944,10 +5950,10 @@ class CGDictionary(CGThing):
|
||||
# NOTE: jsids are per-runtime, so don't use them in workers
|
||||
(" if (cx && !initedIds && !InitIds(cx)) {\n"
|
||||
" return false;\n"
|
||||
" }\n" if not self.workers else "") +
|
||||
"${initParent}"
|
||||
" JSBool found;\n"
|
||||
" JS::Value temp;\n"
|
||||
" }\n" if self.needToInitIds else "") +
|
||||
"${initParent}" +
|
||||
(" JSBool found;\n"
|
||||
" JS::Value temp;\n" if len(memberInits) > 0 else "") +
|
||||
" bool isNull = val.isNullOrUndefined();\n"
|
||||
" if (!isNull && !val.isObject()) {\n"
|
||||
" return ThrowErrorMessage(cx, MSG_NOT_OBJECT);\n"
|
||||
@ -5963,7 +5969,7 @@ class CGDictionary(CGThing):
|
||||
# NOTE: jsids are per-runtime, so don't use them in workers
|
||||
(" if (!initedIds && !InitIds(cx)) {\n"
|
||||
" return false;\n"
|
||||
" }\n" if not self.workers else "") +
|
||||
" }\n" if self.needToInitIds else "") +
|
||||
"${toObjectParent}"
|
||||
"${ensureObject}"
|
||||
"\n"
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
USING_FILE_NAMESPACE
|
||||
|
||||
ArchiveReader::ArchiveReader()
|
||||
@ -33,6 +35,12 @@ ArchiveReader::~ArchiveReader()
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
bool
|
||||
ArchiveReader::PrefEnabled()
|
||||
{
|
||||
return Preferences::GetBool("dom.archivereader.enabled", true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ArchiveReader::Initialize(nsISupports* aOwner,
|
||||
JSContext* aCx,
|
||||
@ -42,6 +50,10 @@ ArchiveReader::Initialize(nsISupports* aOwner,
|
||||
{
|
||||
NS_ENSURE_TRUE(aArgc == 1 || aArgc == 2, NS_ERROR_INVALID_ARG);
|
||||
|
||||
if (!PrefEnabled()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// We expect to get a Blob object
|
||||
if (!aArgv[0].isObject()) {
|
||||
return NS_ERROR_INVALID_ARG; // We're not interested
|
||||
|
@ -48,6 +48,8 @@ public:
|
||||
nsresult GetInputStream(nsIInputStream** aInputStream);
|
||||
nsresult GetSize(uint64_t* aSize);
|
||||
|
||||
static bool PrefEnabled();
|
||||
|
||||
public: // for the ArchiveRequest:
|
||||
nsresult RegisterRequest(ArchiveRequest* aRequest);
|
||||
|
||||
|
@ -13,11 +13,14 @@ var fileStorages = [
|
||||
|
||||
var utils = SpecialPowers.getDOMWindowUtils(window);
|
||||
|
||||
var archiveReaderEnabled = false;
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function runTest()
|
||||
{
|
||||
allowUnlimitedQuota();
|
||||
enableArchiveReader();
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
testGenerator.next();
|
||||
@ -26,6 +29,7 @@ function runTest()
|
||||
function finishTest()
|
||||
{
|
||||
resetUnlimitedQuota();
|
||||
resetArchiveReader();
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
testGenerator.close();
|
||||
@ -98,6 +102,17 @@ function resetUnlimitedQuota(url)
|
||||
removePermission("indexedDB-unlimited", url);
|
||||
}
|
||||
|
||||
function enableArchiveReader()
|
||||
{
|
||||
archiveReaderEnabled = SpecialPowers.getBoolPref("dom.archivereader.enabled");
|
||||
SpecialPowers.setBoolPref("dom.archivereader.enabled", true);
|
||||
}
|
||||
|
||||
function resetArchiveReader()
|
||||
{
|
||||
SpecialPowers.setBoolPref("dom.archivereader.enabled", archiveReaderEnabled);
|
||||
}
|
||||
|
||||
function getFileHandle(fileStorageKey, name)
|
||||
{
|
||||
var requestService = SpecialPowers.getDOMRequestService();
|
||||
|
@ -8,14 +8,8 @@
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="display">
|
||||
<input id="fileList" type="file"></input>
|
||||
</p>
|
||||
|
||||
<script type="text/javascript;version=1.7">
|
||||
<script type="text/javascript;version=1.7">
|
||||
function createZipFileWithData(fileData) {
|
||||
var Cc = SpecialPowers.Cc;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
@ -58,7 +52,7 @@
|
||||
function markTestDone() {
|
||||
++handleFinished;
|
||||
if (isFinished()) {
|
||||
SimpleTest.finish();
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
function isFinished() {
|
||||
@ -251,11 +245,17 @@
|
||||
ok(false, "ArchiveReader.getFiles() should not return an 'error'");
|
||||
markTestDone();
|
||||
}
|
||||
yield;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
testSteps();
|
||||
</script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
</head>
|
||||
|
||||
<body onload="runTest();">
|
||||
<p id="display">
|
||||
<input id="fileList" type="file"></input>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
var archiveReaderEnabled = false;
|
||||
|
||||
// The test js is shared between xpcshell (which has no SpecialPowers object)
|
||||
// and content mochitests (where the |Components| object is accessible only as
|
||||
@ -68,6 +69,8 @@ if (!window.runTest) {
|
||||
allowUnlimitedQuota();
|
||||
}
|
||||
|
||||
enableArchiveReader();
|
||||
|
||||
clearAllDatabases(function () { testGenerator.next(); });
|
||||
}
|
||||
}
|
||||
@ -75,6 +78,7 @@ if (!window.runTest) {
|
||||
function finishTest()
|
||||
{
|
||||
resetUnlimitedQuota();
|
||||
resetArchiveReader();
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
testGenerator.close();
|
||||
@ -163,12 +167,12 @@ function compareKeys(k1, k2) {
|
||||
if (!(k2 instanceof Array) ||
|
||||
k1.length != k2.length)
|
||||
return false;
|
||||
|
||||
|
||||
for (let i = 0; i < k1.length; ++i) {
|
||||
if (!compareKeys(k1[i], k2[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -211,6 +215,17 @@ function resetUnlimitedQuota(url)
|
||||
removePermission("indexedDB-unlimited", url);
|
||||
}
|
||||
|
||||
function enableArchiveReader()
|
||||
{
|
||||
archiveReaderEnabled = SpecialPowers.getBoolPref("dom.archivereader.enabled");
|
||||
SpecialPowers.setBoolPref("dom.archivereader.enabled", true);
|
||||
}
|
||||
|
||||
function resetArchiveReader()
|
||||
{
|
||||
SpecialPowers.setBoolPref("dom.archivereader.enabled", archiveReaderEnabled);
|
||||
}
|
||||
|
||||
function gc()
|
||||
{
|
||||
SpecialPowers.forceGC();
|
||||
|
@ -16,13 +16,6 @@ interface nsIPrompt;
|
||||
interface nsISelection;
|
||||
interface nsIVariant;
|
||||
|
||||
[scriptable, uuid(8fc58f56-f769-4368-a098-edd08550cf1a)]
|
||||
interface nsIDOMMozURLProperty : nsISupports
|
||||
{
|
||||
DOMString createObjectURL(in nsIDOMBlob blob);
|
||||
void revokeObjectURL(in DOMString URL);
|
||||
};
|
||||
|
||||
/**
|
||||
* The nsIDOMWindow interface is the primary interface for a DOM
|
||||
* window object. It represents a single window object that may
|
||||
@ -32,7 +25,7 @@ interface nsIDOMMozURLProperty : nsISupports
|
||||
* @see <http://www.whatwg.org/html/#window>
|
||||
*/
|
||||
|
||||
[scriptable, uuid(1534ecd7-e298-420e-9063-e6c2d1243d49)]
|
||||
[scriptable, uuid(b9c71e0b-7f81-419a-8253-91f4c8893c4f)]
|
||||
interface nsIDOMWindow : nsISupports
|
||||
{
|
||||
// the current browsing context
|
||||
@ -461,11 +454,6 @@ interface nsIDOMWindow : nsISupports
|
||||
*/
|
||||
readonly attribute long long mozAnimationStartTime;
|
||||
|
||||
/**
|
||||
* @see <http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking>
|
||||
*/
|
||||
readonly attribute nsIDOMMozURLProperty URL;
|
||||
|
||||
/**
|
||||
* HTML5 event attributes that only apply to windows and <body>/<frameset>
|
||||
*/
|
||||
@ -525,5 +513,5 @@ interface nsIWindowCrypto : nsISupports
|
||||
* Empty interface for compatibility with older versions.
|
||||
* @deprecated Use nsIDOMWindow instead
|
||||
*/
|
||||
[scriptable, uuid(8da641ab-906a-456e-97f2-b77df4ca2d95)]
|
||||
[scriptable, uuid(a5cd0946-bac1-4606-9aaa-9e68dd0a3279)]
|
||||
interface nsIDOMWindowInternal : nsIDOMWindow {};
|
||||
|
@ -130,6 +130,11 @@ MOCHITEST_FILES = \
|
||||
test_bug755320.html \
|
||||
test_bug777628.html \
|
||||
test_bug665548.html \
|
||||
test_bug809290.html \
|
||||
file_bug809290_b1.html \
|
||||
file_bug809290_b2.html \
|
||||
file_bug809290_c.html \
|
||||
file_empty.html \
|
||||
$(NULL)
|
||||
|
||||
ifneq (Linux,$(OS_ARCH))
|
||||
|
14
dom/tests/mochitest/bugs/file_bug809290_b1.html
Normal file
14
dom/tests/mochitest/bugs/file_bug809290_b1.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function innerLoad() {
|
||||
var win = document.getElementById('ifr').contentWindow;
|
||||
win.location = "file_bug809290_c.html";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="ifr" src="file_empty.html">
|
||||
</body>
|
||||
</html>
|
14
dom/tests/mochitest/bugs/file_bug809290_b2.html
Normal file
14
dom/tests/mochitest/bugs/file_bug809290_b2.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function eventHandlerLoad() {
|
||||
var win = document.getElementById('ifr').contentWindow;
|
||||
win.location = "file_bug809290_c.html";
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="eventHandlerLoad();">
|
||||
<iframe id="ifr" src="file_empty.html">
|
||||
</body>
|
||||
</html>
|
10
dom/tests/mochitest/bugs/file_bug809290_c.html
Normal file
10
dom/tests/mochitest/bugs/file_bug809290_c.html
Normal file
@ -0,0 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
window.parent.parent.notifyReferrer(document.referrer);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
2
dom/tests/mochitest/bugs/file_empty.html
Normal file
2
dom/tests/mochitest/bugs/file_empty.html
Normal file
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html><head></head><body></body></html>
|
@ -56,8 +56,15 @@ function iframeLoaded(identifier) {
|
||||
is(iframeCw.getInnerIframeReferrer(), iframeCw.location, 'inner iframe referrer');
|
||||
|
||||
// Now do the test again, this time with a popup.
|
||||
popup = window.open('file_bug593174_1.html');
|
||||
popup.onload = iframeLoaded('popup/outer');
|
||||
//
|
||||
// NB: in this situation, we're actually getting called in an event handler from
|
||||
// the iframe, meaning that it serves as the script entry point. But that's a detail,
|
||||
// and we want to pretend like this window is doing the call. So let's use setTimeout
|
||||
// to forget about the iframe.
|
||||
window.setTimeout(function() {
|
||||
popup = window.open('file_bug593174_1.html');
|
||||
popup.onload = iframeLoaded('popup/outer');
|
||||
}, 0);
|
||||
}
|
||||
else if (loadCount == 4) {
|
||||
history.replaceState('', '', Math.random());
|
||||
|
48
dom/tests/mochitest/bugs/test_bug809290.html
Normal file
48
dom/tests/mochitest/bugs/test_bug809290.html
Normal file
@ -0,0 +1,48 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=809290
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 809290</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=809290">Mozilla Bug 809290</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 809290 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var gNotifyCount = 0;
|
||||
function notifyReferrer(referrer) {
|
||||
++gNotifyCount;
|
||||
if (gNotifyCount == 1) {
|
||||
is(referrer, window.location.href, "Referrer should be the script entry point (this script)");
|
||||
document.getElementById('ifr').setAttribute('src', 'file_bug809290_b2.html');
|
||||
} else {
|
||||
is(gNotifyCount, 2);
|
||||
is(referrer, window.location.href.replace(/test_bug.*/, 'file_bug809290_b2.html'),
|
||||
"Referrer should be the script entry point (iframe)");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function go() {
|
||||
var ifr = document.getElementById('ifr');
|
||||
ifr.onload = null;
|
||||
ifr.contentWindow.innerLoad();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<iframe id="ifr" src="file_bug809290_b1.html" onload="go();"></iframe>
|
||||
</body>
|
||||
</html>
|
@ -207,8 +207,6 @@ var interfaceNamesInGlobalScope =
|
||||
"SVGAltGlyphElement",
|
||||
"Screen",
|
||||
"FileReader",
|
||||
"ArchiveReader",
|
||||
"ArchiveRequest",
|
||||
"SVGSwitchElement",
|
||||
"SVGPolylineElement",
|
||||
"SVGPathSegLinetoAbs",
|
||||
@ -342,7 +340,7 @@ var interfaceNamesInGlobalScope =
|
||||
"HTMLSelectElement",
|
||||
"MessageEvent",
|
||||
"SVGFEImageElement",
|
||||
"MozURLProperty",
|
||||
"URL",
|
||||
"DeviceStorage",
|
||||
"SVGFEOffsetElement",
|
||||
"DOMImplementation",
|
||||
|
@ -31,6 +31,8 @@ interface mozAudioContext {
|
||||
[Creator]
|
||||
DelayNode createDelay(optional float maxDelayTime = 1);
|
||||
[Creator]
|
||||
BiquadFilterNode createBiquadFilter();
|
||||
[Creator]
|
||||
PannerNode createPanner();
|
||||
|
||||
[Creator]
|
||||
|
37
dom/webidl/BiquadFilterNode.webidl
Normal file
37
dom/webidl/BiquadFilterNode.webidl
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[PrefControlled]
|
||||
interface BiquadFilterNode : AudioNode {
|
||||
|
||||
// Filter type.
|
||||
const unsigned short LOWPASS = 0;
|
||||
const unsigned short HIGHPASS = 1;
|
||||
const unsigned short BANDPASS = 2;
|
||||
const unsigned short LOWSHELF = 3;
|
||||
const unsigned short HIGHSHELF = 4;
|
||||
const unsigned short PEAKING = 5;
|
||||
const unsigned short NOTCH = 6;
|
||||
const unsigned short ALLPASS = 7;
|
||||
|
||||
[SetterThrows]
|
||||
attribute unsigned short type;
|
||||
readonly attribute AudioParam frequency; // in Hertz
|
||||
readonly attribute AudioParam Q; // Quality factor
|
||||
readonly attribute AudioParam gain; // in Decibels
|
||||
|
||||
// void getFrequencyResponse(Float32Array frequencyHz,
|
||||
// Float32Array magResponse,
|
||||
// Float32Array phaseResponse);
|
||||
|
||||
};
|
||||
|
27
dom/webidl/URL.webidl
Normal file
27
dom/webidl/URL.webidl
Normal file
@ -0,0 +1,27 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* The origins of this IDL file are
|
||||
* http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking
|
||||
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html#url
|
||||
*
|
||||
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
interface MediaStream;
|
||||
|
||||
interface URL {
|
||||
[Throws]
|
||||
static DOMString? createObjectURL(Blob blob, optional objectURLOptions options);
|
||||
[Throws]
|
||||
static DOMString? createObjectURL(MediaStream stream, optional objectURLOptions options);
|
||||
static void revokeObjectURL(DOMString url);
|
||||
};
|
||||
|
||||
dictionary objectURLOptions
|
||||
{
|
||||
/* boolean autoRevoke = true; */ /* not supported yet */
|
||||
};
|
@ -17,6 +17,7 @@ webidl_files = \
|
||||
AudioNode.webidl \
|
||||
AudioParam.webidl \
|
||||
AudioSourceNode.webidl \
|
||||
BiquadFilterNode.webidl \
|
||||
Blob.webidl \
|
||||
CanvasRenderingContext2D.webidl \
|
||||
ClientRectList.webidl \
|
||||
@ -52,6 +53,7 @@ webidl_files = \
|
||||
SVGTransformList.webidl \
|
||||
TextDecoder.webidl \
|
||||
TextEncoder.webidl \
|
||||
URL.webidl \
|
||||
WebSocket.webidl \
|
||||
XMLHttpRequest.webidl \
|
||||
XMLHttpRequestEventTarget.webidl \
|
||||
|
@ -992,6 +992,10 @@ LayerManagerOGL::Render()
|
||||
// Allow widget to render a custom background.
|
||||
mWidget->DrawWindowUnderlay(this, rect);
|
||||
|
||||
// Reset some state that might of been clobbered by the underlay.
|
||||
mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
|
||||
LOCAL_GL_ONE, LOCAL_GL_ONE);
|
||||
|
||||
// Render our layers.
|
||||
RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,
|
||||
nsIntPoint(0, 0));
|
||||
|
@ -501,8 +501,7 @@ nsresult nsExtensibleStringBundle::GetSimpleEnumeration(nsISimpleEnumerator ** a
|
||||
|
||||
#define MAX_CACHED_BUNDLES 16
|
||||
|
||||
struct bundleCacheEntry_t {
|
||||
PRCList list;
|
||||
struct bundleCacheEntry_t : public LinkedListElement<bundleCacheEntry_t> {
|
||||
nsCStringKey *mHashKey;
|
||||
// do not use a nsCOMPtr - this is a struct not a class!
|
||||
nsIStringBundle* mBundle;
|
||||
@ -516,7 +515,6 @@ nsStringBundleService::nsStringBundleService() :
|
||||
printf("\n++ nsStringBundleService::nsStringBundleService ++\n");
|
||||
#endif
|
||||
|
||||
PR_INIT_CLIST(&mBundleCache);
|
||||
PL_InitArenaPool(&mCacheEntryPool, "srEntries",
|
||||
sizeof(bundleCacheEntry_t)*MAX_CACHED_BUNDLES,
|
||||
sizeof(bundleCacheEntry_t));
|
||||
@ -582,16 +580,10 @@ nsStringBundleService::flushBundleCache()
|
||||
// release all bundles in the cache
|
||||
mBundleMap.Reset();
|
||||
|
||||
PRCList *current = PR_LIST_HEAD(&mBundleCache);
|
||||
while (current != &mBundleCache) {
|
||||
bundleCacheEntry_t *cacheEntry = (bundleCacheEntry_t*)current;
|
||||
while (!mBundleCache.isEmpty()) {
|
||||
bundleCacheEntry_t *cacheEntry = mBundleCache.popFirst();
|
||||
|
||||
recycleEntry(cacheEntry);
|
||||
PRCList *oldItem = current;
|
||||
current = PR_NEXT_LINK(current);
|
||||
|
||||
// will be freed in PL_FreeArenaPool
|
||||
PR_REMOVE_LINK(oldItem);
|
||||
}
|
||||
PL_FreeArenaPool(&mCacheEntryPool);
|
||||
}
|
||||
@ -616,7 +608,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
|
||||
// cache hit!
|
||||
// remove it from the list, it will later be reinserted
|
||||
// at the head of the list
|
||||
PR_REMOVE_LINK((PRCList*)cacheEntry);
|
||||
cacheEntry->remove();
|
||||
|
||||
} else {
|
||||
|
||||
@ -633,8 +625,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
|
||||
// at this point the cacheEntry should exist in the hashtable,
|
||||
// but is not in the LRU cache.
|
||||
// put the cache entry at the front of the list
|
||||
|
||||
PR_INSERT_LINK((PRCList *)cacheEntry, &mBundleCache);
|
||||
mBundleCache.insertFront(cacheEntry);
|
||||
|
||||
// finally, return the value
|
||||
*aResult = cacheEntry->mBundle;
|
||||
@ -654,12 +645,12 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle,
|
||||
|
||||
void *cacheEntryArena;
|
||||
PL_ARENA_ALLOCATE(cacheEntryArena, &mCacheEntryPool, sizeof(bundleCacheEntry_t));
|
||||
cacheEntry = (bundleCacheEntry_t*)cacheEntryArena;
|
||||
cacheEntry = new (cacheEntryArena) bundleCacheEntry_t();
|
||||
|
||||
} else {
|
||||
// cache is full
|
||||
// take the last entry in the list, and recycle it.
|
||||
cacheEntry = (bundleCacheEntry_t*)PR_LIST_TAIL(&mBundleCache);
|
||||
cacheEntry = mBundleCache.getLast();
|
||||
|
||||
// remove it from the hash table and linked list
|
||||
NS_ASSERTION(mBundleMap.Exists(cacheEntry->mHashKey),
|
||||
@ -670,7 +661,7 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle,
|
||||
aHashKey->GetString()).get());
|
||||
#endif
|
||||
mBundleMap.Remove(cacheEntry->mHashKey);
|
||||
PR_REMOVE_LINK((PRCList*)cacheEntry);
|
||||
cacheEntry->remove();
|
||||
|
||||
// free up excess memory
|
||||
recycleEntry(cacheEntry);
|
||||
|
@ -6,7 +6,6 @@
|
||||
#ifndef nsStringBundleService_h__
|
||||
#define nsStringBundleService_h__
|
||||
|
||||
#include "prclist.h"
|
||||
#include "plarena.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
@ -18,6 +17,8 @@
|
||||
#include "nsIErrorService.h"
|
||||
#include "nsIStringBundleOverride.h"
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
|
||||
struct bundleCacheEntry_t;
|
||||
|
||||
class nsStringBundleService : public nsIStringBundleService,
|
||||
@ -48,7 +49,7 @@ private:
|
||||
static void recycleEntry(bundleCacheEntry_t*);
|
||||
|
||||
nsHashtable mBundleMap;
|
||||
PRCList mBundleCache;
|
||||
mozilla::LinkedList<bundleCacheEntry_t> mBundleCache;
|
||||
PLArenaPool mCacheEntryPool;
|
||||
|
||||
nsCOMPtr<nsIErrorService> mErrorService;
|
||||
|
@ -243,8 +243,17 @@ case "$target" in
|
||||
android_platform_tools="$android_sdk"/tools # SDK Tools < r8
|
||||
fi
|
||||
ANDROID_SDK="${android_sdk}"
|
||||
if test -e "${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar" ; then
|
||||
ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/compatibility/v4/android-support-v4.jar"
|
||||
else
|
||||
ANDROID_COMPAT_LIB="${android_sdk}/../../extras/android/support/v4/android-support-v4.jar";
|
||||
fi
|
||||
ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
|
||||
AC_SUBST(ANDROID_SDK)
|
||||
AC_SUBST(ANDROID_COMPAT_LIB)
|
||||
if ! test -e $ANDROID_COMPAT_LIB ; then
|
||||
AC_MSG_ERROR([You must download the andrioid compatibility library when targeting Android. (found $ANDROID_COMPAT_LIB)])
|
||||
fi
|
||||
AC_SUBST(ANDROID_PLATFORM_TOOLS)
|
||||
;;
|
||||
esac
|
||||
|
@ -1701,9 +1701,9 @@ ion::InvalidateAll(FreeOp *fop, JSCompartment *c)
|
||||
CancelOffThreadIonCompile(c, NULL);
|
||||
|
||||
FinishAllOffThreadCompilations(c->ionCompartment());
|
||||
|
||||
for (IonActivationIterator iter(fop->runtime()); iter.more(); ++iter) {
|
||||
if (iter.activation()->compartment() == c) {
|
||||
IonContext ictx(NULL, c, NULL);
|
||||
AutoFlushCache afc ("InvalidateAll", c->ionCompartment());
|
||||
IonSpew(IonSpew_Invalidate, "Invalidating all frames for GC");
|
||||
InvalidateActivation(fop, iter.top(), true);
|
||||
@ -1875,10 +1875,8 @@ AutoFlushCache::AutoFlushCache(const char *nonce, IonCompartment *comp)
|
||||
name_(nonce),
|
||||
used_(false)
|
||||
{
|
||||
if (comp == NULL) {
|
||||
if (CurrentIonContext() != NULL)
|
||||
comp = GetIonContext()->compartment->ionCompartment();
|
||||
}
|
||||
if (CurrentIonContext() != NULL)
|
||||
comp = GetIonContext()->compartment->ionCompartment();
|
||||
// If a compartment isn't available, then be a nop, nobody will ever see this flusher
|
||||
if (comp) {
|
||||
if (comp->flusher())
|
||||
|
@ -471,7 +471,6 @@ struct GetNativePropertyStub
|
||||
|
||||
// TODO: ensure stack is aligned?
|
||||
DebugOnly<uint32> initialStack = masm.framePushed();
|
||||
masm.checkStackAlignment();
|
||||
|
||||
Label success, exception;
|
||||
|
||||
|
@ -230,6 +230,8 @@ ion::CheckLogging()
|
||||
EnableChannel(IonSpew_Safepoints);
|
||||
if (ContainsFlag(env, "pools"))
|
||||
EnableChannel(IonSpew_Pools);
|
||||
if (ContainsFlag(env, "cacheflush"))
|
||||
EnableChannel(IonSpew_CacheFlush);
|
||||
if (ContainsFlag(env, "logs"))
|
||||
EnableIonDebugLogging();
|
||||
if (ContainsFlag(env, "all"))
|
||||
|
@ -958,9 +958,20 @@ MMul::analyzeEdgeCasesBackward()
|
||||
canBeNegativeZero_ = NeedNegativeZeroCheck(this);
|
||||
}
|
||||
|
||||
bool
|
||||
MMul::updateForReplacement(MDefinition *ins)
|
||||
void
|
||||
MMul::analyzeTruncateBackward()
|
||||
{
|
||||
if (!isPossibleTruncated())
|
||||
setPossibleTruncated(js::ion::EdgeCaseAnalysis::AllUsesTruncate(this));
|
||||
}
|
||||
|
||||
bool
|
||||
MMul::updateForReplacement(MDefinition *ins_)
|
||||
{
|
||||
JS_ASSERT(ins_->isMul());
|
||||
MMul *ins = ins_->toMul();
|
||||
if (isPossibleTruncated())
|
||||
setPossibleTruncated(ins->isPossibleTruncated());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2498,11 +2498,24 @@ class MSub : public MBinaryArithInstruction
|
||||
|
||||
class MMul : public MBinaryArithInstruction
|
||||
{
|
||||
// Annotation the result could be a negative zero
|
||||
// and we need to guard this during execution.
|
||||
bool canBeNegativeZero_;
|
||||
|
||||
// Annotation the result of this Mul is only used in int32 domain
|
||||
// and we could possible truncate the result.
|
||||
bool possibleTruncate_;
|
||||
|
||||
// Annotation the Mul can truncate. This is only set after range analysis,
|
||||
// because the result could be in the imprecise double range.
|
||||
// In that case the truncated result isn't correct.
|
||||
bool implicitTruncate_;
|
||||
|
||||
MMul(MDefinition *left, MDefinition *right, MIRType type)
|
||||
: MBinaryArithInstruction(left, right),
|
||||
canBeNegativeZero_(true)
|
||||
canBeNegativeZero_(true),
|
||||
possibleTruncate_(false),
|
||||
implicitTruncate_(false)
|
||||
{
|
||||
if (type != MIRType_Value)
|
||||
specialization_ = type;
|
||||
@ -2521,13 +2534,14 @@ class MMul : public MBinaryArithInstruction
|
||||
MDefinition *foldsTo(bool useValueNumbers);
|
||||
void analyzeEdgeCasesForward();
|
||||
void analyzeEdgeCasesBackward();
|
||||
void analyzeTruncateBackward();
|
||||
|
||||
double getIdentity() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool canOverflow() {
|
||||
return !range()->isFinite();
|
||||
return !implicitTruncate_ && !range()->isFinite();
|
||||
}
|
||||
|
||||
bool canBeNegativeZero() {
|
||||
@ -2546,8 +2560,18 @@ class MMul : public MBinaryArithInstruction
|
||||
return false;
|
||||
Range *left = getOperand(0)->range();
|
||||
Range *right = getOperand(1)->range();
|
||||
if (isPossibleTruncated())
|
||||
implicitTruncate_ = !Range::precisionLossMul(left, right);
|
||||
return range()->update(Range::mul(left, right));
|
||||
}
|
||||
|
||||
bool isPossibleTruncated() const {
|
||||
return possibleTruncate_;
|
||||
}
|
||||
|
||||
void setPossibleTruncated(bool truncate) {
|
||||
possibleTruncate_ = truncate;
|
||||
}
|
||||
};
|
||||
|
||||
class MDiv : public MBinaryArithInstruction
|
||||
|
@ -417,6 +417,24 @@ Range::shr(const Range *lhs, int32 c)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
Range::precisionLossMul(const Range *lhs, const Range *rhs)
|
||||
{
|
||||
int64_t loss = 1LL<<53; // result must be lower than 2^53
|
||||
int64_t a = (int64_t)lhs->lower_ * (int64_t)rhs->lower_;
|
||||
int64_t b = (int64_t)lhs->lower_ * (int64_t)rhs->upper_;
|
||||
int64_t c = (int64_t)lhs->upper_ * (int64_t)rhs->lower_;
|
||||
int64_t d = (int64_t)lhs->upper_ * (int64_t)rhs->upper_;
|
||||
int64_t lower = Min( Min(a, b), Min(c, d) );
|
||||
int64_t upper = Max( Max(a, b), Max(c, d) );
|
||||
if (lower < 0)
|
||||
lower = -lower;
|
||||
if (upper < 0)
|
||||
upper = -upper;
|
||||
|
||||
return lower > loss || upper > loss;
|
||||
}
|
||||
|
||||
bool
|
||||
Range::update(const Range *other)
|
||||
{
|
||||
|
@ -126,6 +126,8 @@ class Range {
|
||||
static Range shl(const Range *lhs, int32 c);
|
||||
static Range shr(const Range *lhs, int32 c);
|
||||
|
||||
static bool precisionLossMul(const Range *lhs, const Range *rhs);
|
||||
|
||||
inline void makeLowerInfinite() {
|
||||
lower_infinite_ = true;
|
||||
lower_ = JSVAL_INT_MIN;
|
||||
|
@ -72,7 +72,6 @@ struct EnterJITStack
|
||||
IonCode *
|
||||
IonCompartment::generateEnterJIT(JSContext *cx)
|
||||
{
|
||||
AutoFlushCache afc("GenerateEnterJIT", cx->compartment->ionCompartment());
|
||||
|
||||
const Register reg_code = r0;
|
||||
const Register reg_argc = r1;
|
||||
@ -85,6 +84,7 @@ IonCompartment::generateEnterJIT(JSContext *cx)
|
||||
JS_ASSERT(OsrFrameReg == reg_frame);
|
||||
|
||||
MacroAssembler masm(cx);
|
||||
AutoFlushCache afc("GenerateEnterJIT", cx->compartment->ionCompartment());
|
||||
Assembler *aasm = &masm;
|
||||
|
||||
// Save non-volatile registers. These must be saved by the trampoline,
|
||||
|
19
js/src/jit-test/tests/ion/bug809472.js
Normal file
19
js/src/jit-test/tests/ion/bug809472.js
Normal file
@ -0,0 +1,19 @@
|
||||
function test1(x) {
|
||||
return (x*((2<<23)-1))|0
|
||||
}
|
||||
function test2(x) {
|
||||
return (x*((2<<22)-1))|0
|
||||
}
|
||||
function test3(x) {
|
||||
return (x*((2<<21)-1))|0
|
||||
}
|
||||
function test4(x) {
|
||||
var b = x + x + 3
|
||||
return (b*b) | 0
|
||||
}
|
||||
//MAX_INT
|
||||
var x = 0x7ffffffe;
|
||||
assertEq(test1(x), 2113929216);
|
||||
assertEq(test2(x), 2130706434);
|
||||
assertEq(test3(x), 2139095042);
|
||||
assertEq(test4(x), 0);
|
3
js/src/jit-test/tests/proxy/testBug793160.js
Normal file
3
js/src/jit-test/tests/proxy/testBug793160.js
Normal file
@ -0,0 +1,3 @@
|
||||
var obj = new Proxy(Object.create(null), {});
|
||||
assertEq(typeof obj, 'object');
|
||||
assertEq(obj != null, true);
|
@ -3156,9 +3156,12 @@ proxy(JSContext *cx, unsigned argc, jsval *vp)
|
||||
RootedObject proto(cx);
|
||||
if (!JSObject::getProto(cx, target, &proto))
|
||||
return false;
|
||||
JSObject *parent = NULL;
|
||||
if (proto)
|
||||
parent = proto->getParent();
|
||||
RootedObject fun(cx, target->isCallable() ? target : (JSObject *) NULL);
|
||||
JSObject *proxy = NewProxyObject(cx, &ScriptedDirectProxyHandler::singleton,
|
||||
ObjectValue(*target), proto, proto->getParent(),
|
||||
ObjectValue(*target), proto, parent,
|
||||
fun, fun);
|
||||
if (!proxy)
|
||||
return false;
|
||||
|
@ -944,8 +944,7 @@ SourceCompressorThread::internalCompress()
|
||||
// Try to keep the maximum memory usage down by only allocating half the
|
||||
// size of the string, first.
|
||||
size_t firstSize = nbytes / 2;
|
||||
ss->data.compressed = static_cast<unsigned char *>(js_malloc(firstSize));
|
||||
if (!ss->data.compressed)
|
||||
if (!ss->adjustDataSize(firstSize))
|
||||
return false;
|
||||
Compressor comp(reinterpret_cast<const unsigned char *>(tok->chars), nbytes);
|
||||
if (!comp.init())
|
||||
@ -964,13 +963,8 @@ SourceCompressorThread::internalCompress()
|
||||
|
||||
// The compressed output is greater than half the size of the
|
||||
// original string. Reallocate to the full size.
|
||||
void *newmem = js_realloc(ss->data.compressed, nbytes);
|
||||
if (!newmem) {
|
||||
js_free(ss->data.compressed);
|
||||
ss->data.compressed = NULL;
|
||||
if (!ss->adjustDataSize(nbytes))
|
||||
return false;
|
||||
}
|
||||
ss->data.compressed = static_cast<unsigned char *>(newmem);
|
||||
comp.setOutput(ss->data.compressed, nbytes);
|
||||
break;
|
||||
}
|
||||
@ -988,22 +982,12 @@ SourceCompressorThread::internalCompress()
|
||||
}
|
||||
#endif
|
||||
if (compressedLength == 0) {
|
||||
// Note ss->data.source might be NULL.
|
||||
jschar *buf = static_cast<jschar *>(js_realloc(ss->data.source, nbytes));
|
||||
if (!buf) {
|
||||
if (ss->data.source) {
|
||||
js_free(ss->data.source);
|
||||
ss->data.source = NULL;
|
||||
}
|
||||
if (!ss->adjustDataSize(nbytes))
|
||||
return false;
|
||||
}
|
||||
ss->data.source = buf;
|
||||
PodCopy(ss->data.source, tok->chars, ss->length());
|
||||
} else {
|
||||
// Shrink the buffer to the size of the compressed data. Shouldn't fail.
|
||||
void *newmem = js_realloc(ss->data.compressed, compressedLength);
|
||||
JS_ASSERT(newmem);
|
||||
ss->data.compressed = static_cast<unsigned char *>(newmem);
|
||||
JS_ALWAYS_TRUE(ss->adjustDataSize(compressedLength));
|
||||
}
|
||||
ss->compressedLength_ = compressedLength;
|
||||
return true;
|
||||
@ -1085,6 +1069,29 @@ SourceCompressorThread::abort(SourceCompressionToken *userTok)
|
||||
}
|
||||
#endif /* JS_THREADSAFE */
|
||||
|
||||
static const unsigned char emptySource[] = "";
|
||||
|
||||
/* Adjust the amount of memory this script source uses for source data,
|
||||
reallocating if needed. */
|
||||
bool
|
||||
ScriptSource::adjustDataSize(size_t nbytes)
|
||||
{
|
||||
// Allocating 0 bytes has undefined behavior, so special-case it.
|
||||
if (nbytes == 0) {
|
||||
if (data.compressed != emptySource)
|
||||
js_free(data.compressed);
|
||||
data.compressed = const_cast<unsigned char *>(emptySource);
|
||||
return true;
|
||||
}
|
||||
|
||||
// |data.compressed| can be NULL.
|
||||
void *buf = js_realloc(data.compressed, nbytes);
|
||||
if (!buf && data.compressed != emptySource)
|
||||
js_free(data.compressed);
|
||||
data.compressed = static_cast<unsigned char *>(buf);
|
||||
return !!data.compressed;
|
||||
}
|
||||
|
||||
void
|
||||
JSScript::setScriptSource(ScriptSource *ss)
|
||||
{
|
||||
@ -1210,8 +1217,7 @@ ScriptSource::setSourceCopy(JSContext *cx, StableCharPtr src, uint32_t length,
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
data.source = cx->runtime->pod_malloc<jschar>(length);
|
||||
if (!data.source)
|
||||
if (!adjustDataSize(sizeof(jschar) * length))
|
||||
return false;
|
||||
PodCopy(data.source, src.get(), length_);
|
||||
}
|
||||
@ -1257,7 +1263,7 @@ void
|
||||
ScriptSource::destroy(JSRuntime *rt)
|
||||
{
|
||||
JS_ASSERT(ready());
|
||||
js_free(data.compressed);
|
||||
adjustDataSize(0);
|
||||
js_free(sourceMap_);
|
||||
#ifdef DEBUG
|
||||
ready_ = false;
|
||||
@ -1270,9 +1276,9 @@ ScriptSource::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
JS_ASSERT(ready());
|
||||
|
||||
// data is a union, but both members are pointers to allocated memory or
|
||||
// NULL, so just using compressed will work.
|
||||
return mallocSizeOf(this) + mallocSizeOf(data.compressed);
|
||||
// |data| is a union, but both members are pointers to allocated memory,
|
||||
// |emptySource|, or NULL, so just using |data.compressed| will work.
|
||||
return mallocSizeOf(this) + ((data.compressed != emptySource) ? mallocSizeOf(data.compressed) : 0);
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
@ -1305,8 +1311,7 @@ ScriptSource::performXDR(XDRState<mode> *xdr)
|
||||
|
||||
size_t byteLen = compressedLength ? compressedLength : (length * sizeof(jschar));
|
||||
if (mode == XDR_DECODE) {
|
||||
data.compressed = static_cast<unsigned char *>(xdr->cx()->malloc_(byteLen));
|
||||
if (!data.compressed)
|
||||
if (!adjustDataSize(byteLen))
|
||||
return false;
|
||||
}
|
||||
if (!xdr->codeBytes(data.compressed, byteLen)) {
|
||||
|
@ -990,9 +990,14 @@ struct ScriptSource
|
||||
friend class SourceCompressorThread;
|
||||
private:
|
||||
union {
|
||||
// When the script source is ready, compressedLength_ != 0 implies
|
||||
// compressed holds the compressed data; otherwise, source holds the
|
||||
// uncompressed source.
|
||||
// Before setSourceCopy or setSource are successfully called, this union
|
||||
// has a NULL pointer. When the script source is ready,
|
||||
// compressedLength_ != 0 implies compressed holds the compressed data;
|
||||
// otherwise, source holds the uncompressed source. There is a special
|
||||
// pointer |emptySource| for source code for length 0.
|
||||
//
|
||||
// The only function allowed to malloc, realloc, or free the pointers in
|
||||
// this union is adjustDataSize(). Don't do it elsewhere.
|
||||
jschar *source;
|
||||
unsigned char *compressed;
|
||||
} data;
|
||||
@ -1068,6 +1073,7 @@ struct ScriptSource
|
||||
size_t computedSizeOfData() const {
|
||||
return compressed() ? compressedLength_ : sizeof(jschar) * length_;
|
||||
}
|
||||
bool adjustDataSize(size_t nbytes);
|
||||
};
|
||||
|
||||
class ScriptSourceHolder
|
||||
|
@ -87,6 +87,7 @@ MOCHITEST_FILES = chrome_wrappers_helper.html \
|
||||
test_bug800864.html \
|
||||
test_bug802557.html \
|
||||
file_bug802557.html \
|
||||
test_bug809547.html \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(OS_TARGET),Android)
|
||||
|
42
js/xpconnect/tests/mochitest/test_bug809547.html
Normal file
42
js/xpconnect/tests/mochitest/test_bug809547.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=809547
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 809547</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="go()">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=809547">Mozilla Bug 809547</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 809547 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var gObj = {};
|
||||
function go() {
|
||||
window.location.expando = gObj;
|
||||
is(window.location.expando, gObj, "Expando appears");
|
||||
SimpleTest.executeSoon(finish);
|
||||
}
|
||||
|
||||
function finish() {
|
||||
SpecialPowers.forceGC();
|
||||
SpecialPowers.forceCC();
|
||||
SpecialPowers.forceGC();
|
||||
SpecialPowers.forceCC();
|
||||
is(window.location.expando, gObj, "Expando preserved");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -80,8 +80,8 @@
|
||||
#include "ArchiveReader.h"
|
||||
|
||||
#include "nsFormData.h"
|
||||
#include "nsBlobProtocolHandler.h"
|
||||
#include "nsBlobURI.h"
|
||||
#include "nsHostObjectProtocolHandler.h"
|
||||
#include "nsHostObjectURI.h"
|
||||
#include "nsGlobalWindowCommands.h"
|
||||
#include "nsIControllerCommandTable.h"
|
||||
#include "nsJSProtocolHandler.h"
|
||||
@ -278,7 +278,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDOMFileReader, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(ArchiveReader)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormData)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobURI)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMediaStreamProtocolHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsHostObjectURI)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser)
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager,
|
||||
nsDOMStorageManager::GetInstance)
|
||||
@ -773,7 +774,8 @@ NS_DEFINE_NAMED_CID(NS_FILEREADER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ARCHIVEREADER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FORMDATA_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_BLOBURI_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MEDIASTREAMPROTOCOLHANDLER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_HOSTOBJECTURI_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_XMLHTTPREQUEST_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EVENTSOURCE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_DOMACTIVITY_CID);
|
||||
@ -1058,7 +1060,8 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
||||
{ &kNS_ARCHIVEREADER_CID, false, NULL, ArchiveReaderConstructor },
|
||||
{ &kNS_FORMDATA_CID, false, NULL, nsFormDataConstructor },
|
||||
{ &kNS_BLOBPROTOCOLHANDLER_CID, false, NULL, nsBlobProtocolHandlerConstructor },
|
||||
{ &kNS_BLOBURI_CID, false, NULL, nsBlobURIConstructor },
|
||||
{ &kNS_MEDIASTREAMPROTOCOLHANDLER_CID, false, NULL, nsMediaStreamProtocolHandlerConstructor },
|
||||
{ &kNS_HOSTOBJECTURI_CID, false, NULL, nsHostObjectURIConstructor },
|
||||
{ &kNS_XMLHTTPREQUEST_CID, false, NULL, nsXMLHttpRequestConstructor },
|
||||
{ &kNS_EVENTSOURCE_CID, false, NULL, nsEventSourceConstructor },
|
||||
{ &kNS_DOMACTIVITY_CID, false, NULL, ActivityConstructor },
|
||||
@ -1206,6 +1209,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
||||
{ NS_ARCHIVEREADER_CONTRACTID, &kNS_ARCHIVEREADER_CID },
|
||||
{ NS_FORMDATA_CONTRACTID, &kNS_FORMDATA_CID },
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID },
|
||||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX MEDIASTREAMURI_SCHEME, &kNS_MEDIASTREAMPROTOCOLHANDLER_CID },
|
||||
{ NS_XMLHTTPREQUEST_CONTRACTID, &kNS_XMLHTTPREQUEST_CID },
|
||||
{ NS_EVENTSOURCE_CONTRACTID, &kNS_EVENTSOURCE_CID },
|
||||
{ NS_DOMACTIVITY_CONTRACTID, &kNS_DOMACTIVITY_CID },
|
||||
|
@ -3058,9 +3058,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
// constrained height to turn into an unconstrained one.
|
||||
aState.mY = startingY;
|
||||
aState.mPrevBottomMargin = incomingMargin;
|
||||
PushLines(aState, aLine.prev());
|
||||
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
|
||||
*aKeepReflowGoing = false;
|
||||
if (ShouldAvoidBreakInside(aState.mReflowState)) {
|
||||
aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
|
||||
} else {
|
||||
PushLines(aState, aLine.prev());
|
||||
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3120,9 +3124,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
|
||||
if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) {
|
||||
// None of the child block fits.
|
||||
PushLines(aState, aLine.prev());
|
||||
*aKeepReflowGoing = false;
|
||||
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
|
||||
if (ShouldAvoidBreakInside(aState.mReflowState)) {
|
||||
aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
|
||||
} else {
|
||||
PushLines(aState, aLine.prev());
|
||||
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Note: line-break-after a block is a nop
|
||||
@ -3141,6 +3149,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
collapsedBottomMargin,
|
||||
aLine->mBounds, overflowAreas,
|
||||
frameReflowStatus);
|
||||
if (!NS_FRAME_IS_FULLY_COMPLETE(frameReflowStatus) &&
|
||||
ShouldAvoidBreakInside(aState.mReflowState)) {
|
||||
*aKeepReflowGoing = false;
|
||||
}
|
||||
|
||||
if (aLine->SetCarriedOutBottomMargin(collapsedBottomMargin)) {
|
||||
line_iterator nextLine = aLine;
|
||||
++nextLine;
|
||||
@ -3281,16 +3294,14 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
||||
brc.GetCarriedOutBottomMargin(), collapsedBottomMargin.get(),
|
||||
aState.mPrevBottomMargin);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// None of the block fits. Determine the correct reflow status.
|
||||
if (aLine == mLines.front() && !GetPrevInFlow()) {
|
||||
// If it's our very first line then we need to be pushed to
|
||||
// our parents next-in-flow. Therefore, return break-before
|
||||
// status for our reflow status.
|
||||
} else {
|
||||
if ((aLine == mLines.front() && !GetPrevInFlow()) ||
|
||||
ShouldAvoidBreakInside(aState.mReflowState)) {
|
||||
// If it's our very first line *or* we're not at the top of the page
|
||||
// and we have page-break-inside:avoid, then we need to be pushed to
|
||||
// our parent's next-in-flow.
|
||||
aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Push the line that didn't fit and any lines that follow it
|
||||
// to our next-in-flow.
|
||||
PushLines(aState, aLine.prev());
|
||||
@ -3399,12 +3410,10 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
|
||||
void
|
||||
nsBlockFrame::PushTruncatedLine(nsBlockReflowState& aState,
|
||||
line_iterator aLine,
|
||||
bool& aKeepReflowGoing)
|
||||
bool* aKeepReflowGoing)
|
||||
{
|
||||
line_iterator prevLine = aLine;
|
||||
--prevLine;
|
||||
PushLines(aState, prevLine);
|
||||
aKeepReflowGoing = false;
|
||||
PushLines(aState, aLine.prev());
|
||||
*aKeepReflowGoing = false;
|
||||
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
|
||||
}
|
||||
|
||||
@ -3625,8 +3634,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||
// it to the next page/column where its contents can fit not
|
||||
// next to a float.
|
||||
lineReflowStatus = LINE_REFLOW_TRUNCATED;
|
||||
// Push the line that didn't fit
|
||||
PushTruncatedLine(aState, aLine, *aKeepReflowGoing);
|
||||
PushTruncatedLine(aState, aLine, aKeepReflowGoing);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4191,21 +4199,25 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||
newY = aState.mY + dy;
|
||||
}
|
||||
|
||||
// See if the line fit. If it doesn't we need to push it. Our first
|
||||
// line will always fit.
|
||||
if (!NS_FRAME_IS_FULLY_COMPLETE(aState.mReflowStatus) &&
|
||||
ShouldAvoidBreakInside(aState.mReflowState)) {
|
||||
aLine->AppendFloats(aState.mCurrentLineFloats);
|
||||
aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
|
||||
return true;
|
||||
}
|
||||
|
||||
// See if the line fit (our first line always does).
|
||||
if (mLines.front() != aLine &&
|
||||
newY > aState.mBottomEdge &&
|
||||
aState.mBottomEdge != NS_UNCONSTRAINEDSIZE) {
|
||||
// Push this line and all of its children and anything else that
|
||||
// follows to our next-in-flow
|
||||
NS_ASSERTION((aState.mCurrentLine == aLine), "oops");
|
||||
PushLines(aState, aLine.prev());
|
||||
|
||||
// Stop reflow and whack the reflow status if reflow hasn't
|
||||
// already been stopped.
|
||||
if (*aKeepReflowGoing) {
|
||||
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
|
||||
*aKeepReflowGoing = false;
|
||||
NS_ASSERTION(aState.mCurrentLine == aLine, "oops");
|
||||
if (ShouldAvoidBreakInside(aState.mReflowState)) {
|
||||
// All our content doesn't fit, start on the next page.
|
||||
aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
|
||||
} else {
|
||||
// Push aLine and all of its children and anything else that
|
||||
// follows to our next-in-flow.
|
||||
PushTruncatedLine(aState, aLine, aKeepReflowGoing);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -5755,11 +5767,15 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
|
||||
aReflowStatus, aState);
|
||||
} while (NS_SUCCEEDED(rv) && clearanceFrame);
|
||||
|
||||
// An incomplete reflow status means we should split the float
|
||||
// if the height is constrained (bug 145305).
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) &&
|
||||
(NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.height))
|
||||
if (!NS_FRAME_IS_FULLY_COMPLETE(aReflowStatus) &&
|
||||
ShouldAvoidBreakInside(floatRS)) {
|
||||
aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
|
||||
} else if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) &&
|
||||
(NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.height)) {
|
||||
// An incomplete reflow status means we should split the float
|
||||
// if the height is constrained (bug 145305).
|
||||
aReflowStatus = NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) {
|
||||
aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
|
||||
|
@ -631,11 +631,14 @@ protected:
|
||||
nsIFrame* aFrame,
|
||||
bool& aMadeNewFrame);
|
||||
|
||||
// Push aLine, which cannot be placed on this page/column but should
|
||||
// fit on a future one. Set aKeepReflowGoing to false.
|
||||
/**
|
||||
* Push aLine (and any after it), since it cannot be placed on this
|
||||
* page/column. Set aKeepReflowGoing to false and set
|
||||
* flag aState.mReflowStatus as incomplete.
|
||||
*/
|
||||
void PushTruncatedLine(nsBlockReflowState& aState,
|
||||
line_iterator aLine,
|
||||
bool& aKeepReflowGoing);
|
||||
bool* aKeepReflowGoing);
|
||||
|
||||
nsresult SplitLine(nsBlockReflowState& aState,
|
||||
nsLineLayout& aLineLayout,
|
||||
|
@ -760,15 +760,28 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
||||
// (This code is only for DISABLE_FLOAT_BREAKING_IN_COLUMNS .)
|
||||
//
|
||||
// Likewise, if none of the float fit, and it needs to be pushed in
|
||||
// its entirety to the next page (NS_FRAME_IS_TRUNCATED), we need to
|
||||
// do the same.
|
||||
// its entirety to the next page (NS_FRAME_IS_TRUNCATED or
|
||||
// NS_INLINE_IS_BREAK_BEFORE), we need to do the same.
|
||||
if ((mContentArea.height != NS_UNCONSTRAINEDSIZE &&
|
||||
adjustedAvailableSpace.height == NS_UNCONSTRAINEDSIZE &&
|
||||
!mustPlaceFloat &&
|
||||
aFloat->GetSize().height + floatMargin.TopBottom() >
|
||||
mContentArea.YMost() - floatY) ||
|
||||
NS_FRAME_IS_TRUNCATED(reflowStatus)) {
|
||||
NS_FRAME_IS_TRUNCATED(reflowStatus) ||
|
||||
NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) {
|
||||
PushFloatPastBreak(aFloat);
|
||||
return false;
|
||||
}
|
||||
|
||||
// We can't use aFloat->ShouldAvoidBreakInside(mReflowState) here since
|
||||
// its mIsTopOfPage may be true even though the float isn't at the
|
||||
// top when floatY > 0.
|
||||
if (!mustPlaceFloat && (!mReflowState.mFlags.mIsTopOfPage || floatY > 0) &&
|
||||
NS_STYLE_PAGE_BREAK_AVOID == aFloat->GetStyleDisplay()->mBreakInside &&
|
||||
(!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus) ||
|
||||
aFloat->GetSize().height + floatMargin.TopBottom() >
|
||||
mContentArea.YMost() - floatY) &&
|
||||
!aFloat->GetPrevInFlow()) {
|
||||
PushFloatPastBreak(aFloat);
|
||||
return false;
|
||||
}
|
||||
|
@ -2876,11 +2876,10 @@ nsFrame::SelectByTypeAtPoint(nsPresContext* aPresContext,
|
||||
if (!offsets.content)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIFrame* theFrame;
|
||||
int32_t offset;
|
||||
const nsFrameSelection* frameSelection =
|
||||
PresContext()->GetPresShell()->ConstFrameSelection();
|
||||
theFrame = frameSelection->
|
||||
nsIFrame* theFrame = frameSelection->
|
||||
GetFrameForNodeOffset(offsets.content, offsets.offset,
|
||||
nsFrameSelection::HINT(offsets.associateWithNext),
|
||||
&offset);
|
||||
@ -2888,8 +2887,8 @@ nsFrame::SelectByTypeAtPoint(nsPresContext* aPresContext,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsFrame* frame = static_cast<nsFrame*>(theFrame);
|
||||
return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType,
|
||||
offsets.offset, aPresContext,
|
||||
return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType,
|
||||
offset, aPresContext,
|
||||
aBeginAmountType != eSelectWord,
|
||||
aSelectFlags);
|
||||
}
|
||||
|
@ -408,6 +408,15 @@ public:
|
||||
virtual const void* GetStyleDataExternal(nsStyleStructID aSID) const;
|
||||
|
||||
|
||||
/**
|
||||
* @return true if we should avoid a page/column break in this frame.
|
||||
*/
|
||||
bool ShouldAvoidBreakInside(const nsHTMLReflowState& aReflowState) const {
|
||||
return !aReflowState.mFlags.mIsTopOfPage &&
|
||||
NS_STYLE_PAGE_BREAK_AVOID == GetStyleDisplay()->mBreakInside &&
|
||||
!GetPrevInFlow();
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* Tracing method that writes a method enter/exit routine to the
|
||||
|
@ -1,4 +1,4 @@
|
||||
<html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
</head>
|
||||
<body style="direction: rtl;">
|
||||
@ -13,6 +13,7 @@ var a=document.getElementById('a');
|
||||
a.style.outline = '1px solid transparent';
|
||||
document.body.offsetHeight;
|
||||
a.style.outline = '';
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
setTimeout(doe, 500);
|
||||
</script>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>CSS 2.1 Test Suite: dynamic changes to 'counter-increment'</title>
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counters"/>
|
||||
@ -21,11 +21,13 @@
|
||||
s.setAttribute("class", "increment");
|
||||
s.appendChild(document.createTextNode("new-"));
|
||||
t.insertBefore(s, t.childNodes.item(1));
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", run, false);
|
||||
</script>
|
||||
</head>
|
||||
<body onload="setTimeout('run()', 0)">
|
||||
<body>
|
||||
|
||||
<div id="test"><span class="increment"></span><span class="increment"></span><span class="increment"></span></div>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>CSS 2.1 Test Suite: dynamic changes to 'counter-increment'</title>
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counters"/>
|
||||
@ -18,11 +18,13 @@
|
||||
function run() {
|
||||
var t = document.getElementById("test");
|
||||
t.removeChild(t.childNodes.item(1));
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", run, false);
|
||||
</script>
|
||||
</head>
|
||||
<body onload="setTimeout('run()', 0)">
|
||||
<body>
|
||||
|
||||
<div id="test"><span class="increment"></span><span class="increment">FAIL-</span><span class="increment"></span><span class="increment"></span></div>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>CSS 2.1 Test Suite: dynamic changes to 'counter-increment'</title>
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counters"/>
|
||||
@ -20,11 +20,13 @@
|
||||
document.getElementById("one").removeAttribute("class");
|
||||
document.getElementById("two").setAttribute("class", "increment");
|
||||
document.getElementById("three").setAttribute("style", "counter-increment: c");
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", run, false);
|
||||
</script>
|
||||
</head>
|
||||
<body onload="setTimeout('run()', 0)">
|
||||
<body>
|
||||
|
||||
<div id="test"><span id="one" class="increment"></span><span><span class="reset"><span class="increment"></span><span id="two" class="increment"></span></span></span><span id="three" class="use"></span><span class="increment"></span></div>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head>
|
||||
<title>CSS 2.1 Test Suite: dynamic changes to 'counter-increment'</title>
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counters"/>
|
||||
@ -18,11 +18,13 @@
|
||||
function run() {
|
||||
var t = document.getElementById("test");
|
||||
t.removeChild(t.childNodes.item(1));
|
||||
document.documentElement.removeAttribute('class');
|
||||
}
|
||||
|
||||
document.addEventListener("MozReftestInvalidate", run, false);
|
||||
</script>
|
||||
</head>
|
||||
<body onload="setTimeout('run()', 0)">
|
||||
<body>
|
||||
|
||||
<div id="test"><span class="increment"></span><span class="reset"></span><span class="increment"></span><span class="increment"></span></div>
|
||||
|
||||
|
@ -0,0 +1,48 @@
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=685012">
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/page.html#propdef-page-break-inside">
|
||||
<meta name="flags" content="paged">
|
||||
<meta charset="utf-8">
|
||||
<title>Balancing Overflow, page-break-inside:avoid</title>
|
||||
<style>
|
||||
/* Sets of heights that trigger crash:
|
||||
100px/50px/51+px
|
||||
100px/30px/74+px
|
||||
Get only an assert unless you set ".d { position: absolute; }".
|
||||
|
||||
Trigger hang (separate issue, absolute not needed):
|
||||
10px/10px/9999px
|
||||
10px/10px/999999px --> "bad height" notreached
|
||||
*/
|
||||
/* Note: The -moz-column-gap and the backgrounds
|
||||
are just added here for easier visualization */
|
||||
#colset { width: 200px;
|
||||
padding: 2px;
|
||||
-moz-column-count: 3;
|
||||
-moz-column-gap: 2px; }
|
||||
#a { height: 100px; background: lightblue;}
|
||||
#b { height: 50px; background: lightblue;}
|
||||
#c { height: 51px; background: orange;}
|
||||
</style>
|
||||
<script>
|
||||
function boom() {
|
||||
document.getElementById('colset').offsetHeight;
|
||||
document.getElementById('a').style.height = 'auto';
|
||||
document.documentElement.className = ''
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<!-- Removing whitespace in body for simpler frame trees -->
|
||||
<body onload="boom()"
|
||||
><div id="colset"
|
||||
><div
|
||||
><div id="a"></div
|
||||
><div id="b"
|
||||
><div id="c"></div
|
||||
><div id="d"></div
|
||||
></div
|
||||
></div
|
||||
></div
|
||||
></body>
|
||||
</html>
|
@ -0,0 +1,49 @@
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=685012">
|
||||
<link rel="help" href="http://www.w3.org/TR/CSS21/page.html#propdef-page-break-inside">
|
||||
<meta name="flags" content="paged">
|
||||
<meta charset="utf-8">
|
||||
<title>Balancing Overflow, page-break-inside:avoid</title>
|
||||
<style>
|
||||
/* Sets of heights that trigger crash:
|
||||
100px/50px/51+px
|
||||
100px/30px/74+px
|
||||
Get only an assert unless you set ".d { position: absolute; }".
|
||||
|
||||
Trigger hang (separate issue, absolute not needed):
|
||||
10px/10px/9999px
|
||||
10px/10px/999999px --> "bad height" notreached
|
||||
*/
|
||||
/* Note: The -moz-column-gap and the backgrounds
|
||||
are just added here for easier visualization */
|
||||
#colset { width: 200px;
|
||||
padding: 2px;
|
||||
-moz-column-count: 3;
|
||||
-moz-column-gap: 2px; }
|
||||
#a { height: 100px; background: lightblue;}
|
||||
#b { height: 50px; background: lightblue;}
|
||||
#c { height: 51px; background: orange;}
|
||||
div {page-break-inside:avoid; }
|
||||
</style>
|
||||
<script>
|
||||
function boom() {
|
||||
document.getElementById('colset').offsetHeight;
|
||||
document.getElementById('a').style.height = 'auto';
|
||||
document.documentElement.className = ''
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<!-- Removing whitespace in body for simpler frame trees -->
|
||||
<body onload="boom()"
|
||||
><div id="colset"
|
||||
><div
|
||||
><div id="a"></div
|
||||
><div id="b"
|
||||
><div id="c"></div
|
||||
><div id="d"></div
|
||||
></div
|
||||
></div
|
||||
></div
|
||||
></body>
|
||||
</html>
|
@ -1,3 +1,5 @@
|
||||
# For more pagination tests, see layout/reftests/w3c-css/submitted/css21/pagination/
|
||||
# and layout/reftests/w3c-css/submitted/multicol3/
|
||||
# Pagination tests
|
||||
== abspos-breaking-000.xhtml abspos-breaking-000.ref.xhtml
|
||||
== abspos-breaking-001.xhtml abspos-breaking-000.ref.xhtml
|
||||
@ -57,3 +59,4 @@ fails == float-continuations-000.html float-continuations-000.ref.html
|
||||
# == table-caption-splitaftercaption-9.html blank.html # bug 672654
|
||||
# == table-caption-splitaftercaption-10.html blank.html # bug 672654
|
||||
# == table-caption-splitaftercaption-11.html blank.html # bug 672654
|
||||
== column-balancing-break-inside-avoid-2.html column-balancing-break-inside-avoid-2-ref.html
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user