Merge the last PGO-green inbound changeset to m-c.

This commit is contained in:
Ryan VanderMeulen 2012-11-08 19:52:11 -05:00
commit be3c66b5a5
184 changed files with 3421 additions and 930 deletions

View File

@ -9,7 +9,12 @@
<?xml-stylesheet href="chrome://browser/content/downloads/downloads.css"?> <?xml-stylesheet href="chrome://browser/content/downloads/downloads.css"?>
<?xml-stylesheet href="chrome://browser/skin/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#" <overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
@ -23,7 +28,7 @@
toolbar handling code could remove it from the document. --> toolbar handling code could remove it from the document. -->
<toolbarbutton id="downloads-indicator" <toolbarbutton id="downloads-indicator"
class="toolbarbutton-1 chromeclass-toolbar-additional" class="toolbarbutton-1 chromeclass-toolbar-additional"
tooltiptext="&indicator.tooltiptext;" tooltiptext="&downloads.tooltip;"
collapsed="true" collapsed="true"
oncommand="DownloadsIndicatorView.onCommand(event);" oncommand="DownloadsIndicatorView.onCommand(event);"
ondrop="DownloadsIndicatorView.onDrop(event);" ondrop="DownloadsIndicatorView.onDrop(event);"

View File

@ -14,6 +14,7 @@ include $(DEPTH)/config/autoconf.mk
# browser_526613.js is disabled because of frequent failures (bug 534489) # browser_526613.js is disabled because of frequent failures (bug 534489)
# browser_589246.js is disabled for leaking browser windows (bug 752467) # browser_589246.js is disabled for leaking browser windows (bug 752467)
# browser_580512.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 = \ MOCHITEST_BROWSER_FILES = \
head.js \ head.js \
@ -88,7 +89,6 @@ MOCHITEST_BROWSER_FILES = \
browser_586068-browser_state_interrupted.js \ browser_586068-browser_state_interrupted.js \
browser_586068-cascade.js \ browser_586068-cascade.js \
browser_586068-multi_window.js \ browser_586068-multi_window.js \
browser_586068-reload.js \
browser_586068-select.js \ browser_586068-select.js \
browser_586068-window_state.js \ browser_586068-window_state.js \
browser_586068-window_state_override.js \ browser_586068-window_state_override.js \

View File

@ -2,11 +2,6 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this file, - 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/. --> - 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): <!-- LOCALIZATION NOTE (downloads.title):
Used by screen readers to describe the Downloads Panel. Used by screen readers to describe the Downloads Panel.
--> -->

View File

@ -160,37 +160,53 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
/*** Status and progress indicator ***/ /*** Status and progress indicator ***/
#downloads-indicator {
width: 35px;
}
#downloads-indicator-anchor { #downloads-indicator-anchor {
min-width: 18px;
min-height: 18px;
/* Makes the outermost stack element positioned, so that its contents are /* 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 rendered over the main browser window in the Z order. This is required by
the animated event notification. */ the animated event notification. */
position: relative; 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 ***/ /*** Main indicator icon ***/
#downloads-indicator-icon { toolbar[iconsize="small"] #downloads-indicator-icon {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"), background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"),
0, 16, 16, 0) center no-repeat; 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 { #downloads-indicator[attention] > #downloads-indicator-anchor > #downloads-indicator-icon {
background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"), background: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
16, 32, 32, 16) center no-repeat; 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"), background: -moz-image-rect(url("chrome://browser/skin/Toolbar-small.png"),
0, 16, 16, 0) center no-repeat; 0, 16, 16, 0) center no-repeat;
background-size: 12px; 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 { #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"), background-image: -moz-image-rect(url("chrome://browser/skin/downloads/download-glow.png"),
16, 32, 32, 16); 16, 32, 32, 16);

View File

@ -157,10 +157,6 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
/*** Status and progress indicator ***/ /*** Status and progress indicator ***/
#downloads-indicator {
width: 35px;
}
#downloads-indicator-anchor { #downloads-indicator-anchor {
min-width: 20px; min-width: 20px;
min-height: 20px; min-height: 20px;

View File

@ -159,13 +159,7 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
/*** Status and progress indicator ***/ /*** Status and progress indicator ***/
#downloads-indicator {
width: 35px;
}
#downloads-indicator-anchor { #downloads-indicator-anchor {
min-width: 18px;
min-height: 18px;
/* Makes the outermost stack element positioned, so that its contents are /* 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 rendered over the main browser window in the Z order. This is required by
the animated event notification. */ the animated event notification. */
@ -177,6 +171,8 @@ richlistitem[type="download"][state="1"]:hover > .downloadButton.downloadShow:ac
#downloads-indicator-icon { #downloads-indicator-icon {
background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"), background: -moz-image-rect(url("chrome://browser/skin/Toolbar.png"),
0, 108, 18, 90) center no-repeat; 0, 108, 18, 90) center no-repeat;
min-width: 18px;
min-height: 18px;
} }
#downloads-indicator-icon:-moz-lwtheme-brighttext { #downloads-indicator-icon:-moz-lwtheme-brighttext {

View File

@ -243,8 +243,17 @@ case "$target" in
android_platform_tools="$android_sdk"/tools # SDK Tools < r8 android_platform_tools="$android_sdk"/tools # SDK Tools < r8
fi fi
ANDROID_SDK="${android_sdk}" 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}" ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
AC_SUBST(ANDROID_SDK) 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) AC_SUBST(ANDROID_PLATFORM_TOOLS)
;; ;;
esac esac

View File

@ -93,7 +93,7 @@ classes.dex: $(_JAVA_HARNESS)
classes.dex: $(_JAVA_TESTS) classes.dex: $(_JAVA_TESTS)
$(NSINSTALL) -D classes $(NSINSTALL) -D classes
$(JAVAC) $(JAVAC_FLAGS) -d classes $(JAVAFILES) $(_JAVA_HARNESS) $(addprefix $(DEPTH)/mobile/android/base/tests/,$(_JAVA_TESTS)) $(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/* 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 ./ $(AAPT) package -f -M AndroidManifest.xml -I $(ANDROID_SDK)/android.jar -I . -S res -A $(TESTPATH)/assets -F $@ -J ./

View File

@ -4,12 +4,13 @@
package com.mozilla.SUTAgentAndroid.service; package com.mozilla.SUTAgentAndroid.service;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.util.Timer; import java.util.Timer;
import java.io.IOException;
import java.net.InetAddress;
import com.mozilla.SUTAgentAndroid.SUTAgentAndroid; import com.mozilla.SUTAgentAndroid.SUTAgentAndroid;
import com.mozilla.SUTAgentAndroid.R; import com.mozilla.SUTAgentAndroid.R;
@ -39,6 +40,7 @@ public class ASMozStub extends android.app.Service {
RunDataThread runDataThrd = null; RunDataThread runDataThrd = null;
Thread monitor = null; Thread monitor = null;
Timer timer = null; Timer timer = null;
boolean doZeroConfig = false;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static final Class<?>[] mSetForegroundSignature = new Class[] { private static final Class<?>[] mSetForegroundSignature = new Class[] {
@ -178,14 +180,24 @@ public class ASMozStub extends android.app.Service {
runDataThrd.start(); runDataThrd.start();
doToast(String.format("Data channel port %d ...", DATA_PORT)); 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(); Notification notification = new Notification();
startForegroundCompat(R.string.foreground_service_started, notification); startForegroundCompat(R.string.foreground_service_started, notification);
} }
catch (Exception e) { catch (Exception e) {
doToast(e.toString()); doToast(e.toString());
// Toast.makeText(getApplication().getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
} }
return; return;
@ -195,7 +207,9 @@ public class ASMozStub extends android.app.Service {
{ {
super.onDestroy(); super.onDestroy();
stopZeroConf(); if (this.doZeroConfig) {
stopZeroConf();
}
if (runCmdThrd.isAlive()) if (runCmdThrd.isAlive())
{ {

View File

@ -8,11 +8,14 @@ import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileReader; import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -46,6 +49,8 @@ import android.os.Environment;
public class WatcherService extends Service public class WatcherService extends Service
{ {
private final String prgVersion = "Watcher Version 1.15";
String sErrorPrefix = "##Installer Error## "; String sErrorPrefix = "##Installer Error## ";
String currentDir = "/"; String currentDir = "/";
String sPingTarget = ""; String sPingTarget = "";
@ -53,6 +58,7 @@ public class WatcherService extends Service
long lPeriod = 300000; long lPeriod = 300000;
int nMaxStrikes = 0; // maximum number of tries before we consider network unreachable (0 means don't check) int nMaxStrikes = 0; // maximum number of tries before we consider network unreachable (0 means don't check)
boolean bStartSUTAgent = true; boolean bStartSUTAgent = true;
boolean bStartedTimer = false;
Process pProc; Process pProc;
Context myContext = null; Context myContext = null;
@ -217,9 +223,13 @@ public class WatcherService extends Service
} }
else if (sCmd.equalsIgnoreCase("start")) else if (sCmd.equalsIgnoreCase("start"))
{ {
doToast("WatcherService started"); if (!this.bStartedTimer) {
myTimer = new Timer(); doToast("WatcherService started");
myTimer.scheduleAtFixedRate(new MyTime(), lDelay, lPeriod); myTimer = new Timer();
Date startSchedule = new Date(System.currentTimeMillis() + lDelay);
myTimer.schedule(new MyTime(), startSchedule, lPeriod);
this.bStartedTimer = true;
}
} }
else else
{ {
@ -230,15 +240,33 @@ public class WatcherService extends Service
doToast("WatcherService created"); 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 @Override
public void onStart(Intent intent, int startId) { public void onStart(Intent intent, int startId) {
writeVersion();
handleCommand(intent); handleCommand(intent);
return; return;
} }
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
writeVersion();
handleCommand(intent); handleCommand(intent);
return START_STICKY; return START_STICKY;
} }

View File

@ -23,7 +23,7 @@ endif
# For Android, this defaults to $(ANDROID_SDK)/android.jar # For Android, this defaults to $(ANDROID_SDK)/android.jar
ifndef JAVA_BOOTCLASSPATH ifndef JAVA_BOOTCLASSPATH
JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar JAVA_BOOTCLASSPATH = $(ANDROID_SDK)/android.jar:$(ANDROID_COMPAT_LIB)
endif endif
# For Android, we default to 1.5 # For Android, we default to 1.5

View File

@ -42,7 +42,7 @@ nsReferencedElement.h \
nsTreeSanitizer.h \ nsTreeSanitizer.h \
nsXMLNameSpaceMap.h \ nsXMLNameSpaceMap.h \
nsIXFormsUtilityService.h \ nsIXFormsUtilityService.h \
nsBlobProtocolHandler.h \ nsHostObjectProtocolHandler.h \
$(NULL) $(NULL)
EXPORTS_NAMESPACES = mozilla/dom mozilla EXPORTS_NAMESPACES = mozilla/dom mozilla

View File

@ -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 */

View 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 */

View File

@ -79,8 +79,8 @@ class Element;
} // namespace mozilla } // namespace mozilla
#define NS_IDOCUMENT_IID \ #define NS_IDOCUMENT_IID \
{ 0x0e1324c9, 0xc997, 0x447e, \ { 0x20d19edb, 0xa74c, 0x4ce4, \
{ 0xbc, 0xd9, 0xa6, 0x57, 0x80, 0x29, 0x91, 0xe4 } } { 0xb2, 0x7c, 0x5b, 0xdd, 0x6f, 0xbd, 0x2b, 0x66 } }
// Flag for AddStyleSheet(). // Flag for AddStyleSheet().
#define NS_STYLESHEET_FROM_CATALOG (1 << 0) #define NS_STYLESHEET_FROM_CATALOG (1 << 0)
@ -1557,13 +1557,13 @@ public:
virtual nsISupports* GetCurrentContentSink() = 0; 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 * I.e. that its lifetime is connected with this document. When the document
* goes away it should "kill" the uri by calling * goes away it should "kill" the uri by calling
* nsBlobProtocolHandler::RemoveFileDataEntry * nsHostObjectProtocolHandler::RemoveDataEntry
*/ */
virtual void RegisterFileDataUri(const nsACString& aUri) = 0; virtual void RegisterHostObjectUri(const nsACString& aUri) = 0;
virtual void UnregisterFileDataUri(const nsACString& aUri) = 0; virtual void UnregisterHostObjectUri(const nsACString& aUri) = 0;
virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0; virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0;
virtual void ScrollToRef() = 0; virtual void ScrollToRef() = 0;

View File

@ -127,8 +127,8 @@ CPPSRCS = \
nsXMLNameSpaceMap.cpp \ nsXMLNameSpaceMap.cpp \
FragmentOrElement.cpp \ FragmentOrElement.cpp \
Link.cpp \ Link.cpp \
nsBlobProtocolHandler.cpp \ nsHostObjectProtocolHandler.cpp \
nsBlobURI.cpp \ nsHostObjectURI.cpp \
nsFrameMessageManager.cpp \ nsFrameMessageManager.cpp \
nsInProcessTabChildGlobal.cpp \ nsInProcessTabChildGlobal.cpp \
ThirdPartyUtil.cpp \ ThirdPartyUtil.cpp \

View File

@ -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);
}

View File

