mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge the last PGO-green inbound changeset to m-c.
This commit is contained in:
commit
be3c66b5a5
@ -9,7 +9,12 @@
|
|||||||
<?xml-stylesheet href="chrome://browser/content/downloads/downloads.css"?>
|
<?xml-stylesheet href="chrome://browser/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);"
|
||||||
|
@ -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 \
|
||||||
|
@ -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.
|
||||||
-->
|
-->
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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 ./
|
||||||
|
@ -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())
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef nsBlobProtocolHandler_h
|
|
||||||
#define nsBlobProtocolHandler_h
|
|
||||||
|
|
||||||
#include "nsIProtocolHandler.h"
|
|
||||||
#include "nsIURI.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
|
|
||||||
#define BLOBURI_SCHEME "blob"
|
|
||||||
|
|
||||||
class nsIDOMBlob;
|
|
||||||
class nsIPrincipal;
|
|
||||||
class nsIInputStream;
|
|
||||||
|
|
||||||
inline bool IsBlobURI(nsIURI* aUri)
|
|
||||||
{
|
|
||||||
bool isBlob;
|
|
||||||
return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern nsresult
|
|
||||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
|
|
||||||
|
|
||||||
class nsBlobProtocolHandler : public nsIProtocolHandler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
|
|
||||||
// nsIProtocolHandler methods:
|
|
||||||
NS_DECL_NSIPROTOCOLHANDLER
|
|
||||||
|
|
||||||
// nsBlobProtocolHandler methods:
|
|
||||||
nsBlobProtocolHandler() {}
|
|
||||||
virtual ~nsBlobProtocolHandler() {}
|
|
||||||
|
|
||||||
// Methods for managing uri->file mapping
|
|
||||||
static void AddFileDataEntry(nsACString& aUri,
|
|
||||||
nsIDOMBlob* aFile,
|
|
||||||
nsIPrincipal* aPrincipal);
|
|
||||||
static void RemoveFileDataEntry(nsACString& aUri);
|
|
||||||
static nsIPrincipal* GetFileDataEntryPrincipal(nsACString& aUri);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NS_BLOBPROTOCOLHANDLER_CID \
|
|
||||||
{ 0xb43964aa, 0xa078, 0x44b2, \
|
|
||||||
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
|
|
||||||
|
|
||||||
#endif /* nsBlobProtocolHandler_h */
|
|
81
content/base/public/nsHostObjectProtocolHandler.h
Normal file
81
content/base/public/nsHostObjectProtocolHandler.h
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef nsHostObjectProtocolHandler_h
|
||||||
|
#define nsHostObjectProtocolHandler_h
|
||||||
|
|
||||||
|
#include "nsIProtocolHandler.h"
|
||||||
|
#include "nsIURI.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
|
||||||
|
#define BLOBURI_SCHEME "blob"
|
||||||
|
#define MEDIASTREAMURI_SCHEME "mediastream"
|
||||||
|
|
||||||
|
class nsIDOMBlob;
|
||||||
|
class nsIDOMMediaStream;
|
||||||
|
class nsIPrincipal;
|
||||||
|
class nsIInputStream;
|
||||||
|
|
||||||
|
class nsHostObjectProtocolHandler : public nsIProtocolHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
// nsIProtocolHandler methods, except for GetScheme which is only defined
|
||||||
|
// in subclasses.
|
||||||
|
NS_IMETHOD GetDefaultPort(int32_t *aDefaultPort);
|
||||||
|
NS_IMETHOD GetProtocolFlags(uint32_t *aProtocolFlags);
|
||||||
|
NS_IMETHOD NewURI(const nsACString & aSpec, const char * aOriginCharset, nsIURI *aBaseURI, nsIURI * *_retval);
|
||||||
|
NS_IMETHOD NewChannel(nsIURI *aURI, nsIChannel * *_retval);
|
||||||
|
NS_IMETHOD AllowPort(int32_t port, const char * scheme, bool *_retval);
|
||||||
|
|
||||||
|
// Methods for managing uri->object mapping
|
||||||
|
// AddDataEntry creates the URI with the given scheme and returns it in aUri
|
||||||
|
static nsresult AddDataEntry(const nsACString& aScheme,
|
||||||
|
nsISupports* aObject,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
|
nsACString& aUri);
|
||||||
|
static void RemoveDataEntry(const nsACString& aUri);
|
||||||
|
static nsIPrincipal* GetDataEntryPrincipal(const nsACString& aUri);
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsBlobProtocolHandler : public nsHostObjectProtocolHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_IMETHOD GetScheme(nsACString &result);
|
||||||
|
};
|
||||||
|
|
||||||
|
class nsMediaStreamProtocolHandler : public nsHostObjectProtocolHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_IMETHOD GetScheme(nsACString &result);
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool IsBlobURI(nsIURI* aUri)
|
||||||
|
{
|
||||||
|
bool isBlob;
|
||||||
|
return NS_SUCCEEDED(aUri->SchemeIs(BLOBURI_SCHEME, &isBlob)) && isBlob;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsMediaStreamURI(nsIURI* aUri)
|
||||||
|
{
|
||||||
|
bool isStream;
|
||||||
|
return NS_SUCCEEDED(aUri->SchemeIs(MEDIASTREAMURI_SCHEME, &isStream)) && isStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern nsresult
|
||||||
|
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
|
||||||
|
|
||||||
|
extern nsresult
|
||||||
|
NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream);
|
||||||
|
|
||||||
|
#define NS_BLOBPROTOCOLHANDLER_CID \
|
||||||
|
{ 0xb43964aa, 0xa078, 0x44b2, \
|
||||||
|
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
|
||||||
|
|
||||||
|
#define NS_MEDIASTREAMPROTOCOLHANDLER_CID \
|
||||||
|
{ 0x27d1fa24, 0x2b73, 0x4db3, \
|
||||||
|
{ 0xab, 0x48, 0xb9, 0x83, 0x83, 0x40, 0xe0, 0x81 } }
|
||||||
|
|
||||||
|
#endif /* nsHostObjectProtocolHandler_h */
|
@ -79,8 +79,8 @@ class Element;
|
|||||||
} // namespace mozilla
|
} // 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;
|
||||||
|
@ -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 \
|
||||||
|
@ -1,217 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "nsBlobProtocolHandler.h"
|
|
||||||
#include "nsBlobURI.h"
|
|
||||||
#include "nsError.h"
|
|
||||||
#include "nsClassHashtable.h"
|
|
||||||
#include "nsNetUtil.h"
|
|
||||||
#include "nsIPrincipal.h"
|
|
||||||
#include "nsIDOMFile.h"
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
// Hash table
|
|
||||||
struct FileDataInfo
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMBlob> mFile;
|
|
||||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
|
||||||
};
|
|
||||||
|
|
||||||
static nsClassHashtable<nsCStringHashKey, FileDataInfo>* gFileDataTable;
|
|
||||||
|
|
||||||
void
|
|
||||||
nsBlobProtocolHandler::AddFileDataEntry(nsACString& aUri,
|
|
||||||
nsIDOMBlob* aFile,
|
|
||||||
nsIPrincipal* aPrincipal)
|
|
||||||
{
|
|
||||||
if (!gFileDataTable) {
|
|
||||||
gFileDataTable = new nsClassHashtable<nsCStringHashKey, FileDataInfo>;
|
|
||||||
gFileDataTable->Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
FileDataInfo* info = new FileDataInfo;
|
|
||||||
|
|
||||||
info->mFile = aFile;
|
|
||||||
info->mPrincipal = aPrincipal;
|
|
||||||
|
|
||||||
gFileDataTable->Put(aUri, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsBlobProtocolHandler::RemoveFileDataEntry(nsACString& aUri)
|
|
||||||
{
|
|
||||||
if (gFileDataTable) {
|
|
||||||
gFileDataTable->Remove(aUri);
|
|
||||||
if (gFileDataTable->Count() == 0) {
|
|
||||||
delete gFileDataTable;
|
|
||||||
gFileDataTable = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsIPrincipal*
|
|
||||||
nsBlobProtocolHandler::GetFileDataEntryPrincipal(nsACString& aUri)
|
|
||||||
{
|
|
||||||
if (!gFileDataTable) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileDataInfo* res;
|
|
||||||
gFileDataTable->Get(aUri, &res);
|
|
||||||
if (!res) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res->mPrincipal;
|
|
||||||
}
|
|
||||||
|
|
||||||
static FileDataInfo*
|
|
||||||
GetFileDataInfo(const nsACString& aUri)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(StringBeginsWith(aUri,
|
|
||||||
NS_LITERAL_CSTRING(BLOBURI_SCHEME ":")),
|
|
||||||
"Bad URI");
|
|
||||||
|
|
||||||
if (!gFileDataTable) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileDataInfo* res;
|
|
||||||
gFileDataTable->Get(aUri, &res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
|
||||||
// Protocol handler
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsBlobProtocolHandler, nsIProtocolHandler)
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsBlobProtocolHandler::GetScheme(nsACString &result)
|
|
||||||
{
|
|
||||||
result.AssignLiteral(BLOBURI_SCHEME);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsBlobProtocolHandler::GetDefaultPort(int32_t *result)
|
|
||||||
{
|
|
||||||
*result = -1;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsBlobProtocolHandler::GetProtocolFlags(uint32_t *result)
|
|
||||||
{
|
|
||||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS |
|
|
||||||
URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsBlobProtocolHandler::NewURI(const nsACString& aSpec,
|
|
||||||
const char *aCharset,
|
|
||||||
nsIURI *aBaseURI,
|
|
||||||
nsIURI **aResult)
|
|
||||||
{
|
|
||||||
*aResult = nullptr;
|
|
||||||
nsresult rv;
|
|
||||||
|
|
||||||
FileDataInfo* info =
|
|
||||||
GetFileDataInfo(aSpec);
|
|
||||||
|
|
||||||
nsRefPtr<nsBlobURI> uri =
|
|
||||||
new nsBlobURI(info ? info->mPrincipal.get() : nullptr);
|
|
||||||
|
|
||||||
rv = uri->SetSpec(aSpec);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
NS_TryToSetImmutable(uri);
|
|
||||||
uri.forget(aResult);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsBlobProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
|
||||||
{
|
|
||||||
*result = nullptr;
|
|
||||||
|
|
||||||
nsCString spec;
|
|
||||||
uri->GetSpec(spec);
|
|
||||||
|
|
||||||
FileDataInfo* info =
|
|
||||||
GetFileDataInfo(spec);
|
|
||||||
|
|
||||||
if (!info) {
|
|
||||||
return NS_ERROR_DOM_BAD_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
|
|
||||||
nsCOMPtr<nsIPrincipal> principal;
|
|
||||||
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
|
||||||
NS_ASSERTION(info->mPrincipal == principal, "Wrong principal!");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsCOMPtr<nsIInputStream> stream;
|
|
||||||
nsresult rv = info->mFile->GetInternalStream(getter_AddRefs(stream));
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIChannel> channel;
|
|
||||||
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
|
|
||||||
uri,
|
|
||||||
stream);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
|
|
||||||
|
|
||||||
nsAutoString type;
|
|
||||||
rv = info->mFile->GetType(type);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
uint64_t size;
|
|
||||||
rv = info->mFile->GetSize(&size);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
channel->SetOwner(owner);
|
|
||||||
channel->SetOriginalURI(uri);
|
|
||||||
channel->SetContentType(NS_ConvertUTF16toUTF8(type));
|
|
||||||
channel->SetContentLength(size);
|
|
||||||
|
|
||||||
channel.forget(result);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
nsBlobProtocolHandler::AllowPort(int32_t port, const char *scheme,
|
|
||||||
bool *_retval)
|
|
||||||
{
|
|
||||||
// don't override anything.
|
|
||||||
*_retval = false;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs");
|
|
||||||
|
|
||||||
*aStream = nullptr;
|
|
||||||
|
|
||||||
nsCString spec;
|
|
||||||
aURI->GetSpec(spec);
|
|
||||||
|
|
||||||
FileDataInfo* info =
|
|
||||||
GetFileDataInfo(spec);
|
|
||||||
|
|
||||||
if (!info) {
|
|
||||||
return NS_ERROR_DOM_BAD_URI;
|
|
||||||
}
|
|
||||||
|
|
||||||
return info->mFile->GetInternalStream(aStream);
|
|
||||||
}
|
|
@ -27,7 +27,7 @@
|
|||||||
#include "nsNetCID.h"
|
#include "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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
|
264
content/base/src/nsHostObjectProtocolHandler.cpp
Normal file
264
content/base/src/nsHostObjectProtocolHandler.cpp
Normal file
@ -0,0 +1,264 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "nsHostObjectProtocolHandler.h"
|
||||||
|
#include "nsHostObjectURI.h"
|
||||||
|
#include "nsError.h"
|
||||||
|
#include "nsClassHashtable.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
|
#include "nsIPrincipal.h"
|
||||||
|
#include "nsIDOMFile.h"
|
||||||
|
#include "nsIDOMMediaStream.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Hash table
|
||||||
|
struct DataInfo
|
||||||
|
{
|
||||||
|
// mObject must be an nsIDOMBlob or an nsIDOMMediaStream
|
||||||
|
nsCOMPtr<nsISupports> mObject;
|
||||||
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
|
};
|
||||||
|
|
||||||
|
static nsClassHashtable<nsCStringHashKey, DataInfo>* gDataTable;
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsHostObjectProtocolHandler::AddDataEntry(const nsACString& aScheme,
|
||||||
|
nsISupports* aObject,
|
||||||
|
nsIPrincipal* aPrincipal,
|
||||||
|
nsACString& aUri)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIUUIDGenerator> uuidgen =
|
||||||
|
do_GetService("@mozilla.org/uuid-generator;1", &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsID id;
|
||||||
|
rv = uuidgen->GenerateUUIDInPlace(&id);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
char chars[NSID_LENGTH];
|
||||||
|
id.ToProvidedString(chars);
|
||||||
|
|
||||||
|
aUri += aScheme;
|
||||||
|
aUri += NS_LITERAL_CSTRING(":");
|
||||||
|
aUri += Substring(chars + 1, chars + NSID_LENGTH - 2);
|
||||||
|
|
||||||
|
if (!gDataTable) {
|
||||||
|
gDataTable = new nsClassHashtable<nsCStringHashKey, DataInfo>;
|
||||||
|
gDataTable->Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
DataInfo* info = new DataInfo;
|
||||||
|
|
||||||
|
info->mObject = aObject;
|
||||||
|
info->mPrincipal = aPrincipal;
|
||||||
|
|
||||||
|
gDataTable->Put(aUri, info);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsHostObjectProtocolHandler::RemoveDataEntry(const nsACString& aUri)
|
||||||
|
{
|
||||||
|
if (gDataTable) {
|
||||||
|
gDataTable->Remove(aUri);
|
||||||
|
if (gDataTable->Count() == 0) {
|
||||||
|
delete gDataTable;
|
||||||
|
gDataTable = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIPrincipal*
|
||||||
|
nsHostObjectProtocolHandler::GetDataEntryPrincipal(const nsACString& aUri)
|
||||||
|
{
|
||||||
|
if (!gDataTable) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataInfo* res;
|
||||||
|
gDataTable->Get(aUri, &res);
|
||||||
|
if (!res) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res->mPrincipal;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DataInfo*
|
||||||
|
GetDataInfo(const nsACString& aUri)
|
||||||
|
{
|
||||||
|
if (!gDataTable) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataInfo* res;
|
||||||
|
gDataTable->Get(aUri, &res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsISupports*
|
||||||
|
GetDataObject(nsIURI* aURI)
|
||||||
|
{
|
||||||
|
nsCString spec;
|
||||||
|
aURI->GetSpec(spec);
|
||||||
|
|
||||||
|
DataInfo* info = GetDataInfo(spec);
|
||||||
|
return info ? info->mObject : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// Protocol handler
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsHostObjectProtocolHandler, nsIProtocolHandler)
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHostObjectProtocolHandler::GetDefaultPort(int32_t *result)
|
||||||
|
{
|
||||||
|
*result = -1;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHostObjectProtocolHandler::GetProtocolFlags(uint32_t *result)
|
||||||
|
{
|
||||||
|
*result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS |
|
||||||
|
URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec,
|
||||||
|
const char *aCharset,
|
||||||
|
nsIURI *aBaseURI,
|
||||||
|
nsIURI **aResult)
|
||||||
|
{
|
||||||
|
*aResult = nullptr;
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
DataInfo* info = GetDataInfo(aSpec);
|
||||||
|
|
||||||
|
nsRefPtr<nsHostObjectURI> uri =
|
||||||
|
new nsHostObjectURI(info ? info->mPrincipal.get() : nullptr);
|
||||||
|
|
||||||
|
rv = uri->SetSpec(aSpec);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
NS_TryToSetImmutable(uri);
|
||||||
|
uri.forget(aResult);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
|
||||||
|
{
|
||||||
|
*result = nullptr;
|
||||||
|
|
||||||
|
nsCString spec;
|
||||||
|
uri->GetSpec(spec);
|
||||||
|
|
||||||
|
DataInfo* info = GetDataInfo(spec);
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
return NS_ERROR_DOM_BAD_URI;
|
||||||
|
}
|
||||||
|
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(info->mObject);
|
||||||
|
if (!blob) {
|
||||||
|
return NS_ERROR_DOM_BAD_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
|
||||||
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
|
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||||
|
NS_ASSERTION(info->mPrincipal == principal, "Wrong principal!");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> stream;
|
||||||
|
nsresult rv = blob->GetInternalStream(getter_AddRefs(stream));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIChannel> channel;
|
||||||
|
rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
|
||||||
|
uri,
|
||||||
|
stream);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
|
||||||
|
|
||||||
|
nsAutoString type;
|
||||||
|
rv = blob->GetType(type);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
uint64_t size;
|
||||||
|
rv = blob->GetSize(&size);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
channel->SetOwner(owner);
|
||||||
|
channel->SetOriginalURI(uri);
|
||||||
|
channel->SetContentType(NS_ConvertUTF16toUTF8(type));
|
||||||
|
channel->SetContentLength(size);
|
||||||
|
|
||||||
|
channel.forget(result);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsHostObjectProtocolHandler::AllowPort(int32_t port, const char *scheme,
|
||||||
|
bool *_retval)
|
||||||
|
{
|
||||||
|
// don't override anything.
|
||||||
|
*_retval = false;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsBlobProtocolHandler::GetScheme(nsACString &result)
|
||||||
|
{
|
||||||
|
result.AssignLiteral(BLOBURI_SCHEME);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsMediaStreamProtocolHandler::GetScheme(nsACString &result)
|
||||||
|
{
|
||||||
|
result.AssignLiteral(MEDIASTREAMURI_SCHEME);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs");
|
||||||
|
|
||||||
|
*aStream = nullptr;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(GetDataObject(aURI));
|
||||||
|
if (!blob) {
|
||||||
|
return NS_ERROR_DOM_BAD_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return blob->GetInternalStream(aStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(IsMediaStreamURI(aURI), "Only call this with mediastream URIs");
|
||||||
|
|
||||||
|
*aStream = nullptr;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIDOMMediaStream> stream = do_QueryInterface(GetDataObject(aURI));
|
||||||
|
if (!stream) {
|
||||||
|
return NS_ERROR_DOM_BAD_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
*aStream = stream;
|
||||||
|
NS_ADDREF(*aStream);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
@ -2,24 +2,24 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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;
|
||||||
}
|
}
|
@ -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 */
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test that a MediaStream captured from one element plays back in another</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
<script type="text/javascript" src="manifest.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
var manager = new MediaTestManager;
|
||||||
|
|
||||||
|
function checkDrawImage(vout) {
|
||||||
|
var canvas = document.createElement("canvas");
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.drawImage(vout, 0, 0);
|
||||||
|
var imgData = ctx.getImageData(0, 0, 1, 1);
|
||||||
|
is(imgData.data[3], 255, "Check video frame pixel has been drawn");
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTest(test, token) {
|
||||||
|
manager.started(token);
|
||||||
|
|
||||||
|
var v = document.createElement('video');
|
||||||
|
var vout = document.createElement('video');
|
||||||
|
vout.token = token;
|
||||||
|
|
||||||
|
v.src = test.name;
|
||||||
|
var stream = v.mozCaptureStreamUntilEnded();
|
||||||
|
is(stream.currentTime, 0, test.name + " stream initial currentTime");
|
||||||
|
vout.src = URL.createObjectURL(stream);
|
||||||
|
|
||||||
|
var checkEnded = function(test, vout, stream) { return function() {
|
||||||
|
is(stream.currentTime, vout.currentTime, test.name + " stream final currentTime");
|
||||||
|
if (test.duration) {
|
||||||
|
ok(Math.abs(vout.currentTime - test.duration) < 0.1,
|
||||||
|
test.name + " current time at end: " + vout.currentTime + " should be: " + test.duration);
|
||||||
|
}
|
||||||
|
is(vout.readyState, vout.HAVE_CURRENT_DATA, test.name + " checking readyState");
|
||||||
|
ok(vout.ended, test.name + " checking playback has ended");
|
||||||
|
if (test.type.match(/^video/)) {
|
||||||
|
checkDrawImage(vout);
|
||||||
|
}
|
||||||
|
vout.parentNode.removeChild(vout);
|
||||||
|
URL.revokeObjectURL(vout.src);
|
||||||
|
manager.finished(vout.token);
|
||||||
|
}}(test, vout, stream);
|
||||||
|
vout.addEventListener("ended", checkEnded, false);
|
||||||
|
|
||||||
|
document.body.appendChild(vout);
|
||||||
|
v.play();
|
||||||
|
vout.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.runTests([getPlayableVideo(gSmallTests)], startTest);
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -17,6 +17,7 @@
|
|||||||
#include "PannerNode.h"
|
#include "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()
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
57
content/media/webaudio/BiquadFilterNode.cpp
Normal file
57
content/media/webaudio/BiquadFilterNode.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "BiquadFilterNode.h"
|
||||||
|
#include "mozilla/dom/BiquadFilterNodeBinding.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_CLASS(BiquadFilterNode)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BiquadFilterNode, AudioNode)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFrequency)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mQ)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mGain)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BiquadFilterNode, AudioNode)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mFrequency, AudioParam, "frequency value")
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mQ, AudioParam, "Q value")
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(tmp->mGain, AudioParam, "gain value")
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BiquadFilterNode)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(AudioNode)
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(BiquadFilterNode, AudioNode)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(BiquadFilterNode, AudioNode)
|
||||||
|
|
||||||
|
static float
|
||||||
|
Nyquist(AudioContext* aContext)
|
||||||
|
{
|
||||||
|
// TODO: Replace the hardcoded 44100 here with AudioContext::SampleRate()
|
||||||
|
// when we implement that.
|
||||||
|
return 0.5f * 44100;
|
||||||
|
}
|
||||||
|
|
||||||
|
BiquadFilterNode::BiquadFilterNode(AudioContext* aContext)
|
||||||
|
: AudioNode(aContext)
|
||||||
|
, mType(BiquadTypeEnum::LOWPASS)
|
||||||
|
, mFrequency(new AudioParam(aContext, 350.f, 10.f, Nyquist(aContext)))
|
||||||
|
, mQ(new AudioParam(aContext, 1.f, 0.0001f, 1000.f))
|
||||||
|
, mGain(new AudioParam(aContext, 0.f, -40.f, 40.f))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
JSObject*
|
||||||
|
BiquadFilterNode::WrapObject(JSContext* aCx, JSObject* aScope,
|
||||||
|
bool* aTriedToWrap)
|
||||||
|
{
|
||||||
|
return BiquadFilterNodeBinding::Wrap(aCx, aScope, this, aTriedToWrap);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
92
content/media/webaudio/BiquadFilterNode.h
Normal file
92
content/media/webaudio/BiquadFilterNode.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef BiquadFilterNode_h_
|
||||||
|
#define BiquadFilterNode_h_
|
||||||
|
|
||||||
|
#include "AudioNode.h"
|
||||||
|
#include "AudioParam.h"
|
||||||
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/ErrorResult.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class AudioContext;
|
||||||
|
|
||||||
|
MOZ_BEGIN_ENUM_CLASS(BiquadTypeEnum, uint16_t)
|
||||||
|
LOWPASS = 0,
|
||||||
|
HIGHPASS = 1,
|
||||||
|
BANDPASS = 2,
|
||||||
|
LOWSHELF = 3,
|
||||||
|
HIGHSHELF = 4,
|
||||||
|
PEAKING = 5,
|
||||||
|
NOTCH = 6,
|
||||||
|
ALLPASS = 7,
|
||||||
|
Max = 7
|
||||||
|
MOZ_END_ENUM_CLASS(BiquadTypeEnum)
|
||||||
|
|
||||||
|
class BiquadFilterNode : public AudioNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit BiquadFilterNode(AudioContext* aContext);
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BiquadFilterNode, AudioNode)
|
||||||
|
|
||||||
|
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
|
||||||
|
bool* aTriedToWrap);
|
||||||
|
|
||||||
|
virtual uint32_t MaxNumberOfInputs() const MOZ_FINAL MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
virtual uint32_t MaxNumberOfOutputs() const MOZ_FINAL MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Type() const
|
||||||
|
{
|
||||||
|
return static_cast<uint16_t> (mType);
|
||||||
|
}
|
||||||
|
void SetType(uint16_t aType, ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
BiquadTypeEnum type = static_cast<BiquadTypeEnum> (aType);
|
||||||
|
if (type > BiquadTypeEnum::Max) {
|
||||||
|
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
|
} else {
|
||||||
|
mType = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioParam* Frequency() const
|
||||||
|
{
|
||||||
|
return mFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioParam* Q() const
|
||||||
|
{
|
||||||
|
return mQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioParam* Gain() const
|
||||||
|
{
|
||||||
|
return mGain;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BiquadTypeEnum mType;
|
||||||
|
nsRefPtr<AudioParam> mFrequency;
|
||||||
|
nsRefPtr<AudioParam> mQ;
|
||||||
|
nsRefPtr<AudioParam> mGain;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -23,6 +23,7 @@ CPPSRCS := \
|
|||||||
AudioNode.cpp \
|
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 \
|
||||||
|
@ -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 \
|
||||||
|
@ -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);
|
||||||
|
73
content/media/webaudio/test/test_biquadFilterNode.html
Normal file
73
content/media/webaudio/test/test_biquadFilterNode.html
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Test BiquadFilterNode</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<pre id="test">
|
||||||
|
<script src="webaudio.js" type="text/javascript"></script>
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
|
function near(a, b, msg) {
|
||||||
|
ok(Math.abs(a - b) < 1e-3, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
addLoadEvent(function() {
|
||||||
|
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
|
||||||
|
|
||||||
|
var context = new mozAudioContext();
|
||||||
|
var buffer = context.createBuffer(1, 2048, 44100);
|
||||||
|
for (var i = 0; i < 2048; ++i) {
|
||||||
|
buffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / 44100);
|
||||||
|
}
|
||||||
|
|
||||||
|
var destination = context.destination;
|
||||||
|
|
||||||
|
var source = context.createBufferSource();
|
||||||
|
|
||||||
|
var filter = context.createBiquadFilter();
|
||||||
|
|
||||||
|
source.buffer = buffer;
|
||||||
|
|
||||||
|
source.connect(filter);
|
||||||
|
filter.connect(destination);
|
||||||
|
|
||||||
|
// Verify default values
|
||||||
|
is(filter.type, 0, "Correct default value for type");
|
||||||
|
near(filter.frequency.minValue, 10, "Correct min value for filter frequency");
|
||||||
|
near(filter.frequency.maxValue, 22050, "Correct max value for filter frequency");
|
||||||
|
near(filter.frequency.defaultValue, 350, "Correct default value for filter frequency");
|
||||||
|
near(filter.Q.minValue, 0.001, "Correct min value for filter Q");
|
||||||
|
near(filter.Q.maxValue, 1000, "Correct max value for filter Q");
|
||||||
|
near(filter.Q.defaultValue, 1, "Correct default value for filter Q");
|
||||||
|
near(filter.gain.minValue, -40, "Correct min value for filter gain");
|
||||||
|
near(filter.gain.maxValue, 40, "Correct max value for filter gain");
|
||||||
|
near(filter.gain.defaultValue, 0, "Correct default value for filter gain");
|
||||||
|
|
||||||
|
// Make sure that we can set all of the valid type values
|
||||||
|
for (var i = 0; i <= 7; ++i) {
|
||||||
|
filter.type = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
expectException(function() {
|
||||||
|
filter.type = 8;
|
||||||
|
}, DOMException.INDEX_SIZE_ERR);
|
||||||
|
|
||||||
|
source.start(0);
|
||||||
|
SimpleTest.executeSoon(function() {
|
||||||
|
source.stop(0);
|
||||||
|
source.disconnect();
|
||||||
|
filter.disconnect();
|
||||||
|
|
||||||
|
SpecialPowers.clearUserPref("media.webaudio.enabled");
|
||||||
|
SimpleTest.finish();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
14
content/media/webaudio/test/webaudio.js
Normal file
14
content/media/webaudio/test/webaudio.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Helpers for Web Audio tests
|
||||||
|
|
||||||
|
function expectException(func, exceptionCode) {
|
||||||
|
var threw = false;
|
||||||
|
try {
|
||||||
|
func();
|
||||||
|
} catch (ex) {
|
||||||
|
threw = true;
|
||||||
|
ok(ex instanceof DOMException, "Expect a DOM exception");
|
||||||
|
ok(ex.code, exceptionCode, "Expect the correct exception code");
|
||||||
|
}
|
||||||
|
ok(threw, "The exception was thrown");
|
||||||
|
}
|
||||||
|
|
@ -84,6 +84,7 @@ EXPORTS_mozilla/dom = \
|
|||||||
DOMRequest.h \
|
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
101
dom/base/URL.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "URL.h"
|
||||||
|
|
||||||
|
#include "nsGlobalWindow.h"
|
||||||
|
#include "nsIDOMFile.h"
|
||||||
|
#include "nsIDOMMediaStream.h"
|
||||||
|
#include "nsIDocument.h"
|
||||||
|
#include "nsIPrincipal.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsHostObjectProtocolHandler.h"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
void
|
||||||
|
URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob,
|
||||||
|
const objectURLOptions& aOptions,
|
||||||
|
nsAString& aResult,
|
||||||
|
ErrorResult& aError)
|
||||||
|
{
|
||||||
|
CreateObjectURLInternal(aGlobal, aBlob, NS_LITERAL_CSTRING(BLOBURI_SCHEME),
|
||||||
|
aOptions, aResult, aError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
URL::CreateObjectURL(nsISupports* aGlobal, nsIDOMMediaStream* aStream,
|
||||||
|
const mozilla::dom::objectURLOptions& aOptions,
|
||||||
|
nsAString& aResult,
|
||||||
|
ErrorResult& aError)
|
||||||
|
{
|
||||||
|
CreateObjectURLInternal(aGlobal, aStream, NS_LITERAL_CSTRING(MEDIASTREAMURI_SCHEME),
|
||||||
|
aOptions, aResult, aError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
URL::CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
|
||||||
|
const nsACString& aScheme,
|
||||||
|
const mozilla::dom::objectURLOptions& aOptions,
|
||||||
|
nsAString& aResult,
|
||||||
|
ErrorResult& aError)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal);
|
||||||
|
nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
|
||||||
|
NS_PRECONDITION(!window || window->IsInnerWindow(),
|
||||||
|
"Should be inner window");
|
||||||
|
|
||||||
|
if (!window || !window->GetExtantDoc()) {
|
||||||
|
aError.Throw(NS_ERROR_INVALID_POINTER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIDocument* doc = window->GetExtantDoc();
|
||||||
|
|
||||||
|
nsCString url;
|
||||||
|
nsresult rv = nsHostObjectProtocolHandler::AddDataEntry(aScheme, aObject,
|
||||||
|
doc->NodePrincipal(), url);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
aError.Throw(rv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
doc->RegisterHostObjectUri(url);
|
||||||
|
CopyASCIItoUTF16(url, aResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
URL::RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL)
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsPIDOMWindow> w = do_QueryInterface(aGlobal);
|
||||||
|
nsGlobalWindow* window = static_cast<nsGlobalWindow*>(w.get());
|
||||||
|
NS_PRECONDITION(!window || window->IsInnerWindow(),
|
||||||
|
"Should be inner window");
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
NS_LossyConvertUTF16toASCII asciiurl(aURL);
|
||||||
|
|
||||||
|
nsIPrincipal* winPrincipal = window->GetPrincipal();
|
||||||
|
if (!winPrincipal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIPrincipal* principal =
|
||||||
|
nsHostObjectProtocolHandler::GetDataEntryPrincipal(asciiurl);
|
||||||
|
bool subsumes;
|
||||||
|
if (principal && winPrincipal &&
|
||||||
|
NS_SUCCEEDED(winPrincipal->Subsumes(principal, &subsumes)) &&
|
||||||
|
subsumes) {
|
||||||
|
if (window->GetExtantDoc()) {
|
||||||
|
window->GetExtantDoc()->UnregisterHostObjectUri(asciiurl);
|
||||||
|
}
|
||||||
|
nsHostObjectProtocolHandler::RemoveDataEntry(asciiurl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
42
dom/base/URL.h
Normal file
42
dom/base/URL.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#ifndef URL_h___
|
||||||
|
#define URL_h___
|
||||||
|
|
||||||
|
#include "nscore.h"
|
||||||
|
#include "mozilla/dom/URLBinding.h"
|
||||||
|
|
||||||
|
class nsIDOMBlob;
|
||||||
|
class nsIDOMMediaStream;
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
class URL MOZ_FINAL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// WebIDL methods
|
||||||
|
static void CreateObjectURL(nsISupports* aGlobal, nsIDOMBlob* aBlob,
|
||||||
|
const objectURLOptions& aOptions,
|
||||||
|
nsAString& aResult,
|
||||||
|
ErrorResult& aError);
|
||||||
|
static void CreateObjectURL(nsISupports* aGlobal, nsIDOMMediaStream* aStream,
|
||||||
|
const mozilla::dom::objectURLOptions& aOptions,
|
||||||
|
nsAString& aResult,
|
||||||
|
mozilla::ErrorResult& aError);
|
||||||
|
static void RevokeObjectURL(nsISupports* aGlobal, const nsAString& aURL);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
|
||||||
|
const nsACString& aScheme,
|
||||||
|
const mozilla::dom::objectURLOptions& aOptions,
|
||||||
|
nsAString& aResult,
|
||||||
|
mozilla::ErrorResult& aError);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* URL_h___ */
|
@ -1434,8 +1434,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
|||||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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',
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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>
|
||||||
|
@ -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();
|
||||||
|
@ -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 {};
|
||||||
|
@ -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))
|
||||||
|
14
dom/tests/mochitest/bugs/file_bug809290_b1.html
Normal file
14
dom/tests/mochitest/bugs/file_bug809290_b1.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
function innerLoad() {
|
||||||
|
var win = document.getElementById('ifr').contentWindow;
|
||||||
|
win.location = "file_bug809290_c.html";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<iframe id="ifr" src="file_empty.html">
|
||||||
|
</body>
|
||||||
|
</html>
|
14
dom/tests/mochitest/bugs/file_bug809290_b2.html
Normal file
14
dom/tests/mochitest/bugs/file_bug809290_b2.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
function eventHandlerLoad() {
|
||||||
|
var win = document.getElementById('ifr').contentWindow;
|
||||||
|
win.location = "file_bug809290_c.html";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="eventHandlerLoad();">
|
||||||
|
<iframe id="ifr" src="file_empty.html">
|
||||||
|
</body>
|
||||||
|
</html>
|
10
dom/tests/mochitest/bugs/file_bug809290_c.html
Normal file
10
dom/tests/mochitest/bugs/file_bug809290_c.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
window.parent.parent.notifyReferrer(document.referrer);
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
2
dom/tests/mochitest/bugs/file_empty.html
Normal file
2
dom/tests/mochitest/bugs/file_empty.html
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html><head></head><body></body></html>
|
@ -56,8 +56,15 @@ function iframeLoaded(identifier) {
|
|||||||
is(iframeCw.getInnerIframeReferrer(), iframeCw.location, 'inner iframe referrer');
|
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());
|
||||||
|
48
dom/tests/mochitest/bugs/test_bug809290.html
Normal file
48
dom/tests/mochitest/bugs/test_bug809290.html
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=809290
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for Bug 809290</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=809290">Mozilla Bug 809290</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
/** Test for Bug 809290 **/
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
var gNotifyCount = 0;
|
||||||
|
function notifyReferrer(referrer) {
|
||||||
|
++gNotifyCount;
|
||||||
|
if (gNotifyCount == 1) {
|
||||||
|
is(referrer, window.location.href, "Referrer should be the script entry point (this script)");
|
||||||
|
document.getElementById('ifr').setAttribute('src', 'file_bug809290_b2.html');
|
||||||
|
} else {
|
||||||
|
is(gNotifyCount, 2);
|
||||||
|
is(referrer, window.location.href.replace(/test_bug.*/, 'file_bug809290_b2.html'),
|
||||||
|
"Referrer should be the script entry point (iframe)");
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function go() {
|
||||||
|
var ifr = document.getElementById('ifr');
|
||||||
|
ifr.onload = null;
|
||||||
|
ifr.contentWindow.innerLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
<iframe id="ifr" src="file_bug809290_b1.html" onload="go();"></iframe>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -207,8 +207,6 @@ var interfaceNamesInGlobalScope =
|
|||||||
"SVGAltGlyphElement",
|
"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",
|
||||||
|
@ -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]
|
||||||
|
37
dom/webidl/BiquadFilterNode.webidl
Normal file
37
dom/webidl/BiquadFilterNode.webidl
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* The origin of this IDL file is
|
||||||
|
* https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
|
||||||
|
*
|
||||||
|
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||||
|
* liability, trademark and document use rules apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[PrefControlled]
|
||||||
|
interface BiquadFilterNode : AudioNode {
|
||||||
|
|
||||||
|
// Filter type.
|
||||||
|
const unsigned short LOWPASS = 0;
|
||||||
|
const unsigned short HIGHPASS = 1;
|
||||||
|
const unsigned short BANDPASS = 2;
|
||||||
|
const unsigned short LOWSHELF = 3;
|
||||||
|
const unsigned short HIGHSHELF = 4;
|
||||||
|
const unsigned short PEAKING = 5;
|
||||||
|
const unsigned short NOTCH = 6;
|
||||||
|
const unsigned short ALLPASS = 7;
|
||||||
|
|
||||||
|
[SetterThrows]
|
||||||
|
attribute unsigned short type;
|
||||||
|
readonly attribute AudioParam frequency; // in Hertz
|
||||||
|
readonly attribute AudioParam Q; // Quality factor
|
||||||
|
readonly attribute AudioParam gain; // in Decibels
|
||||||
|
|
||||||
|
// void getFrequencyResponse(Float32Array frequencyHz,
|
||||||
|
// Float32Array magResponse,
|
||||||
|
// Float32Array phaseResponse);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
27
dom/webidl/URL.webidl
Normal file
27
dom/webidl/URL.webidl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* The origins of this IDL file are
|
||||||
|
* http://dev.w3.org/2006/webapi/FileAPI/#creating-revoking
|
||||||
|
* http://dev.w3.org/2011/webrtc/editor/getusermedia.html#url
|
||||||
|
*
|
||||||
|
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
|
||||||
|
* liability, trademark and document use rules apply.
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface MediaStream;
|
||||||
|
|
||||||
|
interface URL {
|
||||||
|
[Throws]
|
||||||
|
static DOMString? createObjectURL(Blob blob, optional objectURLOptions options);
|
||||||
|
[Throws]
|
||||||
|
static DOMString? createObjectURL(MediaStream stream, optional objectURLOptions options);
|
||||||
|
static void revokeObjectURL(DOMString url);
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary objectURLOptions
|
||||||
|
{
|
||||||
|
/* boolean autoRevoke = true; */ /* not supported yet */
|
||||||
|
};
|
@ -17,6 +17,7 @@ webidl_files = \
|
|||||||
AudioNode.webidl \
|
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 \
|
||||||
|
@ -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));
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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())
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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"))
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
19
js/src/jit-test/tests/ion/bug809472.js
Normal file
19
js/src/jit-test/tests/ion/bug809472.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
function test1(x) {
|
||||||
|
return (x*((2<<23)-1))|0
|
||||||
|
}
|
||||||
|
function test2(x) {
|
||||||
|
return (x*((2<<22)-1))|0
|
||||||
|
}
|
||||||
|
function test3(x) {
|
||||||
|
return (x*((2<<21)-1))|0
|
||||||
|
}
|
||||||
|
function test4(x) {
|
||||||
|
var b = x + x + 3
|
||||||
|
return (b*b) | 0
|
||||||
|
}
|
||||||
|
//MAX_INT
|
||||||
|
var x = 0x7ffffffe;
|
||||||
|
assertEq(test1(x), 2113929216);
|
||||||
|
assertEq(test2(x), 2130706434);
|
||||||
|
assertEq(test3(x), 2139095042);
|
||||||
|
assertEq(test4(x), 0);
|
3
js/src/jit-test/tests/proxy/testBug793160.js
Normal file
3
js/src/jit-test/tests/proxy/testBug793160.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
var obj = new Proxy(Object.create(null), {});
|
||||||
|
assertEq(typeof obj, 'object');
|
||||||
|
assertEq(obj != null, true);
|
@ -3156,9 +3156,12 @@ proxy(JSContext *cx, unsigned argc, jsval *vp)
|
|||||||
RootedObject proto(cx);
|
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;
|
||||||
|
@ -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)) {
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
42
js/xpconnect/tests/mochitest/test_bug809547.html
Normal file
42
js/xpconnect/tests/mochitest/test_bug809547.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=809547
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for Bug 809547</title>
|
||||||
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||||
|
</head>
|
||||||
|
<body onload="go()">
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=809547">Mozilla Bug 809547</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script type="application/javascript">
|
||||||
|
|
||||||
|
/** Test for Bug 809547 **/
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
var gObj = {};
|
||||||
|
function go() {
|
||||||
|
window.location.expando = gObj;
|
||||||
|
is(window.location.expando, gObj, "Expando appears");
|
||||||
|
SimpleTest.executeSoon(finish);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finish() {
|
||||||
|
SpecialPowers.forceGC();
|
||||||
|
SpecialPowers.forceCC();
|
||||||
|
SpecialPowers.forceGC();
|
||||||
|
SpecialPowers.forceCC();
|
||||||
|
is(window.location.expando, gObj, "Expando preserved");
|
||||||
|
SimpleTest.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -80,8 +80,8 @@
|
|||||||
#include "ArchiveReader.h"
|
#include "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 },
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
<html class="reftest-wait">
|
||||||
|
<head>
|
||||||
|
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=685012">
|
||||||
|
<link rel="help" href="http://www.w3.org/TR/CSS21/page.html#propdef-page-break-inside">
|
||||||
|
<meta name="flags" content="paged">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Balancing Overflow, page-break-inside:avoid</title>
|
||||||
|
<style>
|
||||||
|
/* Sets of heights that trigger crash:
|
||||||
|
100px/50px/51+px
|
||||||
|
100px/30px/74+px
|
||||||
|
Get only an assert unless you set ".d { position: absolute; }".
|
||||||
|
|
||||||
|
Trigger hang (separate issue, absolute not needed):
|
||||||
|
10px/10px/9999px
|
||||||
|
10px/10px/999999px --> "bad height" notreached
|
||||||
|
*/
|
||||||
|
/* Note: The -moz-column-gap and the backgrounds
|
||||||
|
are just added here for easier visualization */
|
||||||
|
#colset { width: 200px;
|
||||||
|
padding: 2px;
|
||||||
|
-moz-column-count: 3;
|
||||||
|
-moz-column-gap: 2px; }
|
||||||
|
#a { height: 100px; background: lightblue;}
|
||||||
|
#b { height: 50px; background: lightblue;}
|
||||||
|
#c { height: 51px; background: orange;}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function boom() {
|
||||||
|
document.getElementById('colset').offsetHeight;
|
||||||
|
document.getElementById('a').style.height = 'auto';
|
||||||
|
document.documentElement.className = ''
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<!-- Removing whitespace in body for simpler frame trees -->
|
||||||
|
<body onload="boom()"
|
||||||
|
><div id="colset"
|
||||||
|
><div
|
||||||
|
><div id="a"></div
|
||||||
|
><div id="b"
|
||||||
|
><div id="c"></div
|
||||||
|
><div id="d"></div
|
||||||
|
></div
|
||||||
|
></div
|
||||||
|
></div
|
||||||
|
></body>
|
||||||
|
</html>
|
@ -0,0 +1,49 @@
|
|||||||
|
<html class="reftest-wait">
|
||||||
|
<head>
|
||||||
|
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=685012">
|
||||||
|
<link rel="help" href="http://www.w3.org/TR/CSS21/page.html#propdef-page-break-inside">
|
||||||
|
<meta name="flags" content="paged">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Balancing Overflow, page-break-inside:avoid</title>
|
||||||
|
<style>
|
||||||
|
/* Sets of heights that trigger crash:
|
||||||
|
100px/50px/51+px
|
||||||
|
100px/30px/74+px
|
||||||
|
Get only an assert unless you set ".d { position: absolute; }".
|
||||||
|
|
||||||
|
Trigger hang (separate issue, absolute not needed):
|
||||||
|
10px/10px/9999px
|
||||||
|
10px/10px/999999px --> "bad height" notreached
|
||||||
|
*/
|
||||||
|
/* Note: The -moz-column-gap and the backgrounds
|
||||||
|
are just added here for easier visualization */
|
||||||
|
#colset { width: 200px;
|
||||||
|
padding: 2px;
|
||||||
|
-moz-column-count: 3;
|
||||||
|
-moz-column-gap: 2px; }
|
||||||
|
#a { height: 100px; background: lightblue;}
|
||||||
|
#b { height: 50px; background: lightblue;}
|
||||||
|
#c { height: 51px; background: orange;}
|
||||||
|
div {page-break-inside:avoid; }
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
function boom() {
|
||||||
|
document.getElementById('colset').offsetHeight;
|
||||||
|
document.getElementById('a').style.height = 'auto';
|
||||||
|
document.documentElement.className = ''
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<!-- Removing whitespace in body for simpler frame trees -->
|
||||||
|
<body onload="boom()"
|
||||||
|
><div id="colset"
|
||||||
|
><div
|
||||||
|
><div id="a"></div
|
||||||
|
><div id="b"
|
||||||
|
><div id="c"></div
|
||||||
|
><div id="d"></div
|
||||||
|
></div
|
||||||
|
></div
|
||||||
|
></div
|
||||||
|
></body>
|
||||||
|
</html>
|
@ -1,3 +1,5 @@
|
|||||||
|
# For more pagination tests, see layout/reftests/w3c-css/submitted/css21/pagination/
|
||||||
|
# and layout/reftests/w3c-css/submitted/multicol3/
|
||||||
# Pagination tests
|
# 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
Loading…
Reference in New Issue
Block a user