@ -27,7 +27,7 @@
#include "nsNetCID.h" #include "nsNetCID.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsIUUIDGenerator.h" #include "nsIUUIDGenerator.h"
#include "nsBlobProtocolHandler.h" #include "nsHostObjectProtocolHandler.h"
#include "nsStringStream.h" #include "nsStringStream.h"
#include "nsJSUtils.h" #include "nsJSUtils.h"
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
@ -284,26 +284,15 @@ nsDOMFileBase::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
{ {
NS_ENSURE_STATE(aPrincipal); NS_ENSURE_STATE(aPrincipal);
nsresult rv; nsCString url;
nsCOMPtr<nsIUUIDGenerator> uuidgen = nsresult rv = nsBlobProtocolHandler::AddDataEntry(
do_GetService("@mozilla.org/uuid-generator;1", &rv); NS_LITERAL_CSTRING(BLOBURI_SCHEME),
NS_ENSURE_SUCCESS(rv, rv); static_cast<nsIDOMBlob*>(this), aPrincipal, url);
if (NS_FAILED(rv)) {
nsID id; return rv;
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);
CopyASCIItoUTF16(url, aURL); CopyASCIItoUTF16(url, aURL);
return NS_OK; return NS_OK;
} }
@ -859,6 +848,6 @@ nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() {
if (!mUrl.IsEmpty()) { if (!mUrl.IsEmpty()) {
nsAutoCString narrowUrl; nsAutoCString narrowUrl;
CopyUTF16toUTF8(mUrl, narrowUrl); CopyUTF16toUTF8(mUrl, narrowUrl);
nsBlobProtocolHandler::RemoveFileDataEntry(narrowUrl); nsBlobProtocolHandler::RemoveDataEntry(narrowUrl);
} }
} }

View File

@ -38,7 +38,7 @@
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsLayoutStatics.h" #include "nsLayoutStatics.h"
#include "nsIScriptObjectPrincipal.h" #include "nsIScriptObjectPrincipal.h"
#include "nsBlobProtocolHandler.h" #include "nsHostObjectProtocolHandler.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/dom/EncodingUtils.h" #include "mozilla/dom/EncodingUtils.h"
#include "xpcpublic.h" #include "xpcpublic.h"

View File

@ -107,7 +107,7 @@
#include "nsIDOMHTMLFormElement.h" #include "nsIDOMHTMLFormElement.h"
#include "nsIRequest.h" #include "nsIRequest.h"
#include "nsILink.h" #include "nsILink.h"
#include "nsBlobProtocolHandler.h" #include "nsHostObjectProtocolHandler.h"
#include "nsCharsetAlias.h" #include "nsCharsetAlias.h"
#include "nsCharsetSource.h" #include "nsCharsetSource.h"
@ -1445,8 +1445,8 @@ nsDocument::~nsDocument()
mPendingTitleChangeEvent.Revoke(); mPendingTitleChangeEvent.Revoke();
for (uint32_t i = 0; i < mFileDataUris.Length(); ++i) { for (uint32_t i = 0; i < mHostObjectURIs.Length(); ++i) {
nsBlobProtocolHandler::RemoveFileDataEntry(mFileDataUris[i]); nsHostObjectProtocolHandler::RemoveDataEntry(mHostObjectURIs[i]);
} }
// We don't want to leave residual locks on images. Make sure we're in an // We don't want to leave residual locks on images. Make sure we're in an
@ -7595,15 +7595,15 @@ nsDocument::GetCurrentContentSink()
} }
void void
nsDocument::RegisterFileDataUri(const nsACString& aUri) nsDocument::RegisterHostObjectUri(const nsACString& aUri)
{ {
mFileDataUris.AppendElement(aUri); mHostObjectURIs.AppendElement(aUri);
} }
void void
nsDocument::UnregisterFileDataUri(const nsACString& aUri) nsDocument::UnregisterHostObjectUri(const nsACString& aUri)
{ {
mFileDataUris.RemoveElement(aUri); mHostObjectURIs.RemoveElement(aUri);
} }
void void

View File

@ -839,7 +839,7 @@ public:
virtual NS_HIDDEN_(void) virtual NS_HIDDEN_(void)
EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData); EnumerateExternalResources(nsSubDocEnumFunc aCallback, void* aData);
nsTArray<nsCString> mFileDataUris; nsTArray<nsCString> mHostObjectURIs;
// Returns our (lazily-initialized) animation controller. // Returns our (lazily-initialized) animation controller.
// If HasAnimationController is true, this is guaranteed to return non-null. // If HasAnimationController is true, this is guaranteed to return non-null.
@ -891,8 +891,8 @@ public:
virtual nsEventStates GetDocumentState(); virtual nsEventStates GetDocumentState();
virtual void RegisterFileDataUri(const nsACString& aUri); virtual void RegisterHostObjectUri(const nsACString& aUri);
virtual void UnregisterFileDataUri(const nsACString& aUri); virtual void UnregisterHostObjectUri(const nsACString& aUri);
// Only BlockOnload should call this! // Only BlockOnload should call this!
void AsyncBlockOnload(); void AsyncBlockOnload();

View 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;
}

View File

@ -2,24 +2,24 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsBlobURI.h" #include "nsHostObjectURI.h"
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsIObjectInputStream.h" #include "nsIObjectInputStream.h"
#include "nsIObjectOutputStream.h" #include "nsIObjectOutputStream.h"
#include "nsIProgrammingLanguage.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, static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
NS_THIS_SIMPLEURI_IMPLEMENTATION_CID); NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
NS_IMPL_ADDREF_INHERITED(nsBlobURI, nsSimpleURI) NS_IMPL_ADDREF_INHERITED(nsHostObjectURI, nsSimpleURI)
NS_IMPL_RELEASE_INHERITED(nsBlobURI, nsSimpleURI) NS_IMPL_RELEASE_INHERITED(nsHostObjectURI, nsSimpleURI)
NS_INTERFACE_MAP_BEGIN(nsBlobURI) NS_INTERFACE_MAP_BEGIN(nsHostObjectURI)
NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal) NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal)
if (aIID.Equals(kBLOBURICID)) if (aIID.Equals(kHOSTOBJECTURICID))
foundInterface = static_cast<nsIURI*>(this); foundInterface = static_cast<nsIURI*>(this);
else if (aIID.Equals(kThisSimpleURIImplementationCID)) { else if (aIID.Equals(kThisSimpleURIImplementationCID)) {
// Need to return explicitly here, because if we just set foundInterface // Need to return explicitly here, because if we just set foundInterface
@ -34,7 +34,7 @@ NS_INTERFACE_MAP_END_INHERITING(nsSimpleURI)
// nsIURIWithPrincipal methods: // nsIURIWithPrincipal methods:
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetPrincipal(nsIPrincipal** aPrincipal) nsHostObjectURI::GetPrincipal(nsIPrincipal** aPrincipal)
{ {
NS_IF_ADDREF(*aPrincipal = mPrincipal); NS_IF_ADDREF(*aPrincipal = mPrincipal);
@ -42,7 +42,7 @@ nsBlobURI::GetPrincipal(nsIPrincipal** aPrincipal)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetPrincipalUri(nsIURI** aUri) nsHostObjectURI::GetPrincipalUri(nsIURI** aUri)
{ {
if (mPrincipal) { if (mPrincipal) {
mPrincipal->GetURI(aUri); mPrincipal->GetURI(aUri);
@ -57,7 +57,7 @@ nsBlobURI::GetPrincipalUri(nsIURI** aUri)
// nsISerializable methods: // nsISerializable methods:
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::Read(nsIObjectInputStream* aStream) nsHostObjectURI::Read(nsIObjectInputStream* aStream)
{ {
nsresult rv = nsSimpleURI::Read(aStream); nsresult rv = nsSimpleURI::Read(aStream);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -66,7 +66,7 @@ nsBlobURI::Read(nsIObjectInputStream* aStream)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::Write(nsIObjectOutputStream* aStream) nsHostObjectURI::Write(nsIObjectOutputStream* aStream)
{ {
nsresult rv = nsSimpleURI::Write(aStream); nsresult rv = nsSimpleURI::Write(aStream);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -78,8 +78,8 @@ nsBlobURI::Write(nsIObjectOutputStream* aStream)
// nsIURI methods: // nsIURI methods:
nsresult nsresult
nsBlobURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode, nsHostObjectURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
nsIURI** aClone) nsIURI** aClone)
{ {
nsCOMPtr<nsIURI> simpleClone; nsCOMPtr<nsIURI> simpleClone;
nsresult rv = nsresult rv =
@ -87,56 +87,56 @@ nsBlobURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
#ifdef DEBUG #ifdef DEBUG
nsRefPtr<nsBlobURI> uriCheck; nsRefPtr<nsHostObjectURI> uriCheck;
rv = simpleClone->QueryInterface(kBLOBURICID, getter_AddRefs(uriCheck)); rv = simpleClone->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(uriCheck));
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) && uriCheck, NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) && uriCheck,
"Unexpected!"); "Unexpected!");
#endif #endif
nsBlobURI* blobURI = static_cast<nsBlobURI*>(simpleClone.get()); nsHostObjectURI* u = static_cast<nsHostObjectURI*>(simpleClone.get());
blobURI->mPrincipal = mPrincipal; u->mPrincipal = mPrincipal;
simpleClone.forget(aClone); simpleClone.forget(aClone);
return NS_OK; return NS_OK;
} }
/* virtual */ nsresult /* virtual */ nsresult
nsBlobURI::EqualsInternal(nsIURI* aOther, nsHostObjectURI::EqualsInternal(nsIURI* aOther,
nsSimpleURI::RefHandlingEnum aRefHandlingMode, nsSimpleURI::RefHandlingEnum aRefHandlingMode,
bool* aResult) bool* aResult)
{ {
if (!aOther) { if (!aOther) {
*aResult = false; *aResult = false;
return NS_OK; return NS_OK;
} }
nsRefPtr<nsBlobURI> otherBlobUri; nsRefPtr<nsHostObjectURI> otherUri;
aOther->QueryInterface(kBLOBURICID, getter_AddRefs(otherBlobUri)); aOther->QueryInterface(kHOSTOBJECTURICID, getter_AddRefs(otherUri));
if (!otherBlobUri) { if (!otherUri) {
*aResult = false; *aResult = false;
return NS_OK; return NS_OK;
} }
// Compare the member data that our base class knows about. // Compare the member data that our base class knows about.
if (!nsSimpleURI::EqualsInternal(otherBlobUri, aRefHandlingMode)) { if (!nsSimpleURI::EqualsInternal(otherUri, aRefHandlingMode)) {
*aResult = false; *aResult = false;
return NS_OK; return NS_OK;
} }
// Compare the piece of additional member data that we add to base class. // 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. // 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. // 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; return NS_OK;
} }
// nsIClassInfo methods: // nsIClassInfo methods:
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetInterfaces(uint32_t *count, nsIID * **array) nsHostObjectURI::GetInterfaces(uint32_t *count, nsIID * **array)
{ {
*count = 0; *count = 0;
*array = nullptr; *array = nullptr;
@ -144,14 +144,14 @@ nsBlobURI::GetInterfaces(uint32_t *count, nsIID * **array)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetHelperForLanguage(uint32_t language, nsISupports **_retval) nsHostObjectURI::GetHelperForLanguage(uint32_t language, nsISupports **_retval)
{ {
*_retval = nullptr; *_retval = nullptr;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetContractID(char * *aContractID) nsHostObjectURI::GetContractID(char * *aContractID)
{ {
// Make sure to modify any subclasses as needed if this ever // Make sure to modify any subclasses as needed if this ever
// changes. // changes.
@ -160,14 +160,14 @@ nsBlobURI::GetContractID(char * *aContractID)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetClassDescription(char * *aClassDescription) nsHostObjectURI::GetClassDescription(char * *aClassDescription)
{ {
*aClassDescription = nullptr; *aClassDescription = nullptr;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetClassID(nsCID * *aClassID) nsHostObjectURI::GetClassID(nsCID * *aClassID)
{ {
// Make sure to modify any subclasses as needed if this ever // Make sure to modify any subclasses as needed if this ever
// changes to not call the virtual GetClassIDNoAlloc. // changes to not call the virtual GetClassIDNoAlloc.
@ -178,22 +178,22 @@ nsBlobURI::GetClassID(nsCID * *aClassID)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetImplementationLanguage(uint32_t *aImplementationLanguage) nsHostObjectURI::GetImplementationLanguage(uint32_t *aImplementationLanguage)
{ {
*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetFlags(uint32_t *aFlags) nsHostObjectURI::GetFlags(uint32_t *aFlags)
{ {
*aFlags = nsIClassInfo::MAIN_THREAD_ONLY; *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP
nsBlobURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) nsHostObjectURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{ {
*aClassIDNoAlloc = kBLOBURICID; *aClassIDNoAlloc = kHOSTOBJECTURICID;
return NS_OK; return NS_OK;
} }

View File

@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsBlobURI_h #ifndef nsHostObjectURI_h
#define nsBlobURI_h #define nsHostObjectURI_h
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsIClassInfo.h" #include "nsIClassInfo.h"
@ -12,17 +12,21 @@
#include "nsIURIWithPrincipal.h" #include "nsIURIWithPrincipal.h"
#include "nsSimpleURI.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: public:
nsBlobURI(nsIPrincipal* aPrincipal) : nsHostObjectURI(nsIPrincipal* aPrincipal) :
nsSimpleURI(), mPrincipal(aPrincipal) nsSimpleURI(), mPrincipal(aPrincipal)
{} {}
virtual ~nsBlobURI() {} virtual ~nsHostObjectURI() {}
// For use only from deserialization // For use only from deserialization
nsBlobURI() : nsSimpleURI() {} nsHostObjectURI() : nsSimpleURI() {}
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIURIWITHPRINCIPAL NS_DECL_NSIURIWITHPRINCIPAL
@ -36,15 +40,15 @@ public:
RefHandlingEnum aRefHandlingMode, RefHandlingEnum aRefHandlingMode,
bool* aResult); bool* aResult);
// Override StartClone to hand back a nsBlobURI // Override StartClone to hand back a nsHostObjectURI
virtual nsSimpleURI* StartClone(RefHandlingEnum /* unused */) virtual nsSimpleURI* StartClone(RefHandlingEnum /* unused */)
{ return new nsBlobURI(); } { return new nsHostObjectURI(); }
nsCOMPtr<nsIPrincipal> mPrincipal; nsCOMPtr<nsIPrincipal> mPrincipal;
}; };
#define NS_BLOBURI_CID \ #define NS_HOSTOBJECTURI_CID \
{ 0xf5475c51, 0x59a7, 0x4757, \ { 0xf5475c51, 0x59a7, 0x4757, \
{ 0xb3, 0xd9, 0xe2, 0x11, 0xa9, 0x41, 0x08, 0x72 } } { 0xb3, 0xd9, 0xe2, 0x11, 0xa9, 0x41, 0x08, 0x72 } }
#endif /* nsBlobURI_h */ #endif /* nsHostObjectURI_h */

View File

@ -429,9 +429,9 @@ protected:
void SetPlayedOrSeeked(bool aValue); 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. * Stop playback on mSrcStream.
*/ */

View File

@ -64,6 +64,7 @@
#include "MediaStreamGraph.h" #include "MediaStreamGraph.h"
#include "nsDOMMediaStream.h" #include "nsDOMMediaStream.h"
#include "nsIScriptError.h" #include "nsIScriptError.h"
#include "nsHostObjectProtocolHandler.h"
#include "nsCSSParser.h" #include "nsCSSParser.h"
#include "nsIMediaList.h" #include "nsIMediaList.h"
@ -758,7 +759,7 @@ void nsHTMLMediaElement::SelectResource()
// If we have a 'src' attribute, use that exclusively. // If we have a 'src' attribute, use that exclusively.
nsAutoString src; nsAutoString src;
if (mSrcAttrStream) { if (mSrcAttrStream) {
SetupSrcMediaStreamPlayback(); SetupSrcMediaStreamPlayback(mSrcAttrStream);
} else if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) { } else if (GetAttr(kNameSpaceID_None, nsGkAtoms::src, src)) {
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
nsresult rv = NewURIFromString(src, getter_AddRefs(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())); LOG(PR_LOG_DEBUG, ("%p Trying load from src=%s", this, NS_ConvertUTF16toUTF8(src).get()));
NS_ASSERTION(!mIsLoadingFromSourceChildren, NS_ASSERTION(!mIsLoadingFromSourceChildren,
"Should think we're not loading from source children by default"); "Should think we're not loading from source children by default");
mLoadingSrc = uri; mLoadingSrc = uri;
if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) { if (mPreloadAction == nsHTMLMediaElement::PRELOAD_NONE) {
// preload:none media, suspend the load here before we make any // preload:none media, suspend the load here before we make any
@ -1035,7 +1037,7 @@ nsresult nsHTMLMediaElement::LoadResource()
mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)); mCORSMode = AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc); nsHTMLMediaElement* other = LookupMediaElementURITable(mLoadingSrc);
if (other) { if (other && other->mDecoder) {
// Clone it. // Clone it.
nsresult rv = InitializeDecoderAsClone(other->mDecoder); nsresult rv = InitializeDecoderAsClone(other->mDecoder);
// Get the mimetype from the element we clone, since we will not get it via // 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; 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(); nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
// check for a Content Security Policy to pass down to the channel // check for a Content Security Policy to pass down to the channel
@ -2765,11 +2782,11 @@ private:
bool mDidHaveCurrentData; bool mDidHaveCurrentData;
}; };
void nsHTMLMediaElement::SetupSrcMediaStreamPlayback() void nsHTMLMediaElement::SetupSrcMediaStreamPlayback(nsDOMMediaStream* aStream)
{ {
NS_ASSERTION(!mSrcStream && !mSrcStreamListener, "Should have been ended already"); 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 // 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. // playing a stream, we'll need to add a CombineWithPrincipal call here.
mSrcStreamListener = new StreamListener(this); mSrcStreamListener = new StreamListener(this);

View File

@ -28,7 +28,7 @@
#include "nsIAsyncVerifyRedirectCallback.h" #include "nsIAsyncVerifyRedirectCallback.h"
#include "mozilla/Util.h" // for DebugOnly #include "mozilla/Util.h" // for DebugOnly
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsBlobProtocolHandler.h" #include "nsHostObjectProtocolHandler.h"
#ifdef PR_LOGGING #ifdef PR_LOGGING
PRLogModuleInfo* gMediaResourceLog; PRLogModuleInfo* gMediaResourceLog;

View File

@ -138,6 +138,7 @@ ifneq ($(OS_ARCH), WINNT)
MOCHITEST_FILES += \ MOCHITEST_FILES += \
test_streams_element_capture.html \ test_streams_element_capture.html \
test_streams_element_capture_reset.html \ test_streams_element_capture_reset.html \
test_streams_element_capture_createObjectURL.html \
test_timeupdate_small_files.html \ test_timeupdate_small_files.html \
$(NULL) $(NULL)
else else

View File

@ -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>

View File

@ -17,6 +17,7 @@
#include "PannerNode.h" #include "PannerNode.h"
#include "AudioListener.h" #include "AudioListener.h"
#include "DynamicsCompressorNode.h" #include "DynamicsCompressorNode.h"
#include "BiquadFilterNode.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@ -124,6 +125,14 @@ AudioContext::CreateDynamicsCompressor()
return compressorNode.forget(); return compressorNode.forget();
} }
already_AddRefed<BiquadFilterNode>
AudioContext::CreateBiquadFilter()
{
nsRefPtr<BiquadFilterNode> filterNode =
new BiquadFilterNode(this);
return filterNode.forget();
}
AudioListener* AudioListener*
AudioContext::Listener() AudioContext::Listener()
{ {

View File

@ -27,6 +27,7 @@ class AudioBuffer;
class AudioBufferSourceNode; class AudioBufferSourceNode;
class AudioDestinationNode; class AudioDestinationNode;
class AudioListener; class AudioListener;
class BiquadFilterNode;
class DelayNode; class DelayNode;
class DynamicsCompressorNode; class DynamicsCompressorNode;
class GainNode; class GainNode;
@ -80,6 +81,9 @@ public:
already_AddRefed<DynamicsCompressorNode> already_AddRefed<DynamicsCompressorNode>
CreateDynamicsCompressor(); CreateDynamicsCompressor();
already_AddRefed<BiquadFilterNode>
CreateBiquadFilter();
private: private:
nsCOMPtr<nsIDOMWindow> mWindow; nsCOMPtr<nsIDOMWindow> mWindow;
nsRefPtr<AudioDestinationNode> mDestination; nsRefPtr<AudioDestinationNode> mDestination;

View 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);
}
}
}

View 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

View File

@ -23,6 +23,7 @@ CPPSRCS := \
AudioNode.cpp \ AudioNode.cpp \
AudioParam.cpp \ AudioParam.cpp \
AudioSourceNode.cpp \ AudioSourceNode.cpp \
BiquadFilterNode.cpp \
DelayNode.cpp \ DelayNode.cpp \
DynamicsCompressorNode.cpp \ DynamicsCompressorNode.cpp \
EnableWebAudioCheck.cpp \ EnableWebAudioCheck.cpp \
@ -39,6 +40,7 @@ EXPORTS_mozilla/dom := \
AudioNode.h \ AudioNode.h \
AudioParam.h \ AudioParam.h \
AudioSourceNode.h \ AudioSourceNode.h \
BiquadFilterNode.h \
DelayNode.h \ DelayNode.h \
DynamicsCompressorNode.h \ DynamicsCompressorNode.h \
GainNode.h \ GainNode.h \

View File

@ -11,11 +11,13 @@ relativesrcdir := @relativesrcdir@
include $(DEPTH)/config/autoconf.mk include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES := \ MOCHITEST_FILES := \
webaudio.js \
test_bug808374.html \ test_bug808374.html \
test_AudioBuffer.html \ test_AudioBuffer.html \
test_AudioContext.html \ test_AudioContext.html \
test_AudioListener.html \ test_AudioListener.html \
test_badConnect.html \ test_badConnect.html \
test_biquadFilterNode.html \
test_delayNode.html \ test_delayNode.html \
test_dynamicsCompressorNode.html \ test_dynamicsCompressorNode.html \
test_gainNode.html \ test_gainNode.html \

View File

@ -7,20 +7,9 @@
</head> </head>
<body> <body>
<pre id="test"> <pre id="test">
<script src="webaudio.js" type="text/javascript"></script>
<script class="testbody" type="text/javascript"> <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(); SimpleTest.waitForExplicitFinish();
addLoadEvent(function() { addLoadEvent(function() {
SpecialPowers.setBoolPref("media.webaudio.enabled", true); SpecialPowers.setBoolPref("media.webaudio.enabled", true);

View 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>

View 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");
}

View File

@ -84,6 +84,7 @@ EXPORTS_mozilla/dom = \
DOMRequest.h \ DOMRequest.h \
StructuredCloneTags.h \ StructuredCloneTags.h \
ScreenOrientation.h \ ScreenOrientation.h \
URL.h \
$(NULL) $(NULL)
CPPSRCS = \ CPPSRCS = \
@ -115,6 +116,7 @@ CPPSRCS = \
DOMError.cpp \ DOMError.cpp \
DOMRequest.cpp \ DOMRequest.cpp \
Navigator.cpp \ Navigator.cpp \
URL.cpp \
$(NULL) $(NULL)
include $(topsrcdir)/dom/dom-config.mk include $(topsrcdir)/dom/dom-config.mk

101
dom/base/URL.cpp Normal file
View 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
View 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___ */

View File

@ -1434,8 +1434,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(ArchiveRequest, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(ArchiveRequest, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozURLProperty, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH, NS_DEFINE_CLASSINFO_DATA(ModalContentWindow, nsWindowSH,
DEFAULT_SCRIPTABLE_FLAGS | DEFAULT_SCRIPTABLE_FLAGS |
@ -4008,10 +4006,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMRequest) DOM_CLASSINFO_MAP_ENTRY(nsIDOMDOMRequest)
DOM_CLASSINFO_MAP_END 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_MAP_BEGIN_NO_CLASS_IF(ModalContentWindow, nsIDOMWindow)
DOM_CLASSINFO_WINDOW_MAP_ENTRIES(nsGlobalWindow::HasIndexedDBSupport()) DOM_CLASSINFO_WINDOW_MAP_ENTRIES(nsGlobalWindow::HasIndexedDBSupport())
DOM_CLASSINFO_MAP_ENTRY(nsIDOMModalContentWindow) 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; return true;
} }

View File

@ -366,7 +366,6 @@ DOMCI_CLASS(File)
DOMCI_CLASS(FileReader) DOMCI_CLASS(FileReader)
DOMCI_CLASS(ArchiveReader) DOMCI_CLASS(ArchiveReader)
DOMCI_CLASS(ArchiveRequest) DOMCI_CLASS(ArchiveRequest)
DOMCI_CLASS(MozURLProperty)
// DOM modal content window class, almost identical to Window // DOM modal content window class, almost identical to Window
DOMCI_CLASS(ModalContentWindow) DOMCI_CLASS(ModalContentWindow)

View File

@ -148,7 +148,6 @@
#include "nsAutoPtr.h" #include "nsAutoPtr.h"
#include "nsContentUtils.h" #include "nsContentUtils.h"
#include "nsCSSProps.h" #include "nsCSSProps.h"
#include "nsBlobProtocolHandler.h"
#include "nsIDOMFile.h" #include "nsIDOMFile.h"
#include "nsIDOMFileList.h" #include "nsIDOMFileList.h"
#include "nsIURIFixup.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_UPLOAD_EVENT_NAME NS_LITERAL_STRING("moznetworkupload")
#define NETWORK_DOWNLOAD_EVENT_NAME NS_LITERAL_STRING("moznetworkdownload") #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 * An indirect observer object that means we don't have to implement nsIObserver
* on nsGlobalWindow, where any script could see it. * on nsGlobalWindow, where any script could see it.
@ -533,6 +453,14 @@ private:
NS_IMPL_ISUPPORTS2(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor) NS_IMPL_ISUPPORTS2(nsGlobalWindowObserver, nsIObserver, nsIInterfaceRequestor)
nsTimeout::nsTimeout() nsTimeout::nsTimeout()
: mCleared(false),
mRunning(false),
mIsInterval(false),
mPublicId(0),
mInterval(0),
mFiringDepth(0),
mNestingLevel(0),
mPopupState(openAllowed)
{ {
#ifdef DEBUG_jst #ifdef DEBUG_jst
{ {
@ -542,8 +470,6 @@ nsTimeout::nsTimeout()
} }
#endif #endif
memset(this, 0, sizeof(*this));
MOZ_COUNT_CTOR(nsTimeout); MOZ_COUNT_CTOR(nsTimeout);
} }
@ -723,9 +649,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
// Initialize the PRCList (this). // Initialize the PRCList (this).
PR_INIT_CLIST(this); PR_INIT_CLIST(this);
// Initialize timeout storage
PR_INIT_CLIST(&mTimeouts);
if (aOuterWindow) { if (aOuterWindow) {
// |this| is an inner window, add this inner window to the outer // |this| is an inner window, add this inner window to the outer
// window list of inners. // window list of inners.
@ -928,10 +851,6 @@ nsGlobalWindow::~nsGlobalWindow()
nsCycleCollector_DEBUG_wasFreed(static_cast<nsIScriptGlobalObject*>(this)); nsCycleCollector_DEBUG_wasFreed(static_cast<nsIScriptGlobalObject*>(this));
#endif #endif
if (mURLProperty) {
mURLProperty->ClearWindowReference();
}
nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID); nsCOMPtr<nsIDeviceSensors> ac = do_GetService(NS_DEVICE_SENSORS_CONTRACTID);
if (ac) if (ac)
ac->RemoveWindowAsListener(this); ac->RemoveWindowAsListener(this);
@ -1319,9 +1238,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGlobalWindow)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mListenerManager,
nsEventListenerManager) nsEventListenerManager)
for (nsTimeout* timeout = tmp->FirstTimeout(); for (nsTimeout* timeout = tmp->mTimeouts.getFirst();
tmp->IsTimeout(timeout); timeout;
timeout = timeout->Next()) { timeout = timeout->getNext()) {
cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout)); cb.NoteNativeChild(timeout, NS_CYCLE_COLLECTION_PARTICIPANT(nsTimeout));
} }
@ -1426,9 +1345,9 @@ nsGlobalWindow::IsBlackForCC()
void void
nsGlobalWindow::UnmarkGrayTimers() nsGlobalWindow::UnmarkGrayTimers()
{ {
for (nsTimeout* timeout = FirstTimeout(); for (nsTimeout* timeout = mTimeouts.getFirst();
timeout && IsTimeout(timeout); timeout;
timeout = timeout->Next()) { timeout = timeout->getNext()) {
if (timeout->mScriptHandler) { if (timeout->mScriptHandler) {
JSObject* o = timeout->mScriptHandler->GetScriptObject(); JSObject* o = timeout->mScriptHandler->GetScriptObject();
xpc_UnmarkGrayObject(o); xpc_UnmarkGrayObject(o);
@ -2318,8 +2237,7 @@ nsGlobalWindow::DetachFromDocShell()
// (mJSObject) so that it can be retrieved later (until it is // (mJSObject) so that it can be retrieved later (until it is
// finalized by the JS GC). // finalized by the JS GC).
NS_ASSERTION(PR_CLIST_IS_EMPTY(&mTimeouts), NS_ASSERTION(mTimeouts.isEmpty(), "Uh, outer window holds timeouts!");
"Uh, outer window holds timeouts!");
// Call FreeInnerObjects on all inner windows, not just the current // Call FreeInnerObjects on all inner windows, not just the current
// one, since some could be held by WindowStateHolder objects that // 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 // timeout events fire "early", so we need to test the timer as well
// as the deadline. // as the deadline.
last_expired_timeout = nullptr; 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)) && if (((timeout == aTimeout) || (timeout->mWhen <= deadline)) &&
(timeout->mFiringDepth == 0)) { (timeout->mFiringDepth == 0)) {
// Mark any timeouts that are on the list to be fired with the // 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. // list for any timeouts inserted as a result of running a timeout.
dummy_timeout.mFiringDepth = firingDepth; dummy_timeout.mFiringDepth = firingDepth;
dummy_timeout.mWhen = now; 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 // Don't let ClearWindowTimeouts throw away our stack-allocated
// dummy timeout. // dummy timeout.
@ -9954,10 +9872,10 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan; Telemetry::AutoCounter<Telemetry::DOM_TIMERS_FIRED_PER_NATIVE_TIMEOUT> timeoutsRan;
for (timeout = FirstTimeout(); for (timeout = mTimeouts.getFirst();
timeout != &dummy_timeout && !IsFrozen(); timeout != &dummy_timeout && !IsFrozen();
timeout = nextTimeout) { timeout = nextTimeout) {
nextTimeout = timeout->Next(); nextTimeout = timeout->getNext();
if (timeout->mFiringDepth != firingDepth) { if (timeout->mFiringDepth != firingDepth) {
// We skip the timeout since it's on the list to run at another // 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 // Running a timeout can cause another timeout to be deleted, so
// we need to reset the pointer to the following timeout. // we need to reset the pointer to the following timeout.
nextTimeout = timeout->Next(); nextTimeout = timeout->getNext();
PR_REMOVE_LINK(timeout); timeout->remove();
if (needsReinsertion) { if (needsReinsertion) {
// Insert interval timeout onto list sorted in deadline order. // 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 // Take the dummy timeout off the head of the list
PR_REMOVE_LINK(&dummy_timeout); dummy_timeout.remove();
mTimeoutInsertionPoint = last_insertion_point; mTimeoutInsertionPoint = last_insertion_point;
} }
@ -10074,9 +9992,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
uint32_t public_id = (uint32_t)aTimerID; uint32_t public_id = (uint32_t)aTimerID;
nsTimeout *timeout; nsTimeout *timeout;
for (timeout = FirstTimeout(); for (timeout = mTimeouts.getFirst(); timeout; timeout = timeout->getNext()) {
IsTimeout(timeout);
timeout = timeout->Next()) {
if (timeout->mPublicId == public_id) { if (timeout->mPublicId == public_id) {
if (timeout->mRunning) { if (timeout->mRunning) {
/* We're running from inside the timeout. Mark this /* We're running from inside the timeout. Mark this
@ -10086,7 +10002,7 @@ nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
} }
else { else {
/* Delete the timeout from the pending timeout list */ /* Delete the timeout from the pending timeout list */
PR_REMOVE_LINK(timeout); timeout->remove();
if (timeout->mTimer) { if (timeout->mTimer) {
timeout->mTimer->Cancel(); timeout->mTimer->Cancel();
@ -10121,13 +10037,13 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// start at the timer after mTimeoutInsertionPoint, if there is one. // start at the timer after mTimeoutInsertionPoint, if there is one.
// Otherwise, start at the beginning of the list. // Otherwise, start at the beginning of the list.
for (nsTimeout *timeout = mTimeoutInsertionPoint ? for (nsTimeout *timeout = mTimeoutInsertionPoint ?
mTimeoutInsertionPoint->Next() : FirstTimeout(); mTimeoutInsertionPoint->getNext() : mTimeouts.getFirst();
IsTimeout(timeout); ) { timeout; ) {
// It's important that this check be <= so that we guarantee that // It's important that this check be <= so that we guarantee that
// taking NS_MAX with |now| won't make a quantity equal to // taking NS_MAX with |now| won't make a quantity equal to
// timeout->mWhen below. // timeout->mWhen below.
if (timeout->mWhen <= now) { if (timeout->mWhen <= now) {
timeout = timeout->Next(); timeout = timeout->getNext();
continue; continue;
} }
@ -10164,14 +10080,14 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
// Get the pointer to the next timeout now, before we move the // Get the pointer to the next timeout now, before we move the
// current timeout in the list. // 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 // 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 // strictly smaller than it used to be, so we know we'll insert
// |timeout| before nextTimeout. // |timeout| before nextTimeout.
NS_ASSERTION(!IsTimeout(nextTimeout) || NS_ASSERTION(!nextTimeout ||
timeout->mWhen < nextTimeout->mWhen, "How did that happen?"); timeout->mWhen < nextTimeout->mWhen, "How did that happen?");
PR_REMOVE_LINK(timeout); timeout->remove();
// InsertTimeoutIntoList will addref |timeout| and reset // InsertTimeoutIntoList will addref |timeout| and reset
// mFiringDepth. Make sure to undo that after calling it. // mFiringDepth. Make sure to undo that after calling it.
uint32_t firingDepth = timeout->mFiringDepth; uint32_t firingDepth = timeout->mFiringDepth;
@ -10188,7 +10104,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
timeout = nextTimeout; timeout = nextTimeout;
} else { } else {
timeout = timeout->Next(); timeout = timeout->getNext();
} }
} }
@ -10200,7 +10116,7 @@ nsGlobalWindow::ClearAllTimeouts()
{ {
nsTimeout *timeout, *nextTimeout; 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 /* If RunTimeout() is higher up on the stack for this
window, e.g. as a result of document.write from a timeout, window, e.g. as a result of document.write from a timeout,
then we need to reset the list insertion point for then we need to reset the list insertion point for
@ -10209,7 +10125,7 @@ nsGlobalWindow::ClearAllTimeouts()
if (mRunningTimeout == timeout) if (mRunningTimeout == timeout)
mTimeoutInsertionPoint = nullptr; mTimeoutInsertionPoint = nullptr;
nextTimeout = timeout->Next(); nextTimeout = timeout->getNext();
if (timeout->mTimer) { if (timeout->mTimer) {
timeout->mTimer->Cancel(); timeout->mTimer->Cancel();
@ -10229,7 +10145,7 @@ nsGlobalWindow::ClearAllTimeouts()
} }
// Clear out our list // Clear out our list
PR_INIT_CLIST(&mTimeouts); mTimeouts.clear();
} }
void void
@ -10242,19 +10158,23 @@ nsGlobalWindow::InsertTimeoutIntoList(nsTimeout *aTimeout)
// mTimeoutInsertionPoint, though. This optimizes for the common case of // mTimeoutInsertionPoint, though. This optimizes for the common case of
// insertion at the end. // insertion at the end.
nsTimeout* prevSibling; nsTimeout* prevSibling;
for (prevSibling = LastTimeout(); for (prevSibling = mTimeouts.getLast();
IsTimeout(prevSibling) && prevSibling != mTimeoutInsertionPoint && prevSibling && prevSibling != mTimeoutInsertionPoint &&
// This condition needs to match the one in SetTimeoutOrInterval that // This condition needs to match the one in SetTimeoutOrInterval that
// determines whether to set mWhen or mTimeRemaining. // determines whether to set mWhen or mTimeRemaining.
((IsFrozen() || mTimeoutsSuspendDepth) ? ((IsFrozen() || mTimeoutsSuspendDepth) ?
prevSibling->mTimeRemaining > aTimeout->mTimeRemaining : prevSibling->mTimeRemaining > aTimeout->mTimeRemaining :
prevSibling->mWhen > aTimeout->mWhen); prevSibling->mWhen > aTimeout->mWhen);
prevSibling = prevSibling->Prev()) { prevSibling = prevSibling->getPrevious()) {
/* Do nothing; just searching */ /* Do nothing; just searching */
} }
// Now link in aTimeout after prevSibling. // Now link in aTimeout after prevSibling.
PR_INSERT_AFTER(aTimeout, prevSibling); if (prevSibling) {
prevSibling->setNext(aTimeout);
} else {
mTimeouts.insertFront(aTimeout);
}
aTimeout->mFiringDepth = 0; aTimeout->mFiringDepth = 0;
@ -10546,7 +10466,7 @@ nsGlobalWindow::SuspendTimeouts(uint32_t aIncrease,
mozilla::dom::workers::SuspendWorkersForWindow(cx, this); mozilla::dom::workers::SuspendWorkersForWindow(cx, this);
TimeStamp now = TimeStamp::Now(); 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. // Set mTimeRemaining to be the time remaining for this timer.
if (t->mWhen > now) if (t->mWhen > now)
t->mTimeRemaining = t->mWhen - now; t->mTimeRemaining = t->mWhen - now;
@ -10634,7 +10554,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
bool _seenDummyTimeout = false; bool _seenDummyTimeout = false;
#endif #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 // 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 // case we have a dummy timeout in the list that *must not* be resumed. It
// can be identified by a null mWindow. // 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 void
nsGlobalWindow::EnableTimeChangeNotifications() nsGlobalWindow::EnableTimeChangeNotifications()
{ {

View File

@ -59,6 +59,7 @@
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIIDBFactory.h" #include "nsIIDBFactory.h"
#include "nsFrameMessageManager.h" #include "nsFrameMessageManager.h"
#include "mozilla/LinkedList.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "nsIDOMTouchEvent.h" #include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h" #include "nsIInlineEventHandlers.h"
@ -111,7 +112,6 @@ class PostMessageEvent;
class nsRunnable; class nsRunnable;
class nsDOMEventTargetHelper; class nsDOMEventTargetHelper;
class nsDOMOfflineResourceList; class nsDOMOfflineResourceList;
class nsDOMMozURLProperty;
class nsDOMWindowUtils; class nsDOMWindowUtils;
class nsIIdleService; class nsIIdleService;
@ -124,6 +124,7 @@ class nsWindowSizes;
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
class Navigator; class Navigator;
class URL;
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla
@ -138,7 +139,7 @@ NS_CreateJSTimeoutHandler(nsGlobalWindow *aWindow,
* timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which * timeout. Holds a strong reference to an nsIScriptTimeoutHandler, which
* abstracts the language specific cruft. * abstracts the language specific cruft.
*/ */
struct nsTimeout : PRCList struct nsTimeout : mozilla::LinkedListElement<nsTimeout>
{ {
nsTimeout(); nsTimeout();
~nsTimeout(); ~nsTimeout();
@ -148,16 +149,6 @@ struct nsTimeout : PRCList
nsrefcnt Release(); nsrefcnt Release();
nsrefcnt AddRef(); 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) { nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) {
return mTimer->InitWithFuncCallback(aFunc, this, delay, return mTimer->InitWithFuncCallback(aFunc, this, delay,
nsITimer::TYPE_ONE_SHOT); nsITimer::TYPE_ONE_SHOT);
@ -282,8 +273,6 @@ class nsGlobalWindow : public nsPIDOMWindow,
#endif // MOZ_B2G #endif // MOZ_B2G
{ {
public: public:
friend class nsDOMMozURLProperty;
typedef mozilla::TimeStamp TimeStamp; typedef mozilla::TimeStamp TimeStamp;
typedef mozilla::TimeDuration TimeDuration; typedef mozilla::TimeDuration TimeDuration;
typedef mozilla::dom::Navigator Navigator; typedef mozilla::dom::Navigator Navigator;
@ -886,20 +875,6 @@ protected:
bool IsInModalState(); 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 // Convenience functions for the many methods that need to scale
// from device to CSS pixels or vice versa. Note: if a presentation // from device to CSS pixels or vice versa. Note: if a presentation
// context is not available, they will assume a 1:1 ratio. // 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 // non-null. In that case, the dummy timeout pointed to by
// mTimeoutInsertionPoint may have a later mWhen than some of the timeouts // mTimeoutInsertionPoint may have a later mWhen than some of the timeouts
// that come after it. // that come after it.
PRCList mTimeouts; mozilla::LinkedList<nsTimeout> mTimeouts;
// If mTimeoutInsertionPoint is non-null, insertions should happen after it. // 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 // This is a dummy timeout at the moment; if that ever changes, the logic in
// ResetTimersForNonBackgroundWindow needs to change. // ResetTimersForNonBackgroundWindow needs to change.
@ -1128,8 +1103,6 @@ protected:
// destroying this window). // destroying this window).
bool mDialogsPermanentlyDisabled; bool mDialogsPermanentlyDisabled;
nsRefPtr<nsDOMMozURLProperty> mURLProperty;
nsTHashtable<nsPtrHashKey<nsDOMEventTargetHelper> > mEventTargetObjects; nsTHashtable<nsPtrHashKey<nsDOMEventTargetHelper> > mEventTargetObjects;
nsTArray<uint32_t> mEnabledSensors; nsTArray<uint32_t> mEnabledSensors;

View File

@ -108,31 +108,6 @@ nsLocation::GetDocShell()
return docshell; 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 nsresult
nsLocation::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo) 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 // current URI as the referrer. If they don't match, use the principal's
// URI. // URI.
JSScript* script = nullptr;
nsCOMPtr<nsIDocument> doc; nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsIURI> docOriginalURI, docCurrentURI, principalURI; nsCOMPtr<nsIURI> docOriginalURI, docCurrentURI, principalURI;
// NB: A false return value from JS_DescribeScriptedCaller means no caller nsCOMPtr<nsPIDOMWindow> entryPoint =
// was found. It does not signal that an exception was thrown. do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(cx));
if (JS_DescribeScriptedCaller(cx, &script, nullptr)) { if (entryPoint) {
doc = GetScriptDocument(cx, script); doc = entryPoint->GetDoc();
} }
if (doc) { if (doc) {
docOriginalURI = doc->GetOriginalURI(); docOriginalURI = doc->GetOriginalURI();

View File

@ -48,8 +48,8 @@ class nsIArray;
class nsPIWindowRoot; class nsPIWindowRoot;
#define NS_PIDOMWINDOW_IID \ #define NS_PIDOMWINDOW_IID \
{ 0x54fd92bd, 0xda33, 0x4451, \ { 0x7b18e421, 0x2179, 0x4e24, \
{ 0x8f, 0xb5, 0x11, 0x20, 0x5c, 0x03, 0xce, 0xaa } } { 0x96, 0x58, 0x26, 0x75, 0xa4, 0x37, 0xf3, 0x8f } }
class nsPIDOMWindow : public nsIDOMWindowInternal class nsPIDOMWindow : public nsIDOMWindowInternal
{ {

View File

@ -114,6 +114,10 @@ DOMInterfaces = {
'concrete': False, 'concrete': False,
}, },
'BiquadFilterNode': {
'resultNotAddRefed': [ 'frequency', 'q', 'gain' ],
},
'Blob': [ 'Blob': [
{ {
'headerFile': 'nsIDOMFile.h', 'headerFile': 'nsIDOMFile.h',
@ -365,6 +369,10 @@ DOMInterfaces = {
'implicitJSContext': [ 'encode' ], 'implicitJSContext': [ 'encode' ],
}, },
'URL' : {
'concrete': False,
},
'WebGLActiveInfo': { 'WebGLActiveInfo': {
'nativeType': 'mozilla::WebGLActiveInfo', 'nativeType': 'mozilla::WebGLActiveInfo',
'headerFile': 'WebGLContext.h', 'headerFile': 'WebGLContext.h',

View File

@ -1095,7 +1095,9 @@ class MethodDefiner(PropertyDefiner):
"flags": "JSPROP_ENUMERATE", "flags": "JSPROP_ENUMERATE",
"pref": None }) "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', self.chrome.append({"name": 'QueryInterface',
"methodInfo": False, "methodInfo": False,
"length": 1, "length": 1,
@ -5634,50 +5636,53 @@ class CGDescriptor(CGThing):
assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject() assert not descriptor.concrete or descriptor.interface.hasInterfacePrototypeObject()
cgThings = [] cgThings = []
if descriptor.interface.hasInterfacePrototypeObject(): # These are set to true if at least one non-static
# These are set to true if at least one non-static # method/getter/setter exist on the interface.
# method/getter/setter exist on the interface. (hasMethod, hasGetter, hasLenientGetter,
(hasMethod, hasGetter, hasLenientGetter, hasSetter, hasLenientSetter) = False, False, False, False, False
hasSetter, hasLenientSetter) = False, False, False, False, False for m in descriptor.interface.members:
for m in descriptor.interface.members: if (m.isMethod() and
if (m.isMethod() and (not m.isIdentifierLess() or m == descriptor.operations['Stringifier'])):
(not m.isIdentifierLess() or m == descriptor.operations['Stringifier'])): if m.isStatic():
if m.isStatic(): assert descriptor.interface.hasInterfaceObject
cgThings.append(CGStaticMethod(descriptor, m)) 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: else:
cgThings.append(CGSpecializedMethod(descriptor, m)) hasGetter = True
cgThings.append(CGMemberJITInfo(descriptor, m)) if not m.readonly:
hasMethod = True
elif m.isAttr():
if m.isStatic(): if m.isStatic():
cgThings.append(CGStaticGetter(descriptor, m)) assert descriptor.interface.hasInterfaceObject
else: cgThings.append(CGStaticSetter(descriptor, m))
cgThings.append(CGSpecializedGetter(descriptor, m)) elif descriptor.interface.hasInterfacePrototypeObject():
cgThings.append(CGSpecializedSetter(descriptor, m))
if m.hasLenientThis(): if m.hasLenientThis():
hasLenientGetter = True hasLenientSetter = True
else: else:
hasGetter = True hasSetter = True
if not m.readonly: elif m.getExtendedAttribute("PutForwards"):
if m.isStatic(): cgThings.append(CGSpecializedForwardingSetter(descriptor, m))
cgThings.append(CGStaticSetter(descriptor, m)) hasSetter = True
else: if (not m.isStatic() and
cgThings.append(CGSpecializedSetter(descriptor, m)) descriptor.interface.hasInterfacePrototypeObject()):
if m.hasLenientThis(): cgThings.append(CGMemberJITInfo(descriptor, m))
hasLenientSetter = True if hasMethod: cgThings.append(CGGenericMethod(descriptor))
else: if hasGetter: cgThings.append(CGGenericGetter(descriptor))
hasSetter = True if hasLenientGetter: cgThings.append(CGGenericGetter(descriptor,
elif m.getExtendedAttribute("PutForwards"): lenientThis=True))
cgThings.append(CGSpecializedForwardingSetter(descriptor, m)) if hasSetter: cgThings.append(CGGenericSetter(descriptor))
hasSetter = True if hasLenientSetter: cgThings.append(CGGenericSetter(descriptor,
if not m.isStatic(): lenientThis=True))
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.concrete:
if descriptor.nativeOwnership == 'owned' or descriptor.nativeOwnership == 'refcounted': if descriptor.nativeOwnership == 'owned' or descriptor.nativeOwnership == 'refcounted':
@ -5805,9 +5810,10 @@ class CGNamespacedEnum(CGThing):
class CGDictionary(CGThing): class CGDictionary(CGThing):
def __init__(self, dictionary, descriptorProvider): def __init__(self, dictionary, descriptorProvider):
self.dictionary = dictionary; self.dictionary = dictionary
self.descriptorProvider = descriptorProvider self.descriptorProvider = descriptorProvider
self.workers = descriptorProvider.workers self.workers = descriptorProvider.workers
self.needToInitIds = not self.workers and len(dictionary.members) > 0
if all(CGDictionary(d, descriptorProvider).generatable for if all(CGDictionary(d, descriptorProvider).generatable for
d in CGDictionary.getDictionaryDependencies(dictionary)): d in CGDictionary.getDictionaryDependencies(dictionary)):
self.generatable = True self.generatable = True
@ -5869,7 +5875,7 @@ class CGDictionary(CGThing):
" ${selfName}(const ${selfName}&) MOZ_DELETE;\n" + " ${selfName}(const ${selfName}&) MOZ_DELETE;\n" +
# NOTE: jsids are per-runtime, so don't use them in workers # NOTE: jsids are per-runtime, so don't use them in workers
(" static bool InitIds(JSContext* cx);\n" (" 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 " + "\n".join(" static jsid " +
self.makeIdName(m.identifier.name) + ";" for self.makeIdName(m.identifier.name) + ";" for
m in d.members) + "\n" m in d.members) + "\n"
@ -5934,7 +5940,7 @@ class CGDictionary(CGThing):
" initedIds = true;\n" " initedIds = true;\n"
" return true;\n" " return true;\n"
"}\n" "}\n"
"\n" if not self.workers else "") + "\n" if self.needToInitIds else "") +
"bool\n" "bool\n"
"${selfName}::Init(JSContext* cx, const JS::Value& val)\n" "${selfName}::Init(JSContext* cx, const JS::Value& val)\n"
"{\n" "{\n"
@ -5944,10 +5950,10 @@ class CGDictionary(CGThing):
# NOTE: jsids are per-runtime, so don't use them in workers # NOTE: jsids are per-runtime, so don't use them in workers
(" if (cx && !initedIds && !InitIds(cx)) {\n" (" if (cx && !initedIds && !InitIds(cx)) {\n"
" return false;\n" " return false;\n"
" }\n" if not self.workers else "") + " }\n" if self.needToInitIds else "") +
"${initParent}" "${initParent}" +
" JSBool found;\n" (" JSBool found;\n"
" JS::Value temp;\n" " JS::Value temp;\n" if len(memberInits) > 0 else "") +
" bool isNull = val.isNullOrUndefined();\n" " bool isNull = val.isNullOrUndefined();\n"
" if (!isNull && !val.isObject()) {\n" " if (!isNull && !val.isObject()) {\n"
" return ThrowErrorMessage(cx, MSG_NOT_OBJECT);\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 # NOTE: jsids are per-runtime, so don't use them in workers
(" if (!initedIds && !InitIds(cx)) {\n" (" if (!initedIds && !InitIds(cx)) {\n"
" return false;\n" " return false;\n"
" }\n" if not self.workers else "") + " }\n" if self.needToInitIds else "") +
"${toObjectParent}" "${toObjectParent}"
"${ensureObject}" "${ensureObject}"
"\n" "\n"

View File

@ -16,6 +16,8 @@
#include "nsIURI.h" #include "nsIURI.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "mozilla/Preferences.h"
USING_FILE_NAMESPACE USING_FILE_NAMESPACE
ArchiveReader::ArchiveReader() ArchiveReader::ArchiveReader()
@ -33,6 +35,12 @@ ArchiveReader::~ArchiveReader()
nsLayoutStatics::Release(); nsLayoutStatics::Release();
} }
bool
ArchiveReader::PrefEnabled()
{
return Preferences::GetBool("dom.archivereader.enabled", true);
}
NS_IMETHODIMP NS_IMETHODIMP
ArchiveReader::Initialize(nsISupports* aOwner, ArchiveReader::Initialize(nsISupports* aOwner,
JSContext* aCx, JSContext* aCx,
@ -42,6 +50,10 @@ ArchiveReader::Initialize(nsISupports* aOwner,
{ {
NS_ENSURE_TRUE(aArgc == 1 || aArgc == 2, NS_ERROR_INVALID_ARG); NS_ENSURE_TRUE(aArgc == 1 || aArgc == 2, NS_ERROR_INVALID_ARG);
if (!PrefEnabled()) {
return NS_ERROR_UNEXPECTED;
}
// We expect to get a Blob object // We expect to get a Blob object
if (!aArgv[0].isObject()) { if (!aArgv[0].isObject()) {
return NS_ERROR_INVALID_ARG; // We're not interested return NS_ERROR_INVALID_ARG; // We're not interested

View File

@ -48,6 +48,8 @@ public:
nsresult GetInputStream(nsIInputStream** aInputStream); nsresult GetInputStream(nsIInputStream** aInputStream);
nsresult GetSize(uint64_t* aSize); nsresult GetSize(uint64_t* aSize);
static bool PrefEnabled();
public: // for the ArchiveRequest: public: // for the ArchiveRequest:
nsresult RegisterRequest(ArchiveRequest* aRequest); nsresult RegisterRequest(ArchiveRequest* aRequest);

View File

@ -13,11 +13,14 @@ var fileStorages = [
var utils = SpecialPowers.getDOMWindowUtils(window); var utils = SpecialPowers.getDOMWindowUtils(window);
var archiveReaderEnabled = false;
var testGenerator = testSteps(); var testGenerator = testSteps();
function runTest() function runTest()
{ {
allowUnlimitedQuota(); allowUnlimitedQuota();
enableArchiveReader();
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
testGenerator.next(); testGenerator.next();
@ -26,6 +29,7 @@ function runTest()
function finishTest() function finishTest()
{ {
resetUnlimitedQuota(); resetUnlimitedQuota();
resetArchiveReader();
SimpleTest.executeSoon(function() { SimpleTest.executeSoon(function() {
testGenerator.close(); testGenerator.close();
@ -98,6 +102,17 @@ function resetUnlimitedQuota(url)
removePermission("indexedDB-unlimited", 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) function getFileHandle(fileStorageKey, name)
{ {
var requestService = SpecialPowers.getDOMRequestService(); var requestService = SpecialPowers.getDOMRequestService();

View File

@ -8,14 +8,8 @@
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body> <script type="text/javascript;version=1.7">
<p id="display">
<input id="fileList" type="file"></input>
</p>
<script type="text/javascript;version=1.7">
function createZipFileWithData(fileData) { function createZipFileWithData(fileData) {
var Cc = SpecialPowers.Cc; var Cc = SpecialPowers.Cc;
var Ci = SpecialPowers.Ci; var Ci = SpecialPowers.Ci;
@ -58,7 +52,7 @@
function markTestDone() { function markTestDone() {
++handleFinished; ++handleFinished;
if (isFinished()) { if (isFinished()) {
SimpleTest.finish(); finishTest();
} }
} }
function isFinished() { function isFinished() {
@ -251,11 +245,17 @@
ok(false, "ArchiveReader.getFiles() should not return an 'error'"); ok(false, "ArchiveReader.getFiles() should not return an 'error'");
markTestDone(); markTestDone();
} }
yield;
} }
SimpleTest.waitForExplicitFinish();
testSteps();
</script> </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> </body>
</html> </html>

View File

@ -4,6 +4,7 @@
*/ */
var testGenerator = testSteps(); var testGenerator = testSteps();
var archiveReaderEnabled = false;
// The test js is shared between xpcshell (which has no SpecialPowers object) // The test js is shared between xpcshell (which has no SpecialPowers object)
// and content mochitests (where the |Components| object is accessible only as // and content mochitests (where the |Components| object is accessible only as
@ -68,6 +69,8 @@ if (!window.runTest) {
allowUnlimitedQuota(); allowUnlimitedQuota();
} }
enableArchiveReader();
clearAllDatabases(function () { testGenerator.next(); }); clearAllDatabases(function () { testGenerator.next(); });
} }
} }
@ -75,6 +78,7 @@ if (!window.runTest) {
function finishTest() function finishTest()
{ {
resetUnlimitedQuota(); resetUnlimitedQuota();
resetArchiveReader();
SimpleTest.executeSoon(function() { SimpleTest.executeSoon(function() {
testGenerator.close(); testGenerator.close();
@ -163,12 +167,12 @@ function compareKeys(k1, k2) {
if (!(k2 instanceof Array) || if (!(k2 instanceof Array) ||
k1.length != k2.length) k1.length != k2.length)
return false; return false;
for (let i = 0; i < k1.length; ++i) { for (let i = 0; i < k1.length; ++i) {
if (!compareKeys(k1[i], k2[i])) if (!compareKeys(k1[i], k2[i]))
return false; return false;
} }
return true; return true;
} }
@ -211,6 +215,17 @@ function resetUnlimitedQuota(url)
removePermission("indexedDB-unlimited", 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() function gc()
{ {
SpecialPowers.forceGC(); SpecialPowers.forceGC();

View File

@ -16,13 +16,6 @@ interface nsIPrompt;
interface nsISelection; interface nsISelection;
interface nsIVariant; 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 * The nsIDOMWindow interface is the primary interface for a DOM
* window object. It represents a single window object that may * window object. It represents a single window object that may
@ -32,7 +25,7 @@ interface nsIDOMMozURLProperty : nsISupports
* @see <http://www.whatwg.org/html/#window> * @see <http://www.whatwg.org/html/#window>
*/ */
[scriptable, uuid(1534ecd7-e298-420e-9063-e6c2d1243d49)] [scriptable, uuid(b9c71e0b-7f81-419a-8253-91f4c8893c4f)]
interface nsIDOMWindow : nsISupports interface nsIDOMWindow : nsISupports
{ {
// the current browsing context // the current browsing context
@ -461,11 +454,6 @@ interface nsIDOMWindow : nsISupports
*/ */
readonly attribute long long mozAnimationStartTime; 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> * 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. * Empty interface for compatibility with older versions.
* @deprecated Use nsIDOMWindow instead * @deprecated Use nsIDOMWindow instead
*/ */
[scriptable, uuid(8da641ab-906a-456e-97f2-b77df4ca2d95)] [scriptable, uuid(a5cd0946-bac1-4606-9aaa-9e68dd0a3279)]
interface nsIDOMWindowInternal : nsIDOMWindow {}; interface nsIDOMWindowInternal : nsIDOMWindow {};

View File

@ -130,6 +130,11 @@ MOCHITEST_FILES = \
test_bug755320.html \ test_bug755320.html \
test_bug777628.html \ test_bug777628.html \
test_bug665548.html \ test_bug665548.html \
test_bug809290.html \
file_bug809290_b1.html \
file_bug809290_b2.html \
file_bug809290_c.html \
file_empty.html \
$(NULL) $(NULL)
ifneq (Linux,$(OS_ARCH)) ifneq (Linux,$(OS_ARCH))

View 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>

View 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>

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<script>
window.parent.parent.notifyReferrer(document.referrer);
</script>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,2 @@
<!DOCTYPE html>
<html><head></head><body></body></html>

View File

@ -56,8 +56,15 @@ function iframeLoaded(identifier) {
is(iframeCw.getInnerIframeReferrer(), iframeCw.location, 'inner iframe referrer'); is(iframeCw.getInnerIframeReferrer(), iframeCw.location, 'inner iframe referrer');
// Now do the test again, this time with a popup. // 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) { else if (loadCount == 4) {
history.replaceState('', '', Math.random()); history.replaceState('', '', Math.random());

View 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>

View File

@ -207,8 +207,6 @@ var interfaceNamesInGlobalScope =
"SVGAltGlyphElement", "SVGAltGlyphElement",
"Screen", "Screen",
"FileReader", "FileReader",
"ArchiveReader",
"ArchiveRequest",
"SVGSwitchElement", "SVGSwitchElement",
"SVGPolylineElement", "SVGPolylineElement",
"SVGPathSegLinetoAbs", "SVGPathSegLinetoAbs",
@ -342,7 +340,7 @@ var interfaceNamesInGlobalScope =
"HTMLSelectElement", "HTMLSelectElement",
"MessageEvent", "MessageEvent",
"SVGFEImageElement", "SVGFEImageElement",
"MozURLProperty", "URL",
"DeviceStorage", "DeviceStorage",
"SVGFEOffsetElement", "SVGFEOffsetElement",
"DOMImplementation", "DOMImplementation",

View File

@ -31,6 +31,8 @@ interface mozAudioContext {
[Creator] [Creator]
DelayNode createDelay(optional float maxDelayTime = 1); DelayNode createDelay(optional float maxDelayTime = 1);
[Creator] [Creator]
BiquadFilterNode createBiquadFilter();
[Creator]
PannerNode createPanner(); PannerNode createPanner();
[Creator] [Creator]

View 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
View 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 */
};

View File

@ -17,6 +17,7 @@ webidl_files = \
AudioNode.webidl \ AudioNode.webidl \
AudioParam.webidl \ AudioParam.webidl \
AudioSourceNode.webidl \ AudioSourceNode.webidl \
BiquadFilterNode.webidl \
Blob.webidl \ Blob.webidl \
CanvasRenderingContext2D.webidl \ CanvasRenderingContext2D.webidl \
ClientRectList.webidl \ ClientRectList.webidl \
@ -52,6 +53,7 @@ webidl_files = \
SVGTransformList.webidl \ SVGTransformList.webidl \
TextDecoder.webidl \ TextDecoder.webidl \
TextEncoder.webidl \ TextEncoder.webidl \
URL.webidl \
WebSocket.webidl \ WebSocket.webidl \
XMLHttpRequest.webidl \ XMLHttpRequest.webidl \
XMLHttpRequestEventTarget.webidl \ XMLHttpRequestEventTarget.webidl \

View File

@ -992,6 +992,10 @@ LayerManagerOGL::Render()
// Allow widget to render a custom background. // Allow widget to render a custom background.
mWidget->DrawWindowUnderlay(this, rect); 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. // Render our layers.
RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO, RootLayer()->RenderLayer(mGLContext->IsDoubleBuffered() ? 0 : mBackBufferFBO,
nsIntPoint(0, 0)); nsIntPoint(0, 0));

View File

@ -501,8 +501,7 @@ nsresult nsExtensibleStringBundle::GetSimpleEnumeration(nsISimpleEnumerator ** a
#define MAX_CACHED_BUNDLES 16 #define MAX_CACHED_BUNDLES 16
struct bundleCacheEntry_t { struct bundleCacheEntry_t : public LinkedListElement<bundleCacheEntry_t> {
PRCList list;
nsCStringKey *mHashKey; nsCStringKey *mHashKey;
// do not use a nsCOMPtr - this is a struct not a class! // do not use a nsCOMPtr - this is a struct not a class!
nsIStringBundle* mBundle; nsIStringBundle* mBundle;
@ -516,7 +515,6 @@ nsStringBundleService::nsStringBundleService() :
printf("\n++ nsStringBundleService::nsStringBundleService ++\n"); printf("\n++ nsStringBundleService::nsStringBundleService ++\n");
#endif #endif
PR_INIT_CLIST(&mBundleCache);
PL_InitArenaPool(&mCacheEntryPool, "srEntries", PL_InitArenaPool(&mCacheEntryPool, "srEntries",
sizeof(bundleCacheEntry_t)*MAX_CACHED_BUNDLES, sizeof(bundleCacheEntry_t)*MAX_CACHED_BUNDLES,
sizeof(bundleCacheEntry_t)); sizeof(bundleCacheEntry_t));
@ -582,16 +580,10 @@ nsStringBundleService::flushBundleCache()
// release all bundles in the cache // release all bundles in the cache
mBundleMap.Reset(); mBundleMap.Reset();
PRCList *current = PR_LIST_HEAD(&mBundleCache); while (!mBundleCache.isEmpty()) {
while (current != &mBundleCache) { bundleCacheEntry_t *cacheEntry = mBundleCache.popFirst();
bundleCacheEntry_t *cacheEntry = (bundleCacheEntry_t*)current;
recycleEntry(cacheEntry); recycleEntry(cacheEntry);
PRCList *oldItem = current;
current = PR_NEXT_LINK(current);
// will be freed in PL_FreeArenaPool
PR_REMOVE_LINK(oldItem);
} }
PL_FreeArenaPool(&mCacheEntryPool); PL_FreeArenaPool(&mCacheEntryPool);
} }
@ -616,7 +608,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
// cache hit! // cache hit!
// remove it from the list, it will later be reinserted // remove it from the list, it will later be reinserted
// at the head of the list // at the head of the list
PR_REMOVE_LINK((PRCList*)cacheEntry); cacheEntry->remove();
} else { } else {
@ -633,8 +625,7 @@ nsStringBundleService::getStringBundle(const char *aURLSpec,
// at this point the cacheEntry should exist in the hashtable, // at this point the cacheEntry should exist in the hashtable,
// but is not in the LRU cache. // but is not in the LRU cache.
// put the cache entry at the front of the list // put the cache entry at the front of the list
mBundleCache.insertFront(cacheEntry);
PR_INSERT_LINK((PRCList *)cacheEntry, &mBundleCache);
// finally, return the value // finally, return the value
*aResult = cacheEntry->mBundle; *aResult = cacheEntry->mBundle;
@ -654,12 +645,12 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle,
void *cacheEntryArena; void *cacheEntryArena;
PL_ARENA_ALLOCATE(cacheEntryArena, &mCacheEntryPool, sizeof(bundleCacheEntry_t)); PL_ARENA_ALLOCATE(cacheEntryArena, &mCacheEntryPool, sizeof(bundleCacheEntry_t));
cacheEntry = (bundleCacheEntry_t*)cacheEntryArena; cacheEntry = new (cacheEntryArena) bundleCacheEntry_t();
} else { } else {
// cache is full // cache is full
// take the last entry in the list, and recycle it. // 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 // remove it from the hash table and linked list
NS_ASSERTION(mBundleMap.Exists(cacheEntry->mHashKey), NS_ASSERTION(mBundleMap.Exists(cacheEntry->mHashKey),
@ -670,7 +661,7 @@ nsStringBundleService::insertIntoCache(nsIStringBundle* aBundle,
aHashKey->GetString()).get()); aHashKey->GetString()).get());
#endif #endif
mBundleMap.Remove(cacheEntry->mHashKey); mBundleMap.Remove(cacheEntry->mHashKey);
PR_REMOVE_LINK((PRCList*)cacheEntry); cacheEntry->remove();
// free up excess memory // free up excess memory
recycleEntry(cacheEntry); recycleEntry(cacheEntry);

View File

@ -6,7 +6,6 @@
#ifndef nsStringBundleService_h__ #ifndef nsStringBundleService_h__
#define nsStringBundleService_h__ #define nsStringBundleService_h__
#include "prclist.h"
#include "plarena.h" #include "plarena.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
@ -18,6 +17,8 @@
#include "nsIErrorService.h" #include "nsIErrorService.h"
#include "nsIStringBundleOverride.h" #include "nsIStringBundleOverride.h"
#include "mozilla/LinkedList.h"
struct bundleCacheEntry_t; struct bundleCacheEntry_t;
class nsStringBundleService : public nsIStringBundleService, class nsStringBundleService : public nsIStringBundleService,
@ -48,7 +49,7 @@ private:
static void recycleEntry(bundleCacheEntry_t*); static void recycleEntry(bundleCacheEntry_t*);
nsHashtable mBundleMap; nsHashtable mBundleMap;
PRCList mBundleCache; mozilla::LinkedList<bundleCacheEntry_t> mBundleCache;
PLArenaPool mCacheEntryPool; PLArenaPool mCacheEntryPool;
nsCOMPtr<nsIErrorService> mErrorService; nsCOMPtr<nsIErrorService> mErrorService;

View File

@ -243,8 +243,17 @@ case "$target" in
android_platform_tools="$android_sdk"/tools # SDK Tools < r8 android_platform_tools="$android_sdk"/tools # SDK Tools < r8
fi fi
ANDROID_SDK="${android_sdk}" 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}" ANDROID_PLATFORM_TOOLS="${android_platform_tools}"
AC_SUBST(ANDROID_SDK) 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) AC_SUBST(ANDROID_PLATFORM_TOOLS)
;; ;;
esac esac

View File

@ -1701,9 +1701,9 @@ ion::InvalidateAll(FreeOp *fop, JSCompartment *c)
CancelOffThreadIonCompile(c, NULL); CancelOffThreadIonCompile(c, NULL);
FinishAllOffThreadCompilations(c->ionCompartment()); FinishAllOffThreadCompilations(c->ionCompartment());
for (IonActivationIterator iter(fop->runtime()); iter.more(); ++iter) { for (IonActivationIterator iter(fop->runtime()); iter.more(); ++iter) {
if (iter.activation()->compartment() == c) { if (iter.activation()->compartment() == c) {
IonContext ictx(NULL, c, NULL);
AutoFlushCache afc ("InvalidateAll", c->ionCompartment()); AutoFlushCache afc ("InvalidateAll", c->ionCompartment());
IonSpew(IonSpew_Invalidate, "Invalidating all frames for GC"); IonSpew(IonSpew_Invalidate, "Invalidating all frames for GC");
InvalidateActivation(fop, iter.top(), true); InvalidateActivation(fop, iter.top(), true);
@ -1875,10 +1875,8 @@ AutoFlushCache::AutoFlushCache(const char *nonce, IonCompartment *comp)
name_(nonce), name_(nonce),
used_(false) used_(false)
{ {
if (comp == NULL) { if (CurrentIonContext() != NULL)
if (CurrentIonContext() != NULL) comp = GetIonContext()->compartment->ionCompartment();
comp = GetIonContext()->compartment->ionCompartment();
}
// If a compartment isn't available, then be a nop, nobody will ever see this flusher // If a compartment isn't available, then be a nop, nobody will ever see this flusher
if (comp) { if (comp) {
if (comp->flusher()) if (comp->flusher())

View File

@ -471,7 +471,6 @@ struct GetNativePropertyStub
// TODO: ensure stack is aligned? // TODO: ensure stack is aligned?
DebugOnly<uint32> initialStack = masm.framePushed(); DebugOnly<uint32> initialStack = masm.framePushed();
masm.checkStackAlignment();
Label success, exception; Label success, exception;

View File

@ -230,6 +230,8 @@ ion::CheckLogging()
EnableChannel(IonSpew_Safepoints); EnableChannel(IonSpew_Safepoints);
if (ContainsFlag(env, "pools")) if (ContainsFlag(env, "pools"))
EnableChannel(IonSpew_Pools); EnableChannel(IonSpew_Pools);
if (ContainsFlag(env, "cacheflush"))
EnableChannel(IonSpew_CacheFlush);
if (ContainsFlag(env, "logs")) if (ContainsFlag(env, "logs"))
EnableIonDebugLogging(); EnableIonDebugLogging();
if (ContainsFlag(env, "all")) if (ContainsFlag(env, "all"))

View File

@ -958,9 +958,20 @@ MMul::analyzeEdgeCasesBackward()
canBeNegativeZero_ = NeedNegativeZeroCheck(this); canBeNegativeZero_ = NeedNegativeZeroCheck(this);
} }
bool void
MMul::updateForReplacement(MDefinition *ins) 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; return true;
} }

View File

@ -2498,11 +2498,24 @@ class MSub : public MBinaryArithInstruction
class MMul : public MBinaryArithInstruction class MMul : public MBinaryArithInstruction
{ {
// Annotation the result could be a negative zero
// and we need to guard this during execution.
bool canBeNegativeZero_; 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) MMul(MDefinition *left, MDefinition *right, MIRType type)
: MBinaryArithInstruction(left, right), : MBinaryArithInstruction(left, right),
canBeNegativeZero_(true) canBeNegativeZero_(true),
possibleTruncate_(false),
implicitTruncate_(false)
{ {
if (type != MIRType_Value) if (type != MIRType_Value)
specialization_ = type; specialization_ = type;
@ -2521,13 +2534,14 @@ class MMul : public MBinaryArithInstruction
MDefinition *foldsTo(bool useValueNumbers); MDefinition *foldsTo(bool useValueNumbers);
void analyzeEdgeCasesForward(); void analyzeEdgeCasesForward();
void analyzeEdgeCasesBackward(); void analyzeEdgeCasesBackward();
void analyzeTruncateBackward();
double getIdentity() { double getIdentity() {
return 1; return 1;
} }
bool canOverflow() { bool canOverflow() {
return !range()->isFinite(); return !implicitTruncate_ && !range()->isFinite();
} }
bool canBeNegativeZero() { bool canBeNegativeZero() {
@ -2546,8 +2560,18 @@ class MMul : public MBinaryArithInstruction
return false; return false;
Range *left = getOperand(0)->range(); Range *left = getOperand(0)->range();
Range *right = getOperand(1)->range(); Range *right = getOperand(1)->range();
if (isPossibleTruncated())
implicitTruncate_ = !Range::precisionLossMul(left, right);
return range()->update(Range::mul(left, right)); return range()->update(Range::mul(left, right));
} }
bool isPossibleTruncated() const {
return possibleTruncate_;
}
void setPossibleTruncated(bool truncate) {
possibleTruncate_ = truncate;
}
}; };
class MDiv : public MBinaryArithInstruction class MDiv : public MBinaryArithInstruction

View File

@ -417,6 +417,24 @@ Range::shr(const Range *lhs, int32 c)
return ret; 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 bool
Range::update(const Range *other) Range::update(const Range *other)
{ {

View File

@ -126,6 +126,8 @@ class Range {
static Range shl(const Range *lhs, int32 c); static Range shl(const Range *lhs, int32 c);
static Range shr(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() { inline void makeLowerInfinite() {
lower_infinite_ = true; lower_infinite_ = true;
lower_ = JSVAL_INT_MIN; lower_ = JSVAL_INT_MIN;

View File

@ -72,7 +72,6 @@ struct EnterJITStack
IonCode * IonCode *
IonCompartment::generateEnterJIT(JSContext *cx) IonCompartment::generateEnterJIT(JSContext *cx)
{ {
AutoFlushCache afc("GenerateEnterJIT", cx->compartment->ionCompartment());
const Register reg_code = r0; const Register reg_code = r0;
const Register reg_argc = r1; const Register reg_argc = r1;
@ -85,6 +84,7 @@ IonCompartment::generateEnterJIT(JSContext *cx)
JS_ASSERT(OsrFrameReg == reg_frame); JS_ASSERT(OsrFrameReg == reg_frame);
MacroAssembler masm(cx); MacroAssembler masm(cx);
AutoFlushCache afc("GenerateEnterJIT", cx->compartment->ionCompartment());
Assembler *aasm = &masm; Assembler *aasm = &masm;
// Save non-volatile registers. These must be saved by the trampoline, // Save non-volatile registers. These must be saved by the trampoline,

View 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);

View File

@ -0,0 +1,3 @@
var obj = new Proxy(Object.create(null), {});
assertEq(typeof obj, 'object');
assertEq(obj != null, true);

View File

@ -3156,9 +3156,12 @@ proxy(JSContext *cx, unsigned argc, jsval *vp)
RootedObject proto(cx); RootedObject proto(cx);
if (!JSObject::getProto(cx, target, &proto)) if (!JSObject::getProto(cx, target, &proto))
return false; return false;
JSObject *parent = NULL;
if (proto)
parent = proto->getParent();
RootedObject fun(cx, target->isCallable() ? target : (JSObject *) NULL); RootedObject fun(cx, target->isCallable() ? target : (JSObject *) NULL);
JSObject *proxy = NewProxyObject(cx, &ScriptedDirectProxyHandler::singleton, JSObject *proxy = NewProxyObject(cx, &ScriptedDirectProxyHandler::singleton,
ObjectValue(*target), proto, proto->getParent(), ObjectValue(*target), proto, parent,
fun, fun); fun, fun);
if (!proxy) if (!proxy)
return false; return false;

View File

@ -944,8 +944,7 @@ SourceCompressorThread::internalCompress()
// Try to keep the maximum memory usage down by only allocating half the // Try to keep the maximum memory usage down by only allocating half the
// size of the string, first. // size of the string, first.
size_t firstSize = nbytes / 2; size_t firstSize = nbytes / 2;
ss->data.compressed = static_cast<unsigned char *>(js_malloc(firstSize)); if (!ss->adjustDataSize(firstSize))
if (!ss->data.compressed)
return false; return false;
Compressor comp(reinterpret_cast<const unsigned char *>(tok->chars), nbytes); Compressor comp(reinterpret_cast<const unsigned char *>(tok->chars), nbytes);
if (!comp.init()) if (!comp.init())
@ -964,13 +963,8 @@ SourceCompressorThread::internalCompress()
// The compressed output is greater than half the size of the // The compressed output is greater than half the size of the
// original string. Reallocate to the full size. // original string. Reallocate to the full size.
void *newmem = js_realloc(ss->data.compressed, nbytes); if (!ss->adjustDataSize(nbytes))
if (!newmem) {
js_free(ss->data.compressed);
ss->data.compressed = NULL;
return false; return false;
}
ss->data.compressed = static_cast<unsigned char *>(newmem);
comp.setOutput(ss->data.compressed, nbytes); comp.setOutput(ss->data.compressed, nbytes);
break; break;
} }
@ -988,22 +982,12 @@ SourceCompressorThread::internalCompress()
} }
#endif #endif
if (compressedLength == 0) { if (compressedLength == 0) {
// Note ss->data.source might be NULL. if (!ss->adjustDataSize(nbytes))
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;
}
return false; return false;
}
ss->data.source = buf;
PodCopy(ss->data.source, tok->chars, ss->length()); PodCopy(ss->data.source, tok->chars, ss->length());
} else { } else {
// Shrink the buffer to the size of the compressed data. Shouldn't fail. // Shrink the buffer to the size of the compressed data. Shouldn't fail.
void *newmem = js_realloc(ss->data.compressed, compressedLength); JS_ALWAYS_TRUE(ss->adjustDataSize(compressedLength));
JS_ASSERT(newmem);
ss->data.compressed = static_cast<unsigned char *>(newmem);
} }
ss->compressedLength_ = compressedLength; ss->compressedLength_ = compressedLength;
return true; return true;
@ -1085,6 +1069,29 @@ SourceCompressorThread::abort(SourceCompressionToken *userTok)
} }
#endif /* JS_THREADSAFE */ #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 void
JSScript::setScriptSource(ScriptSource *ss) JSScript::setScriptSource(ScriptSource *ss)
{ {
@ -1210,8 +1217,7 @@ ScriptSource::setSourceCopy(JSContext *cx, StableCharPtr src, uint32_t length,
} else } else
#endif #endif
{ {
data.source = cx->runtime->pod_malloc<jschar>(length); if (!adjustDataSize(sizeof(jschar) * length))
if (!data.source)
return false; return false;
PodCopy(data.source, src.get(), length_); PodCopy(data.source, src.get(), length_);
} }
@ -1257,7 +1263,7 @@ void
ScriptSource::destroy(JSRuntime *rt) ScriptSource::destroy(JSRuntime *rt)
{ {
JS_ASSERT(ready()); JS_ASSERT(ready());
js_free(data.compressed); adjustDataSize(0);
js_free(sourceMap_); js_free(sourceMap_);
#ifdef DEBUG #ifdef DEBUG
ready_ = false; ready_ = false;
@ -1270,9 +1276,9 @@ ScriptSource::sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf)
{ {
JS_ASSERT(ready()); JS_ASSERT(ready());
// data is a union, but both members are pointers to allocated memory or // |data| is a union, but both members are pointers to allocated memory,
// NULL, so just using compressed will work. // |emptySource|, or NULL, so just using |data.compressed| will work.
return mallocSizeOf(this) + mallocSizeOf(data.compressed); return mallocSizeOf(this) + ((data.compressed != emptySource) ? mallocSizeOf(data.compressed) : 0);
} }
template<XDRMode mode> template<XDRMode mode>
@ -1305,8 +1311,7 @@ ScriptSource::performXDR(XDRState<mode> *xdr)
size_t byteLen = compressedLength ? compressedLength : (length * sizeof(jschar)); size_t byteLen = compressedLength ? compressedLength : (length * sizeof(jschar));
if (mode == XDR_DECODE) { if (mode == XDR_DECODE) {
data.compressed = static_cast<unsigned char *>(xdr->cx()->malloc_(byteLen)); if (!adjustDataSize(byteLen))
if (!data.compressed)
return false; return false;
} }
if (!xdr->codeBytes(data.compressed, byteLen)) { if (!xdr->codeBytes(data.compressed, byteLen)) {

View File

@ -990,9 +990,14 @@ struct ScriptSource
friend class SourceCompressorThread; friend class SourceCompressorThread;
private: private:
union { union {
// When the script source is ready, compressedLength_ != 0 implies // Before setSourceCopy or setSource are successfully called, this union
// compressed holds the compressed data; otherwise, source holds the // has a NULL pointer. When the script source is ready,
// uncompressed source. // 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; jschar *source;
unsigned char *compressed; unsigned char *compressed;
} data; } data;
@ -1068,6 +1073,7 @@ struct ScriptSource
size_t computedSizeOfData() const { size_t computedSizeOfData() const {
return compressed() ? compressedLength_ : sizeof(jschar) * length_; return compressed() ? compressedLength_ : sizeof(jschar) * length_;
} }
bool adjustDataSize(size_t nbytes);
}; };
class ScriptSourceHolder class ScriptSourceHolder

View File

@ -87,6 +87,7 @@ MOCHITEST_FILES = chrome_wrappers_helper.html \
test_bug800864.html \ test_bug800864.html \
test_bug802557.html \ test_bug802557.html \
file_bug802557.html \ file_bug802557.html \
test_bug809547.html \
$(NULL) $(NULL)
ifneq ($(OS_TARGET),Android) ifneq ($(OS_TARGET),Android)

View 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>

View File

@ -80,8 +80,8 @@
#include "ArchiveReader.h" #include "ArchiveReader.h"
#include "nsFormData.h" #include "nsFormData.h"
#include "nsBlobProtocolHandler.h" #include "nsHostObjectProtocolHandler.h"
#include "nsBlobURI.h" #include "nsHostObjectURI.h"
#include "nsGlobalWindowCommands.h" #include "nsGlobalWindowCommands.h"
#include "nsIControllerCommandTable.h" #include "nsIControllerCommandTable.h"
#include "nsJSProtocolHandler.h" #include "nsJSProtocolHandler.h"
@ -278,7 +278,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDOMFileReader, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR(ArchiveReader) NS_GENERIC_FACTORY_CONSTRUCTOR(ArchiveReader)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormData) NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormData)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler) 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_CONSTRUCTOR(nsDOMParser)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager, NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager,
nsDOMStorageManager::GetInstance) 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_ARCHIVEREADER_CID);
NS_DEFINE_NAMED_CID(NS_FORMDATA_CID); NS_DEFINE_NAMED_CID(NS_FORMDATA_CID);
NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_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_XMLHTTPREQUEST_CID);
NS_DEFINE_NAMED_CID(NS_EVENTSOURCE_CID); NS_DEFINE_NAMED_CID(NS_EVENTSOURCE_CID);
NS_DEFINE_NAMED_CID(NS_DOMACTIVITY_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_ARCHIVEREADER_CID, false, NULL, ArchiveReaderConstructor },
{ &kNS_FORMDATA_CID, false, NULL, nsFormDataConstructor }, { &kNS_FORMDATA_CID, false, NULL, nsFormDataConstructor },
{ &kNS_BLOBPROTOCOLHANDLER_CID, false, NULL, nsBlobProtocolHandlerConstructor }, { &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_XMLHTTPREQUEST_CID, false, NULL, nsXMLHttpRequestConstructor },
{ &kNS_EVENTSOURCE_CID, false, NULL, nsEventSourceConstructor }, { &kNS_EVENTSOURCE_CID, false, NULL, nsEventSourceConstructor },
{ &kNS_DOMACTIVITY_CID, false, NULL, ActivityConstructor }, { &kNS_DOMACTIVITY_CID, false, NULL, ActivityConstructor },
@ -1206,6 +1209,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ NS_ARCHIVEREADER_CONTRACTID, &kNS_ARCHIVEREADER_CID }, { NS_ARCHIVEREADER_CONTRACTID, &kNS_ARCHIVEREADER_CID },
{ NS_FORMDATA_CONTRACTID, &kNS_FORMDATA_CID }, { NS_FORMDATA_CONTRACTID, &kNS_FORMDATA_CID },
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_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_XMLHTTPREQUEST_CONTRACTID, &kNS_XMLHTTPREQUEST_CID },
{ NS_EVENTSOURCE_CONTRACTID, &kNS_EVENTSOURCE_CID }, { NS_EVENTSOURCE_CONTRACTID, &kNS_EVENTSOURCE_CID },
{ NS_DOMACTIVITY_CONTRACTID, &kNS_DOMACTIVITY_CID }, { NS_DOMACTIVITY_CONTRACTID, &kNS_DOMACTIVITY_CID },

View File

@ -3058,9 +3058,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// constrained height to turn into an unconstrained one. // constrained height to turn into an unconstrained one.
aState.mY = startingY; aState.mY = startingY;
aState.mPrevBottomMargin = incomingMargin; aState.mPrevBottomMargin = incomingMargin;
PushLines(aState, aLine.prev());
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
*aKeepReflowGoing = false; *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; return NS_OK;
} }
@ -3120,9 +3124,13 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) { if (NS_INLINE_IS_BREAK_BEFORE(frameReflowStatus)) {
// None of the child block fits. // None of the child block fits.
PushLines(aState, aLine.prev());
*aKeepReflowGoing = false; *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 { else {
// Note: line-break-after a block is a nop // Note: line-break-after a block is a nop
@ -3141,6 +3149,11 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
collapsedBottomMargin, collapsedBottomMargin,
aLine->mBounds, overflowAreas, aLine->mBounds, overflowAreas,
frameReflowStatus); frameReflowStatus);
if (!NS_FRAME_IS_FULLY_COMPLETE(frameReflowStatus) &&
ShouldAvoidBreakInside(aState.mReflowState)) {
*aKeepReflowGoing = false;
}
if (aLine->SetCarriedOutBottomMargin(collapsedBottomMargin)) { if (aLine->SetCarriedOutBottomMargin(collapsedBottomMargin)) {
line_iterator nextLine = aLine; line_iterator nextLine = aLine;
++nextLine; ++nextLine;
@ -3281,16 +3294,14 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
brc.GetCarriedOutBottomMargin(), collapsedBottomMargin.get(), brc.GetCarriedOutBottomMargin(), collapsedBottomMargin.get(),
aState.mPrevBottomMargin); aState.mPrevBottomMargin);
#endif #endif
} } else {
else { if ((aLine == mLines.front() && !GetPrevInFlow()) ||
// None of the block fits. Determine the correct reflow status. ShouldAvoidBreakInside(aState.mReflowState)) {
if (aLine == mLines.front() && !GetPrevInFlow()) { // If it's our very first line *or* we're not at the top of the page
// If it's our very first line then we need to be pushed to // and we have page-break-inside:avoid, then we need to be pushed to
// our parents next-in-flow. Therefore, return break-before // our parent's next-in-flow.
// status for our reflow status.
aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE(); aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
} } else {
else {
// Push the line that didn't fit and any lines that follow it // Push the line that didn't fit and any lines that follow it
// to our next-in-flow. // to our next-in-flow.
PushLines(aState, aLine.prev()); PushLines(aState, aLine.prev());
@ -3399,12 +3410,10 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
void void
nsBlockFrame::PushTruncatedLine(nsBlockReflowState& aState, nsBlockFrame::PushTruncatedLine(nsBlockReflowState& aState,
line_iterator aLine, line_iterator aLine,
bool& aKeepReflowGoing) bool* aKeepReflowGoing)
{ {
line_iterator prevLine = aLine; PushLines(aState, aLine.prev());
--prevLine; *aKeepReflowGoing = false;
PushLines(aState, prevLine);
aKeepReflowGoing = false;
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus); 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 // it to the next page/column where its contents can fit not
// next to a float. // next to a float.
lineReflowStatus = LINE_REFLOW_TRUNCATED; 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; newY = aState.mY + dy;
} }
// See if the line fit. If it doesn't we need to push it. Our first if (!NS_FRAME_IS_FULLY_COMPLETE(aState.mReflowStatus) &&
// line will always fit. 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 && if (mLines.front() != aLine &&
newY > aState.mBottomEdge && newY > aState.mBottomEdge &&
aState.mBottomEdge != NS_UNCONSTRAINEDSIZE) { aState.mBottomEdge != NS_UNCONSTRAINEDSIZE) {
// Push this line and all of its children and anything else that NS_ASSERTION(aState.mCurrentLine == aLine, "oops");
// follows to our next-in-flow if (ShouldAvoidBreakInside(aState.mReflowState)) {
NS_ASSERTION((aState.mCurrentLine == aLine), "oops"); // All our content doesn't fit, start on the next page.
PushLines(aState, aLine.prev()); aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
} else {
// Stop reflow and whack the reflow status if reflow hasn't // Push aLine and all of its children and anything else that
// already been stopped. // follows to our next-in-flow.
if (*aKeepReflowGoing) { PushTruncatedLine(aState, aLine, aKeepReflowGoing);
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
*aKeepReflowGoing = false;
} }
return true; return true;
} }
@ -5755,11 +5767,15 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
aReflowStatus, aState); aReflowStatus, aState);
} while (NS_SUCCEEDED(rv) && clearanceFrame); } while (NS_SUCCEEDED(rv) && clearanceFrame);
// An incomplete reflow status means we should split the float if (!NS_FRAME_IS_FULLY_COMPLETE(aReflowStatus) &&
// if the height is constrained (bug 145305). ShouldAvoidBreakInside(floatRS)) {
if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) && aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
(NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.height)) } 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; aReflowStatus = NS_FRAME_COMPLETE;
}
if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) { if (aReflowStatus & NS_FRAME_REFLOW_NEXTINFLOW) {
aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW; aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;

View File

@ -631,11 +631,14 @@ protected:
nsIFrame* aFrame, nsIFrame* aFrame,
bool& aMadeNewFrame); 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, void PushTruncatedLine(nsBlockReflowState& aState,
line_iterator aLine, line_iterator aLine,
bool& aKeepReflowGoing); bool* aKeepReflowGoing);
nsresult SplitLine(nsBlockReflowState& aState, nsresult SplitLine(nsBlockReflowState& aState,
nsLineLayout& aLineLayout, nsLineLayout& aLineLayout,

View File

@ -760,15 +760,28 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// (This code is only for DISABLE_FLOAT_BREAKING_IN_COLUMNS .) // (This code is only for DISABLE_FLOAT_BREAKING_IN_COLUMNS .)
// //
// Likewise, if none of the float fit, and it needs to be pushed in // 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 // its entirety to the next page (NS_FRAME_IS_TRUNCATED or
// do the same. // NS_INLINE_IS_BREAK_BEFORE), we need to do the same.
if ((mContentArea.height != NS_UNCONSTRAINEDSIZE && if ((mContentArea.height != NS_UNCONSTRAINEDSIZE &&
adjustedAvailableSpace.height == NS_UNCONSTRAINEDSIZE && adjustedAvailableSpace.height == NS_UNCONSTRAINEDSIZE &&
!mustPlaceFloat && !mustPlaceFloat &&
aFloat->GetSize().height + floatMargin.TopBottom() > aFloat->GetSize().height + floatMargin.TopBottom() >
mContentArea.YMost() - floatY) || 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); PushFloatPastBreak(aFloat);
return false; return false;
} }

View File

@ -2876,11 +2876,10 @@ nsFrame::SelectByTypeAtPoint(nsPresContext* aPresContext,
if (!offsets.content) if (!offsets.content)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
nsIFrame* theFrame;
int32_t offset; int32_t offset;
const nsFrameSelection* frameSelection = const nsFrameSelection* frameSelection =
PresContext()->GetPresShell()->ConstFrameSelection(); PresContext()->GetPresShell()->ConstFrameSelection();
theFrame = frameSelection-> nsIFrame* theFrame = frameSelection->
GetFrameForNodeOffset(offsets.content, offsets.offset, GetFrameForNodeOffset(offsets.content, offsets.offset,
nsFrameSelection::HINT(offsets.associateWithNext), nsFrameSelection::HINT(offsets.associateWithNext),
&offset); &offset);
@ -2888,8 +2887,8 @@ nsFrame::SelectByTypeAtPoint(nsPresContext* aPresContext,
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
nsFrame* frame = static_cast<nsFrame*>(theFrame); nsFrame* frame = static_cast<nsFrame*>(theFrame);
return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType, return frame->PeekBackwardAndForward(aBeginAmountType, aEndAmountType,
offsets.offset, aPresContext, offset, aPresContext,
aBeginAmountType != eSelectWord, aBeginAmountType != eSelectWord,
aSelectFlags); aSelectFlags);
} }

View File

@ -408,6 +408,15 @@ public:
virtual const void* GetStyleDataExternal(nsStyleStructID aSID) const; 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 #ifdef DEBUG
/** /**
* Tracing method that writes a method enter/exit routine to the * Tracing method that writes a method enter/exit routine to the

View File

@ -1,4 +1,4 @@
<html> <html class="reftest-wait">
<head> <head>
</head> </head>
<body style="direction: rtl;"> <body style="direction: rtl;">
@ -13,6 +13,7 @@ var a=document.getElementById('a');
a.style.outline = '1px solid transparent'; a.style.outline = '1px solid transparent';
document.body.offsetHeight; document.body.offsetHeight;
a.style.outline = ''; a.style.outline = '';
document.documentElement.removeAttribute('class');
} }
setTimeout(doe, 500); setTimeout(doe, 500);
</script> </script>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <!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> <head>
<title>CSS 2.1 Test Suite: dynamic changes to 'counter-increment'</title> <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"/> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counters"/>
@ -21,11 +21,13 @@
s.setAttribute("class", "increment"); s.setAttribute("class", "increment");
s.appendChild(document.createTextNode("new-")); s.appendChild(document.createTextNode("new-"));
t.insertBefore(s, t.childNodes.item(1)); t.insertBefore(s, t.childNodes.item(1));
document.documentElement.removeAttribute('class');
} }
document.addEventListener("MozReftestInvalidate", run, false);
</script> </script>
</head> </head>
<body onload="setTimeout('run()', 0)"> <body>
<div id="test"><span class="increment"></span><span class="increment"></span><span class="increment"></span></div> <div id="test"><span class="increment"></span><span class="increment"></span><span class="increment"></span></div>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <!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> <head>
<title>CSS 2.1 Test Suite: dynamic changes to 'counter-increment'</title> <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"/> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counters"/>
@ -18,11 +18,13 @@
function run() { function run() {
var t = document.getElementById("test"); var t = document.getElementById("test");
t.removeChild(t.childNodes.item(1)); t.removeChild(t.childNodes.item(1));
document.documentElement.removeAttribute('class');
} }
document.addEventListener("MozReftestInvalidate", run, false);
</script> </script>
</head> </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> <div id="test"><span class="increment"></span><span class="increment">FAIL-</span><span class="increment"></span><span class="increment"></span></div>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <!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> <head>
<title>CSS 2.1 Test Suite: dynamic changes to 'counter-increment'</title> <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"/> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counters"/>
@ -20,11 +20,13 @@
document.getElementById("one").removeAttribute("class"); document.getElementById("one").removeAttribute("class");
document.getElementById("two").setAttribute("class", "increment"); document.getElementById("two").setAttribute("class", "increment");
document.getElementById("three").setAttribute("style", "counter-increment: c"); document.getElementById("three").setAttribute("style", "counter-increment: c");
document.documentElement.removeAttribute('class');
} }
document.addEventListener("MozReftestInvalidate", run, false);
</script> </script>
</head> </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> <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>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <!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> <head>
<title>CSS 2.1 Test Suite: dynamic changes to 'counter-increment'</title> <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"/> <link rel="help" href="http://www.w3.org/TR/CSS21/generate.html#counters"/>
@ -18,11 +18,13 @@
function run() { function run() {
var t = document.getElementById("test"); var t = document.getElementById("test");
t.removeChild(t.childNodes.item(1)); t.removeChild(t.childNodes.item(1));
document.documentElement.removeAttribute('class');
} }
document.addEventListener("MozReftestInvalidate", run, false);
</script> </script>
</head> </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> <div id="test"><span class="increment"></span><span class="reset"></span><span class="increment"></span><span class="increment"></span></div>

View File

@ -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>

View File

@ -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>

View File

@ -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 # Pagination tests
== abspos-breaking-000.xhtml abspos-breaking-000.ref.xhtml == abspos-breaking-000.xhtml abspos-breaking-000.ref.xhtml
== abspos-breaking-001.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-9.html blank.html # bug 672654
# == table-caption-splitaftercaption-10.html blank.html # bug 672654 # == table-caption-splitaftercaption-10.html blank.html # bug 672654
# == table-caption-splitaftercaption-11.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