зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
a6cd041140
|
@ -11,10 +11,6 @@
|
|||
-> Dwell (x)
|
||||
-> Swipe (x)
|
||||
|
||||
AndroidTap -> TripleTap (x)
|
||||
-> TapHold (x)
|
||||
-> Swipe (x)
|
||||
|
||||
DoubleTap -> TripleTap (x)
|
||||
-> TapHold (x)
|
||||
-> Explore (x)
|
||||
|
@ -77,12 +73,6 @@ const TAP_MAX_RADIUS = 0.2;
|
|||
// Directness coefficient. It is based on the maximum 15 degree angle between
|
||||
// consequent pointer move lines.
|
||||
const DIRECTNESS_COEFF = 1.44;
|
||||
// An android flag.
|
||||
const IS_ANDROID = Utils.MozBuildApp === 'mobile/android' &&
|
||||
Utils.AndroidSdkVersion >= 14;
|
||||
// A single pointer down/up sequence periodically precedes the tripple swipe
|
||||
// gesture on Android. This delay acounts for that.
|
||||
const ANDROID_TRIPLE_SWIPE_DELAY = 50;
|
||||
// The virtual touch ID generated by a mouse event.
|
||||
const MOUSE_ID = 'mouse';
|
||||
// Amount in inches from the edges of the screen for it to be an edge swipe
|
||||
|
@ -211,12 +201,6 @@ this.GestureTracker = { // jshint ignore:line
|
|||
}
|
||||
let points = aDetail.points;
|
||||
let GestureConstructor = aGesture;
|
||||
if (IS_ANDROID && GestureConstructor === Tap && points.length === 1 &&
|
||||
points[0].identifier !== MOUSE_ID) {
|
||||
// Handle Android events when EBT is enabled. Two finger gestures are
|
||||
// translated to one.
|
||||
GestureConstructor = AndroidTap;
|
||||
}
|
||||
this._create(GestureConstructor);
|
||||
this._update(aDetail, aTimeStamp);
|
||||
},
|
||||
|
@ -743,54 +727,6 @@ function Tap(aTimeStamp, aPoints, aLastEvent) {
|
|||
Tap.prototype = Object.create(TapGesture.prototype);
|
||||
Tap.prototype.type = 'tap';
|
||||
|
||||
/**
|
||||
* Tap (multi) gesture on Android.
|
||||
* @param {Number} aTimeStamp An original pointer event's timeStamp that started
|
||||
* the gesture resolution sequence.
|
||||
* @param {Object} aPoints An existing set of points (from previous events).
|
||||
* @param {?String} aLastEvent Last pointer event type.
|
||||
*/
|
||||
function AndroidTap(aTimeStamp, aPoints, aLastEvent) {
|
||||
// If the pointer travels, reject to Swipe. On dwell threshold reject to
|
||||
// TapHold.
|
||||
TapGesture.call(this, aTimeStamp, aPoints, aLastEvent, TapHold, Swipe, TripleTap);
|
||||
}
|
||||
AndroidTap.prototype = Object.create(TapGesture.prototype);
|
||||
// Android double taps are translated to single taps.
|
||||
AndroidTap.prototype.type = 'doubletap';
|
||||
|
||||
/**
|
||||
* Clear the pointerup handler timer in case of the 3 pointer swipe.
|
||||
*/
|
||||
AndroidTap.prototype.clearThreeFingerSwipeTimer = function AndroidTap_clearThreeFingerSwipeTimer() {
|
||||
clearTimeout(this._threeFingerSwipeTimer);
|
||||
delete this._threeFingerSwipeTimer;
|
||||
};
|
||||
|
||||
AndroidTap.prototype.pointerdown = function AndroidTap_pointerdown(aPoints, aTimeStamp) {
|
||||
this.clearThreeFingerSwipeTimer();
|
||||
TapGesture.prototype.pointerdown.call(this, aPoints, aTimeStamp);
|
||||
};
|
||||
|
||||
AndroidTap.prototype.pointermove = function AndroidTap_pointermove(aPoints) {
|
||||
this.clearThreeFingerSwipeTimer();
|
||||
this._moved = true;
|
||||
TapGesture.prototype.pointermove.call(this, aPoints);
|
||||
};
|
||||
|
||||
AndroidTap.prototype.pointerup = function AndroidTap_pointerup(aPoints) {
|
||||
if (this._moved) {
|
||||
// If there was a pointer move - handle the real gesture.
|
||||
TapGesture.prototype.pointerup.call(this, aPoints);
|
||||
} else {
|
||||
// Primptively delay the multi pointer gesture resolution, because Android
|
||||
// sometimes fires a pointerdown/poitnerup sequence before the real events.
|
||||
this._threeFingerSwipeTimer = setTimeout(() => {
|
||||
delete this._threeFingerSwipeTimer;
|
||||
TapGesture.prototype.pointerup.call(this, aPoints);
|
||||
}, ANDROID_TRIPLE_SWIPE_DELAY);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Double Tap gesture.
|
||||
|
|
|
@ -39,8 +39,14 @@ let PointerRelay = { // jshint ignore:line
|
|||
delete this._eventsOfInterest;
|
||||
|
||||
switch (Utils.widgetToolkit) {
|
||||
case 'gonk':
|
||||
case 'android':
|
||||
this._eventsOfInterest = {
|
||||
'touchstart' : true,
|
||||
'touchmove' : true,
|
||||
'touchend' : true };
|
||||
break;
|
||||
|
||||
case 'gonk':
|
||||
this._eventsOfInterest = {
|
||||
'touchstart' : true,
|
||||
'touchmove' : true,
|
||||
|
@ -117,12 +123,7 @@ let PointerRelay = { // jshint ignore:line
|
|||
|
||||
if (Utils.widgetToolkit === 'android' &&
|
||||
changedTouches.length === 1 && changedTouches[0].identifier === 1) {
|
||||
changedTouches = [{
|
||||
identifier: 0,
|
||||
screenX: changedTouches[0].screenX + 5,
|
||||
screenY: changedTouches[0].screenY + 5,
|
||||
target: changedTouches[0].target
|
||||
}, changedTouches[0]];
|
||||
return;
|
||||
}
|
||||
|
||||
if (changedTouches.length === 1 &&
|
||||
|
|
|
@ -1308,35 +1308,54 @@ AccessibleWrap::GetChildIDFor(Accessible* aAccessible)
|
|||
HWND
|
||||
AccessibleWrap::GetHWNDFor(Accessible* aAccessible)
|
||||
{
|
||||
if (aAccessible) {
|
||||
DocAccessible* document = aAccessible->Document();
|
||||
if(!document)
|
||||
return nullptr;
|
||||
if (!aAccessible) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Popup lives in own windows, use its HWND until the popup window is
|
||||
// hidden to make old JAWS versions work with collapsed comboboxes (see
|
||||
// discussion in bug 379678).
|
||||
nsIFrame* frame = aAccessible->GetFrame();
|
||||
if (frame) {
|
||||
nsIWidget* widget = frame->GetNearestWidget();
|
||||
if (widget && widget->IsVisible()) {
|
||||
nsIPresShell* shell = document->PresShell();
|
||||
nsViewManager* vm = shell->GetViewManager();
|
||||
if (vm) {
|
||||
nsCOMPtr<nsIWidget> rootWidget;
|
||||
vm->GetRootWidget(getter_AddRefs(rootWidget));
|
||||
// Make sure the accessible belongs to popup. If not then use
|
||||
// document HWND (which might be different from root widget in the
|
||||
// case of window emulation).
|
||||
if (rootWidget != widget)
|
||||
return static_cast<HWND>(widget->GetNativeData(NS_NATIVE_WINDOW));
|
||||
}
|
||||
}
|
||||
// Accessibles in child processes are said to have the HWND of the window
|
||||
// their tab is within. Popups are always in the parent process, and so
|
||||
// never proxied, which means this is basically correct.
|
||||
if (aAccessible->IsProxy()) {
|
||||
ProxyAccessible* proxy = aAccessible->Proxy();
|
||||
if (!proxy) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return static_cast<HWND>(document->GetNativeWindow());
|
||||
Accessible* outerDoc = proxy->OuterDocOfRemoteBrowser();
|
||||
NS_ASSERTION(outerDoc, "no outer doc for accessible remote tab!");
|
||||
if (!outerDoc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return GetHWNDFor(outerDoc);
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
DocAccessible* document = aAccessible->Document();
|
||||
if(!document)
|
||||
return nullptr;
|
||||
|
||||
// Popup lives in own windows, use its HWND until the popup window is
|
||||
// hidden to make old JAWS versions work with collapsed comboboxes (see
|
||||
// discussion in bug 379678).
|
||||
nsIFrame* frame = aAccessible->GetFrame();
|
||||
if (frame) {
|
||||
nsIWidget* widget = frame->GetNearestWidget();
|
||||
if (widget && widget->IsVisible()) {
|
||||
nsIPresShell* shell = document->PresShell();
|
||||
nsViewManager* vm = shell->GetViewManager();
|
||||
if (vm) {
|
||||
nsCOMPtr<nsIWidget> rootWidget;
|
||||
vm->GetRootWidget(getter_AddRefs(rootWidget));
|
||||
// Make sure the accessible belongs to popup. If not then use
|
||||
// document HWND (which might be different from root widget in the
|
||||
// case of window emulation).
|
||||
if (rootWidget != widget)
|
||||
return static_cast<HWND>(widget->GetNativeData(NS_NATIVE_WINDOW));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<HWND>(document->GetNativeWindow());
|
||||
}
|
||||
|
||||
IDispatch*
|
||||
|
|
|
@ -11,27 +11,13 @@ module.metadata = {
|
|||
const { Cc, Ci } = require('chrome');
|
||||
const system = require('../sdk/system');
|
||||
const runtime = require('../sdk/system/runtime');
|
||||
const { XPCOMUtils } = require("resource://gre/modules/XPCOMUtils.jsm");
|
||||
const oscpu = Cc["@mozilla.org/network/protocol;1?name=http"]
|
||||
.getService(Ci.nsIHttpProtocolHandler).oscpu;
|
||||
const hostname = Cc["@mozilla.org/network/dns-service;1"]
|
||||
.getService(Ci.nsIDNSService).myHostName;
|
||||
const isWindows = system.platform === 'win32';
|
||||
const endianness = ((new Uint32Array((new Uint8Array([1,2,3,4])).buffer))[0] === 0x04030201) ? 'LE' : 'BE';
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "oscpu", () => {
|
||||
try {
|
||||
return Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).oscpu;
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "hostname", () => {
|
||||
try {
|
||||
// On some platforms (Linux according to try), this service does not exist and fails.
|
||||
return Cc["@mozilla.org/network/dns-service;1"].getService(Ci.nsIDNSService).myHostName;
|
||||
} catch (e) {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Returns a path to a temp directory
|
||||
*/
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="27eb2f04e149fc2c9976d881b1b5984bbe7ee089"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="e935894ef5f27e2f04b9e929a45a958e6288a223">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "6280500a6cb8d1b178cdd163450e36d22846fbed",
|
||||
"git_revision": "758c75ee087ea3722213ea2c185cca1d952c8a29",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "dc781340a4ceea99ea5f3e1be005befeff2be31b",
|
||||
"revision": "df25432ca94953b1b9072fe01b705ebbf34478d1",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="f5d65f5b17d9766d7925aefd0486a1e526ae9bf0"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="c6cace53426b5be7e56c0fd202118009689bc707"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="6280500a6cb8d1b178cdd163450e36d22846fbed"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="758c75ee087ea3722213ea2c185cca1d952c8a29"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="e9e2923fd6cab93cf88b4b9ada82225e44fe6635"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -112,9 +112,6 @@ endif
|
|||
ifdef MOZ_SHARED_ICU
|
||||
DEFINES += -DMOZ_SHARED_ICU
|
||||
endif
|
||||
ifdef MOZ_JEMALLOC4
|
||||
DEFINES += -DMOZ_JEMALLOC4
|
||||
endif
|
||||
DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
|
||||
|
||||
ifdef MOZ_WIDGET_GTK
|
||||
|
|
|
@ -113,11 +113,6 @@
|
|||
#ifdef MOZ_SHARED_MOZGLUE
|
||||
@BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
|
||||
#endif
|
||||
#ifdef MOZ_REPLACE_MALLOC
|
||||
#ifndef MOZ_JEMALLOC4
|
||||
@BINPATH@/@DLL_PREFIX@replace_jemalloc@DLL_SUFFIX@
|
||||
#endif
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
@RESPATH@/AndroidManifest.xml
|
||||
@RESPATH@/resources.arsc
|
||||
|
@ -627,9 +622,6 @@
|
|||
@RESPATH@/components/DOMSecureElement.manifest
|
||||
@RESPATH@/components/DOMSecureElement.js
|
||||
#endif
|
||||
#ifdef MOZ_ENABLE_DBUS
|
||||
@RESPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
|
||||
#endif
|
||||
@RESPATH@/components/nsINIProcessor.manifest
|
||||
@RESPATH@/components/nsINIProcessor.js
|
||||
@RESPATH@/components/nsPrompter.manifest
|
||||
|
|
|
@ -52,6 +52,8 @@ pref("extensions.getAddons.link.url", "https://addons.mozilla.org/%LOCALE%/firef
|
|||
|
||||
// Blocklist preferences
|
||||
pref("extensions.blocklist.enabled", true);
|
||||
// OneCRL freshness checking depends on this value, so if you change it,
|
||||
// please also update security.onecrl.maximum_staleness_in_seconds.
|
||||
pref("extensions.blocklist.interval", 86400);
|
||||
// Controls what level the blocklist switches from warning about items to forcibly
|
||||
// blocking them.
|
||||
|
@ -1746,8 +1748,8 @@ pref("security.mixed_content.block_active_content", true);
|
|||
pref("security.cert_pinning.enforcement_level", 1);
|
||||
|
||||
// Required blocklist freshness for OneCRL OCSP bypass
|
||||
// (default should be at least as large as extensions.blocklist.interval)
|
||||
pref("security.onecrl.maximum_staleness_in_seconds", 0);
|
||||
// (default is 1.25x extensions.blocklist.interval, or 30 hours)
|
||||
pref("security.onecrl.maximum_staleness_in_seconds", 108000);
|
||||
|
||||
// Override the Gecko-default value of false for Firefox.
|
||||
pref("plain_text.wrap_long_lines", true);
|
||||
|
|
|
@ -2499,6 +2499,7 @@
|
|||
let modifiedAttrs = [];
|
||||
if (aOtherTab.hasAttribute("muted")) {
|
||||
aOurTab.setAttribute("muted", "true");
|
||||
ourBrowser.mute();
|
||||
modifiedAttrs.push("muted");
|
||||
}
|
||||
if (aOtherTab.hasAttribute("soundplaying")) {
|
||||
|
|
|
@ -213,6 +213,10 @@ function* test_swapped_browser(oldTab, newBrowser, isPlaying) {
|
|||
|
||||
ok(newTab.hasAttribute("muted"), "Expected the correct muted attribute on the new tab");
|
||||
is(newTab.hasAttribute("soundplaying"), isPlaying, "Expected the correct soundplaying attribute on the new tab");
|
||||
|
||||
let icon = document.getAnonymousElementByAttribute(newTab, "anonid",
|
||||
"soundplaying-icon");
|
||||
yield test_tooltip(icon, "Unmute tab", true);
|
||||
}
|
||||
|
||||
function* test_browser_swapping(tab, browser) {
|
||||
|
|
|
@ -10,8 +10,16 @@
|
|||
"filename": "clang.tar.bz2"
|
||||
},
|
||||
{
|
||||
"size": 2581027,
|
||||
"digest": "9b59abef2bd4ae3a5b792de96e1336d879c1c5b6b07382797ae1bcc299e74ddf805bc95b7bc813cf3b4586db5eb4d0f41d09b2f85f0629cf27e57a4de851129c",
|
||||
"size": 80458572,
|
||||
"digest": "e5101f9dee1e462f6cbd3897ea57eede41d23981825c7b20d91d23ab461875d54d3dfc24999aa58a31e8b01f49fb3140e05ffe5af2957ef1d1afb89fd0dfe1ad",
|
||||
"algorithm": "sha512",
|
||||
"filename": "gcc.tar.xz",
|
||||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 3008804,
|
||||
"visibility": "public",
|
||||
"digest": "ba6937f14f3d8b26dcb2d39490dee6b0a8afb60f672f5debb71d7b62c1ec52103201b4b1a3d258f945567de531384b36ddb2ce4aa73dc63d72305b11c146847c",
|
||||
"algorithm": "sha512",
|
||||
"unpack": true,
|
||||
"filename": "cctools.tar.gz"
|
||||
|
@ -30,5 +38,21 @@
|
|||
"algorithm": "sha512",
|
||||
"unpack": true,
|
||||
"filename": "sccache.tar.bz2"
|
||||
},
|
||||
{
|
||||
"size": 57060,
|
||||
"visibility": "public",
|
||||
"digest": "9649ca595f4cf088d118da26201f92cc94cda7af49c7c48112ee31cd13c83b2935b3e145de9dd78060cff2480b4c2e7ff5fb24235876956fed13c87852071998",
|
||||
"algorithm": "sha512",
|
||||
"unpack": true,
|
||||
"filename": "dmg.tar.xz"
|
||||
},
|
||||
{
|
||||
"size": 188880,
|
||||
"visibility": "public",
|
||||
"digest": "1ffddd43efb03aed897ee42035d9d8d758a8d66ab6c867599ef755e1a586768fc22011ce03698af61454920b00fe8bed08c9a681e7bd324d7f8f78c026c83943",
|
||||
"algorithm": "sha512",
|
||||
"unpack": true,
|
||||
"filename": "genisoimage.tar.xz"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -16,6 +16,7 @@ browser.jar:
|
|||
content/browser/devtools/netmonitor.css (netmonitor/netmonitor.css)
|
||||
content/browser/devtools/netmonitor-controller.js (netmonitor/netmonitor-controller.js)
|
||||
content/browser/devtools/netmonitor-view.js (netmonitor/netmonitor-view.js)
|
||||
content/browser/devtools/NetworkPanel.xhtml (webconsole/NetworkPanel.xhtml)
|
||||
content/browser/devtools/webconsole.xul (webconsole/webconsole.xul)
|
||||
* content/browser/devtools/scratchpad.xul (scratchpad/scratchpad.xul)
|
||||
content/browser/devtools/scratchpad.js (scratchpad/scratchpad.js)
|
||||
|
|
|
@ -322,37 +322,6 @@ let NetMonitorController = {
|
|||
return promise.reject(new Error("Invalid activity type"));
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the specified request in the waterfall and opens the details view.
|
||||
*
|
||||
* @param string requestId
|
||||
* The actor ID of the request to inspect.
|
||||
* @return object
|
||||
* A promise resolved once the task finishes.
|
||||
*/
|
||||
inspectRequest: function(requestId) {
|
||||
// Look for the request in the existing ones or wait for it to appear, if
|
||||
// the network monitor is still loading.
|
||||
let deferred = promise.defer();
|
||||
let request = null;
|
||||
let inspector = function() {
|
||||
let predicate = i => i.value === requestId;
|
||||
request = NetMonitorView.RequestsMenu.getItemForPredicate(predicate);
|
||||
if (request) {
|
||||
window.off(EVENTS.REQUEST_ADDED, inspector);
|
||||
NetMonitorView.RequestsMenu.filterOn("all");
|
||||
NetMonitorView.RequestsMenu.selectedItem = request;
|
||||
deferred.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
inspector();
|
||||
if (!request) {
|
||||
window.on(EVENTS.REQUEST_ADDED, inspector);
|
||||
}
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Getter that tells if the server supports sending custom network requests.
|
||||
* @type boolean
|
||||
|
|
|
@ -82,6 +82,7 @@ skip-if = os == 'linux' # bug 1186322
|
|||
[browser_perf-overview-selection-03.js]
|
||||
[browser_perf-overview-time-interval.js]
|
||||
[browser_perf-states.js]
|
||||
skip-if = os == 'linux' # bug 1203888
|
||||
[browser_perf-refresh.js]
|
||||
[browser_perf-ui-recording.js]
|
||||
skip-if = os == 'linux' # bug 1186322
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" [
|
||||
<!ENTITY % webConsoleDTD SYSTEM "chrome://browser/locale/devtools/webConsole.dtd" >
|
||||
%webConsoleDTD;
|
||||
]>
|
||||
|
||||
<!-- 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/. -->
|
||||
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" href="chrome://browser/skin/devtools/webconsole_networkpanel.css" type="text/css"/>
|
||||
</head>
|
||||
<body role="application">
|
||||
<table id="header">
|
||||
<tr>
|
||||
<th class="property-name"
|
||||
scope="row">&networkPanel.requestURLColon;</th>
|
||||
<td class="property-value"
|
||||
id="headUrl"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="property-name"
|
||||
scope="row">&networkPanel.requestMethodColon;</th>
|
||||
<td class="property-value"
|
||||
id="headMethod"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="property-name"
|
||||
scope="row">&networkPanel.statusCodeColon;</th>
|
||||
<td class="property-value"
|
||||
id="headStatus"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="group">
|
||||
<h1>
|
||||
&networkPanel.requestHeaders;
|
||||
<span id="requestHeadersInfo" class="info"></span>
|
||||
</h1>
|
||||
<table class="property-table" id="requestHeadersContent"></table>
|
||||
|
||||
<div id="requestCookie" style="display:none">
|
||||
<h1>&networkPanel.requestCookie;</h1>
|
||||
<table class="property-table" id="requestCookieContent"></table>
|
||||
</div>
|
||||
|
||||
<div id="requestBody" style="display:none">
|
||||
<h1>&networkPanel.requestBody;</h1>
|
||||
<table class="property-table" id="requestBodyContent"></table>
|
||||
</div>
|
||||
<div id="requestFormData" style="display:none">
|
||||
<h1>&networkPanel.requestFormData;</h1>
|
||||
<table class="property-table" id="requestFormDataContent"></table>
|
||||
</div>
|
||||
<p id="requestBodyFetchLink" style="display:none"></p>
|
||||
</div>
|
||||
|
||||
<div class="group" id="responseContainer" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseHeaders;
|
||||
<span id="responseHeadersInfo" class="info">Δ</span>
|
||||
</h1>
|
||||
<table class="property-table" id="responseHeadersContent"></table>
|
||||
|
||||
<div id="responseCookie" style="display:none">
|
||||
<h1>&networkPanel.responseCookie;</h1>
|
||||
<table class="property-table" id="responseCookieContent"></table>
|
||||
</div>
|
||||
|
||||
<div id="responseBody" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseBody;
|
||||
<span class="info" id="responseBodyInfo">Δ</span>
|
||||
</h1>
|
||||
<table class="property-table" id="responseBodyContent"></table>
|
||||
</div>
|
||||
<div id="responseBodyCached" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseBodyCached;
|
||||
<span class="info" id="responseBodyCachedInfo">Δ</span>
|
||||
</h1>
|
||||
<table class="property-table" id="responseBodyCachedContent"></table>
|
||||
</div>
|
||||
<div id="responseNoBody" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseNoBody;
|
||||
<span id="responseNoBodyInfo" class="info">Δ</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div id="responseBodyUnknownType" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseBodyUnknownType;
|
||||
<span id="responseBodyUnknownTypeInfo" class="info">Δ</span>
|
||||
</h1>
|
||||
<table class="property-table" id="responseBodyUnknownTypeContent"></table>
|
||||
</div>
|
||||
<div id="responseImage" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseImage;
|
||||
<span id="responseImageInfo" class="info"></span>
|
||||
</h1>
|
||||
<div id="responseImageNodeDiv">
|
||||
<img id="responseImageNode" />
|
||||
</div>
|
||||
</div>
|
||||
<div id="responseImageCached" style="display:none">
|
||||
<h1>
|
||||
&networkPanel.responseImageCached;
|
||||
<span id="responseImageCachedInfo" class="info"></span>
|
||||
</h1>
|
||||
<div id="responseImageNodeDiv">
|
||||
<img id="responseImageCachedNode" />
|
||||
</div>
|
||||
</div>
|
||||
<p id="responseBodyFetchLink" style="display:none"></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -10,6 +10,7 @@ EXTRA_JS_MODULES.devtools.webconsole += [
|
|||
'console-commands.js',
|
||||
'console-output.js',
|
||||
'hudservice.js',
|
||||
'network-panel.js',
|
||||
'panel.js',
|
||||
'webconsole.js',
|
||||
]
|
||||
|
|
|
@ -0,0 +1,835 @@
|
|||
/* -*- js-indent-level: 2; indent-tabs-mode: nil -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {Cc, Ci, Cu} = require("chrome");
|
||||
|
||||
loader.lazyGetter(this, "NetworkHelper", () => require("devtools/toolkit/webconsole/network-helper"));
|
||||
loader.lazyImporter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
|
||||
loader.lazyServiceGetter(this, "mimeService", "@mozilla.org/mime;1", "nsIMIMEService");
|
||||
|
||||
let WebConsoleUtils = require("devtools/toolkit/webconsole/utils").Utils;
|
||||
|
||||
const STRINGS_URI = "chrome://browser/locale/devtools/webconsole.properties";
|
||||
let l10n = new WebConsoleUtils.l10n(STRINGS_URI);
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new NetworkPanel.
|
||||
*
|
||||
* @constructor
|
||||
* @param nsIDOMNode aParent
|
||||
* Parent node to append the created panel to.
|
||||
* @param object aHttpActivity
|
||||
* HttpActivity to display in the panel.
|
||||
* @param object aWebConsoleFrame
|
||||
* The parent WebConsoleFrame object that owns this network panel
|
||||
* instance.
|
||||
*/
|
||||
function NetworkPanel(aParent, aHttpActivity, aWebConsoleFrame)
|
||||
{
|
||||
let doc = aParent.ownerDocument;
|
||||
this.httpActivity = aHttpActivity;
|
||||
this.webconsole = aWebConsoleFrame;
|
||||
this._responseBodyFetch = this._responseBodyFetch.bind(this);
|
||||
this._requestBodyFetch = this._requestBodyFetch.bind(this);
|
||||
|
||||
// Create the underlaying panel
|
||||
this.panel = createElement(doc, "panel", {
|
||||
label: l10n.getStr("NetworkPanel.label"),
|
||||
titlebar: "normal",
|
||||
noautofocus: "true",
|
||||
noautohide: "true",
|
||||
close: "true"
|
||||
});
|
||||
|
||||
// Create the iframe that displays the NetworkPanel XHTML.
|
||||
this.iframe = createAndAppendElement(this.panel, "iframe", {
|
||||
src: "chrome://browser/content/devtools/NetworkPanel.xhtml",
|
||||
type: "content",
|
||||
flex: "1"
|
||||
});
|
||||
|
||||
let self = this;
|
||||
|
||||
// Destroy the panel when it's closed.
|
||||
this.panel.addEventListener("popuphidden", function onPopupHide() {
|
||||
self.panel.removeEventListener("popuphidden", onPopupHide, false);
|
||||
self.panel.parentNode.removeChild(self.panel);
|
||||
self.panel = null;
|
||||
self.iframe = null;
|
||||
self.httpActivity = null;
|
||||
self.webconsole = null;
|
||||
|
||||
if (self.linkNode) {
|
||||
self.linkNode._panelOpen = false;
|
||||
self.linkNode = null;
|
||||
}
|
||||
}, false);
|
||||
|
||||
// Set the document object and update the content once the panel is loaded.
|
||||
this.iframe.addEventListener("load", function onLoad() {
|
||||
if (!self.iframe) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.iframe.removeEventListener("load", onLoad, true);
|
||||
self.update();
|
||||
}, true);
|
||||
|
||||
this.panel.addEventListener("popupshown", function onPopupShown() {
|
||||
self.panel.removeEventListener("popupshown", onPopupShown, true);
|
||||
self.update();
|
||||
}, true);
|
||||
|
||||
// Create the footer.
|
||||
let footer = createElement(doc, "hbox", { align: "end" });
|
||||
createAndAppendElement(footer, "spacer", { flex: 1 });
|
||||
|
||||
createAndAppendElement(footer, "resizer", { dir: "bottomend" });
|
||||
this.panel.appendChild(footer);
|
||||
|
||||
aParent.appendChild(this.panel);
|
||||
}
|
||||
exports.NetworkPanel = NetworkPanel;
|
||||
|
||||
NetworkPanel.prototype =
|
||||
{
|
||||
/**
|
||||
* The current state of the output.
|
||||
*/
|
||||
_state: 0,
|
||||
|
||||
/**
|
||||
* State variables.
|
||||
*/
|
||||
_INIT: 0,
|
||||
_DISPLAYED_REQUEST_HEADER: 1,
|
||||
_DISPLAYED_REQUEST_BODY: 2,
|
||||
_DISPLAYED_RESPONSE_HEADER: 3,
|
||||
_TRANSITION_CLOSED: 4,
|
||||
|
||||
_fromDataRegExp: /Content-Type\:\s*application\/x-www-form-urlencoded/,
|
||||
|
||||
_contentType: null,
|
||||
|
||||
/**
|
||||
* Function callback invoked whenever the panel content is updated. This is
|
||||
* used only by tests.
|
||||
*
|
||||
* @private
|
||||
* @type function
|
||||
*/
|
||||
_onUpdate: null,
|
||||
|
||||
get document() {
|
||||
return this.iframe && this.iframe.contentWindow ?
|
||||
this.iframe.contentWindow.document : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Small helper function that is nearly equal to l10n.getFormatStr
|
||||
* except that it prefixes aName with "NetworkPanel.".
|
||||
*
|
||||
* @param string aName
|
||||
* The name of an i10n string to format. This string is prefixed with
|
||||
* "NetworkPanel." before calling the HUDService.getFormatStr function.
|
||||
* @param array aArray
|
||||
* Values used as placeholder for the i10n string.
|
||||
* @returns string
|
||||
* The i10n formated string.
|
||||
*/
|
||||
_format: function NP_format(aName, aArray)
|
||||
{
|
||||
return l10n.getFormatStr("NetworkPanel." + aName, aArray);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the content type of the response body. This is based on the
|
||||
* response.content.mimeType property. If this value is not available, then
|
||||
* the content type is guessed by the file extension of the request URL.
|
||||
*
|
||||
* @return string
|
||||
* Content type or empty string if no content type could be figured
|
||||
* out.
|
||||
*/
|
||||
get contentType()
|
||||
{
|
||||
if (this._contentType) {
|
||||
return this._contentType;
|
||||
}
|
||||
|
||||
let request = this.httpActivity.request;
|
||||
let response = this.httpActivity.response;
|
||||
|
||||
let contentType = "";
|
||||
let types = response.content ?
|
||||
(response.content.mimeType || "").split(/,|;/) : [];
|
||||
for (let i = 0; i < types.length; i++) {
|
||||
if (types[i] in NetworkHelper.mimeCategoryMap) {
|
||||
contentType = types[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (contentType) {
|
||||
this._contentType = contentType;
|
||||
return contentType;
|
||||
}
|
||||
|
||||
// Try to get the content type from the request file extension.
|
||||
let uri = NetUtil.newURI(request.url);
|
||||
if ((uri instanceof Ci.nsIURL) && uri.fileExtension) {
|
||||
try {
|
||||
contentType = mimeService.getTypeFromExtension(uri.fileExtension);
|
||||
}
|
||||
catch(ex) {
|
||||
// Added to prevent failures on OS X 64. No Flash?
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
this._contentType = contentType;
|
||||
return contentType;
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns boolean
|
||||
* True if the response is an image, false otherwise.
|
||||
*/
|
||||
get _responseIsImage()
|
||||
{
|
||||
return this.contentType &&
|
||||
NetworkHelper.mimeCategoryMap[this.contentType] == "image";
|
||||
},
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns boolean
|
||||
* True if the response body contains text, false otherwise.
|
||||
*/
|
||||
get _isResponseBodyTextData()
|
||||
{
|
||||
return this.contentType ?
|
||||
NetworkHelper.isTextMimeType(this.contentType) : false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the server response is cached.
|
||||
*
|
||||
* @returns boolean
|
||||
* Returns true if the server responded that the request is already
|
||||
* in the browser's cache, false otherwise.
|
||||
*/
|
||||
get _isResponseCached()
|
||||
{
|
||||
return this.httpActivity.response.status == 304;
|
||||
},
|
||||
|
||||
/**
|
||||
* Tells if the request body includes form data.
|
||||
*
|
||||
* @returns boolean
|
||||
* Returns true if the posted body contains form data.
|
||||
*/
|
||||
get _isRequestBodyFormData()
|
||||
{
|
||||
let requestBody = this.httpActivity.request.postData.text;
|
||||
if (typeof requestBody == "object" && requestBody.type == "longString") {
|
||||
requestBody = requestBody.initial;
|
||||
}
|
||||
return this._fromDataRegExp.test(requestBody);
|
||||
},
|
||||
|
||||
/**
|
||||
* Appends the node with id=aId by the text aValue.
|
||||
*
|
||||
* @private
|
||||
* @param string aId
|
||||
* @param string aValue
|
||||
* @return nsIDOMElement
|
||||
* The DOM element with id=aId.
|
||||
*/
|
||||
_appendTextNode: function NP__appendTextNode(aId, aValue)
|
||||
{
|
||||
let textNode = this.document.createTextNode(aValue);
|
||||
let elem = this.document.getElementById(aId);
|
||||
elem.appendChild(textNode);
|
||||
return elem;
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates some HTML to display the key-value pair of the aList data. The
|
||||
* generated HTML is added to node with id=aParentId.
|
||||
*
|
||||
* @param string aParentId
|
||||
* Id of the parent node to append the list to.
|
||||
* @oaram array aList
|
||||
* Array that holds the objects you want to display. Each object must
|
||||
* have two properties: name and value.
|
||||
* @param boolean aIgnoreCookie
|
||||
* If true, the key-value named "Cookie" is not added to the list.
|
||||
* @returns void
|
||||
*/
|
||||
_appendList: function NP_appendList(aParentId, aList, aIgnoreCookie)
|
||||
{
|
||||
let parent = this.document.getElementById(aParentId);
|
||||
let doc = this.document;
|
||||
|
||||
aList.sort(function(a, b) {
|
||||
return a.name.toLowerCase() < b.name.toLowerCase();
|
||||
});
|
||||
|
||||
aList.forEach((aItem) => {
|
||||
let name = aItem.name;
|
||||
if (aIgnoreCookie && (name == "Cookie" || name == "Set-Cookie")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let value = aItem.value;
|
||||
let longString = null;
|
||||
if (typeof value == "object" && value.type == "longString") {
|
||||
value = value.initial;
|
||||
longString = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following code creates the HTML:
|
||||
* <tr>
|
||||
* <th scope="row" class="property-name">${line}:</th>
|
||||
* <td class="property-value">${aList[line]}</td>
|
||||
* </tr>
|
||||
* and adds it to parent.
|
||||
*/
|
||||
let row = doc.createElement("tr");
|
||||
let textNode = doc.createTextNode(name + ":");
|
||||
let th = doc.createElement("th");
|
||||
th.setAttribute("scope", "row");
|
||||
th.setAttribute("class", "property-name");
|
||||
th.appendChild(textNode);
|
||||
row.appendChild(th);
|
||||
|
||||
textNode = doc.createTextNode(value);
|
||||
let td = doc.createElement("td");
|
||||
td.setAttribute("class", "property-value");
|
||||
td.appendChild(textNode);
|
||||
|
||||
if (longString) {
|
||||
let a = doc.createElement("a");
|
||||
a.href = "#";
|
||||
a.className = "longStringEllipsis";
|
||||
a.addEventListener("mousedown", this._longStringClick.bind(this, aItem));
|
||||
a.textContent = l10n.getStr("longStringEllipsis");
|
||||
td.appendChild(a);
|
||||
}
|
||||
|
||||
row.appendChild(td);
|
||||
|
||||
parent.appendChild(row);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* The click event handler for the ellipsis which allows the user to retrieve
|
||||
* the full header value.
|
||||
*
|
||||
* @private
|
||||
* @param object aHeader
|
||||
* The header object with the |name| and |value| properties.
|
||||
* @param nsIDOMEvent aEvent
|
||||
* The DOM click event object.
|
||||
*/
|
||||
_longStringClick: function NP__longStringClick(aHeader, aEvent)
|
||||
{
|
||||
aEvent.preventDefault();
|
||||
|
||||
let longString = this.webconsole.webConsoleClient.longString(aHeader.value);
|
||||
|
||||
longString.substring(longString.initial.length, longString.length,
|
||||
function NP__onLongStringSubstring(aResponse)
|
||||
{
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("NP__onLongStringSubstring error: " + aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHeader.value = aHeader.value.initial + aResponse.substring;
|
||||
|
||||
let textNode = aEvent.target.previousSibling;
|
||||
textNode.textContent += aResponse.substring;
|
||||
textNode.parentNode.removeChild(aEvent.target);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the node with id=aId.
|
||||
*
|
||||
* @private
|
||||
* @param string aId
|
||||
* @return nsIDOMElement
|
||||
* The element with id=aId.
|
||||
*/
|
||||
_displayNode: function NP__displayNode(aId)
|
||||
{
|
||||
let elem = this.document.getElementById(aId);
|
||||
elem.style.display = "block";
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the request URL, request method, the timing information when the
|
||||
* request started and the request header content on the NetworkPanel.
|
||||
* If the request header contains cookie data, a list of sent cookies is
|
||||
* generated and a special sent cookie section is displayed + the cookie list
|
||||
* added to it.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayRequestHeader: function NP__displayRequestHeader()
|
||||
{
|
||||
let request = this.httpActivity.request;
|
||||
let requestTime = new Date(this.httpActivity.startedDateTime);
|
||||
|
||||
this._appendTextNode("headUrl", request.url);
|
||||
this._appendTextNode("headMethod", request.method);
|
||||
this._appendTextNode("requestHeadersInfo",
|
||||
l10n.timestampString(requestTime));
|
||||
|
||||
this._appendList("requestHeadersContent", request.headers, true);
|
||||
|
||||
if (request.cookies.length > 0) {
|
||||
this._displayNode("requestCookie");
|
||||
this._appendList("requestCookieContent", request.cookies);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the request body section of the NetworkPanel and set the request
|
||||
* body content on the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayRequestBody: function NP__displayRequestBody()
|
||||
{
|
||||
let postData = this.httpActivity.request.postData;
|
||||
this._displayNode("requestBody");
|
||||
this._appendTextNode("requestBodyContent", postData.text);
|
||||
},
|
||||
|
||||
/*
|
||||
* Displays the `sent form data` section. Parses the request header for the
|
||||
* submitted form data displays it inside of the `sent form data` section.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayRequestForm: function NP__processRequestForm()
|
||||
{
|
||||
let postData = this.httpActivity.request.postData.text;
|
||||
let requestBodyLines = postData.split("\n");
|
||||
let formData = requestBodyLines[requestBodyLines.length - 1].
|
||||
replace(/\+/g, " ").split("&");
|
||||
|
||||
function unescapeText(aText)
|
||||
{
|
||||
try {
|
||||
return decodeURIComponent(aText);
|
||||
}
|
||||
catch (ex) {
|
||||
return decodeURIComponent(unescape(aText));
|
||||
}
|
||||
}
|
||||
|
||||
let formDataArray = [];
|
||||
for (let i = 0; i < formData.length; i++) {
|
||||
let data = formData[i];
|
||||
let idx = data.indexOf("=");
|
||||
let key = data.substring(0, idx);
|
||||
let value = data.substring(idx + 1);
|
||||
formDataArray.push({
|
||||
name: unescapeText(key),
|
||||
value: unescapeText(value)
|
||||
});
|
||||
}
|
||||
|
||||
this._appendList("requestFormDataContent", formDataArray);
|
||||
this._displayNode("requestFormData");
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the response section of the NetworkPanel, sets the response status,
|
||||
* the duration between the start of the request and the receiving of the
|
||||
* response header as well as the response header content on the the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayResponseHeader: function NP__displayResponseHeader()
|
||||
{
|
||||
let timing = this.httpActivity.timings;
|
||||
let response = this.httpActivity.response;
|
||||
|
||||
this._appendTextNode("headStatus",
|
||||
[response.httpVersion, response.status,
|
||||
response.statusText].join(" "));
|
||||
|
||||
// Calculate how much time it took from the request start, until the
|
||||
// response started to be received.
|
||||
let deltaDuration = 0;
|
||||
["dns", "connect", "send", "wait"].forEach(function (aValue) {
|
||||
let ms = timing[aValue];
|
||||
if (ms > -1) {
|
||||
deltaDuration += ms;
|
||||
}
|
||||
});
|
||||
|
||||
this._appendTextNode("responseHeadersInfo",
|
||||
this._format("durationMS", [deltaDuration]));
|
||||
|
||||
this._displayNode("responseContainer");
|
||||
this._appendList("responseHeadersContent", response.headers, true);
|
||||
|
||||
if (response.cookies.length > 0) {
|
||||
this._displayNode("responseCookie");
|
||||
this._appendList("responseCookieContent", response.cookies);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the respones image section, sets the source of the image displayed
|
||||
* in the image response section to the request URL and the duration between
|
||||
* the receiving of the response header and the end of the request. Once the
|
||||
* image is loaded, the size of the requested image is set.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayResponseImage: function NP__displayResponseImage()
|
||||
{
|
||||
let self = this;
|
||||
let timing = this.httpActivity.timings;
|
||||
let request = this.httpActivity.request;
|
||||
let response = this.httpActivity.response;
|
||||
let cached = "";
|
||||
|
||||
if (this._isResponseCached) {
|
||||
cached = "Cached";
|
||||
}
|
||||
|
||||
let imageNode = this.document.getElementById("responseImage" +
|
||||
cached + "Node");
|
||||
|
||||
let text = response.content.text;
|
||||
if (typeof text == "object" && text.type == "longString") {
|
||||
this._showResponseBodyFetchLink();
|
||||
}
|
||||
else {
|
||||
imageNode.setAttribute("src",
|
||||
"data:" + this.contentType + ";base64," + text);
|
||||
}
|
||||
|
||||
// This function is called to set the imageInfo.
|
||||
function setImageInfo() {
|
||||
self._appendTextNode("responseImage" + cached + "Info",
|
||||
self._format("imageSizeDeltaDurationMS",
|
||||
[ imageNode.width, imageNode.height, timing.receive ]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Check if the image is already loaded.
|
||||
if (imageNode.width != 0) {
|
||||
setImageInfo();
|
||||
}
|
||||
else {
|
||||
// Image is not loaded yet therefore add a load event.
|
||||
imageNode.addEventListener("load", function imageNodeLoad() {
|
||||
imageNode.removeEventListener("load", imageNodeLoad, false);
|
||||
setImageInfo();
|
||||
}, false);
|
||||
}
|
||||
|
||||
this._displayNode("responseImage" + cached);
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the response body section, sets the the duration between
|
||||
* the receiving of the response header and the end of the request as well as
|
||||
* the content of the response body on the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayResponseBody: function NP__displayResponseBody()
|
||||
{
|
||||
let timing = this.httpActivity.timings;
|
||||
let response = this.httpActivity.response;
|
||||
let cached = this._isResponseCached ? "Cached" : "";
|
||||
|
||||
this._appendTextNode("responseBody" + cached + "Info",
|
||||
this._format("durationMS", [timing.receive]));
|
||||
|
||||
this._displayNode("responseBody" + cached);
|
||||
|
||||
let text = response.content.text;
|
||||
if (typeof text == "object") {
|
||||
text = text.initial;
|
||||
this._showResponseBodyFetchLink();
|
||||
}
|
||||
|
||||
this._appendTextNode("responseBody" + cached + "Content", text);
|
||||
},
|
||||
|
||||
/**
|
||||
* Show the "fetch response body" link.
|
||||
* @private
|
||||
*/
|
||||
_showResponseBodyFetchLink: function NP__showResponseBodyFetchLink()
|
||||
{
|
||||
let content = this.httpActivity.response.content;
|
||||
|
||||
let elem = this._appendTextNode("responseBodyFetchLink",
|
||||
this._format("fetchRemainingResponseContentLink",
|
||||
[content.text.length - content.text.initial.length]));
|
||||
|
||||
elem.style.display = "block";
|
||||
elem.addEventListener("mousedown", this._responseBodyFetch);
|
||||
},
|
||||
|
||||
/**
|
||||
* Click event handler for the link that allows users to fetch the remaining
|
||||
* response body.
|
||||
*
|
||||
* @private
|
||||
* @param nsIDOMEvent aEvent
|
||||
*/
|
||||
_responseBodyFetch: function NP__responseBodyFetch(aEvent)
|
||||
{
|
||||
aEvent.target.style.display = "none";
|
||||
aEvent.target.removeEventListener("mousedown", this._responseBodyFetch);
|
||||
|
||||
let content = this.httpActivity.response.content;
|
||||
let longString = this.webconsole.webConsoleClient.longString(content.text);
|
||||
longString.substring(longString.initial.length, longString.length,
|
||||
(aResponse) =>
|
||||
{
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("NP__onLongStringSubstring error: " + aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
content.text = content.text.initial + aResponse.substring;
|
||||
let cached = this._isResponseCached ? "Cached" : "";
|
||||
|
||||
if (this._responseIsImage) {
|
||||
let imageNode = this.document.getElementById("responseImage" +
|
||||
cached + "Node");
|
||||
imageNode.src =
|
||||
"data:" + this.contentType + ";base64," + content.text;
|
||||
}
|
||||
else {
|
||||
this._appendTextNode("responseBody" + cached + "Content",
|
||||
aResponse.substring);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the `Unknown Content-Type hint` and sets the duration between the
|
||||
* receiving of the response header on the NetworkPanel.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayResponseBodyUnknownType: function NP__displayResponseBodyUnknownType()
|
||||
{
|
||||
let timing = this.httpActivity.timings;
|
||||
|
||||
this._displayNode("responseBodyUnknownType");
|
||||
this._appendTextNode("responseBodyUnknownTypeInfo",
|
||||
this._format("durationMS", [timing.receive]));
|
||||
|
||||
this._appendTextNode("responseBodyUnknownTypeContent",
|
||||
this._format("responseBodyUnableToDisplay.content", [this.contentType]));
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the `no response body` section and sets the the duration between
|
||||
* the receiving of the response header and the end of the request.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
_displayNoResponseBody: function NP_displayNoResponseBody()
|
||||
{
|
||||
let timing = this.httpActivity.timings;
|
||||
|
||||
this._displayNode("responseNoBody");
|
||||
this._appendTextNode("responseNoBodyInfo",
|
||||
this._format("durationMS", [timing.receive]));
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the content of the NetworkPanel's iframe.
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
update: function NP_update()
|
||||
{
|
||||
if (!this.document || this.document.readyState != "complete") {
|
||||
return;
|
||||
}
|
||||
|
||||
let updates = this.httpActivity.updates;
|
||||
let timing = this.httpActivity.timings;
|
||||
let request = this.httpActivity.request;
|
||||
let response = this.httpActivity.response;
|
||||
|
||||
switch (this._state) {
|
||||
case this._INIT:
|
||||
this._displayRequestHeader();
|
||||
this._state = this._DISPLAYED_REQUEST_HEADER;
|
||||
// FALL THROUGH
|
||||
|
||||
case this._DISPLAYED_REQUEST_HEADER:
|
||||
// Process the request body if there is one.
|
||||
if (!this.httpActivity.discardRequestBody && request.postData.text) {
|
||||
this._updateRequestBody();
|
||||
this._state = this._DISPLAYED_REQUEST_BODY;
|
||||
}
|
||||
// FALL THROUGH
|
||||
|
||||
case this._DISPLAYED_REQUEST_BODY:
|
||||
if (!response.headers.length || !Object.keys(timing).length) {
|
||||
break;
|
||||
}
|
||||
this._displayResponseHeader();
|
||||
this._state = this._DISPLAYED_RESPONSE_HEADER;
|
||||
// FALL THROUGH
|
||||
|
||||
case this._DISPLAYED_RESPONSE_HEADER:
|
||||
if (updates.indexOf("responseContent") == -1 ||
|
||||
updates.indexOf("eventTimings") == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
this._state = this._TRANSITION_CLOSED;
|
||||
if (this.httpActivity.discardResponseBody) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!response.content || !response.content.text) {
|
||||
this._displayNoResponseBody();
|
||||
}
|
||||
else if (this._responseIsImage) {
|
||||
this._displayResponseImage();
|
||||
}
|
||||
else if (!this._isResponseBodyTextData) {
|
||||
this._displayResponseBodyUnknownType();
|
||||
}
|
||||
else if (response.content.text) {
|
||||
this._displayResponseBody();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (this._onUpdate) {
|
||||
this._onUpdate();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the panel to hold the current information we have about the request
|
||||
* body.
|
||||
* @private
|
||||
*/
|
||||
_updateRequestBody: function NP__updateRequestBody()
|
||||
{
|
||||
let postData = this.httpActivity.request.postData;
|
||||
if (typeof postData.text == "object" && postData.text.type == "longString") {
|
||||
let elem = this._appendTextNode("requestBodyFetchLink",
|
||||
this._format("fetchRemainingRequestContentLink",
|
||||
[postData.text.length - postData.text.initial.length]));
|
||||
|
||||
elem.style.display = "block";
|
||||
elem.addEventListener("mousedown", this._requestBodyFetch);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we send some form data. If so, display the form data special.
|
||||
if (this._isRequestBodyFormData) {
|
||||
this._displayRequestForm();
|
||||
}
|
||||
else {
|
||||
this._displayRequestBody();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Click event handler for the link that allows users to fetch the remaining
|
||||
* request body.
|
||||
*
|
||||
* @private
|
||||
* @param nsIDOMEvent aEvent
|
||||
*/
|
||||
_requestBodyFetch: function NP__requestBodyFetch(aEvent)
|
||||
{
|
||||
aEvent.target.style.display = "none";
|
||||
aEvent.target.removeEventListener("mousedown", this._responseBodyFetch);
|
||||
|
||||
let postData = this.httpActivity.request.postData;
|
||||
let longString = this.webconsole.webConsoleClient.longString(postData.text);
|
||||
longString.substring(longString.initial.length, longString.length,
|
||||
(aResponse) =>
|
||||
{
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("NP__onLongStringSubstring error: " + aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
postData.text = postData.text.initial + aResponse.substring;
|
||||
this._updateRequestBody();
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a DOMNode and sets all the attributes of aAttributes on the created
|
||||
* element.
|
||||
*
|
||||
* @param nsIDOMDocument aDocument
|
||||
* Document to create the new DOMNode.
|
||||
* @param string aTag
|
||||
* Name of the tag for the DOMNode.
|
||||
* @param object aAttributes
|
||||
* Attributes set on the created DOMNode.
|
||||
*
|
||||
* @returns nsIDOMNode
|
||||
*/
|
||||
function createElement(aDocument, aTag, aAttributes)
|
||||
{
|
||||
let node = aDocument.createElement(aTag);
|
||||
if (aAttributes) {
|
||||
for (let attr in aAttributes) {
|
||||
node.setAttribute(attr, aAttributes[attr]);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new DOMNode and appends it to aParent.
|
||||
*
|
||||
* @param nsIDOMNode aParent
|
||||
* A parent node to append the created element.
|
||||
* @param string aTag
|
||||
* Name of the tag for the DOMNode.
|
||||
* @param object aAttributes
|
||||
* Attributes set on the created DOMNode.
|
||||
*
|
||||
* @returns nsIDOMNode
|
||||
*/
|
||||
function createAndAppendElement(aParent, aTag, aAttributes)
|
||||
{
|
||||
let node = createElement(aParent.ownerDocument, aTag, aAttributes);
|
||||
aParent.appendChild(node);
|
||||
return node;
|
||||
}
|
|
@ -189,6 +189,8 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
[browser_eval_in_debugger_stackframe2.js]
|
||||
[browser_jsterm_inspect.js]
|
||||
[browser_longstring_hang.js]
|
||||
[browser_netpanel_longstring_expand.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_output_breaks_after_console_dir_uninspectable.js]
|
||||
[browser_output_longstring_expand.js]
|
||||
[browser_repeated_messages_accuracy.js]
|
||||
|
@ -225,6 +227,7 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
[browser_webconsole_bug_592442_closing_brackets.js]
|
||||
[browser_webconsole_bug_593003_iframe_wrong_hud.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_594477_clickable_output.js]
|
||||
[browser_webconsole_bug_594497_history_arrow_keys.js]
|
||||
[browser_webconsole_bug_595223_file_uri.js]
|
||||
[browser_webconsole_bug_595350_multiple_windows_and_tabs.js]
|
||||
|
@ -242,6 +245,8 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
[browser_webconsole_bug_601177_log_levels.js]
|
||||
[browser_webconsole_bug_601352_scroll.js]
|
||||
[browser_webconsole_bug_601667_filter_buttons.js]
|
||||
[browser_webconsole_bug_602572_log_bodies_checkbox.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_603750_websocket.js]
|
||||
[browser_webconsole_bug_611795.js]
|
||||
[browser_webconsole_bug_613013_console_api_iframe.js]
|
||||
|
@ -250,6 +255,7 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
[browser_webconsole_bug_613642_prune_scroll.js]
|
||||
[browser_webconsole_bug_614793_jsterm_scroll.js]
|
||||
[browser_webconsole_bug_618078_network_exceptions.js]
|
||||
[browser_webconsole_bug_618311_close_panels.js]
|
||||
[browser_webconsole_bug_621644_jsterm_dollar.js]
|
||||
[browser_webconsole_bug_622303_persistent_filters.js]
|
||||
[browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js]
|
||||
|
@ -328,6 +334,7 @@ skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
|||
[browser_webconsole_live_filtering_on_search_strings.js]
|
||||
[browser_webconsole_message_node_id.js]
|
||||
[browser_webconsole_netlogging.js]
|
||||
[browser_webconsole_network_panel.js]
|
||||
[browser_webconsole_notifications.js]
|
||||
[browser_webconsole_open-links-without-callback.js]
|
||||
[browser_webconsole_promise.js]
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
// Tests that the network panel works with LongStringActors.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-console.html";
|
||||
const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-image.png";
|
||||
|
||||
const TEST_IMG_BASE64 =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAVRJ" +
|
||||
"REFUOI2lk7FLw0AUxr+YpC1CBqcMWfsvCCLdXFzqEJCgDl1EQRGxg9AhSBEJONhFhG52UCuF" +
|
||||
"Djq5dxD8FwoO0qGDOBQkl7vLOeWa2EQDffDBvTu+373Hu1OEEJgntGgxGD6J+7fLXKbt5VNU" +
|
||||
"yhsKAChRBQcPFVFeWskFGH694mZroCQqCLlAwPxcgJBP254CmAD5B7C7dgHLMLF3uzoL4DQE" +
|
||||
"od+Z5sP1FizDxGgyBqfhLID9AahX29J89bwPFgMsSEAQglAf9WobhPpScbPXr4FQHyzIADTs" +
|
||||
"DizDRMPuIOC+zEeTMZo9BwH3EfAMACccbtfGaDKGZZg423yUZrdrg3EqxQlPr0BTdTR7joRE" +
|
||||
"N2uqnlBmCwW1hIJagtev4f3zA16/JvfiigMSYyzqJXlw/XKUyOORMUaBor6YavgdjKa8xGOn" +
|
||||
"idadmwtwsnMu18q83/kHSou+bFNDDr4AAAAASUVORK5CYII=";
|
||||
|
||||
let testDriver;
|
||||
|
||||
function test() {
|
||||
loadTab(TEST_URI).then(() => {
|
||||
openConsole().then(testNetworkPanel);
|
||||
});
|
||||
}
|
||||
|
||||
function testNetworkPanel() {
|
||||
testDriver = testGen();
|
||||
testDriver.next();
|
||||
}
|
||||
|
||||
function checkIsVisible(aPanel, aList) {
|
||||
for (let id in aList) {
|
||||
let node = aPanel.document.getElementById(id);
|
||||
let isVisible = aList[id];
|
||||
is(node.style.display, (isVisible ? "block" : "none"),
|
||||
id + " isVisible=" + isVisible);
|
||||
}
|
||||
}
|
||||
|
||||
function checkNodeContent(aPanel, aId, aContent) {
|
||||
let node = aPanel.document.getElementById(aId);
|
||||
if (node == null) {
|
||||
ok(false, "Tried to access node " + aId + " that doesn't exist!");
|
||||
} else if (node.textContent.indexOf(aContent) != -1) {
|
||||
ok(true, "checking content of " + aId);
|
||||
} else {
|
||||
ok(false, "Got false value for " + aId + ": " + node.textContent +
|
||||
" doesn't have " + aContent);
|
||||
}
|
||||
}
|
||||
|
||||
function checkNodeKeyValue(aPanel, aId, aKey, aValue) {
|
||||
let node = aPanel.document.getElementById(aId);
|
||||
|
||||
let headers = node.querySelectorAll("th");
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
if (headers[i].textContent == (aKey + ":")) {
|
||||
is(headers[i].nextElementSibling.textContent, aValue,
|
||||
"checking content of " + aId + " for key " + aKey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ok(false, "content check failed for " + aId + ", key " + aKey);
|
||||
}
|
||||
|
||||
function* testGen() {
|
||||
let hud = HUDService.getHudByWindow(content);
|
||||
let filterBox = hud.ui.filterBox;
|
||||
|
||||
let headerValue = (new Array(456)).join("fooz bar");
|
||||
let headerValueGrip = {
|
||||
type: "longString",
|
||||
initial: headerValue.substr(0, 123),
|
||||
length: headerValue.length,
|
||||
actor: "faktor",
|
||||
_fullString: headerValue,
|
||||
};
|
||||
|
||||
let imageContentGrip = {
|
||||
type: "longString",
|
||||
initial: TEST_IMG_BASE64.substr(0, 143),
|
||||
length: TEST_IMG_BASE64.length,
|
||||
actor: "faktor2",
|
||||
_fullString: TEST_IMG_BASE64,
|
||||
};
|
||||
|
||||
let postDataValue = (new Array(123)).join("post me");
|
||||
let postDataGrip = {
|
||||
type: "longString",
|
||||
initial: postDataValue.substr(0, 172),
|
||||
length: postDataValue.length,
|
||||
actor: "faktor3",
|
||||
_fullString: postDataValue,
|
||||
};
|
||||
|
||||
let httpActivity = {
|
||||
updates: ["responseContent", "eventTimings"],
|
||||
discardRequestBody: false,
|
||||
discardResponseBody: false,
|
||||
startedDateTime: (new Date()).toISOString(),
|
||||
request: {
|
||||
url: TEST_IMG,
|
||||
method: "GET",
|
||||
cookies: [],
|
||||
headers: [
|
||||
{ name: "foo", value: "bar" },
|
||||
{ name: "loongstring", value: headerValueGrip },
|
||||
],
|
||||
postData: { text: postDataGrip },
|
||||
},
|
||||
response: {
|
||||
httpVersion: "HTTP/3.14",
|
||||
status: 2012,
|
||||
statusText: "ddahl likes tacos :)",
|
||||
headers: [
|
||||
{ name: "Content-Type", value: "image/png" },
|
||||
],
|
||||
content: { mimeType: "image/png", text: imageContentGrip },
|
||||
cookies: [],
|
||||
},
|
||||
timings: { wait: 15, receive: 23 },
|
||||
};
|
||||
|
||||
let networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on the anchor object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
info("test 1: check if a header value is expandable");
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestCookie: false,
|
||||
requestFormData: false,
|
||||
requestBody: false,
|
||||
requestBodyFetchLink: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: true,
|
||||
responseImageCached: false,
|
||||
responseBodyFetchLink: true,
|
||||
});
|
||||
|
||||
checkNodeKeyValue(networkPanel, "requestHeadersContent", "foo", "bar");
|
||||
checkNodeKeyValue(networkPanel, "requestHeadersContent", "loongstring",
|
||||
headerValueGrip.initial + "[\u2026]");
|
||||
|
||||
let webConsoleClient = networkPanel.webconsole.webConsoleClient;
|
||||
let longStringFn = webConsoleClient.longString;
|
||||
|
||||
let expectedGrip = headerValueGrip;
|
||||
|
||||
function longStringClientProvider(aLongString) {
|
||||
is(aLongString, expectedGrip,
|
||||
"longString grip is correct");
|
||||
|
||||
return {
|
||||
initial: expectedGrip.initial,
|
||||
length: expectedGrip.length,
|
||||
substring: function(aStart, aEnd, aCallback) {
|
||||
is(aStart, expectedGrip.initial.length,
|
||||
"substring start is correct");
|
||||
is(aEnd, expectedGrip.length,
|
||||
"substring end is correct");
|
||||
|
||||
executeSoon(function() {
|
||||
aCallback({
|
||||
substring: expectedGrip._fullString.substring(aStart, aEnd),
|
||||
});
|
||||
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
webConsoleClient.longString = longStringClientProvider;
|
||||
|
||||
let clickable = networkPanel.document
|
||||
.querySelector("#requestHeadersContent .longStringEllipsis");
|
||||
ok(clickable, "long string ellipsis is shown");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown"}, clickable,
|
||||
networkPanel.document.defaultView);
|
||||
|
||||
yield undefined;
|
||||
|
||||
clickable = networkPanel.document
|
||||
.querySelector("#requestHeadersContent .longStringEllipsis");
|
||||
ok(!clickable, "long string ellipsis is not shown");
|
||||
|
||||
checkNodeKeyValue(networkPanel, "requestHeadersContent", "loongstring",
|
||||
expectedGrip._fullString);
|
||||
|
||||
info("test 2: check that response body image fetching works");
|
||||
expectedGrip = imageContentGrip;
|
||||
|
||||
let imgNode = networkPanel.document.getElementById("responseImageNode");
|
||||
ok(!imgNode.getAttribute("src"), "no image is displayed");
|
||||
|
||||
clickable = networkPanel.document.querySelector("#responseBodyFetchLink");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown"}, clickable,
|
||||
networkPanel.document.defaultView);
|
||||
|
||||
yield undefined;
|
||||
|
||||
imgNode = networkPanel.document.getElementById("responseImageNode");
|
||||
is(imgNode.getAttribute("src"), "data:image/png;base64," + TEST_IMG_BASE64,
|
||||
"displayed image is correct");
|
||||
is(clickable.style.display, "none", "#responseBodyFetchLink is not visible");
|
||||
|
||||
info("test 3: expand the request body");
|
||||
|
||||
expectedGrip = postDataGrip;
|
||||
|
||||
clickable = networkPanel.document.querySelector("#requestBodyFetchLink");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown"}, clickable,
|
||||
networkPanel.document.defaultView);
|
||||
yield undefined;
|
||||
|
||||
is(clickable.style.display, "none", "#requestBodyFetchLink is not visible");
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestBodyFetchLink: false,
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "requestBodyContent",
|
||||
expectedGrip._fullString);
|
||||
|
||||
webConsoleClient.longString = longStringFn;
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
info("test 4: reponse body long text");
|
||||
|
||||
httpActivity.response.content.mimeType = "text/plain";
|
||||
httpActivity.response.headers[0].value = "text/plain";
|
||||
|
||||
expectedGrip = imageContentGrip;
|
||||
|
||||
// Reset response.content.text to avoid caching of the full string.
|
||||
httpActivity.response.content.text = expectedGrip;
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on httpActivity object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestCookie: false,
|
||||
requestFormData: false,
|
||||
requestBody: true,
|
||||
requestBodyFetchLink: false,
|
||||
responseContainer: true,
|
||||
responseBody: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false,
|
||||
responseBodyFetchLink: true,
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "responseBodyContent", expectedGrip.initial);
|
||||
|
||||
webConsoleClient.longString = longStringClientProvider;
|
||||
|
||||
clickable = networkPanel.document.querySelector("#responseBodyFetchLink");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown"}, clickable,
|
||||
networkPanel.document.defaultView);
|
||||
|
||||
yield undefined;
|
||||
|
||||
webConsoleClient.longString = longStringFn;
|
||||
is(clickable.style.display, "none", "#responseBodyFetchLink is not visible");
|
||||
checkNodeContent(networkPanel, "responseBodyContent",
|
||||
expectedGrip._fullString);
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// All done!
|
||||
testDriver = null;
|
||||
executeSoon(finishTest);
|
||||
|
||||
yield undefined;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-console.html";
|
||||
let HUD;
|
||||
let outputItem;
|
||||
let outputNode;
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
HUD = yield openConsole();
|
||||
outputNode = HUD.outputNode;
|
||||
|
||||
// reload the tab
|
||||
BrowserReload();
|
||||
yield loadBrowser(gBrowser.selectedBrowser);
|
||||
|
||||
let event = yield clickEvents();
|
||||
yield testClickAgain(event);
|
||||
yield networkPanelHidden();
|
||||
|
||||
HUD = outputItem = outputNode = null;
|
||||
});
|
||||
|
||||
function clickEvents() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
waitForMessages({
|
||||
webconsole: HUD,
|
||||
messages: [{
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
}).then(([result]) => {
|
||||
let msg = [...result.matched][0];
|
||||
outputItem = msg.querySelector(".message-body .url");
|
||||
ok(outputItem, "found a network message");
|
||||
document.addEventListener("popupshown", function onPanelShown(event) {
|
||||
document.removeEventListener("popupshown", onPanelShown, false);
|
||||
deferred.resolve(event);
|
||||
}, false);
|
||||
|
||||
// Send the mousedown and click events such that the network panel opens.
|
||||
EventUtils.sendMouseEvent({type: "mousedown"}, outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click"}, outputItem);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testClickAgain(event) {
|
||||
info("testClickAgain");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
document.addEventListener("popupshown", networkPanelShowFailure, false);
|
||||
|
||||
// The network panel should not open for the second time.
|
||||
EventUtils.sendMouseEvent({type: "mousedown"}, outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click"}, outputItem);
|
||||
|
||||
executeSoon(function() {
|
||||
document.addEventListener("popuphidden", function onHidden() {
|
||||
document.removeEventListener("popuphidden", onHidden, false);
|
||||
deferred.resolve();
|
||||
}, false);
|
||||
event.target.hidePopup();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function networkPanelShowFailure() {
|
||||
ok(false, "the network panel should not show");
|
||||
}
|
||||
|
||||
function networkPanelHidden() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
info("networkPanelHidden");
|
||||
|
||||
// The network panel should not show because this is a mouse event that starts
|
||||
// in a position and ends in another.
|
||||
EventUtils.sendMouseEvent({type: "mousedown", clientX: 3, clientY: 4},
|
||||
outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click", clientX: 5, clientY: 6},
|
||||
outputItem);
|
||||
|
||||
// The network panel should not show because this is a middle-click.
|
||||
EventUtils.sendMouseEvent({type: "mousedown", button: 1},
|
||||
outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click", button: 1},
|
||||
outputItem);
|
||||
|
||||
// The network panel should not show because this is a right-click.
|
||||
EventUtils.sendMouseEvent({type: "mousedown", button: 2},
|
||||
outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click", button: 2},
|
||||
outputItem);
|
||||
|
||||
executeSoon(function() {
|
||||
document.removeEventListener("popupshown", networkPanelShowFailure, false);
|
||||
|
||||
// Done with the network output. Now test the jsterm output and the property
|
||||
// panel.
|
||||
HUD.jsterm.execute("document").then((msg) => {
|
||||
info("jsterm execute 'document' callback");
|
||||
|
||||
HUD.jsterm.once("variablesview-open", deferred.resolve);
|
||||
outputItem = msg.querySelector(".message-body a");
|
||||
ok(outputItem, "jsterm output message found");
|
||||
|
||||
// Send the mousedown and click events such that the property panel opens.
|
||||
EventUtils.sendMouseEvent({type: "mousedown"}, outputItem);
|
||||
EventUtils.sendMouseEvent({type: "click"}, outputItem);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
|
@ -0,0 +1,186 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
"use strict";
|
||||
|
||||
let menuitems = [];
|
||||
let menupopups = [];
|
||||
let huds = [];
|
||||
let tabs = [];
|
||||
let runCount = 0;
|
||||
|
||||
const TEST_URI1 = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"bug 602572: log bodies checkbox. tab 1";
|
||||
const TEST_URI2 = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"bug 602572: log bodies checkbox. tab 2";
|
||||
|
||||
function test() {
|
||||
if (runCount == 0) {
|
||||
requestLongerTimeout(2);
|
||||
}
|
||||
|
||||
// open tab 2
|
||||
function openTab() {
|
||||
loadTab(TEST_URI2).then((tab) => {
|
||||
tabs.push(tab.tab);
|
||||
openConsole().then((hud) => {
|
||||
hud.iframeWindow.requestAnimationFrame(startTest);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// open tab 1
|
||||
loadTab(TEST_URI1).then((tab) => {
|
||||
tabs.push(tab.tab);
|
||||
openConsole().then((hud) => {
|
||||
hud.iframeWindow.requestAnimationFrame(() => {
|
||||
info("iframe1 root height " + hud.ui.rootElement.clientHeight);
|
||||
|
||||
openTab();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
// Find the relevant elements in the Web Console of tab 2.
|
||||
let win2 = tabs[runCount * 2 + 1].linkedBrowser.contentWindow;
|
||||
huds[1] = HUDService.getHudByWindow(win2);
|
||||
info("startTest: iframe2 root height " + huds[1].ui.rootElement.clientHeight);
|
||||
|
||||
if (runCount == 0) {
|
||||
menuitems[1] = huds[1].ui.rootElement.querySelector("#saveBodies");
|
||||
} else {
|
||||
menuitems[1] = huds[1].ui.rootElement
|
||||
.querySelector("#saveBodiesContextMenu");
|
||||
}
|
||||
menupopups[1] = menuitems[1].parentNode;
|
||||
|
||||
// Open the context menu from tab 2.
|
||||
menupopups[1].addEventListener("popupshown", onpopupshown2, false);
|
||||
executeSoon(function() {
|
||||
menupopups[1].openPopup();
|
||||
});
|
||||
}
|
||||
|
||||
function onpopupshown2(evt) {
|
||||
menupopups[1].removeEventListener(evt.type, onpopupshown2, false);
|
||||
|
||||
// By default bodies are not logged.
|
||||
isnot(menuitems[1].getAttribute("checked"), "true",
|
||||
"menuitems[1] is not checked");
|
||||
|
||||
ok(!huds[1].ui._saveRequestAndResponseBodies, "bodies are not logged");
|
||||
|
||||
// Enable body logging.
|
||||
huds[1].ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
menupopups[1].hidePopup();
|
||||
});
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(evtPopup) {
|
||||
menupopups[1].removeEventListener(evtPopup.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Reopen the context menu.
|
||||
huds[1].ui.once("save-bodies-ui-toggled", () => testpopup2b(evtPopup));
|
||||
menupopups[1].openPopup();
|
||||
}, false);
|
||||
}
|
||||
|
||||
function testpopup2b() {
|
||||
is(menuitems[1].getAttribute("checked"), "true", "menuitems[1] is checked");
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(evtPopup) {
|
||||
menupopups[1].removeEventListener(evtPopup.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Switch to tab 1 and open the Web Console context menu from there.
|
||||
gBrowser.selectedTab = tabs[runCount * 2];
|
||||
waitForFocus(function() {
|
||||
// Find the relevant elements in the Web Console of tab 1.
|
||||
let win1 = tabs[runCount * 2].linkedBrowser.contentWindow;
|
||||
huds[0] = HUDService.getHudByWindow(win1);
|
||||
|
||||
info("iframe1 root height " + huds[0].ui.rootElement.clientHeight);
|
||||
|
||||
menuitems[0] = huds[0].ui.rootElement.querySelector("#saveBodies");
|
||||
menupopups[0] = huds[0].ui.rootElement.querySelector("menupopup");
|
||||
|
||||
menupopups[0].addEventListener("popupshown", onpopupshown1, false);
|
||||
executeSoon(() => menupopups[0].openPopup());
|
||||
}, tabs[runCount * 2].linkedBrowser.contentWindow);
|
||||
}, false);
|
||||
|
||||
executeSoon(function() {
|
||||
menupopups[1].hidePopup();
|
||||
});
|
||||
}
|
||||
|
||||
function onpopupshown1(evt) {
|
||||
menupopups[0].removeEventListener(evt.type, onpopupshown1, false);
|
||||
|
||||
// The menuitem checkbox must not be in sync with the other tabs.
|
||||
isnot(menuitems[0].getAttribute("checked"), "true",
|
||||
"menuitems[0] is not checked");
|
||||
|
||||
// Enable body logging for tab 1 as well.
|
||||
huds[0].ui.setSaveRequestAndResponseBodies(true).then(() => {
|
||||
menupopups[0].hidePopup();
|
||||
});
|
||||
|
||||
// Close the menu, and switch back to tab 2.
|
||||
menupopups[0].addEventListener("popuphidden", function _onhidden(evtPopup) {
|
||||
menupopups[0].removeEventListener(evtPopup.type, _onhidden, false);
|
||||
|
||||
info("menupopups[0] hidden");
|
||||
|
||||
gBrowser.selectedTab = tabs[runCount * 2 + 1];
|
||||
waitForFocus(function() {
|
||||
// Reopen the context menu from tab 2.
|
||||
huds[1].ui.once("save-bodies-ui-toggled", () => testpopup2c(evtPopup));
|
||||
menupopups[1].openPopup();
|
||||
}, tabs[runCount * 2 + 1].linkedBrowser.contentWindow);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function testpopup2c() {
|
||||
is(menuitems[1].getAttribute("checked"), "true", "menuitems[1] is checked");
|
||||
|
||||
menupopups[1].addEventListener("popuphidden", function _onhidden(evtPopup) {
|
||||
menupopups[1].removeEventListener(evtPopup.type, _onhidden, false);
|
||||
|
||||
info("menupopups[1] hidden");
|
||||
|
||||
// Done if on second run
|
||||
closeConsole(gBrowser.selectedTab).then(function() {
|
||||
if (runCount == 0) {
|
||||
runCount++;
|
||||
info("start second run");
|
||||
executeSoon(test);
|
||||
} else {
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[2];
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[1];
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.selectedTab = tabs[0];
|
||||
gBrowser.removeCurrentTab();
|
||||
huds = menuitems = menupopups = tabs = null;
|
||||
executeSoon(finishTest);
|
||||
}
|
||||
});
|
||||
}, false);
|
||||
|
||||
executeSoon(function() {
|
||||
menupopups[1].hidePopup();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
let test = asyncTest(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
BrowserReload();
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
yield performTest(hud, results);
|
||||
});
|
||||
|
||||
function performTest(HUD, results) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let networkMessage = [...results[0].matched][0];
|
||||
ok(networkMessage, "network message element");
|
||||
|
||||
let networkLink = networkMessage.querySelector(".url");
|
||||
ok(networkLink, "found network message link");
|
||||
|
||||
let popupset = document.getElementById("mainPopupSet");
|
||||
ok(popupset, "found #mainPopupSet");
|
||||
|
||||
let popupsShown = 0;
|
||||
let hiddenPopups = 0;
|
||||
|
||||
let onpopupshown = function() {
|
||||
document.removeEventListener("popupshown", onpopupshown, false);
|
||||
popupsShown++;
|
||||
|
||||
executeSoon(function() {
|
||||
let popups = popupset.querySelectorAll("panel[hudId=" + HUD.hudId + "]");
|
||||
is(popups.length, 1, "found one popup");
|
||||
|
||||
document.addEventListener("popuphidden", onpopuphidden, false);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(hiddenPopups, 1, "correct number of popups hidden");
|
||||
if (hiddenPopups != 1) {
|
||||
document.removeEventListener("popuphidden", onpopuphidden, false);
|
||||
}
|
||||
});
|
||||
|
||||
executeSoon(closeConsole);
|
||||
});
|
||||
};
|
||||
|
||||
let onpopuphidden = function() {
|
||||
document.removeEventListener("popuphidden", onpopuphidden, false);
|
||||
hiddenPopups++;
|
||||
|
||||
executeSoon(function() {
|
||||
let popups = popupset.querySelectorAll("panel[hudId=" + HUD.hudId + "]");
|
||||
is(popups.length, 0, "no popups found");
|
||||
|
||||
executeSoon(deferred.resolve);
|
||||
});
|
||||
};
|
||||
|
||||
document.addEventListener("popupshown", onpopupshown, false);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
is(popupsShown, 1, "correct number of popups shown");
|
||||
if (popupsShown != 1) {
|
||||
document.removeEventListener("popupshown", onpopupshown, false);
|
||||
}
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, networkLink,
|
||||
HUD.iframeWindow);
|
||||
EventUtils.sendMouseEvent({ type: "mouseup" }, networkLink, HUD.iframeWindow);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, networkLink, HUD.iframeWindow);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
|
@ -191,22 +191,20 @@ function testFormSubmission() {
|
|||
function testNetworkPanel() {
|
||||
// Open the NetworkPanel. The functionality of the NetworkPanel is tested
|
||||
// within separate test files.
|
||||
hud.ui.openNetworkPanel(lastRequest.actor).then(() => {
|
||||
let toolbox = gDevTools.getToolbox(hud.target);
|
||||
is(toolbox.currentToolId, "netmonitor", "Network panel was opened");
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
let selected = panel.panelWin.NetMonitorView.RequestsMenu.selectedItem;
|
||||
is(selected.attachment.method, lastRequest.request.method,
|
||||
"The correct request is selected");
|
||||
is(selected.attachment.url, lastRequest.request.url,
|
||||
"The correct request is definitely selected");
|
||||
let networkPanel = hud.ui.openNetworkPanel(hud.ui.filterBox, lastRequest);
|
||||
|
||||
networkPanel.panel.addEventListener("popupshown", function onPopupShown() {
|
||||
networkPanel.panel.removeEventListener("popupshown", onPopupShown, true);
|
||||
|
||||
is(hud.ui.filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on anchor node");
|
||||
ok(true, "NetworkPanel was opened");
|
||||
|
||||
// All tests are done. Shutdown.
|
||||
networkPanel.panel.hidePopup();
|
||||
lastRequest = null;
|
||||
HUDService.lastFinishedRequest.callback = null;
|
||||
browser = requestCallback = hud = null;
|
||||
executeSoon(finishTest);
|
||||
}).then(null, error => {
|
||||
ok(false, "Got an error: " + error.message + "\n" + error.stack);
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,551 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
// Tests that the network panel works.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-console.html";
|
||||
const TEST_IMG = "http://example.com/browser/browser/devtools/webconsole/" +
|
||||
"test/test-image.png";
|
||||
const TEST_ENCODING_ISO_8859_1 = "http://example.com/browser/browser/" +
|
||||
"devtools/webconsole/test/" +
|
||||
"test-encoding-ISO-8859-1.html";
|
||||
|
||||
const TEST_IMG_BASE64 =
|
||||
"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAVRJ" +
|
||||
"REFUOI2lk7FLw0AUxr+YpC1CBqcMWfsvCCLdXFzqEJCgDl1EQRGxg9AhSBEJONhFhG52UCuF" +
|
||||
"Djq5dxD8FwoO0qGDOBQkl7vLOeWa2EQDffDBvTu+373Hu1OEEJgntGgxGD6J+7fLXKbt5VNU" +
|
||||
"yhsKAChRBQcPFVFeWskFGH694mZroCQqCLlAwPxcgJBP254CmAD5B7C7dgHLMLF3uzoL4DQE" +
|
||||
"od+Z5sP1FizDxGgyBqfhLID9AahX29J89bwPFgMsSEAQglAf9WobhPpScbPXr4FQHyzIADTs" +
|
||||
"DizDRMPuIOC+zEeTMZo9BwH3EfAMACccbtfGaDKGZZg423yUZrdrg3EqxQlPr0BTdTR7joRE" +
|
||||
"N2uqnlBmCwW1hIJagtev4f3zA16/JvfiigMSYyzqJXlw/XKUyOORMUaBor6YavgdjKa8xGOn" +
|
||||
"idadmwtwsnMu18q83/kHSou+bFNDDr4AAAAASUVORK5CYII=";
|
||||
|
||||
let testDriver, hud;
|
||||
|
||||
function test() {
|
||||
loadTab(TEST_URI).then(() => {
|
||||
openConsole().then(testNetworkPanel);
|
||||
});
|
||||
}
|
||||
|
||||
function testNetworkPanel(aHud) {
|
||||
hud = aHud;
|
||||
testDriver = testGen();
|
||||
testDriver.next();
|
||||
}
|
||||
|
||||
function checkIsVisible(aPanel, aList) {
|
||||
for (let id in aList) {
|
||||
let node = aPanel.document.getElementById(id);
|
||||
let isVisible = aList[id];
|
||||
is(node.style.display, (isVisible ? "block" : "none"),
|
||||
id + " isVisible=" + isVisible);
|
||||
}
|
||||
}
|
||||
|
||||
function checkNodeContent(aPanel, aId, aContent) {
|
||||
let node = aPanel.document.getElementById(aId);
|
||||
if (node == null) {
|
||||
ok(false, "Tried to access node " + aId + " that doesn't exist!");
|
||||
} else if (node.textContent.indexOf(aContent) != -1) {
|
||||
ok(true, "checking content of " + aId);
|
||||
} else {
|
||||
ok(false, "Got false value for " + aId + ": " + node.textContent +
|
||||
" doesn't have " + aContent);
|
||||
}
|
||||
}
|
||||
|
||||
function checkNodeKeyValue(aPanel, aId, aKey, aValue) {
|
||||
let node = aPanel.document.getElementById(aId);
|
||||
|
||||
let headers = node.querySelectorAll("th");
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
if (headers[i].textContent == (aKey + ":")) {
|
||||
is(headers[i].nextElementSibling.textContent, aValue,
|
||||
"checking content of " + aId + " for key " + aKey);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ok(false, "content check failed for " + aId + ", key " + aKey);
|
||||
}
|
||||
|
||||
function* testGen() {
|
||||
let filterBox = hud.ui.filterBox;
|
||||
|
||||
let httpActivity = {
|
||||
updates: [],
|
||||
discardRequestBody: true,
|
||||
discardResponseBody: true,
|
||||
startedDateTime: (new Date()).toISOString(),
|
||||
request: {
|
||||
url: "http://www.testpage.com",
|
||||
method: "GET",
|
||||
cookies: [],
|
||||
headers: [
|
||||
{ name: "foo", value: "bar" },
|
||||
],
|
||||
},
|
||||
response: {
|
||||
headers: [],
|
||||
content: {},
|
||||
cookies: [],
|
||||
},
|
||||
timings: {},
|
||||
};
|
||||
|
||||
let networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on the anchor object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
info("test 1");
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestCookie: false,
|
||||
requestFormData: false,
|
||||
requestBody: false,
|
||||
responseContainer: false,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "header", "http://www.testpage.com");
|
||||
checkNodeContent(networkPanel, "header", "GET");
|
||||
checkNodeKeyValue(networkPanel, "requestHeadersContent", "foo", "bar");
|
||||
|
||||
// Test request body.
|
||||
info("test 2: request body");
|
||||
httpActivity.discardRequestBody = false;
|
||||
httpActivity.request.postData = { text: "hello world" };
|
||||
networkPanel.update();
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: false,
|
||||
responseContainer: false,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
checkNodeContent(networkPanel, "requestBodyContent", "hello world");
|
||||
|
||||
// Test response header.
|
||||
info("test 3: response header");
|
||||
httpActivity.timings.wait = 10;
|
||||
httpActivity.response.httpVersion = "HTTP/3.14";
|
||||
httpActivity.response.status = 999;
|
||||
httpActivity.response.statusText = "earthquake win";
|
||||
httpActivity.response.content.mimeType = "text/html";
|
||||
httpActivity.response.headers.push(
|
||||
{ name: "Content-Type", value: "text/html" },
|
||||
{ name: "leaveHouses", value: "true" }
|
||||
);
|
||||
|
||||
networkPanel.update();
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: false,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "header", "HTTP/3.14 999 earthquake win");
|
||||
checkNodeKeyValue(networkPanel, "responseHeadersContent", "leaveHouses",
|
||||
"true");
|
||||
checkNodeContent(networkPanel, "responseHeadersInfo", "10ms");
|
||||
|
||||
info("test 4");
|
||||
|
||||
httpActivity.discardResponseBody = false;
|
||||
httpActivity.timings.receive = 2;
|
||||
networkPanel.update();
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: false,
|
||||
requestFormData: false,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
info("test 5");
|
||||
|
||||
httpActivity.updates.push("responseContent", "eventTimings");
|
||||
networkPanel.update();
|
||||
|
||||
checkNodeContent(networkPanel, "responseNoBodyInfo", "2ms");
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestCookie: false,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: true,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Second run: Test for cookies and response body.
|
||||
info("test 6: cookies and response body");
|
||||
httpActivity.request.cookies.push(
|
||||
{ name: "foo", value: "bar" },
|
||||
{ name: "hello", value: "world" }
|
||||
);
|
||||
httpActivity.response.content.text = "get out here";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on httpActivity object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseCookie: false,
|
||||
responseBody: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeKeyValue(networkPanel, "requestCookieContent", "foo", "bar");
|
||||
checkNodeKeyValue(networkPanel, "requestCookieContent", "hello", "world");
|
||||
checkNodeContent(networkPanel, "responseBodyContent", "get out here");
|
||||
checkNodeContent(networkPanel, "responseBodyInfo", "2ms");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Third run: Test for response cookies.
|
||||
info("test 6b: response cookies");
|
||||
httpActivity.response.cookies.push(
|
||||
{ name: "foobar", value: "boom" },
|
||||
{ name: "foobaz", value: "omg" }
|
||||
);
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
is(filterBox._netPanel, networkPanel,
|
||||
"Network panel stored on httpActivity object");
|
||||
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseCookie: true,
|
||||
responseBody: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false,
|
||||
responseBodyFetchLink: false,
|
||||
});
|
||||
|
||||
checkNodeKeyValue(networkPanel, "responseCookieContent", "foobar", "boom");
|
||||
checkNodeKeyValue(networkPanel, "responseCookieContent", "foobaz", "omg");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Check image request.
|
||||
info("test 7: image request");
|
||||
httpActivity.response.headers[1].value = "image/png";
|
||||
httpActivity.response.content.mimeType = "image/png";
|
||||
httpActivity.response.content.text = TEST_IMG_BASE64;
|
||||
httpActivity.request.url = TEST_IMG;
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: true,
|
||||
responseImageCached: false,
|
||||
responseBodyFetchLink: false,
|
||||
});
|
||||
|
||||
let imgNode = networkPanel.document.getElementById("responseImageNode");
|
||||
is(imgNode.getAttribute("src"), "data:image/png;base64," + TEST_IMG_BASE64,
|
||||
"Displayed image is correct");
|
||||
|
||||
function checkImageResponseInfo() {
|
||||
checkNodeContent(networkPanel, "responseImageInfo", "2ms");
|
||||
checkNodeContent(networkPanel, "responseImageInfo", "16x16px");
|
||||
}
|
||||
|
||||
// Check if the image is loaded already.
|
||||
imgNode.addEventListener("load", function onLoad() {
|
||||
imgNode.removeEventListener("load", onLoad, false);
|
||||
checkImageResponseInfo();
|
||||
networkPanel.panel.hidePopup();
|
||||
testDriver.next();
|
||||
}, false);
|
||||
yield undefined;
|
||||
|
||||
// Check cached image request.
|
||||
info("test 8: cached image request");
|
||||
httpActivity.response.httpVersion = "HTTP/1.1";
|
||||
httpActivity.response.status = 304;
|
||||
httpActivity.response.statusText = "Not Modified";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: true,
|
||||
requestFormData: false,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: true
|
||||
});
|
||||
|
||||
imgNode = networkPanel.document.getElementById("responseImageCachedNode");
|
||||
is(imgNode.getAttribute("src"), "data:image/png;base64," + TEST_IMG_BASE64,
|
||||
"Displayed image is correct");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Test sent form data.
|
||||
info("test 9: sent form data");
|
||||
httpActivity.request.postData.text = [
|
||||
"Content-Type: application/x-www-form-urlencoded",
|
||||
"Content-Length: 59",
|
||||
"name=rob&age=20"
|
||||
].join("\n");
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: true
|
||||
});
|
||||
|
||||
checkNodeKeyValue(networkPanel, "requestFormDataContent", "name", "rob");
|
||||
checkNodeKeyValue(networkPanel, "requestFormDataContent", "age", "20");
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Test no space after Content-Type:
|
||||
info("test 10: no space after Content-Type header in post data");
|
||||
httpActivity.request.postData.text = "Content-Type:application/x-www-" +
|
||||
"form-urlencoded\n";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: true
|
||||
});
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Test cached data.
|
||||
|
||||
info("test 11: cached data");
|
||||
|
||||
httpActivity.request.url = TEST_ENCODING_ISO_8859_1;
|
||||
httpActivity.response.headers[1].value = "application/json";
|
||||
httpActivity.response.content.mimeType = "application/json";
|
||||
httpActivity.response.content.text = "my cached data is here!";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseBodyCached: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
checkNodeContent(networkPanel, "responseBodyCachedContent",
|
||||
"my cached data is here!");
|
||||
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
// Test a response with a content type that can't be displayed in the
|
||||
// NetworkPanel.
|
||||
info("test 12: unknown content type");
|
||||
httpActivity.response.headers[1].value = "application/x-shockwave-flash";
|
||||
httpActivity.response.content.mimeType = "application/x-shockwave-flash";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel._onUpdate = function() {
|
||||
networkPanel._onUpdate = null;
|
||||
executeSoon(function() {
|
||||
testDriver.next();
|
||||
});
|
||||
};
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseBodyCached: false,
|
||||
responseBodyUnknownType: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
let responseString =
|
||||
WCUL10n.getFormatStr("NetworkPanel.responseBodyUnableToDisplay.content",
|
||||
["application/x-shockwave-flash"]);
|
||||
checkNodeContent(networkPanel,
|
||||
"responseBodyUnknownTypeContent",
|
||||
responseString);
|
||||
networkPanel.panel.hidePopup();
|
||||
|
||||
/*
|
||||
|
||||
// This test disabled. See bug 603620.
|
||||
|
||||
// Test if the NetworkPanel figures out the content type based on an URL as
|
||||
// well.
|
||||
delete httpActivity.response.header["Content-Type"];
|
||||
httpActivity.url = "http://www.test.com/someCrazyFile.swf?done=right&ending=txt";
|
||||
|
||||
networkPanel = hud.ui.openNetworkPanel(filterBox, httpActivity);
|
||||
networkPanel.isDoneCallback = function NP_doneCallback() {
|
||||
networkPanel.isDoneCallback = null;
|
||||
testDriver.next();
|
||||
}
|
||||
|
||||
yield undefined;
|
||||
|
||||
checkIsVisible(networkPanel, {
|
||||
requestBody: false,
|
||||
requestFormData: true,
|
||||
requestCookie: true,
|
||||
responseContainer: true,
|
||||
responseBody: false,
|
||||
responseBodyCached: false,
|
||||
responseBodyUnknownType: true,
|
||||
responseNoBody: false,
|
||||
responseImage: false,
|
||||
responseImageCached: false
|
||||
});
|
||||
|
||||
// Systems without Flash installed will return an empty string here. Ignore.
|
||||
if (networkPanel.document.getElementById("responseBodyUnknownTypeContent").textContent !== "")
|
||||
checkNodeContent(networkPanel, "responseBodyUnknownTypeContent", responseString);
|
||||
else
|
||||
ok(true, "Flash not installed");
|
||||
|
||||
networkPanel.panel.hidePopup(); */
|
||||
|
||||
// All done!
|
||||
testDriver = hud = null;
|
||||
executeSoon(finishTest);
|
||||
|
||||
yield undefined;
|
||||
}
|
|
@ -20,6 +20,8 @@ loader.lazyGetter(this, "AutocompletePopup",
|
|||
() => require("devtools/shared/autocomplete-popup").AutocompletePopup);
|
||||
loader.lazyGetter(this, "ToolSidebar",
|
||||
() => require("devtools/framework/sidebar").ToolSidebar);
|
||||
loader.lazyGetter(this, "NetworkPanel",
|
||||
() => require("devtools/webconsole/network-panel").NetworkPanel);
|
||||
loader.lazyGetter(this, "ConsoleOutput",
|
||||
() => require("devtools/webconsole/console-output").ConsoleOutput);
|
||||
loader.lazyGetter(this, "Messages",
|
||||
|
@ -1671,7 +1673,11 @@ WebConsoleFrame.prototype = {
|
|||
statusNode.className = "status";
|
||||
body.appendChild(statusNode);
|
||||
|
||||
let onClick = () => this.openNetworkPanel(networkInfo.actor);
|
||||
let onClick = () => {
|
||||
if (!messageNode._panelOpen) {
|
||||
this.openNetworkPanel(messageNode, networkInfo);
|
||||
}
|
||||
};
|
||||
|
||||
this._addMessageLinkCallback(urlNode, onClick);
|
||||
this._addMessageLinkCallback(statusNode, onClick);
|
||||
|
@ -1963,17 +1969,134 @@ WebConsoleFrame.prototype = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Opens the network monitor and highlights the specified request.
|
||||
* Opens a NetworkPanel.
|
||||
*
|
||||
* @param string requestId
|
||||
* The actor ID of the network request.
|
||||
* @param nsIDOMNode aNode
|
||||
* The message node you want the panel to be anchored to.
|
||||
* @param object aHttpActivity
|
||||
* The HTTP activity object that holds network request and response
|
||||
* information. This object is given to the NetworkPanel constructor.
|
||||
* @return object
|
||||
* The new NetworkPanel instance.
|
||||
*/
|
||||
openNetworkPanel: function WCF_openNetworkPanel(requestId)
|
||||
openNetworkPanel: function WCF_openNetworkPanel(aNode, aHttpActivity)
|
||||
{
|
||||
let toolbox = gDevTools.getToolbox(this.owner.target);
|
||||
return toolbox.selectTool("netmonitor").then(panel => {
|
||||
return panel.panelWin.NetMonitorController.inspectRequest(requestId);
|
||||
});
|
||||
let actor = aHttpActivity.actor;
|
||||
|
||||
if (actor) {
|
||||
this.webConsoleClient.getRequestHeaders(actor, (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getRequestHeaders:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.request.headers = aResponse.headers;
|
||||
|
||||
this.webConsoleClient.getRequestCookies(actor, onRequestCookies);
|
||||
});
|
||||
}
|
||||
|
||||
let onRequestCookies = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getRequestCookies:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.request.cookies = aResponse.cookies;
|
||||
|
||||
this.webConsoleClient.getResponseHeaders(actor, onResponseHeaders);
|
||||
};
|
||||
|
||||
let onResponseHeaders = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getResponseHeaders:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.response.headers = aResponse.headers;
|
||||
|
||||
this.webConsoleClient.getResponseCookies(actor, onResponseCookies);
|
||||
};
|
||||
|
||||
let onResponseCookies = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getResponseCookies:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.response.cookies = aResponse.cookies;
|
||||
|
||||
this.webConsoleClient.getRequestPostData(actor, onRequestPostData);
|
||||
};
|
||||
|
||||
let onRequestPostData = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getRequestPostData:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.request.postData = aResponse.postData;
|
||||
aHttpActivity.discardRequestBody = aResponse.postDataDiscarded;
|
||||
|
||||
this.webConsoleClient.getResponseContent(actor, onResponseContent);
|
||||
};
|
||||
|
||||
let onResponseContent = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getResponseContent:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.response.content = aResponse.content;
|
||||
aHttpActivity.discardResponseBody = aResponse.contentDiscarded;
|
||||
|
||||
this.webConsoleClient.getEventTimings(actor, onEventTimings);
|
||||
};
|
||||
|
||||
let onEventTimings = (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
Cu.reportError("WCF_openNetworkPanel getEventTimings:" +
|
||||
aResponse.error);
|
||||
return;
|
||||
}
|
||||
|
||||
aHttpActivity.timings = aResponse.timings;
|
||||
|
||||
openPanel();
|
||||
};
|
||||
|
||||
let openPanel = () => {
|
||||
aNode._netPanel = netPanel;
|
||||
|
||||
let panel = netPanel.panel;
|
||||
panel.openPopup(aNode, "after_pointer", 0, 0, false, false);
|
||||
panel.sizeTo(450, 500);
|
||||
panel.setAttribute("hudId", this.hudId);
|
||||
|
||||
panel.addEventListener("popuphiding", function WCF_netPanel_onHide() {
|
||||
panel.removeEventListener("popuphiding", WCF_netPanel_onHide);
|
||||
|
||||
aNode._panelOpen = false;
|
||||
aNode._netPanel = null;
|
||||
});
|
||||
|
||||
aNode._panelOpen = true;
|
||||
};
|
||||
|
||||
let netPanel = new NetworkPanel(this.popupset, aHttpActivity, this);
|
||||
netPanel.linkNode = aNode;
|
||||
|
||||
if (!actor) {
|
||||
openPanel();
|
||||
}
|
||||
|
||||
return netPanel;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -141,9 +141,6 @@ endif
|
|||
ifdef MOZ_SHARED_ICU
|
||||
DEFINES += -DMOZ_SHARED_ICU
|
||||
endif
|
||||
ifdef MOZ_JEMALLOC4
|
||||
DEFINES += -DMOZ_JEMALLOC4
|
||||
endif
|
||||
DEFINES += -DMOZ_ICU_DBG_SUFFIX=$(MOZ_ICU_DBG_SUFFIX)
|
||||
ifdef CLANG_CXX
|
||||
DEFINES += -DCLANG_CXX
|
||||
|
|
|
@ -123,11 +123,6 @@
|
|||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#ifdef MOZ_REPLACE_MALLOC
|
||||
#ifndef MOZ_JEMALLOC4
|
||||
@BINPATH@/@DLL_PREFIX@replace_jemalloc@DLL_SUFFIX@
|
||||
#endif
|
||||
#endif
|
||||
#ifdef MOZ_GTK3
|
||||
@BINPATH@/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
|
||||
@BINPATH@/gtk2/@DLL_PREFIX@mozgtk@DLL_SUFFIX@
|
||||
|
|
|
@ -11,6 +11,24 @@
|
|||
<!ENTITY window.title "Web Console">
|
||||
<!ENTITY browserConsole.title "Browser Console">
|
||||
|
||||
<!ENTITY networkPanel.requestURLColon "Request URL:">
|
||||
<!ENTITY networkPanel.requestMethodColon "Request Method:">
|
||||
<!ENTITY networkPanel.statusCodeColon "Status Code:">
|
||||
|
||||
<!ENTITY networkPanel.requestHeaders "Request Headers">
|
||||
<!ENTITY networkPanel.requestCookie "Sent Cookie">
|
||||
<!ENTITY networkPanel.requestBody "Request Body">
|
||||
<!ENTITY networkPanel.requestFormData "Sent Form Data">
|
||||
|
||||
<!ENTITY networkPanel.responseHeaders "Response Headers">
|
||||
<!ENTITY networkPanel.responseCookie "Received Cookie">
|
||||
<!ENTITY networkPanel.responseBody "Response Body">
|
||||
<!ENTITY networkPanel.responseBodyCached "Cached Data">
|
||||
<!ENTITY networkPanel.responseBodyUnknownType "Unknown Content Type">
|
||||
<!ENTITY networkPanel.responseNoBody "No Response Body">
|
||||
<!ENTITY networkPanel.responseImage "Received Image">
|
||||
<!ENTITY networkPanel.responseImageCached "Cached Image">
|
||||
|
||||
<!-- LOCALIZATION NOTE (saveBodies.label): You can see this string in the Web
|
||||
- Console context menu. -->
|
||||
<!ENTITY saveBodies.label "Log Request and Response Bodies">
|
||||
|
|
|
@ -40,12 +40,29 @@ webConsoleCmd.accesskey=W
|
|||
timestampFormat=%02S:%02S:%02S.%03S
|
||||
|
||||
helperFuncUnsupportedTypeError=Can't call pprint on this type of object.
|
||||
NetworkPanel.label=Inspect Network Request
|
||||
|
||||
# LOCALIZATION NOTE (NetworkPanel.deltaDurationMS): this string is used to
|
||||
# show the duration between two network events (e.g request and response
|
||||
# header or response header and response body). Parameters: %S is the duration.
|
||||
NetworkPanel.durationMS=%Sms
|
||||
|
||||
# LOCALIZATION NOTE (NetworkPanel.imageSizeDeltaDurationMS): this string is
|
||||
# used to show the duration between the response header and the response body
|
||||
# event. It also shows the size of the received or cached image. Parameters:
|
||||
# %1$S is the width of the inspected image, %2$S is the height of the
|
||||
# inspected image, %3$S is the duration between the response header and the
|
||||
# response body event. Example: 150x100px, Δ50ms.
|
||||
NetworkPanel.imageSizeDeltaDurationMS=%1$Sx%2$Spx, Δ%3$Sms
|
||||
|
||||
# LOCALIZATION NOTE (NetworkPanel.responseBodyUnableToDisplay.content): this
|
||||
# string is displayed within the response body section of the NetworkPanel if
|
||||
# the content type of the network request can't be displayed. E.g. any kind of
|
||||
# text is easy to display, but some audio or flash data received from the
|
||||
# server can't be displayed. Parameters: %S is the content type that can't be
|
||||
# displayed, examples are application/x-shockwave-flash, music/crescendo.
|
||||
NetworkPanel.responseBodyUnableToDisplay.content=Unable to display responses of type "%S"
|
||||
|
||||
ConsoleAPIDisabled=The Web Console logging API (console.log, console.info, console.warn, console.error) has been disabled by a script on this page.
|
||||
|
||||
# LOCALIZATION NOTE (webConsoleWindowTitleAndURL): the Web Console floating
|
||||
|
|
|
@ -330,6 +330,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/alerticon-warning@2x.png (../shared/devtools/images/alerticon-warning@2x.png)
|
||||
* skin/classic/browser/devtools/ruleview.css (../shared/devtools/ruleview.css)
|
||||
* skin/classic/browser/devtools/webconsole.css (../shared/devtools/webconsole.css)
|
||||
skin/classic/browser/devtools/webconsole_networkpanel.css (../shared/devtools/webconsole_networkpanel.css)
|
||||
skin/classic/browser/devtools/webconsole.svg (../shared/devtools/images/webconsole.svg)
|
||||
skin/classic/browser/devtools/commandline.css (../shared/devtools/commandline.css)
|
||||
skin/classic/browser/devtools/markup-view.css (../shared/devtools/markup-view.css)
|
||||
|
|
|
@ -432,6 +432,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/editor-debug-location.png (../shared/devtools/images/editor-debug-location.png)
|
||||
skin/classic/browser/devtools/editor-debug-location@2x.png (../shared/devtools/images/editor-debug-location@2x.png)
|
||||
* skin/classic/browser/devtools/webconsole.css (../shared/devtools/webconsole.css)
|
||||
skin/classic/browser/devtools/webconsole_networkpanel.css (../shared/devtools/webconsole_networkpanel.css)
|
||||
skin/classic/browser/devtools/webconsole.svg (../shared/devtools/images/webconsole.svg)
|
||||
skin/classic/browser/devtools/breadcrumbs-divider@2x.png (../shared/devtools/images/breadcrumbs-divider@2x.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton.png (../shared/devtools/images/breadcrumbs-scrollbutton.png)
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/* 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/. */
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 11px;
|
||||
background: #EEE;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#header {
|
||||
padding: 5px;
|
||||
overflow-x:auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 13px;
|
||||
line-height: 15px;
|
||||
padding: 3px 10px;
|
||||
vertical-align: bottom;
|
||||
margin: 0px;
|
||||
background: linear-gradient(#BBB, #999);
|
||||
border-radius: 2px;
|
||||
text-shadow: #FFF 0px 1px 0px;
|
||||
}
|
||||
|
||||
h1 .info {
|
||||
font-size: 11px;
|
||||
line-height: 15px;
|
||||
vertical-align: bottom;
|
||||
float: right;
|
||||
color: #333;
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.property-table {
|
||||
padding: 2px 5px;
|
||||
background: linear-gradient(#FFF, #F8F8F8);
|
||||
color: #333;
|
||||
width: 100%;
|
||||
max-height: 330px;
|
||||
overflow: auto;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.property-name {
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
padding-right: 4px;
|
||||
color: #000;
|
||||
white-space: nowrap;
|
||||
text-align: end;
|
||||
vertical-align: top;
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.property-value {
|
||||
padding-right: 5px;
|
||||
font-size: 11px;
|
||||
word-wrap: break-word;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
div.group {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.group,
|
||||
#header {
|
||||
background: #FFF;
|
||||
border-color: #E1E1E1;
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
box-shadow: 0 1px 1.5px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 4px 4px 4px 4px;
|
||||
}
|
||||
|
||||
img#responseImageNode {
|
||||
box-shadow: rgba(0,0,0,0.2) 0px 3px 3.5px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
#responseImageNodeDiv {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#responseBodyFetchLink, #requestBodyFetchLink {
|
||||
padding: 5px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.longStringEllipsis {
|
||||
margin-left: 0.6em;
|
||||
}
|
|
@ -457,6 +457,7 @@ browser.jar:
|
|||
skin/classic/browser/devtools/editor-debug-location.png (../shared/devtools/images/editor-debug-location.png)
|
||||
skin/classic/browser/devtools/editor-debug-location@2x.png (../shared/devtools/images/editor-debug-location@2x.png)
|
||||
* skin/classic/browser/devtools/webconsole.css (../shared/devtools/webconsole.css)
|
||||
skin/classic/browser/devtools/webconsole_networkpanel.css (../shared/devtools/webconsole_networkpanel.css)
|
||||
skin/classic/browser/devtools/webconsole.svg (../shared/devtools/images/webconsole.svg)
|
||||
skin/classic/browser/devtools/breadcrumbs-divider@2x.png (../shared/devtools/images/breadcrumbs-divider@2x.png)
|
||||
skin/classic/browser/devtools/breadcrumbs-scrollbutton.png (../shared/devtools/images/breadcrumbs-scrollbutton.png)
|
||||
|
|
|
@ -280,6 +280,8 @@ static CustomTypeAnnotation HeapClass =
|
|||
CustomTypeAnnotation("moz_heap_class", "heap");
|
||||
static CustomTypeAnnotation MustUse =
|
||||
CustomTypeAnnotation("moz_must_use", "must-use");
|
||||
static CustomTypeAnnotation NonMemMovable =
|
||||
CustomTypeAnnotation("moz_non_memmovable", "non-memmove()able");
|
||||
|
||||
class MozChecker : public ASTConsumer, public RecursiveASTVisitor<MozChecker> {
|
||||
DiagnosticsEngine &Diag;
|
||||
|
@ -474,92 +476,6 @@ bool isClassRefCounted(QualType T) {
|
|||
return clazz ? isClassRefCounted(clazz) : false;
|
||||
}
|
||||
|
||||
/// A cached data of whether classes are memmovable, and if not, what
|
||||
/// declaration
|
||||
/// makes them non-movable
|
||||
typedef DenseMap<const CXXRecordDecl *, const CXXRecordDecl *>
|
||||
InferredMovability;
|
||||
InferredMovability inferredMovability;
|
||||
|
||||
bool isClassNonMemMovable(QualType T);
|
||||
const CXXRecordDecl *isClassNonMemMovableWorker(QualType T);
|
||||
|
||||
const CXXRecordDecl *isClassNonMemMovableWorker(const CXXRecordDecl *D) {
|
||||
// If we have a definition, then we want to standardize our reference to point
|
||||
// to the definition node. If we don't have a definition, that means that
|
||||
// either
|
||||
// we only have a forward declaration of the type in our file, or we are being
|
||||
// passed a template argument which is not used, and thus never instantiated
|
||||
// by
|
||||
// clang.
|
||||
// As the argument isn't used, we can't memmove it (as we don't know it's
|
||||
// size),
|
||||
// which means not reporting an error is OK.
|
||||
if (!D->hasDefinition()) {
|
||||
return 0;
|
||||
}
|
||||
D = D->getDefinition();
|
||||
|
||||
// Are we explicitly marked as non-memmovable class?
|
||||
if (MozChecker::hasCustomAnnotation(D, "moz_non_memmovable")) {
|
||||
return D;
|
||||
}
|
||||
|
||||
// Look through all base cases to figure out if the parent is a non-memmovable
|
||||
// class.
|
||||
for (CXXRecordDecl::base_class_const_iterator base = D->bases_begin();
|
||||
base != D->bases_end(); ++base) {
|
||||
const CXXRecordDecl *result = isClassNonMemMovableWorker(base->getType());
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Look through all members to figure out if a member is a non-memmovable
|
||||
// class.
|
||||
for (RecordDecl::field_iterator field = D->field_begin(), e = D->field_end();
|
||||
field != e; ++field) {
|
||||
const CXXRecordDecl *result = isClassNonMemMovableWorker(field->getType());
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const CXXRecordDecl *isClassNonMemMovableWorker(QualType T) {
|
||||
while (const ArrayType *arrTy = T->getAsArrayTypeUnsafe())
|
||||
T = arrTy->getElementType();
|
||||
const CXXRecordDecl *clazz = T->getAsCXXRecordDecl();
|
||||
return clazz ? isClassNonMemMovableWorker(clazz) : 0;
|
||||
}
|
||||
|
||||
bool isClassNonMemMovable(const CXXRecordDecl *D) {
|
||||
InferredMovability::iterator it = inferredMovability.find(D);
|
||||
if (it != inferredMovability.end())
|
||||
return !!it->second;
|
||||
const CXXRecordDecl *result = isClassNonMemMovableWorker(D);
|
||||
inferredMovability.insert(std::make_pair(D, result));
|
||||
return !!result;
|
||||
}
|
||||
|
||||
bool isClassNonMemMovable(QualType T) {
|
||||
while (const ArrayType *arrTy = T->getAsArrayTypeUnsafe())
|
||||
T = arrTy->getElementType();
|
||||
const CXXRecordDecl *clazz = T->getAsCXXRecordDecl();
|
||||
return clazz ? isClassNonMemMovable(clazz) : false;
|
||||
}
|
||||
|
||||
const CXXRecordDecl *findWhyClassIsNonMemMovable(QualType T) {
|
||||
while (const ArrayType *arrTy = T->getAsArrayTypeUnsafe())
|
||||
T = arrTy->getElementType();
|
||||
CXXRecordDecl *clazz = T->getAsCXXRecordDecl();
|
||||
InferredMovability::iterator it = inferredMovability.find(clazz);
|
||||
assert(it != inferredMovability.end());
|
||||
return it->second;
|
||||
}
|
||||
|
||||
template <class T> bool IsInSystemHeader(const ASTContext &AC, const T &D) {
|
||||
auto &SourceManager = AC.getSourceManager();
|
||||
auto ExpansionLoc = SourceManager.getExpansionLoc(D.getLocStart());
|
||||
|
@ -719,7 +635,9 @@ AST_MATCHER(CXXRecordDecl, hasNeedsNoVTableTypeAttr) {
|
|||
}
|
||||
|
||||
/// This matcher will select classes which are non-memmovable
|
||||
AST_MATCHER(QualType, isNonMemMovable) { return isClassNonMemMovable(Node); }
|
||||
AST_MATCHER(QualType, isNonMemMovable) {
|
||||
return NonMemMovable.hasEffectiveAnnotation(Node);
|
||||
}
|
||||
|
||||
/// This matcher will select classes which require a memmovable template arg
|
||||
AST_MATCHER(CXXRecordDecl, needsMemMovable) {
|
||||
|
@ -803,6 +721,7 @@ void CustomTypeAnnotation::dumpAnnotationReason(DiagnosticsEngine &Diag,
|
|||
break;
|
||||
}
|
||||
default:
|
||||
// FIXME (bug 1203263): note the original annotation.
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1323,11 +1242,6 @@ void DiagnosticsMatcher::NonMemMovableChecker::run(
|
|||
"Cannot instantiate %0 with non-memmovable template argument %1");
|
||||
unsigned note1ID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Note, "instantiation of %0 requested here");
|
||||
unsigned note2ID = Diag.getDiagnosticIDs()->getCustomDiagID(
|
||||
DiagnosticIDs::Note, "%0 is non-memmovable because of the "
|
||||
"MOZ_NON_MEMMOVABLE annotation on %1");
|
||||
unsigned note3ID =
|
||||
Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note, "%0");
|
||||
|
||||
// Get the specialization
|
||||
const ClassTemplateSpecializationDecl *specialization =
|
||||
|
@ -1341,8 +1255,7 @@ void DiagnosticsMatcher::NonMemMovableChecker::run(
|
|||
specialization->getTemplateInstantiationArgs();
|
||||
for (unsigned i = 0; i < args.size(); ++i) {
|
||||
QualType argType = args[i].getAsType();
|
||||
if (isClassNonMemMovable(args[i].getAsType())) {
|
||||
const CXXRecordDecl *reason = findWhyClassIsNonMemMovable(argType);
|
||||
if (NonMemMovable.hasEffectiveAnnotation(args[i].getAsType())) {
|
||||
Diag.Report(specialization->getLocation(), errorID) << specialization
|
||||
<< argType;
|
||||
// XXX It would be really nice if we could get the instantiation stack
|
||||
|
@ -1355,7 +1268,7 @@ void DiagnosticsMatcher::NonMemMovableChecker::run(
|
|||
// cases won't
|
||||
// be useful)
|
||||
Diag.Report(requestLoc, note1ID) << specialization;
|
||||
Diag.Report(reason->getLocation(), note2ID) << argType << reason;
|
||||
NonMemMovable.dumpAnnotationReason(Diag, argType, requestLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,37 @@
|
|||
#define MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS \
|
||||
__attribute__((annotate("moz_inherit_type_annotations_from_template_args")))
|
||||
#define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
|
||||
#define MOZ_NON_MEMMOVABLE __attribute__((annotate("moz_non_memmovable")))
|
||||
#define MOZ_NEEDS_MEMMOVABLE_TYPE __attribute__((annotate("moz_needs_memmovable_type")))
|
||||
|
||||
class Normal {};
|
||||
class MOZ_STACK_CLASS Stack {};
|
||||
class IndirectStack : Stack {}; // expected-note {{'IndirectStack' is a stack type because it inherits from a stack type 'Stack'}}
|
||||
class ContainsStack { Stack m; }; // expected-note {{'ContainsStack' is a stack type because member 'm' is a stack type 'Stack'}}
|
||||
class MOZ_NON_MEMMOVABLE Pointery {};
|
||||
class IndirectPointery : Pointery {}; // expected-note {{'IndirectPointery' is a non-memmove()able type because it inherits from a non-memmove()able type 'Pointery'}}
|
||||
class ContainsPointery { Pointery m; }; // expected-note {{'ContainsPointery' is a non-memmove()able type because member 'm' is a non-memmove()able type 'Pointery'}}
|
||||
|
||||
template<class T>
|
||||
class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Template {}; // expected-note 2 {{'Template<Stack>' is a stack type because it has a template argument stack type 'Stack'}} expected-note {{'Template<IndirectStack>' is a stack type because it has a template argument stack type 'IndirectStack'}}
|
||||
class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Template {}; // expected-note-re 5 {{'Template<{{.*}}>' is a stack type because it has a template argument stack type '{{.*}}'}} expected-note-re 5 {{'Template<{{.*}}>' is a non-memmove()able type because it has a template argument non-memmove()able type '{{.*}}'}}
|
||||
class IndirectTemplate : Template<Stack> {}; // expected-note {{'IndirectTemplate' is a stack type because it inherits from a stack type 'Template<Stack>'}}
|
||||
class ContainsTemplate { Template<Stack> m; }; // expected-note {{'ContainsTemplate' is a stack type because member 'm' is a stack type 'Template<Stack>'}}
|
||||
|
||||
static Template<Stack> a; // expected-error {{variable of type 'Template<Stack>' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}}
|
||||
static Template<IndirectStack> b; // expected-error {{variable of type 'Template<IndirectStack>' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}}
|
||||
static Template<Normal> c;
|
||||
static Template<ContainsStack> c; // expected-error {{variable of type 'Template<ContainsStack>' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}}
|
||||
static IndirectTemplate d; // expected-error {{variable of type 'IndirectTemplate' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}}
|
||||
static ContainsTemplate e; // expected-error {{variable of type 'ContainsTemplate' only valid on the stack}} expected-note {{value incorrectly allocated in a global variable}}
|
||||
static Template<Normal> f;
|
||||
|
||||
template<class T>
|
||||
class MOZ_NEEDS_MEMMOVABLE_TYPE Mover { char mForceInstantiation[sizeof(T)]; }; // expected-error-re 5 {{Cannot instantiate 'Mover<{{.*}}>' with non-memmovable template argument '{{.*}}'}}
|
||||
class IndirectTemplatePointery : Template<Pointery> {}; // expected-note {{'IndirectTemplatePointery' is a non-memmove()able type because it inherits from a non-memmove()able type 'Template<Pointery>'}}
|
||||
class ContainsTemplatePointery { Template<Pointery> m; }; // expected-note {{'ContainsTemplatePointery' is a non-memmove()able type because member 'm' is a non-memmove()able type 'Template<Pointery>'}}
|
||||
|
||||
static Mover<Template<Pointery>> n; // expected-note {{instantiation of 'Mover<Template<Pointery> >' requested here}}
|
||||
static Mover<Template<IndirectPointery>> o; // expected-note {{instantiation of 'Mover<Template<IndirectPointery> >' requested here}}
|
||||
static Mover<Template<ContainsPointery>> p; // expected-note {{instantiation of 'Mover<Template<ContainsPointery> >' requested here}}
|
||||
static Mover<IndirectTemplatePointery> q; // expected-note {{instantiation of 'Mover<IndirectTemplatePointery>' requested here}}
|
||||
static Mover<ContainsTemplatePointery> r; // expected-note {{instantiation of 'Mover<ContainsTemplatePointery>' requested here}}
|
||||
static Mover<Template<Normal>> s;
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
These are a bunch of structs with variable levels of memmovability.
|
||||
They will be used as template parameters to the various NeedyTemplates
|
||||
*/
|
||||
struct MOZ_NON_MEMMOVABLE NonMovable {}; // expected-note-re + {{'{{.*}}' is non-memmovable because of the MOZ_NON_MEMMOVABLE annotation on 'NonMovable'}}
|
||||
struct MOZ_NON_MEMMOVABLE NonMovable {};
|
||||
struct Movable {};
|
||||
|
||||
// Subclasses
|
||||
struct S_NonMovable : NonMovable {};
|
||||
struct S_NonMovable : NonMovable {}; // expected-note 48 {{'S_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'NonMovable'}}
|
||||
struct S_Movable : Movable {};
|
||||
|
||||
// Members
|
||||
struct W_NonMovable {
|
||||
NonMovable m;
|
||||
NonMovable m; // expected-note 32 {{'W_NonMovable' is a non-memmove()able type because member 'm' is a non-memmove()able type 'NonMovable'}}
|
||||
};
|
||||
struct W_Movable {
|
||||
Movable m;
|
||||
|
@ -22,23 +22,23 @@ struct W_Movable {
|
|||
|
||||
// Wrapped Subclasses
|
||||
struct WS_NonMovable {
|
||||
S_NonMovable m;
|
||||
S_NonMovable m; // expected-note 32 {{'WS_NonMovable' is a non-memmove()able type because member 'm' is a non-memmove()able type 'S_NonMovable'}}
|
||||
};
|
||||
struct WS_Movable {
|
||||
S_Movable m;
|
||||
};
|
||||
|
||||
// Combinations of the above
|
||||
struct SW_NonMovable : W_NonMovable {};
|
||||
struct SW_NonMovable : W_NonMovable {}; // expected-note 16 {{'SW_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'W_NonMovable'}}
|
||||
struct SW_Movable : W_Movable {};
|
||||
|
||||
struct SWS_NonMovable : WS_NonMovable {};
|
||||
struct SWS_NonMovable : WS_NonMovable {}; // expected-note 16 {{'SWS_NonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'WS_NonMovable'}}
|
||||
struct SWS_Movable : WS_Movable {};
|
||||
|
||||
// Basic templated wrapper
|
||||
template <class T>
|
||||
struct Template_Inline {
|
||||
T m;
|
||||
T m; // expected-note-re 56 {{'Template_Inline<{{.*}}>' is a non-memmove()able type because member 'm' is a non-memmove()able type '{{.*}}'}}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -50,7 +50,7 @@ template <class T>
|
|||
struct Template_Unused {};
|
||||
|
||||
template <class T>
|
||||
struct MOZ_NON_MEMMOVABLE Template_NonMovable {}; // expected-note-re + {{'{{.*}}' is non-memmovable because of the MOZ_NON_MEMMOVABLE annotation on 'Template_NonMovable<{{.*}}>'}}
|
||||
struct MOZ_NON_MEMMOVABLE Template_NonMovable {};
|
||||
|
||||
/*
|
||||
These tests take the following form:
|
||||
|
@ -499,7 +499,7 @@ struct W_NeedyTemplate6 {
|
|||
template <class T>
|
||||
struct SW_NeedyTemplate6 : W_NeedyTemplate6<T> {};
|
||||
// We create a different NonMovable type here, as NeedyTemplate6 will already be instantiated with NonMovable
|
||||
struct MOZ_NON_MEMMOVABLE NonMovable2 {}; // expected-note {{'NonMovable2' is non-memmovable because of the MOZ_NON_MEMMOVABLE annotation on 'NonMovable2'}}
|
||||
struct MOZ_NON_MEMMOVABLE NonMovable2 {};
|
||||
template <class T = NonMovable2>
|
||||
struct Defaulted_SW_NeedyTemplate6 {
|
||||
SW_NeedyTemplate6<T> m;
|
||||
|
@ -748,8 +748,8 @@ void good8() {
|
|||
instantiate NeedyTemplate.
|
||||
*/
|
||||
|
||||
struct MOZ_NON_MEMMOVABLE SpecializedNonMovable {}; // expected-note 8 {{'S_SpecializedNonMovable' is non-memmovable because of the MOZ_NON_MEMMOVABLE annotation on 'SpecializedNonMovable'}} expected-note 8 {{'Template_Inline<SpecializedNonMovable>' is non-memmovable because of the MOZ_NON_MEMMOVABLE annotation on 'SpecializedNonMovable'}}
|
||||
struct S_SpecializedNonMovable : SpecializedNonMovable {};
|
||||
struct MOZ_NON_MEMMOVABLE SpecializedNonMovable {};
|
||||
struct S_SpecializedNonMovable : SpecializedNonMovable {}; // expected-note 8 {{'S_SpecializedNonMovable' is a non-memmove()able type because it inherits from a non-memmove()able type 'SpecializedNonMovable'}}
|
||||
|
||||
// Specialize all of the NeedyTemplates with SpecializedNonMovable.
|
||||
template <>
|
||||
|
|
|
@ -25,7 +25,7 @@ def GeckoBinary(linkage='dependent', msvcrt='dynamic', mozglue=None):
|
|||
'program' (mozglue linked to an executable program), or 'library' (mozglue
|
||||
linked to a shared library).
|
||||
'''
|
||||
if msvcrt == 'dynamic' or CONFIG['OS_ARCH'] != 'WINNT':
|
||||
if msvcrt == 'dynamic' or CONFIG['OS_ARCH'] != 'WINNT' or CONFIG['MOZ_ASAN']:
|
||||
xpcomglue = 'xpcomglue'
|
||||
elif msvcrt == 'static':
|
||||
USE_STATIC_LIBS = True
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
MOZ_AUTOMATION_L10N_CHECK=0
|
||||
#TODO: bug 935237 - fix packaging
|
||||
MOZ_AUTOMATION_PACKAGE=0
|
||||
#TODO: bug 543111 - fix Breakpad
|
||||
MOZ_AUTOMATION_BUILD_SYMBOLS=0
|
||||
MOZ_AUTOMATION_UPLOAD_SYMBOLS=0
|
||||
|
@ -37,9 +35,13 @@ export AR=${TOOLCHAIN_PREFIX}ar
|
|||
export RANLIB=${TOOLCHAIN_PREFIX}ranlib
|
||||
export STRIP=${TOOLCHAIN_PREFIX}strip
|
||||
export OTOOL=${TOOLCHAIN_PREFIX}otool
|
||||
export GENISOIMAGE=$topsrcdir/genisoimage/genisoimage
|
||||
export DMG_TOOL=$topsrcdir/dmg/dmg
|
||||
|
||||
export HOST_CC=gcc
|
||||
export HOST_CXX=g++
|
||||
# The system gcc installed on CentOS 6 is 4.4, which our
|
||||
# build system rejects.
|
||||
export HOST_CC="$topsrcdir/gcc/bin/gcc"
|
||||
export HOST_CXX="$topsrcdir/gcc/bin/g++"
|
||||
export HOST_LDFLAGS="-g"
|
||||
|
||||
ac_add_options --target=x86_64-apple-darwin
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# Options to enable rust in automation builds.
|
||||
|
||||
if test `uname -s` != Linux; then
|
||||
RUSTC="$topsrcdir/rustc/bin/rustc"
|
||||
mk_add_options "export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$topsrcdir/rustc/lib"
|
||||
ac_add_options --enable-rust
|
||||
fi
|
||||
|
|
|
@ -11,6 +11,8 @@ import platform
|
|||
import json
|
||||
import argparse
|
||||
|
||||
centOS6 = False
|
||||
|
||||
|
||||
def check_run(args):
|
||||
r = subprocess.call(args)
|
||||
|
@ -94,11 +96,17 @@ def build_one_stage_aux(stage_dir, llvm_source_dir, gcc_toolchain_dir):
|
|||
if not is_darwin():
|
||||
targets.append("arm")
|
||||
|
||||
global centOS6
|
||||
if centOS6:
|
||||
python_path = "/usr/bin/python2.7"
|
||||
else:
|
||||
python_path = "/usr/local/bin/python2.7"
|
||||
|
||||
configure_opts = ["--enable-optimized",
|
||||
"--enable-targets=" + ",".join(targets),
|
||||
"--disable-assertions",
|
||||
"--disable-libedit",
|
||||
"--with-python=/usr/local/bin/python2.7",
|
||||
"--with-python=%s" % python_path,
|
||||
"--prefix=%s" % inst_dir,
|
||||
"--with-gcc-toolchain=%s" % gcc_toolchain_dir,
|
||||
"--disable-compiler-version-checks"]
|
||||
|
@ -119,7 +127,11 @@ if __name__ == "__main__":
|
|||
compiler_rt_source_dir = source_dir + "/compiler-rt"
|
||||
libcxx_source_dir = source_dir + "/libcxx"
|
||||
|
||||
gcc_dir = "/tools/gcc-4.7.3-0moz1"
|
||||
global centOS6
|
||||
if centOS6:
|
||||
gcc_dir = "/home/worker/workspace/build/src/gcc"
|
||||
else:
|
||||
gcc_dir = "/tools/gcc-4.7.3-0moz1"
|
||||
|
||||
if is_darwin():
|
||||
os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
INTERNAL_TOOLS = 1
|
||||
|
||||
OS_CXXFLAGS := $(filter-out -fno-exceptions,$(OS_CXXFLAGS)) -fexceptions
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
INTERNAL_TOOLS = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
export:: $(CSRCS:.c=.$(OBJ_SUFFIX))
|
||||
|
|
|
@ -242,11 +242,6 @@ endif # WINNT && !GNU_CC
|
|||
#
|
||||
_ENABLE_PIC=1
|
||||
|
||||
# No sense in profiling tools
|
||||
ifdef INTERNAL_TOOLS
|
||||
NO_PROFILE_GUIDED_OPTIMIZE = 1
|
||||
endif
|
||||
|
||||
# Don't build SIMPLE_PROGRAMS with PGO, since they don't need it anyway,
|
||||
# and we don't have the same build logic to re-link them in the second pass.
|
||||
ifdef SIMPLE_PROGRAMS
|
||||
|
@ -386,6 +381,12 @@ ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_)
|
|||
#// DLL version of the RTL is used...
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
ifdef MOZ_ASAN
|
||||
# ASAN-instrumented code tries to link against the dynamic CRT, which can't be
|
||||
# used in the same link as the static CRT.
|
||||
USE_STATIC_LIBS=
|
||||
endif # MOZ_ASAN
|
||||
|
||||
ifdef USE_STATIC_LIBS
|
||||
RTL_FLAGS=-MT # Statically linked multithreaded RTL
|
||||
ifdef MOZ_DEBUG
|
||||
|
|
|
@ -850,6 +850,8 @@ fi
|
|||
MOZ_PATH_PROG(RPMBUILD, rpmbuild, :)
|
||||
AC_SUBST(RPMBUILD)
|
||||
|
||||
MOZ_PATH_PROG(GENISOIMAGE, genisoimage, :)
|
||||
|
||||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
|
||||
dnl ========================================================
|
||||
|
@ -8780,6 +8782,7 @@ fi
|
|||
AC_SUBST(MOZ_APP_STATIC_INI)
|
||||
|
||||
AC_SUBST(MOZ_PKG_SPECIAL)
|
||||
AC_SUBST(MOZ_SIMPLE_PACKAGE_NAME)
|
||||
|
||||
AC_SUBST(MOZILLA_OFFICIAL)
|
||||
|
||||
|
@ -8985,6 +8988,8 @@ AC_SUBST(SOCORRO_SYMBOL_UPLOAD_TOKEN_FILE)
|
|||
AC_SUBST(MOZ_ENABLE_SZIP)
|
||||
AC_SUBST(MOZ_SZIP_FLAGS)
|
||||
|
||||
AC_SUBST(DMG_TOOL)
|
||||
|
||||
dnl Host JavaScript runtime, if any, to use during cross compiles.
|
||||
AC_SUBST(JS_BINARY)
|
||||
|
||||
|
|
|
@ -4979,6 +4979,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI* aURI,
|
|||
case NS_ERROR_INTERCEPTED_USED_RESPONSE:
|
||||
case NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION:
|
||||
case NS_ERROR_BAD_OPAQUE_REDIRECT_INTERCEPTION:
|
||||
case NS_ERROR_INTERCEPTION_CANCELED:
|
||||
// ServiceWorker intercepted request, but something went wrong.
|
||||
nsContentUtils::MaybeReportInterceptionErrorToConsole(GetDocument(),
|
||||
aError);
|
||||
|
@ -7631,6 +7632,7 @@ nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
|
|||
aStatus == NS_ERROR_INTERCEPTED_ERROR_RESPONSE ||
|
||||
aStatus == NS_ERROR_INTERCEPTED_USED_RESPONSE ||
|
||||
aStatus == NS_ERROR_CLIENT_REQUEST_OPAQUE_INTERCEPTION ||
|
||||
aStatus == NS_ERROR_INTERCEPTION_CANCELED ||
|
||||
NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
|
||||
// Errors to be shown for any frame
|
||||
DisplayLoadError(aStatus, url, nullptr, aChannel);
|
||||
|
|
|
@ -168,13 +168,20 @@ struct AnimationProperty
|
|||
// **NOTE**: For CSS animations, we only bother setting mWinsInCascade
|
||||
// accurately for properties that we can animate on the compositor.
|
||||
// For other properties, we make it always be true.
|
||||
// **NOTE 2**: This member is not included when comparing AnimationProperty
|
||||
// objects for equality.
|
||||
bool mWinsInCascade;
|
||||
|
||||
InfallibleTArray<AnimationPropertySegment> mSegments;
|
||||
|
||||
// NOTE: This operator does *not* compare the mWinsInCascade member.
|
||||
// This is because AnimationProperty objects are compared when recreating
|
||||
// CSS animations to determine if mutation observer change records need to
|
||||
// be created or not. However, at the point when these objects are compared
|
||||
// the mWinsInCascade will not have been set on the new objects so we ignore
|
||||
// this member to avoid generating spurious change records.
|
||||
bool operator==(const AnimationProperty& aOther) const {
|
||||
return mProperty == aOther.mProperty &&
|
||||
mWinsInCascade == aOther.mWinsInCascade &&
|
||||
mSegments == aOther.mSegments;
|
||||
}
|
||||
bool operator!=(const AnimationProperty& aOther) const {
|
||||
|
|
|
@ -737,6 +737,72 @@ function assert_records(expected, desc) {
|
|||
});
|
||||
});
|
||||
|
||||
addAsyncAnimTest("tree_ordering", { observe: div, subtree: true }, function*() {
|
||||
|
||||
// Create a tree with two children:
|
||||
//
|
||||
// div
|
||||
// / \
|
||||
// childA childB
|
||||
var childA = document.createElement("div");
|
||||
var childB = document.createElement("div");
|
||||
|
||||
div.appendChild(childA);
|
||||
div.appendChild(childB);
|
||||
|
||||
// Start an animation on each (using order: childB, div, childA)
|
||||
//
|
||||
// We include multiple animations on some nodes so that we can test batching
|
||||
// works as expected later in this test.
|
||||
childB.style = "animation: anim 100s";
|
||||
div.style = "animation: anim 100s, anim 100s, anim 100s";
|
||||
childA.style = "animation: anim 100s, anim 100s";
|
||||
|
||||
var divAnimations = div.getAnimations();
|
||||
var childAAnimations = childA.getAnimations();
|
||||
var childBAnimations = childB.getAnimations();
|
||||
|
||||
// The order in which we get the corresponding records is currently
|
||||
// based on the order we visit these nodes when updating styles.
|
||||
//
|
||||
// That is because we don't do any document-level batching of animation
|
||||
// mutation records when we flush styles. We may introduce that in the
|
||||
// future but for now all we are interested in testing here is that the order
|
||||
// these records are dispatched is consistent between runs.
|
||||
//
|
||||
// We currently expect to get records in order childA, childB, div
|
||||
yield await_frame();
|
||||
assert_records([{ added: childAAnimations, changed: [], removed: [] },
|
||||
{ added: childBAnimations, changed: [], removed: [] },
|
||||
{ added: divAnimations, changed: [], removed: [] }],
|
||||
"records after simultaneous animation start");
|
||||
|
||||
// The one case where we *do* currently perform document-level (or actually
|
||||
// timeline-level) batching is when animations are updated from a refresh
|
||||
// driver tick. In particular, this means that when animations finish
|
||||
// naturally the removed records should be dispatched according to the
|
||||
// position of the elements in the tree.
|
||||
//
|
||||
// Fast-forward to *just* before the end of the animation.
|
||||
var fastForward = animation => animation.currentTime = 99999;
|
||||
divAnimations.forEach(fastForward);
|
||||
childAAnimations.forEach(fastForward);
|
||||
childBAnimations.forEach(fastForward);
|
||||
|
||||
yield await_event(div, "animationend");
|
||||
|
||||
// We should get records in order div, childA, childB
|
||||
assert_records([{ added: [], changed: [], removed: divAnimations },
|
||||
{ added: [], changed: [], removed: childAAnimations },
|
||||
{ added: [], changed: [], removed: childBAnimations }],
|
||||
"records after finishing");
|
||||
|
||||
// Clean up
|
||||
div.style = "";
|
||||
childA.remove();
|
||||
childB.remove();
|
||||
});
|
||||
|
||||
// Run the tests.
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
|
|
@ -816,7 +816,7 @@ nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
|||
case eScroll:
|
||||
stopEvent = true;
|
||||
break;
|
||||
case NS_USER_DEFINED_EVENT:
|
||||
case eUnidentifiedEvent:
|
||||
if (aVisitor.mDOMEvent) {
|
||||
nsAutoString eventType;
|
||||
aVisitor.mDOMEvent->GetType(eventType);
|
||||
|
|
|
@ -252,7 +252,7 @@ TextInputProcessor::IsValidEventTypeForComposition(
|
|||
if (aKeyboardEvent.mMessage == eKeyDown) {
|
||||
return true;
|
||||
}
|
||||
if (aKeyboardEvent.mMessage == NS_USER_DEFINED_EVENT &&
|
||||
if (aKeyboardEvent.mMessage == eUnidentifiedEvent &&
|
||||
aKeyboardEvent.userType &&
|
||||
nsDependentAtomString(aKeyboardEvent.userType).EqualsLiteral("on")) {
|
||||
return true;
|
||||
|
|
|
@ -3460,6 +3460,8 @@ nsContentUtils::MaybeReportInterceptionErrorToConsole(nsIDocument* aDocument,
|
|||
messageName = "ClientRequestOpaqueInterception";
|
||||
} else if (aError == NS_ERROR_BAD_OPAQUE_REDIRECT_INTERCEPTION) {
|
||||
messageName = "BadOpaqueRedirectInterception";
|
||||
} else if (aError == NS_ERROR_INTERCEPTION_CANCELED) {
|
||||
messageName = "InterceptionCanceled";
|
||||
}
|
||||
|
||||
if (messageName) {
|
||||
|
@ -3682,7 +3684,7 @@ nsContentUtils::GetEventMessage(nsIAtom* aName)
|
|||
}
|
||||
}
|
||||
|
||||
return NS_USER_DEFINED_EVENT;
|
||||
return eUnidentifiedEvent;
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -3705,7 +3707,7 @@ nsContentUtils::GetEventMessageAndAtom(const nsAString& aName,
|
|||
if (sStringEventTable->Get(aName, &mapping)) {
|
||||
*aEventMessage =
|
||||
mapping.mEventClassID == aEventClassID ? mapping.mMessage :
|
||||
NS_USER_DEFINED_EVENT;
|
||||
eUnidentifiedEvent;
|
||||
return mapping.mAtom;
|
||||
}
|
||||
|
||||
|
@ -3718,11 +3720,11 @@ nsContentUtils::GetEventMessageAndAtom(const nsAString& aName,
|
|||
}
|
||||
}
|
||||
|
||||
*aEventMessage = NS_USER_DEFINED_EVENT;
|
||||
*aEventMessage = eUnidentifiedEvent;
|
||||
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aName);
|
||||
sUserDefinedEvents->AppendObject(atom);
|
||||
mapping.mAtom = atom;
|
||||
mapping.mMessage = NS_USER_DEFINED_EVENT;
|
||||
mapping.mMessage = eUnidentifiedEvent;
|
||||
mapping.mType = EventNameType_None;
|
||||
mapping.mEventClassID = eBasicEventClass;
|
||||
sStringEventTable->Put(aName, mapping);
|
||||
|
|
|
@ -1101,7 +1101,7 @@ public:
|
|||
|
||||
/**
|
||||
* Return the event message for the event with the given name. The name is
|
||||
* the event name with the 'on' prefix. Returns NS_USER_DEFINED_EVENT if the
|
||||
* the event name with the 'on' prefix. Returns eUnidentifiedEvent if the
|
||||
* event doesn't match a known event name.
|
||||
*
|
||||
* @param aName the event name to look up
|
||||
|
@ -1120,7 +1120,7 @@ public:
|
|||
/**
|
||||
* Return the event message and atom for the event with the given name.
|
||||
* The name is the event name *without* the 'on' prefix.
|
||||
* Returns NS_USER_DEFINED_EVENT on the aEventID if the
|
||||
* Returns eUnidentifiedEvent on the aEventID if the
|
||||
* event doesn't match a known event name in the category.
|
||||
*
|
||||
* @param aName the event name to look up
|
||||
|
|
|
@ -324,6 +324,7 @@ public:
|
|||
nsMutationReceiverBase* aParent)
|
||||
{
|
||||
nsMutationReceiver* r = new nsMutationReceiver(aRegisterTarget, aParent);
|
||||
aParent->AddClone(r);
|
||||
r->AddObserver();
|
||||
return r;
|
||||
}
|
||||
|
@ -385,7 +386,6 @@ protected:
|
|||
{
|
||||
NS_ASSERTION(!static_cast<nsMutationReceiver*>(aParent)->GetParent(),
|
||||
"Shouldn't create deep observer hierarchies!");
|
||||
aParent->AddClone(this);
|
||||
}
|
||||
|
||||
virtual void AddMutationObserver() override
|
||||
|
@ -409,6 +409,7 @@ public:
|
|||
nsMutationReceiverBase* aParent)
|
||||
{
|
||||
nsAnimationReceiver* r = new nsAnimationReceiver(aRegisterTarget, aParent);
|
||||
aParent->AddClone(r);
|
||||
r->AddObserver();
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -825,7 +825,7 @@ nsDOMWindowUtils::SendWheelEvent(float aX,
|
|||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget);
|
||||
WidgetWheelEvent wheelEvent(true, eWheel, widget);
|
||||
wheelEvent.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
|
||||
wheelEvent.deltaX = aDeltaX;
|
||||
wheelEvent.deltaY = aDeltaY;
|
||||
|
@ -1927,22 +1927,22 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
|
|||
EventMessage message;
|
||||
switch (aType) {
|
||||
case QUERY_SELECTED_TEXT:
|
||||
message = NS_QUERY_SELECTED_TEXT;
|
||||
message = eQuerySelectedText;
|
||||
break;
|
||||
case QUERY_TEXT_CONTENT:
|
||||
message = NS_QUERY_TEXT_CONTENT;
|
||||
message = eQueryTextContent;
|
||||
break;
|
||||
case QUERY_CARET_RECT:
|
||||
message = NS_QUERY_CARET_RECT;
|
||||
message = eQueryCaretRect;
|
||||
break;
|
||||
case QUERY_TEXT_RECT:
|
||||
message = NS_QUERY_TEXT_RECT;
|
||||
break;
|
||||
case QUERY_EDITOR_RECT:
|
||||
message = NS_QUERY_EDITOR_RECT;
|
||||
message = eQueryEditorRect;
|
||||
break;
|
||||
case QUERY_CHARACTER_AT_POINT:
|
||||
message = NS_QUERY_CHARACTER_AT_POINT;
|
||||
message = eQueryCharacterAtPoint;
|
||||
break;
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
@ -1954,9 +1954,9 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
|
|||
bool useNativeLineBreak =
|
||||
!(aAdditionalFlags & QUERY_CONTENT_FLAG_USE_XP_LINE_BREAK);
|
||||
|
||||
if (message == NS_QUERY_CHARACTER_AT_POINT) {
|
||||
if (message == eQueryCharacterAtPoint) {
|
||||
// Looking for the widget at the point.
|
||||
WidgetQueryContentEvent dummyEvent(true, NS_QUERY_CONTENT_STATE, widget);
|
||||
WidgetQueryContentEvent dummyEvent(true, eQueryContentState, widget);
|
||||
dummyEvent.mUseNativeLineBreak = useNativeLineBreak;
|
||||
InitEvent(dummyEvent, &pt);
|
||||
nsIFrame* popupFrame =
|
||||
|
@ -1985,10 +1985,10 @@ nsDOMWindowUtils::SendQueryContentEvent(uint32_t aType,
|
|||
InitEvent(queryEvent, &pt);
|
||||
|
||||
switch (message) {
|
||||
case NS_QUERY_TEXT_CONTENT:
|
||||
case eQueryTextContent:
|
||||
queryEvent.InitForQueryTextContent(aOffset, aLength, useNativeLineBreak);
|
||||
break;
|
||||
case NS_QUERY_CARET_RECT:
|
||||
case eQueryCaretRect:
|
||||
queryEvent.InitForQueryCaretRect(aOffset, useNativeLineBreak);
|
||||
break;
|
||||
case NS_QUERY_TEXT_RECT:
|
||||
|
@ -2055,25 +2055,26 @@ nsDOMWindowUtils::SendContentCommandEvent(const nsAString& aType,
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
EventMessage msg;
|
||||
if (aType.EqualsLiteral("cut"))
|
||||
msg = NS_CONTENT_COMMAND_CUT;
|
||||
else if (aType.EqualsLiteral("copy"))
|
||||
msg = NS_CONTENT_COMMAND_COPY;
|
||||
else if (aType.EqualsLiteral("paste"))
|
||||
msg = NS_CONTENT_COMMAND_PASTE;
|
||||
else if (aType.EqualsLiteral("delete"))
|
||||
msg = NS_CONTENT_COMMAND_DELETE;
|
||||
else if (aType.EqualsLiteral("undo"))
|
||||
msg = NS_CONTENT_COMMAND_UNDO;
|
||||
else if (aType.EqualsLiteral("redo"))
|
||||
msg = NS_CONTENT_COMMAND_REDO;
|
||||
else if (aType.EqualsLiteral("pasteTransferable"))
|
||||
msg = NS_CONTENT_COMMAND_PASTE_TRANSFERABLE;
|
||||
else
|
||||
if (aType.EqualsLiteral("cut")) {
|
||||
msg = eContentCommandCut;
|
||||
} else if (aType.EqualsLiteral("copy")) {
|
||||
msg = eContentCommandCopy;
|
||||
} else if (aType.EqualsLiteral("paste")) {
|
||||
msg = eContentCommandPaste;
|
||||
} else if (aType.EqualsLiteral("delete")) {
|
||||
msg = eContentCommandDelete;
|
||||
} else if (aType.EqualsLiteral("undo")) {
|
||||
msg = eContentCommandUndo;
|
||||
} else if (aType.EqualsLiteral("redo")) {
|
||||
msg = eContentCommandRedo;
|
||||
} else if (aType.EqualsLiteral("pasteTransferable")) {
|
||||
msg = eContentCommandPasteTransferable;
|
||||
} else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
WidgetContentCommandEvent event(true, msg, widget);
|
||||
if (msg == NS_CONTENT_COMMAND_PASTE_TRANSFERABLE) {
|
||||
if (msg == eContentCommandPasteTransferable) {
|
||||
event.mTransferable = aTransferable;
|
||||
}
|
||||
|
||||
|
|
|
@ -3948,13 +3948,7 @@ nsDocument::SetSubDocumentFor(Element* aElement, nsIDocument* aSubDoc)
|
|||
// aSubDoc is nullptr, remove the mapping
|
||||
|
||||
if (mSubDocuments) {
|
||||
SubDocMapEntry *entry =
|
||||
static_cast<SubDocMapEntry*>
|
||||
(PL_DHashTableSearch(mSubDocuments, aElement));
|
||||
|
||||
if (entry) {
|
||||
PL_DHashTableRawRemove(mSubDocuments, entry);
|
||||
}
|
||||
PL_DHashTableRemove(mSubDocuments, aElement);
|
||||
}
|
||||
} else {
|
||||
if (!mSubDocuments) {
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
#include "nsSandboxFlags.h"
|
||||
#include "mozilla/layers/CompositorChild.h"
|
||||
|
||||
#include "mozilla/dom/StructuredCloneIPCHelper.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/WebBrowserPersistLocalDocument.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -2447,10 +2447,10 @@ public:
|
|||
nsAsyncMessageToChild(JSContext* aCx,
|
||||
nsFrameLoader* aFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aHelper, aCpows, aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
, mFrameLoader(aFrameLoader)
|
||||
{
|
||||
}
|
||||
|
@ -2472,7 +2472,7 @@ public:
|
|||
bool
|
||||
nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
|
@ -2480,7 +2480,7 @@ nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
|||
if (tabParent) {
|
||||
ClonedMessageData data;
|
||||
nsIContentParent* cp = tabParent->Manager();
|
||||
if (!BuildClonedMessageDataForParent(cp, aHelper, data)) {
|
||||
if (!BuildClonedMessageDataForParent(cp, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||
|
@ -2494,7 +2494,7 @@ nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
|
|||
|
||||
if (mChildMessageManager) {
|
||||
nsCOMPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage,
|
||||
aHelper, aCpows,
|
||||
aData, aCpows,
|
||||
aPrincipal);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
|
|
|
@ -41,10 +41,13 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
class ContentParent;
|
||||
class PBrowserParent;
|
||||
class StructuredCloneIPCHelper;
|
||||
class TabParent;
|
||||
} // namespace dom
|
||||
|
||||
namespace ipc {
|
||||
class StructuredCloneData;
|
||||
} // namespace ipc
|
||||
|
||||
namespace layout {
|
||||
class RenderFrameParent;
|
||||
} // namespace layout
|
||||
|
@ -90,7 +93,7 @@ public:
|
|||
bool aRunInGlobalScope) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
mozilla::dom::StructuredCloneIPCHelper& aHelper,
|
||||
mozilla::dom::ipc::StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
virtual bool CheckPermission(const nsAString& aPermission) override;
|
||||
|
|
|
@ -37,9 +37,9 @@
|
|||
#include "mozilla/dom/ProcessGlobal.h"
|
||||
#include "mozilla/dom/SameProcessMessageQueue.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/StructuredCloneIPCHelper.h"
|
||||
#include "mozilla/dom/ipc/BlobChild.h"
|
||||
#include "mozilla/dom/ipc/BlobParent.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/dom/DOMStringList.h"
|
||||
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
@ -276,13 +276,13 @@ struct DataBlobs<Child>
|
|||
template<ActorFlavorEnum Flavor>
|
||||
static bool
|
||||
BuildClonedMessageData(typename BlobTraits<Flavor>::ConcreteContentManagerType* aManager,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
SerializedStructuredCloneBuffer& buffer = aClonedData.data();
|
||||
buffer.data = aHelper.Data();
|
||||
buffer.dataLength = aHelper.DataLength();
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = aHelper.BlobImpls();
|
||||
buffer.data = aData.Data();
|
||||
buffer.dataLength = aData.DataLength();
|
||||
const nsTArray<nsRefPtr<BlobImpl>>& blobImpls = aData.BlobImpls();
|
||||
|
||||
if (!blobImpls.IsEmpty()) {
|
||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
||||
|
@ -303,34 +303,34 @@ BuildClonedMessageData(typename BlobTraits<Flavor>::ConcreteContentManagerType*
|
|||
|
||||
bool
|
||||
MessageManagerCallback::BuildClonedMessageDataForParent(nsIContentParent* aParent,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
return BuildClonedMessageData<Parent>(aParent, aHelper, aClonedData);
|
||||
return BuildClonedMessageData<Parent>(aParent, aData, aClonedData);
|
||||
}
|
||||
|
||||
bool
|
||||
MessageManagerCallback::BuildClonedMessageDataForChild(nsIContentChild* aChild,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData)
|
||||
{
|
||||
return BuildClonedMessageData<Child>(aChild, aHelper, aClonedData);
|
||||
return BuildClonedMessageData<Child>(aChild, aData, aClonedData);
|
||||
}
|
||||
|
||||
template<ActorFlavorEnum Flavor>
|
||||
static void
|
||||
UnpackClonedMessageData(const ClonedMessageData& aData,
|
||||
StructuredCloneIPCHelper& aHelper)
|
||||
UnpackClonedMessageData(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
const SerializedStructuredCloneBuffer& buffer = aData.data();
|
||||
const SerializedStructuredCloneBuffer& buffer = aClonedData.data();
|
||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
||||
const InfallibleTArray<ProtocolType*>& blobs = DataBlobs<Flavor>::Blobs(aData);
|
||||
const InfallibleTArray<ProtocolType*>& blobs = DataBlobs<Flavor>::Blobs(aClonedData);
|
||||
|
||||
aHelper.UseExternalData(buffer.data, buffer.dataLength);
|
||||
aData.UseExternalData(buffer.data, buffer.dataLength);
|
||||
|
||||
if (!blobs.IsEmpty()) {
|
||||
uint32_t length = blobs.Length();
|
||||
aHelper.BlobImpls().SetCapacity(length);
|
||||
aData.BlobImpls().SetCapacity(length);
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
auto* blob =
|
||||
static_cast<typename BlobTraits<Flavor>::BlobType*>(blobs[i]);
|
||||
|
@ -339,23 +339,23 @@ UnpackClonedMessageData(const ClonedMessageData& aData,
|
|||
nsRefPtr<BlobImpl> blobImpl = blob->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
aHelper.BlobImpls().AppendElement(blobImpl);
|
||||
aData.BlobImpls().AppendElement(blobImpl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mozilla::dom::ipc::UnpackClonedMessageDataForParent(const ClonedMessageData& aData,
|
||||
StructuredCloneIPCHelper& aHelper)
|
||||
mozilla::dom::ipc::UnpackClonedMessageDataForParent(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
UnpackClonedMessageData<Parent>(aData, aHelper);
|
||||
UnpackClonedMessageData<Parent>(aClonedData, aData);
|
||||
}
|
||||
|
||||
void
|
||||
mozilla::dom::ipc::UnpackClonedMessageDataForChild(const ClonedMessageData& aData,
|
||||
StructuredCloneIPCHelper& aHelper)
|
||||
mozilla::dom::ipc::UnpackClonedMessageDataForChild(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
UnpackClonedMessageData<Child>(aData, aHelper);
|
||||
UnpackClonedMessageData<Child>(aClonedData, aData);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -652,13 +652,13 @@ JSONCreator(const char16_t* aBuf, uint32_t aLen, void* aData)
|
|||
|
||||
static bool
|
||||
GetParamsForMessage(JSContext* aCx,
|
||||
const JS::Value& aData,
|
||||
StructuredCloneIPCHelper& aHelper)
|
||||
const JS::Value& aValue,
|
||||
StructuredCloneData& aData)
|
||||
{
|
||||
// First try to use structured clone on the whole thing.
|
||||
JS::RootedValue v(aCx, aData);
|
||||
JS::RootedValue v(aCx, aValue);
|
||||
ErrorResult rv;
|
||||
aHelper.Write(aCx, v, rv);
|
||||
aData.Write(aCx, v, rv);
|
||||
if (!rv.Failed()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -691,7 +691,7 @@ GetParamsForMessage(JSContext* aCx,
|
|||
NS_ENSURE_TRUE(JS_ParseJSON(aCx, static_cast<const char16_t*>(json.get()),
|
||||
json.Length(), &val), false);
|
||||
|
||||
aHelper.Write(aCx, val, rv);
|
||||
aData.Write(aCx, val, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
|
@ -700,7 +700,6 @@ GetParamsForMessage(JSContext* aCx,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// nsISyncMessageSender
|
||||
|
||||
static bool sSendingSyncMessage = false;
|
||||
|
@ -753,8 +752,8 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
StructuredCloneIPCHelper helper;
|
||||
if (aArgc >= 2 && !GetParamsForMessage(aCx, aJSON, helper)) {
|
||||
StructuredCloneData data;
|
||||
if (aArgc >= 2 && !GetParamsForMessage(aCx, aJSON, data)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
|
@ -763,10 +762,10 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
|||
objects = &aObjects.toObject();
|
||||
}
|
||||
|
||||
nsTArray<StructuredCloneIPCHelper> retval;
|
||||
nsTArray<StructuredCloneData> retval;
|
||||
|
||||
sSendingSyncMessage |= aIsSync;
|
||||
bool ok = mCallback->DoSendBlockingMessage(aCx, aMessageName, helper, objects,
|
||||
bool ok = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects,
|
||||
aPrincipal, &retval, aIsSync);
|
||||
if (aIsSync) {
|
||||
sSendingSyncMessage = false;
|
||||
|
@ -800,7 +799,7 @@ nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
|
|||
nsresult
|
||||
nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
|
@ -808,7 +807,7 @@ nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
|||
int32_t len = mChildManagers.Count();
|
||||
for (int32_t i = 0; i < len; ++i) {
|
||||
static_cast<nsFrameMessageManager*>(mChildManagers[i])->
|
||||
DispatchAsyncMessageInternal(aCx, aMessage, aHelper, aCpows, aPrincipal);
|
||||
DispatchAsyncMessageInternal(aCx, aMessage, aData, aCpows, aPrincipal);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -817,7 +816,7 @@ nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aHelper, aCpows, aPrincipal)) {
|
||||
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows, aPrincipal)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -831,8 +830,8 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
|||
JSContext* aCx,
|
||||
uint8_t aArgc)
|
||||
{
|
||||
StructuredCloneIPCHelper helper;
|
||||
if (aArgc >= 2 && !GetParamsForMessage(aCx, aJSON, helper)) {
|
||||
StructuredCloneData data;
|
||||
if (aArgc >= 2 && !GetParamsForMessage(aCx, aJSON, data)) {
|
||||
return NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
}
|
||||
|
||||
|
@ -841,7 +840,7 @@ nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
|
|||
objects = &aObjects.toObject();
|
||||
}
|
||||
|
||||
return DispatchAsyncMessageInternal(aCx, aMessageName, helper, objects,
|
||||
return DispatchAsyncMessageInternal(aCx, aMessageName, data, objects,
|
||||
aPrincipal);
|
||||
}
|
||||
|
||||
|
@ -1070,13 +1069,13 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
nsIFrameLoader* aTargetFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
bool aIsSync,
|
||||
StructuredCloneIPCHelper* aCloneHelper,
|
||||
StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal)
|
||||
nsTArray<StructuredCloneData>* aRetVal)
|
||||
{
|
||||
return ReceiveMessage(aTarget, aTargetFrameLoader, mClosed, aMessage, aIsSync,
|
||||
aCloneHelper, aCpows, aPrincipal, aRetVal);
|
||||
aCloneData, aCpows, aPrincipal, aRetVal);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1085,10 +1084,10 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
bool aTargetClosed,
|
||||
const nsAString& aMessage,
|
||||
bool aIsSync,
|
||||
StructuredCloneIPCHelper* aCloneHelper,
|
||||
StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal)
|
||||
nsTArray<StructuredCloneData>* aRetVal)
|
||||
{
|
||||
nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
|
||||
mListeners.Get(aMessage);
|
||||
|
@ -1169,9 +1168,9 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
JS::Rooted<JS::Value> cpowsv(cx, JS::ObjectValue(*cpows));
|
||||
|
||||
JS::Rooted<JS::Value> json(cx, JS::NullValue());
|
||||
if (aCloneHelper && aCloneHelper->DataLength()) {
|
||||
if (aCloneData && aCloneData->DataLength()) {
|
||||
ErrorResult rv;
|
||||
aCloneHelper->Read(cx, &json, rv);
|
||||
aCloneData->Read(cx, &json, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
JS_ClearPendingException(cx);
|
||||
|
@ -1268,8 +1267,8 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
}
|
||||
if (aRetVal) {
|
||||
ErrorResult rv;
|
||||
StructuredCloneIPCHelper* helper = aRetVal->AppendElement();
|
||||
helper->Write(cx, rval, rv);
|
||||
StructuredCloneData* data = aRetVal->AppendElement();
|
||||
data->Write(cx, rval, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
aRetVal->RemoveElementAt(aRetVal->Length() - 1);
|
||||
nsString msg = aMessage + NS_LITERAL_STRING(": message reply cannot be cloned. Are you trying to send an XPCOM object?");
|
||||
|
@ -1292,7 +1291,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
|
||||
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aTargetFrameLoader,
|
||||
aTargetClosed, aMessage,
|
||||
aIsSync, aCloneHelper,
|
||||
aIsSync, aCloneData,
|
||||
aCpows, aPrincipal,
|
||||
aRetVal) : NS_OK;
|
||||
}
|
||||
|
@ -1896,10 +1895,10 @@ class nsAsyncMessageToSameProcessChild : public nsSameProcessAsyncMessageBase,
|
|||
public:
|
||||
nsAsyncMessageToSameProcessChild(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aHelper, aCpows, aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1938,12 +1937,12 @@ public:
|
|||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> ev =
|
||||
new nsAsyncMessageToSameProcessChild(aCx, aMessage, aHelper, aCpows,
|
||||
new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows,
|
||||
aPrincipal);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
return true;
|
||||
|
@ -1992,10 +1991,10 @@ public:
|
|||
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override
|
||||
{
|
||||
mozilla::dom::ContentChild* cc =
|
||||
|
@ -2004,7 +2003,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
ClonedMessageData data;
|
||||
if (!BuildClonedMessageDataForChild(cc, aHelper, data)) {
|
||||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||
|
@ -2021,7 +2020,7 @@ public:
|
|||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
|
@ -2031,7 +2030,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
ClonedMessageData data;
|
||||
if (!BuildClonedMessageDataForChild(cc, aHelper, data)) {
|
||||
if (!BuildClonedMessageDataForChild(cc, aData, data)) {
|
||||
return false;
|
||||
}
|
||||
InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
|
||||
|
@ -2051,10 +2050,10 @@ class nsAsyncMessageToSameProcessParent : public nsSameProcessAsyncMessageBase,
|
|||
public:
|
||||
nsAsyncMessageToSameProcessParent(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aHelper, aCpows, aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2083,10 +2082,10 @@ public:
|
|||
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override
|
||||
{
|
||||
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
|
||||
|
@ -2096,20 +2095,20 @@ public:
|
|||
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
||||
nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
|
||||
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr, aMessage,
|
||||
true, &aHelper, &cpows, aPrincipal, aRetVal);
|
||||
true, &aData, &cpows, aPrincipal, aRetVal);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override
|
||||
{
|
||||
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
|
||||
nsRefPtr<nsAsyncMessageToSameProcessParent> ev =
|
||||
new nsAsyncMessageToSameProcessParent(aCx, aMessage, aHelper, aCpows, aPrincipal);
|
||||
new nsAsyncMessageToSameProcessParent(aCx, aMessage, aData, aCpows, aPrincipal);
|
||||
queue->Push(ev);
|
||||
return true;
|
||||
}
|
||||
|
@ -2209,7 +2208,7 @@ nsFrameMessageManager::MarkForCC()
|
|||
|
||||
nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: mRuntime(js::GetRuntime(aCx)),
|
||||
|
@ -2217,12 +2216,12 @@ nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(JSContext* aCx,
|
|||
mCpows(aCx, aCpows),
|
||||
mPrincipal(aPrincipal)
|
||||
{
|
||||
if (!mHelper.Copy(aHelper)) {
|
||||
if (!mData.Copy(aData)) {
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AsyncMessageOOM"),
|
||||
NS_ConvertUTF16toUTF8(aMessage));
|
||||
#endif
|
||||
NS_ABORT_OOM(aHelper.DataLength());
|
||||
NS_ABORT_OOM(aData.DataLength());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2235,7 +2234,7 @@ nsSameProcessAsyncMessageBase::ReceiveMessage(nsISupports* aTarget,
|
|||
SameProcessCpowHolder cpows(mRuntime, mCpows);
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> mm = aManager;
|
||||
mm->ReceiveMessage(aTarget, aTargetFrameLoader, mMessage, false, &mHelper,
|
||||
mm->ReceiveMessage(aTarget, aTargetFrameLoader, mMessage, false, &mData,
|
||||
&cpows, mPrincipal, nullptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include "js/RootingAPI.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "mozilla/dom/SameProcessMessageQueue.h"
|
||||
#include "mozilla/dom/StructuredCloneIPCHelper.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/jsipc/CpowHolder.h"
|
||||
|
||||
class nsIFrameLoader;
|
||||
|
@ -64,10 +64,10 @@ public:
|
|||
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
return true;
|
||||
|
@ -75,7 +75,7 @@ public:
|
|||
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
|
@ -110,18 +110,18 @@ public:
|
|||
|
||||
protected:
|
||||
bool BuildClonedMessageDataForParent(nsIContentParent* aParent,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData);
|
||||
bool BuildClonedMessageDataForChild(nsIContentChild* aChild,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
ClonedMessageData& aClonedData);
|
||||
};
|
||||
|
||||
void UnpackClonedMessageDataForParent(const ClonedMessageData& aData,
|
||||
StructuredCloneIPCHelper& aHelper);
|
||||
void UnpackClonedMessageDataForParent(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData);
|
||||
|
||||
void UnpackClonedMessageDataForChild(const ClonedMessageData& aData,
|
||||
StructuredCloneIPCHelper& aHelper);
|
||||
void UnpackClonedMessageDataForChild(const ClonedMessageData& aClonedData,
|
||||
StructuredCloneData& aData);
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace dom
|
||||
|
@ -163,7 +163,7 @@ class nsFrameMessageManager final : public nsIContentFrameMessageManager,
|
|||
public nsIProcessChecker
|
||||
{
|
||||
friend class mozilla::dom::MessageManagerReporter;
|
||||
typedef mozilla::dom::StructuredCloneIPCHelper StructuredCloneIPCHelper;
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
public:
|
||||
nsFrameMessageManager(mozilla::dom::ipc::MessageManagerCallback* aCallback,
|
||||
nsFrameMessageManager* aParentManager,
|
||||
|
@ -192,9 +192,9 @@ public:
|
|||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
|
||||
const nsAString& aMessage,
|
||||
bool aIsSync, StructuredCloneIPCHelper* aCloneHelper,
|
||||
bool aIsSync, StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal);
|
||||
nsTArray<StructuredCloneData>* aRetVal);
|
||||
|
||||
void AddChildManager(nsFrameMessageManager* aManager);
|
||||
void RemoveChildManager(nsFrameMessageManager* aManager)
|
||||
|
@ -219,7 +219,7 @@ public:
|
|||
uint8_t aArgc);
|
||||
nsresult DispatchAsyncMessageInternal(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal);
|
||||
void RemoveFromParent();
|
||||
|
@ -260,9 +260,9 @@ private:
|
|||
|
||||
nsresult ReceiveMessage(nsISupports* aTarget, nsIFrameLoader* aTargetFrameLoader,
|
||||
bool aTargetClosed, const nsAString& aMessage,
|
||||
bool aIsSync, StructuredCloneIPCHelper* aCloneHelper,
|
||||
bool aIsSync, StructuredCloneData* aCloneData,
|
||||
mozilla::jsipc::CpowHolder* aCpows, nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal);
|
||||
nsTArray<StructuredCloneData>* aRetVal);
|
||||
|
||||
NS_IMETHOD LoadScript(const nsAString& aURL,
|
||||
bool aAllowDelayedLoad,
|
||||
|
@ -326,11 +326,11 @@ private:
|
|||
class nsSameProcessAsyncMessageBase
|
||||
{
|
||||
public:
|
||||
typedef mozilla::dom::StructuredCloneIPCHelper StructuredCloneIPCHelper;
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
|
||||
nsSameProcessAsyncMessageBase(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
|
@ -342,7 +342,7 @@ private:
|
|||
|
||||
JSRuntime* mRuntime;
|
||||
nsString mMessage;
|
||||
StructuredCloneIPCHelper mHelper;
|
||||
StructuredCloneData mData;
|
||||
JS::PersistentRooted<JSObject*> mCpows;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
|
|
@ -940,6 +940,7 @@ GK_ATOM(parent, "parent")
|
|||
GK_ATOM(parentapp, "parentapp")
|
||||
GK_ATOM(parentfocused, "parentfocused")
|
||||
GK_ATOM(parsetype, "parsetype")
|
||||
GK_ATOM(password, "password")
|
||||
GK_ATOM(pattern, "pattern")
|
||||
GK_ATOM(patternSeparator, "pattern-separator")
|
||||
GK_ATOM(perMille, "per-mille")
|
||||
|
@ -2318,7 +2319,6 @@ GK_ATOM(menuitemradio, "menuitemradio")
|
|||
GK_ATOM(mixed, "mixed")
|
||||
GK_ATOM(multiline, "multiline")
|
||||
GK_ATOM(navigation, "navigation")
|
||||
GK_ATOM(password, "password")
|
||||
GK_ATOM(polite, "polite")
|
||||
GK_ATOM(posinset, "posinset")
|
||||
GK_ATOM(presentation, "presentation")
|
||||
|
|
|
@ -666,10 +666,12 @@ public:
|
|||
static const nsOuterWindowProxy singleton;
|
||||
|
||||
protected:
|
||||
static nsGlobalWindow* GetWindow(JSObject *proxy)
|
||||
static nsGlobalWindow* GetOuterWindow(JSObject *proxy)
|
||||
{
|
||||
return nsGlobalWindow::FromSupports(
|
||||
nsGlobalWindow* outerWindow = nsGlobalWindow::FromSupports(
|
||||
static_cast<nsISupports*>(js::GetProxyExtra(proxy, 0).toPrivate()));
|
||||
MOZ_ASSERT_IF(outerWindow, outerWindow->IsOuterWindow());
|
||||
return outerWindow;
|
||||
}
|
||||
|
||||
// False return value means we threw an exception. True return value
|
||||
|
@ -711,15 +713,15 @@ nsOuterWindowProxy::className(JSContext *cx, JS::Handle<JSObject*> proxy) const
|
|||
void
|
||||
nsOuterWindowProxy::finalize(JSFreeOp *fop, JSObject *proxy) const
|
||||
{
|
||||
nsGlobalWindow* global = GetWindow(proxy);
|
||||
if (global) {
|
||||
global->ClearWrapper();
|
||||
nsGlobalWindow* outerWindow = GetOuterWindow(proxy);
|
||||
if (outerWindow) {
|
||||
outerWindow->ClearWrapper();
|
||||
|
||||
// Ideally we would use OnFinalize here, but it's possible that
|
||||
// EnsureScriptEnvironment will later be called on the window, and we don't
|
||||
// want to create a new script object in that case. Therefore, we need to
|
||||
// write a non-null value that will reliably crash when dereferenced.
|
||||
global->PoisonOuterWindowProxy(proxy);
|
||||
outerWindow->PoisonOuterWindowProxy(proxy);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -985,7 +987,7 @@ nsOuterWindowProxy::GetSubframeWindow(JSContext *cx,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsGlobalWindow* win = GetWindow(proxy);
|
||||
nsGlobalWindow* win = GetOuterWindow(proxy);
|
||||
MOZ_ASSERT(win->IsOuterWindow());
|
||||
return win->IndexedGetterOuter(index);
|
||||
}
|
||||
|
@ -994,7 +996,7 @@ bool
|
|||
nsOuterWindowProxy::AppendIndexedPropertyNames(JSContext *cx, JSObject *proxy,
|
||||
JS::AutoIdVector &props) const
|
||||
{
|
||||
uint32_t length = GetWindow(proxy)->Length();
|
||||
uint32_t length = GetOuterWindow(proxy)->Length();
|
||||
MOZ_ASSERT(int32_t(length) >= 0);
|
||||
if (!props.reserve(props.length() + length)) {
|
||||
return false;
|
||||
|
@ -1023,9 +1025,9 @@ nsOuterWindowProxy::unwatch(JSContext *cx, JS::Handle<JSObject*> proxy,
|
|||
void
|
||||
nsOuterWindowProxy::ObjectMoved(JSObject *obj, const JSObject *old)
|
||||
{
|
||||
nsGlobalWindow* global = GetWindow(obj);
|
||||
if (global) {
|
||||
global->UpdateWrapper(obj, old);
|
||||
nsGlobalWindow* outerWindow = GetOuterWindow(obj);
|
||||
if (outerWindow) {
|
||||
outerWindow->UpdateWrapper(obj, old);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,14 +21,15 @@
|
|||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::ipc;
|
||||
|
||||
bool
|
||||
nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync)
|
||||
{
|
||||
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
|
||||
|
@ -38,7 +39,7 @@ nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
|
|||
SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
|
||||
nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
|
||||
nsCOMPtr<nsIFrameLoader> fl = GetFrameLoader();
|
||||
mm->ReceiveMessage(mOwner, fl, aMessage, true, &aHelper, &cpows, aPrincipal,
|
||||
mm->ReceiveMessage(mOwner, fl, aMessage, true, &aData, &cpows, aPrincipal,
|
||||
aRetVal);
|
||||
}
|
||||
return true;
|
||||
|
@ -51,10 +52,10 @@ public:
|
|||
nsAsyncMessageToParent(JSContext* aCx,
|
||||
nsInProcessTabChildGlobal* aTabChild,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aHelper, aCpows, aPrincipal),
|
||||
: nsSameProcessAsyncMessageBase(aCx, aMessage, aData, aCpows, aPrincipal),
|
||||
mTabChild(aTabChild)
|
||||
{
|
||||
}
|
||||
|
@ -71,13 +72,13 @@ public:
|
|||
bool
|
||||
nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
SameProcessMessageQueue* queue = SameProcessMessageQueue::Get();
|
||||
nsRefPtr<nsAsyncMessageToParent> ev =
|
||||
new nsAsyncMessageToParent(aCx, this, aMessage, aHelper, aCpows, aPrincipal);
|
||||
new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows, aPrincipal);
|
||||
queue->Push(ev);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ class nsInProcessTabChildGlobal : public mozilla::DOMEventTargetHelper,
|
|||
public nsSupportsWeakReference,
|
||||
public mozilla::dom::ipc::MessageManagerCallback
|
||||
{
|
||||
typedef mozilla::dom::StructuredCloneIPCHelper StructuredCloneIPCHelper;
|
||||
typedef mozilla::dom::ipc::StructuredCloneData StructuredCloneData;
|
||||
|
||||
public:
|
||||
nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner,
|
||||
|
@ -83,14 +83,14 @@ public:
|
|||
*/
|
||||
virtual bool DoSendBlockingMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal,
|
||||
nsTArray<StructuredCloneIPCHelper>* aRetVal,
|
||||
nsTArray<StructuredCloneData>* aRetVal,
|
||||
bool aIsSync) override;
|
||||
virtual bool DoSendAsyncMessage(JSContext* aCx,
|
||||
const nsAString& aMessage,
|
||||
StructuredCloneIPCHelper& aHelper,
|
||||
StructuredCloneData& aData,
|
||||
JS::Handle<JSObject *> aCpows,
|
||||
nsIPrincipal* aPrincipal) override;
|
||||
|
||||
|
|
|
@ -2962,7 +2962,8 @@ nsObjectLoadingContent::LoadFallback(FallbackType aType, bool aNotify) {
|
|||
aType = eFallbackAlternate;
|
||||
}
|
||||
|
||||
if (thisContent->IsHTMLElement(nsGkAtoms::object) &&
|
||||
if ((thisContent->IsHTMLElement(nsGkAtoms::object) ||
|
||||
thisContent->IsHTMLElement(nsGkAtoms::applet)) &&
|
||||
(aType == eFallbackUnsupported ||
|
||||
aType == eFallbackDisabled ||
|
||||
aType == eFallbackBlocklisted))
|
||||
|
|
|
@ -107,7 +107,7 @@ nsPropertyTable::TransferOrDeleteAllPropertiesFor(nsPropertyOwner aObject,
|
|||
break;
|
||||
}
|
||||
|
||||
PL_DHashTableRawRemove(&prop->mObjectValueMap, entry);
|
||||
prop->mObjectValueMap.RemoveEntry(entry);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -164,7 +164,7 @@ nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject,
|
|||
propValue = entry->value;
|
||||
if (aRemove) {
|
||||
// don't call propertyList->mDtorFunc. That's the caller's job now.
|
||||
PL_DHashTableRawRemove(&propertyList->mObjectValueMap, entry);
|
||||
propertyList->mObjectValueMap.RemoveEntry(entry);
|
||||
}
|
||||
rv = NS_OK;
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ nsPropertyTable::PropertyList::DeletePropertyFor(nsPropertyOwner aObject)
|
|||
return false;
|
||||
|
||||
void* value = entry->value;
|
||||
PL_DHashTableRawRemove(&mObjectValueMap, entry);
|
||||
mObjectValueMap.RemoveEntry(entry);
|
||||
|
||||
if (mDtorFunc)
|
||||
mDtorFunc(const_cast<void*>(aObject.get()), mName, value, mDtorData);
|
||||
|
|
|
@ -19,8 +19,9 @@ NS_INTERFACE_MAP_END
|
|||
NS_IMPL_ADDREF(nsQueryContentEventResult)
|
||||
NS_IMPL_RELEASE(nsQueryContentEventResult)
|
||||
|
||||
nsQueryContentEventResult::nsQueryContentEventResult() :
|
||||
mEventID(0), mSucceeded(false)
|
||||
nsQueryContentEventResult::nsQueryContentEventResult()
|
||||
: mEventMessage(eVoidEvent)
|
||||
, mSucceeded(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -54,20 +55,19 @@ nsQueryContentEventResult::GetTentativeCaretOffset(uint32_t* aOffset)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool IsRectEnabled(uint32_t aEventID)
|
||||
static bool IsRectEnabled(EventMessage aEventMessage)
|
||||
{
|
||||
return aEventID == NS_QUERY_CARET_RECT ||
|
||||
aEventID == NS_QUERY_TEXT_RECT ||
|
||||
aEventID == NS_QUERY_EDITOR_RECT ||
|
||||
aEventID == NS_QUERY_CHARACTER_AT_POINT;
|
||||
return aEventMessage == eQueryCaretRect ||
|
||||
aEventMessage == NS_QUERY_TEXT_RECT ||
|
||||
aEventMessage == eQueryEditorRect ||
|
||||
aEventMessage == eQueryCharacterAtPoint;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsQueryContentEventResult::GetReversed(bool *aReversed)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mEventID == NS_QUERY_SELECTED_TEXT,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mEventMessage == eQuerySelectedText, NS_ERROR_NOT_AVAILABLE);
|
||||
*aReversed = mReversed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ NS_IMETHODIMP
|
|||
nsQueryContentEventResult::GetLeft(int32_t *aLeft)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(IsRectEnabled(mEventID),
|
||||
NS_ENSURE_TRUE(IsRectEnabled(mEventMessage),
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
*aLeft = mRect.x;
|
||||
return NS_OK;
|
||||
|
@ -86,7 +86,7 @@ NS_IMETHODIMP
|
|||
nsQueryContentEventResult::GetWidth(int32_t *aWidth)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(IsRectEnabled(mEventID),
|
||||
NS_ENSURE_TRUE(IsRectEnabled(mEventMessage),
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
*aWidth = mRect.width;
|
||||
return NS_OK;
|
||||
|
@ -96,7 +96,7 @@ NS_IMETHODIMP
|
|||
nsQueryContentEventResult::GetTop(int32_t *aTop)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(IsRectEnabled(mEventID),
|
||||
NS_ENSURE_TRUE(IsRectEnabled(mEventMessage),
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
*aTop = mRect.y;
|
||||
return NS_OK;
|
||||
|
@ -106,7 +106,7 @@ NS_IMETHODIMP
|
|||
nsQueryContentEventResult::GetHeight(int32_t *aHeight)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(IsRectEnabled(mEventID),
|
||||
NS_ENSURE_TRUE(IsRectEnabled(mEventMessage),
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
*aHeight = mRect.height;
|
||||
return NS_OK;
|
||||
|
@ -116,8 +116,8 @@ NS_IMETHODIMP
|
|||
nsQueryContentEventResult::GetText(nsAString &aText)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mEventID == NS_QUERY_SELECTED_TEXT ||
|
||||
mEventID == NS_QUERY_TEXT_CONTENT,
|
||||
NS_ENSURE_TRUE(mEventMessage == eQuerySelectedText ||
|
||||
mEventMessage == eQueryTextContent,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
aText = mString;
|
||||
return NS_OK;
|
||||
|
@ -126,7 +126,7 @@ nsQueryContentEventResult::GetText(nsAString &aText)
|
|||
NS_IMETHODIMP
|
||||
nsQueryContentEventResult::GetSucceeded(bool *aSucceeded)
|
||||
{
|
||||
NS_ENSURE_TRUE(mEventID != 0, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_TRUE(mEventMessage != eVoidEvent, NS_ERROR_NOT_INITIALIZED);
|
||||
*aSucceeded = mSucceeded;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -135,8 +135,8 @@ NS_IMETHODIMP
|
|||
nsQueryContentEventResult::GetNotFound(bool *aNotFound)
|
||||
{
|
||||
NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(mEventID == NS_QUERY_SELECTED_TEXT ||
|
||||
mEventID == NS_QUERY_CHARACTER_AT_POINT,
|
||||
NS_ENSURE_TRUE(mEventMessage == eQuerySelectedText ||
|
||||
mEventMessage == eQueryCharacterAtPoint,
|
||||
NS_ERROR_NOT_AVAILABLE);
|
||||
*aNotFound = (mOffset == WidgetQueryContentEvent::NOT_FOUND);
|
||||
return NS_OK;
|
||||
|
@ -148,7 +148,7 @@ nsQueryContentEventResult::GetTentativeCaretOffsetNotFound(bool* aNotFound)
|
|||
if (NS_WARN_IF(!mSucceeded)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
if (NS_WARN_IF(mEventID != NS_QUERY_CHARACTER_AT_POINT)) {
|
||||
if (NS_WARN_IF(mEventMessage != eQueryCharacterAtPoint)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
*aNotFound = (mTentativeCaretOffset == WidgetQueryContentEvent::NOT_FOUND);
|
||||
|
@ -159,7 +159,7 @@ void
|
|||
nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget,
|
||||
const WidgetQueryContentEvent &aEvent)
|
||||
{
|
||||
mEventID = aEvent.mMessage;
|
||||
mEventMessage = aEvent.mMessage;
|
||||
mSucceeded = aEvent.mSucceeded;
|
||||
mReversed = aEvent.mReply.mReversed;
|
||||
mRect = aEvent.mReply.mRect;
|
||||
|
@ -167,7 +167,7 @@ nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget,
|
|||
mTentativeCaretOffset = aEvent.mReply.mTentativeCaretOffset;
|
||||
mString = aEvent.mReply.mString;
|
||||
|
||||
if (!IsRectEnabled(mEventID) || !aWidget || !mSucceeded) {
|
||||
if (!IsRectEnabled(mEventMessage) || !aWidget || !mSucceeded) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
protected:
|
||||
~nsQueryContentEventResult();
|
||||
|
||||
uint32_t mEventID;
|
||||
mozilla::EventMessage mEventMessage;
|
||||
|
||||
uint32_t mOffset;
|
||||
uint32_t mTentativeCaretOffset;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "nsIStructuredCloneContainer.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/StructuredCloneIPCHelper.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
|
||||
#define NS_STRUCTUREDCLONECONTAINER_CONTRACTID \
|
||||
"@mozilla.org/docshell/structured-clone-container;1"
|
||||
|
@ -23,7 +23,7 @@
|
|||
|
||||
class nsStructuredCloneContainer final
|
||||
: public nsIStructuredCloneContainer
|
||||
, public mozilla::dom::StructuredCloneIPCHelper
|
||||
, public mozilla::dom::ipc::StructuredCloneData
|
||||
{
|
||||
public:
|
||||
nsStructuredCloneContainer();
|
||||
|
|
|
@ -259,6 +259,7 @@ support-files =
|
|||
[test_anonymousContent_insert.html]
|
||||
[test_anonymousContent_manipulate_content.html]
|
||||
[test_anonymousContent_style_csp.html]
|
||||
[test_applet_alternate_content.html]
|
||||
[test_appname_override.html]
|
||||
[test_async_setTimeout_stack.html]
|
||||
[test_async_setTimeout_stack_across_globals.html]
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1200602
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1200602</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SpecialPowers.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=1200602">Mozilla Bug 1200602</a>
|
||||
<pre id="test">
|
||||
<script type="application/javascript;version=1.8">
|
||||
|
||||
function test() {
|
||||
"use strict";
|
||||
|
||||
const objLC = SpecialPowers.Ci.nsIObjectLoadingContent;
|
||||
let obj = document.createElement("applet");
|
||||
obj.appendChild(document.createTextNode("alternate content"));
|
||||
document.body.appendChild(obj);
|
||||
|
||||
obj instanceof objLC;
|
||||
obj = SpecialPowers.wrap(obj);
|
||||
|
||||
// We expect this tag to simply go to alternate content, not get a
|
||||
// pluginProblem binding or fire any events.
|
||||
ok(obj.displayedType == objLC.TYPE_NULL, "expected null type");
|
||||
ok(obj.pluginFallbackType == objLC.PLUGIN_ALTERNATE,
|
||||
"expected alternate fallback mode");
|
||||
}
|
||||
|
||||
// Test all non-plugin types these tags can load to make sure none of them
|
||||
// trigger plugin-specific fallbacks when loaded with no URI
|
||||
test();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -9,16 +9,7 @@ propList = eval(sys.stdin.read())
|
|||
props = ""
|
||||
for [name, prop, id, flags, pref] in propList:
|
||||
extendedAttrs = ["Throws", "TreatNullAs=EmptyString"]
|
||||
# To limit the overhead of Func= annotations, we only generate them when
|
||||
# necessary, which is when the
|
||||
# CSS_PROPERTY_ALWAYS_ENABLED_IN_CHROME_OR_CERTIFIED_APP flag is set.
|
||||
# Otherwise, we try to get by with just a Pref= annotation or no annotation
|
||||
# at all.
|
||||
if "CSS_PROPERTY_ALWAYS_ENABLED_IN_CHROME_OR_CERTIFIED_APP" in flags:
|
||||
extendedAttrs.append('Func="IsCSSPropertyExposedToJS<eCSSProperty_%s>"' % id)
|
||||
# The following is an 'elif' because it is the responsibility of
|
||||
# IsCSSPropertyExposedToJS to handle the pref if there is one.
|
||||
elif pref is not "":
|
||||
if pref is not "":
|
||||
extendedAttrs.append('Pref="%s"' % pref)
|
||||
if not prop.startswith("Moz"):
|
||||
prop = prop[0].lower() + prop[1:]
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "BluetoothService.h"
|
||||
#include "BluetoothSocket.h"
|
||||
#include "BluetoothUtils.h"
|
||||
#include "BluetoothUuid.h"
|
||||
#include "ObexBase.h"
|
||||
|
||||
|
@ -348,7 +349,7 @@ BluetoothMapSmsManager::MasDataHandler(UnixSocketBuffer* aMessage)
|
|||
if (type.EqualsLiteral("x-obex/folder-listing")) {
|
||||
HandleSmsMmsFolderListing(pktHeaders);
|
||||
} else if (type.EqualsLiteral("x-bt/MAP-msg-listing")) {
|
||||
// TODO: Implement this feature in Bug 1166675
|
||||
HandleSmsMmsMsgListing(pktHeaders);
|
||||
} else if (type.EqualsLiteral("x-bt/message")) {
|
||||
// TODO: Implement this feature in Bug 1166679
|
||||
} else {
|
||||
|
@ -688,6 +689,140 @@ BluetoothMapSmsManager::HandleSmsMmsFolderListing(const ObexHeaderSet& aHeader)
|
|||
SendMasObexData(resp, ObexResponseCode::Success, index);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothMapSmsManager::AppendBtNamedValueByTagId(
|
||||
const ObexHeaderSet& aHeader,
|
||||
InfallibleTArray<BluetoothNamedValue>& aValues,
|
||||
const Map::AppParametersTagId aTagId)
|
||||
{
|
||||
uint8_t buf[64];
|
||||
if (!aHeader.GetAppParameter(aTagId, buf, 64)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Follow MAP 6.3.1 Application Parameter Header
|
||||
*/
|
||||
switch (aTagId) {
|
||||
case Map::AppParametersTagId::MaxListCount: {
|
||||
uint16_t maxListCount = *((uint16_t *)buf);
|
||||
// convert big endian to little endian
|
||||
maxListCount = (maxListCount >> 8) | (maxListCount << 8);
|
||||
BT_LOGR("max list count: %d", maxListCount);
|
||||
AppendNamedValue(aValues, "maxListCount", maxListCount);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::StartOffset: {
|
||||
uint16_t startOffset = *((uint16_t *)buf);
|
||||
// convert big endian to little endian
|
||||
startOffset = (startOffset >> 8) | (startOffset << 8);
|
||||
BT_LOGR("start offset : %d", startOffset);
|
||||
AppendNamedValue(aValues, "startOffset", startOffset);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::SubjectLength: {
|
||||
uint8_t subLength = *((uint8_t *)buf);
|
||||
// convert big endian to little endian
|
||||
subLength = (subLength >> 8) | (subLength << 8);
|
||||
BT_LOGR("msg subLength : %d", subLength);
|
||||
AppendNamedValue(aValues, "subLength", subLength);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::ParameterMask: {
|
||||
// 4 bytes
|
||||
uint32_t parameterMask = *((uint32_t *)buf);
|
||||
// convert big endian to little endian
|
||||
parameterMask = (parameterMask >> 8) | (parameterMask << 8);
|
||||
BT_LOGR("msg parameterMask : %d", parameterMask);
|
||||
AppendNamedValue(aValues, "parameterMask", parameterMask);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::FilterMessageType: {
|
||||
uint8_t filterMessageType = *((uint8_t *)buf);
|
||||
// convert big endian to little endian
|
||||
filterMessageType = (filterMessageType >> 8) | (filterMessageType << 8);
|
||||
BT_LOGR("msg filterMessageType : %d", filterMessageType);
|
||||
AppendNamedValue(aValues, "filterMessageType", filterMessageType);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::FilterPeriodBegin: {
|
||||
nsCString filterPeriodBegin((char *) buf);
|
||||
BT_LOGR("msg FilterPeriodBegin : %s", filterPeriodBegin.get());
|
||||
AppendNamedValue(aValues, "filterPeriodBegin", filterPeriodBegin);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::FilterPeriodEnd: {
|
||||
nsCString filterPeriodEnd((char*)buf);
|
||||
BT_LOGR("msg filterPeriodEnd : %s", filterPeriodEnd.get());
|
||||
AppendNamedValue(aValues, "filterPeriodEnd", filterPeriodEnd);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::FilterReadStatus: {
|
||||
uint8_t filterReadStatus = *((uint8_t *)buf);
|
||||
// convert big endian to little endian
|
||||
filterReadStatus = (filterReadStatus >> 8) | (filterReadStatus << 8);
|
||||
BT_LOGR("msg filter read status : %d", filterReadStatus);
|
||||
AppendNamedValue(aValues, "filterReadStatus", filterReadStatus);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::FilterRecipient: {
|
||||
nsCString filterRecipient((char*) buf);
|
||||
BT_LOGR("msg filterRecipient : %s", filterRecipient.get());
|
||||
AppendNamedValue(aValues, "filterRecipient", filterRecipient);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::FilterOriginator: {
|
||||
nsCString filterOriginator((char*) buf);
|
||||
BT_LOGR("msg filter Originator : %s", filterOriginator.get());
|
||||
AppendNamedValue(aValues, "filterOriginator", filterOriginator);
|
||||
break;
|
||||
}
|
||||
case Map::AppParametersTagId::FilterPriority: {
|
||||
uint8_t filterPriority = *((uint8_t *)buf);
|
||||
// convert big endian to little endian
|
||||
filterPriority = (filterPriority >> 8) | (filterPriority << 8);
|
||||
BT_LOGR("msg filter priority: %d", filterPriority);
|
||||
AppendNamedValue(aValues, "filterPriority", filterPriority);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BT_LOGR("Unsupported AppParameterTag: %x", aTagId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothMapSmsManager::HandleSmsMmsMsgListing(const ObexHeaderSet& aHeader)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
BluetoothService* bs = BluetoothService::Get();
|
||||
|
||||
InfallibleTArray<BluetoothNamedValue> data;
|
||||
|
||||
static Map::AppParametersTagId sMsgListingParameters[] = {
|
||||
[0] = Map::AppParametersTagId::MaxListCount,
|
||||
[1] = Map::AppParametersTagId::StartOffset,
|
||||
[2] = Map::AppParametersTagId::SubjectLength,
|
||||
[3] = Map::AppParametersTagId::ParameterMask,
|
||||
[4] = Map::AppParametersTagId::FilterMessageType,
|
||||
[5] = Map::AppParametersTagId::FilterPeriodBegin,
|
||||
[6] = Map::AppParametersTagId::FilterPeriodEnd,
|
||||
[7] = Map::AppParametersTagId::FilterReadStatus,
|
||||
[8] = Map::AppParametersTagId::FilterRecipient,
|
||||
[9] = Map::AppParametersTagId::FilterOriginator,
|
||||
[10] = Map::AppParametersTagId::FilterPriority
|
||||
};
|
||||
|
||||
for (uint8_t i = 0; i < MOZ_ARRAY_LENGTH(sMsgListingParameters); i++) {
|
||||
AppendBtNamedValueByTagId(aHeader, data, sMsgListingParameters[i]);
|
||||
}
|
||||
|
||||
bs->DistributeSignal(NS_LITERAL_STRING(MAP_MESSAGES_LISTING_REQ_ID),
|
||||
NS_LITERAL_STRING(KEY_ADAPTER),
|
||||
data);
|
||||
}
|
||||
|
||||
void
|
||||
BluetoothMapSmsManager::BuildDefaultFolderStructure()
|
||||
{
|
||||
|
|
|
@ -96,6 +96,10 @@ private:
|
|||
void HandleEventReport(const ObexHeaderSet& aHeader);
|
||||
void HandleMessageStatus(const ObexHeaderSet& aHeader);
|
||||
void HandleSmsMmsFolderListing(const ObexHeaderSet& aHeader);
|
||||
void HandleSmsMmsMsgListing(const ObexHeaderSet& aHeader);
|
||||
void AppendBtNamedValueByTagId(const ObexHeaderSet& aHeader,
|
||||
InfallibleTArray<BluetoothNamedValue>& aValues,
|
||||
const Map::AppParametersTagId aTagId);
|
||||
void SendMasObexData(uint8_t* aData, uint8_t aOpcode, int aSize);
|
||||
void SendMnsObexData(uint8_t* aData, uint8_t aOpcode, int aSize);
|
||||
|
||||
|
|
|
@ -275,14 +275,14 @@ BluetoothPbapManager::ReceiveSocketData(BluetoothSocket* aSocket,
|
|||
// All OBEX request messages shall be sent as one OBEX packet containing
|
||||
// all of the headers. I.e. OBEX GET with opcode 0x83 shall always be
|
||||
// used. OBEX GET with opcode 0x03 shall never be used.
|
||||
BT_LOGR("PBAP shall always uses OBEX GetFinal instead of Get.");
|
||||
BT_LOGR("PBAP shall always use OBEX GetFinal instead of Get.");
|
||||
|
||||
// no break. Treat 'Get' as 'GetFinal' for error tolerance.
|
||||
case ObexRequestCode::GetFinal: {
|
||||
// As long as 'mVCardDataStream' requires multiple response packets to
|
||||
// complete, the client should continue to issue GET requests until the
|
||||
// final body information (in an End-of-Body header) arrives, along with
|
||||
// the response code 0xA0 Success.
|
||||
// When |mVCardDataStream| requires multiple response packets to complete,
|
||||
// the client should continue to issue GET requests until the final body
|
||||
// information (i.e., End-of-Body header) arrives, along with
|
||||
// ObexResponseCode::Success
|
||||
if (mVCardDataStream) {
|
||||
if (!ReplyToGet()) {
|
||||
BT_LOGR("Failed to reply to PBAP GET request.");
|
||||
|
@ -731,7 +731,7 @@ BluetoothPbapManager::PackPropertiesMask(uint8_t* aData, int aSize)
|
|||
(aData[5] << 16) | (aData[4] << 24);
|
||||
|
||||
uint32_t count = 0;
|
||||
while (!x) {
|
||||
while (x) {
|
||||
if (x & 1) {
|
||||
propSelector.AppendElement(count);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ EnsureBluetoothSocketHalLoad()
|
|||
}
|
||||
|
||||
class mozilla::dom::bluetooth::DroidSocketImpl
|
||||
: public ipc::UnixFdWatcher
|
||||
: public mozilla::ipc::UnixFdWatcher
|
||||
, public DataSocketIO
|
||||
{
|
||||
public:
|
||||
|
@ -74,7 +74,7 @@ public:
|
|||
DroidSocketImpl(MessageLoop* aConsumerLoop,
|
||||
MessageLoop* aIOLoop,
|
||||
BluetoothSocket* aConsumer)
|
||||
: ipc::UnixFdWatcher(aIOLoop)
|
||||
: mozilla::ipc::UnixFdWatcher(aIOLoop)
|
||||
, DataSocketIO(aConsumerLoop)
|
||||
, mConsumer(aConsumer)
|
||||
, mShuttingDownOnIOThread(false)
|
||||
|
|
|
@ -185,6 +185,12 @@ extern bool gBluetoothDebugFlag;
|
|||
#define PULL_VCARD_ENTRY_REQ_ID "pullvcardentryreq"
|
||||
#define PULL_VCARD_LISTING_REQ_ID "pullvcardlistingreq"
|
||||
|
||||
/**
|
||||
* When receiving a MAP request of 'messages listing' from a remote device,
|
||||
* we'll dispatch an event.
|
||||
*/
|
||||
#define MAP_MESSAGES_LISTING_REQ_ID "mapmessageslistingreq"
|
||||
|
||||
/**
|
||||
* When the value of a characteristic of a remote BLE device changes, we'll
|
||||
* dispatch an event
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/MessageEvent.h"
|
||||
#include "mozilla/dom/MessageEventBinding.h"
|
||||
#include "mozilla/dom/StructuredCloneIPCHelper.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/ipc/PBackgroundChild.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "WorkerPrivate.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -85,17 +85,17 @@ BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
|
|||
return true;
|
||||
}
|
||||
|
||||
StructuredCloneIPCHelper cloneHelper;
|
||||
cloneHelper.BlobImpls().AppendElements(blobs);
|
||||
ipc::StructuredCloneData cloneData;
|
||||
cloneData.BlobImpls().AppendElements(blobs);
|
||||
|
||||
const SerializedStructuredCloneBuffer& buffer = aData.data();
|
||||
cloneHelper.UseExternalData(buffer.data, buffer.dataLength);
|
||||
cloneData.UseExternalData(buffer.data, buffer.dataLength);
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> value(cx, JS::NullValue());
|
||||
if (buffer.dataLength) {
|
||||
ErrorResult rv;
|
||||
cloneHelper.Read(cx, &value, rv);
|
||||
cloneData.Read(cx, &value, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3951,16 +3951,16 @@ gfxFontGroup *CanvasRenderingContext2D::GetCurrentFontStyle()
|
|||
if (err.Failed() || !fontUpdated) {
|
||||
gfxFontStyle style;
|
||||
style.size = kDefaultFontSize;
|
||||
gfxTextPerfMetrics* tp = nullptr;
|
||||
if (presShell && !presShell->IsDestroying()) {
|
||||
tp = presShell->GetPresContext()->GetTextPerfMetrics();
|
||||
}
|
||||
CurrentState().fontGroup =
|
||||
gfxPlatform::GetPlatform()->CreateFontGroup(FontFamilyList(eFamily_sans_serif),
|
||||
&style,
|
||||
&style, tp,
|
||||
nullptr);
|
||||
if (CurrentState().fontGroup) {
|
||||
CurrentState().font = kDefaultFontStyle;
|
||||
if (presShell && !presShell->IsDestroying()) {
|
||||
CurrentState().fontGroup->SetTextPerfMetrics(
|
||||
presShell->GetPresContext()->GetTextPerfMetrics());
|
||||
}
|
||||
} else {
|
||||
NS_ERROR("Default canvas font is invalid");
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@ GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_USER_2] = "user-2";
|
|||
const CB_MESSAGE_SIZE_GSM = 88;
|
||||
const CB_MESSAGE_SIZE_ETWS = 56;
|
||||
|
||||
const CB_UMTS_MESSAGE_TYPE_CBS = 1;
|
||||
const CB_UMTS_MESSAGE_PAGE_SIZE = 82;
|
||||
|
||||
const CB_GSM_MESSAGEID_ETWS_BEGIN = 0x1100;
|
||||
const CB_GSM_MESSAGEID_ETWS_END = 0x1107;
|
||||
|
||||
|
@ -201,18 +204,28 @@ function ensureCellBroadcast() {
|
|||
SpecialPowers.pushPermissions(permissions, function() {
|
||||
ok(true, "permissions pushed: " + JSON.stringify(permissions));
|
||||
|
||||
cbManager = window.navigator.mozCellBroadcast;
|
||||
if (cbManager) {
|
||||
log("navigator.mozCellBroadcast is instance of " + cbManager.constructor);
|
||||
} else {
|
||||
log("navigator.mozCellBroadcast is undefined.");
|
||||
}
|
||||
// Permission changes can't change existing Navigator.prototype
|
||||
// objects, so grab our objects from a new Navigator.
|
||||
let workingFrame = document.createElement("iframe");
|
||||
workingFrame.addEventListener("load", function load() {
|
||||
workingFrame.removeEventListener("load", load);
|
||||
|
||||
if (cbManager instanceof window.MozCellBroadcast) {
|
||||
deferred.resolve(cbManager);
|
||||
} else {
|
||||
deferred.reject();
|
||||
}
|
||||
cbManager = workingFrame.contentWindow.navigator.mozCellBroadcast;
|
||||
|
||||
if (cbManager) {
|
||||
log("navigator.mozCellBroadcast is instance of " + cbManager.constructor);
|
||||
} else {
|
||||
log("navigator.mozCellBroadcast is undefined.");
|
||||
}
|
||||
|
||||
if (cbManager instanceof window.MozCellBroadcast) {
|
||||
deferred.resolve(cbManager);
|
||||
} else {
|
||||
deferred.reject();
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(workingFrame);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
|
|
|
@ -5,5 +5,7 @@ qemu = true
|
|||
|
||||
[test_cellbroadcast_etws.js]
|
||||
[test_cellbroadcast_gsm.js]
|
||||
[test_cellbroadcast_gsm_language_and_body.js]
|
||||
[test_cellbroadcast_multi_sim.js]
|
||||
[test_cellbroadcast_umts.js]
|
||||
[test_cellbroadcast_umts.js]
|
||||
[test_cellbroadcast_umts_language_and_body.js]
|
|
@ -1,7 +1,7 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 20000;
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
function testReceiving_ETWS_MessageAttributes() {
|
||||
|
|
|
@ -110,62 +110,6 @@ function testReceiving_GSM_MessageId() {
|
|||
return promise;
|
||||
}
|
||||
|
||||
function testReceiving_GSM_Language_and_Body() {
|
||||
log("Test receiving GSM Cell Broadcast - Language & Body");
|
||||
|
||||
let promise = Promise.resolve();
|
||||
|
||||
let testDcs = [];
|
||||
let dcs = 0;
|
||||
while (dcs <= 0xFF) {
|
||||
try {
|
||||
let dcsInfo = { dcs: dcs };
|
||||
[ dcsInfo.encoding, dcsInfo.language,
|
||||
dcsInfo.indicator, dcsInfo.messageClass ] = decodeGsmDataCodingScheme(dcs);
|
||||
testDcs.push(dcsInfo);
|
||||
} catch (e) {
|
||||
// Unsupported coding group, skip.
|
||||
dcs = (dcs & PDU_DCS_CODING_GROUP_BITS) + 0x10;
|
||||
}
|
||||
dcs++;
|
||||
}
|
||||
|
||||
let verifyCBMessage = (aMessage, aDcsInfo) => {
|
||||
if (aDcsInfo.language) {
|
||||
is(aMessage.language, aDcsInfo.language, "aMessage.language");
|
||||
} else if (aDcsInfo.indicator) {
|
||||
is(aMessage.language, "@@", "aMessage.language");
|
||||
} else {
|
||||
ok(aMessage.language == null, "aMessage.language");
|
||||
}
|
||||
|
||||
switch (aDcsInfo.encoding) {
|
||||
case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
|
||||
is(aMessage.body, aDcsInfo.indicator ? DUMMY_BODY_7BITS_IND : DUMMY_BODY_7BITS, "aMessage.body");
|
||||
break;
|
||||
case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
|
||||
ok(aMessage.body == null, "aMessage.body");
|
||||
break;
|
||||
case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
|
||||
is(aMessage.body, aDcsInfo.indicator ? DUMMY_BODY_UCS2_IND : DUMMY_BODY_UCS2, "aMessage.body");
|
||||
break;
|
||||
}
|
||||
|
||||
is(aMessage.messageClass, aDcsInfo.messageClass, "aMessage.messageClass");
|
||||
};
|
||||
|
||||
testDcs.forEach(function(aDcsInfo) {
|
||||
let pdu = buildHexStr(0, 8)
|
||||
+ buildHexStr(aDcsInfo.dcs, 2)
|
||||
+ buildHexStr(0, (CB_MESSAGE_SIZE_GSM - 5) * 2);
|
||||
promise = promise
|
||||
.then(() => sendMultipleRawCbsToEmulatorAndWait([pdu]))
|
||||
.then((aMessage) => verifyCBMessage(aMessage, aDcsInfo));
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
function testReceiving_GSM_Timestamp() {
|
||||
log("Test receiving GSM Cell Broadcast - Timestamp");
|
||||
|
||||
|
@ -351,7 +295,6 @@ startTestCommon(function testCaseMain() {
|
|||
.then(() => testReceiving_GSM_GeographicalScope())
|
||||
.then(() => testReceiving_GSM_MessageCode())
|
||||
.then(() => testReceiving_GSM_MessageId())
|
||||
.then(() => testReceiving_GSM_Language_and_Body())
|
||||
.then(() => testReceiving_GSM_Timestamp())
|
||||
.then(() => testReceiving_GSM_WarningType())
|
||||
.then(() => testReceiving_GSM_EmergencyUserAlert())
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 90000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
function testReceiving_GSM_Language_and_Body() {
|
||||
log("Test receiving GSM Cell Broadcast - Language & Body");
|
||||
|
||||
let promise = Promise.resolve();
|
||||
|
||||
let testDcs = [];
|
||||
let dcs = 0;
|
||||
while (dcs <= 0xFF) {
|
||||
try {
|
||||
let dcsInfo = { dcs: dcs };
|
||||
[ dcsInfo.encoding, dcsInfo.language,
|
||||
dcsInfo.indicator, dcsInfo.messageClass ] = decodeGsmDataCodingScheme(dcs);
|
||||
testDcs.push(dcsInfo);
|
||||
} catch (e) {
|
||||
// Unsupported coding group, skip.
|
||||
dcs = (dcs & PDU_DCS_CODING_GROUP_BITS) + 0x10;
|
||||
}
|
||||
dcs++;
|
||||
}
|
||||
|
||||
let verifyCBMessage = (aMessage, aDcsInfo) => {
|
||||
if (aDcsInfo.language) {
|
||||
is(aMessage.language, aDcsInfo.language, "aMessage.language");
|
||||
} else if (aDcsInfo.indicator) {
|
||||
is(aMessage.language, "@@", "aMessage.language");
|
||||
} else {
|
||||
ok(aMessage.language == null, "aMessage.language");
|
||||
}
|
||||
|
||||
switch (aDcsInfo.encoding) {
|
||||
case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
|
||||
is(aMessage.body, aDcsInfo.indicator ? DUMMY_BODY_7BITS_IND : DUMMY_BODY_7BITS, "aMessage.body");
|
||||
break;
|
||||
case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
|
||||
ok(aMessage.body == null, "aMessage.body");
|
||||
break;
|
||||
case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
|
||||
is(aMessage.body, aDcsInfo.indicator ? DUMMY_BODY_UCS2_IND : DUMMY_BODY_UCS2, "aMessage.body");
|
||||
break;
|
||||
}
|
||||
|
||||
is(aMessage.messageClass, aDcsInfo.messageClass, "aMessage.messageClass");
|
||||
};
|
||||
|
||||
ok(testDcs.length, "testDcs.length");
|
||||
testDcs.forEach(function(aDcsInfo) {
|
||||
let pdu = buildHexStr(0, 8)
|
||||
+ buildHexStr(aDcsInfo.dcs, 2)
|
||||
+ buildHexStr(0, (CB_MESSAGE_SIZE_GSM - 5) * 2);
|
||||
promise = promise
|
||||
.then(() => sendMultipleRawCbsToEmulatorAndWait([pdu]))
|
||||
.then((aMessage) => verifyCBMessage(aMessage, aDcsInfo));
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
startTestCommon(() => testReceiving_GSM_Language_and_Body());
|
|
@ -1,7 +1,7 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 10000;
|
||||
MARIONETTE_TIMEOUT = 60000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
function testReceiving_MultiSIM() {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 90000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
const CB_UMTS_MESSAGE_TYPE_CBS = 1;
|
||||
const CB_UMTS_MESSAGE_PAGE_SIZE = 82;
|
||||
|
||||
function testReceiving_UMTS_MessageAttributes() {
|
||||
log("Test receiving UMTS Cell Broadcast - Message Attributes");
|
||||
|
||||
|
@ -126,70 +126,6 @@ function testReceiving_UMTS_MessageId() {
|
|||
return promise;
|
||||
}
|
||||
|
||||
function testReceiving_UMTS_Language_and_Body() {
|
||||
log("Test receiving UMTS Cell Broadcast - Language & Body");
|
||||
|
||||
let promise = Promise.resolve();
|
||||
|
||||
let testDcs = [];
|
||||
let dcs = 0;
|
||||
while (dcs <= 0xFF) {
|
||||
try {
|
||||
let dcsInfo = { dcs: dcs };
|
||||
[ dcsInfo.encoding, dcsInfo.language,
|
||||
dcsInfo.indicator, dcsInfo.messageClass ] = decodeGsmDataCodingScheme(dcs);
|
||||
testDcs.push(dcsInfo);
|
||||
} catch (e) {
|
||||
// Unsupported coding group, skip.
|
||||
dcs = (dcs & PDU_DCS_CODING_GROUP_BITS) + 0x10;
|
||||
}
|
||||
dcs++;
|
||||
}
|
||||
|
||||
let verifyCBMessage = (aMessage, aDcsInfo) => {
|
||||
if (aDcsInfo.language) {
|
||||
is(aMessage.language, aDcsInfo.language, "aMessage.language");
|
||||
} else if (aDcsInfo.indicator) {
|
||||
is(aMessage.language, "@@", "aMessage.language");
|
||||
} else {
|
||||
ok(aMessage.language == null, "aMessage.language");
|
||||
}
|
||||
|
||||
switch (aDcsInfo.encoding) {
|
||||
case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
|
||||
is(aMessage.body,
|
||||
aDcsInfo.indicator ? DUMMY_BODY_7BITS_IND : DUMMY_BODY_7BITS,
|
||||
"aMessage.body");
|
||||
break;
|
||||
case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
|
||||
ok(aMessage.body == null, "aMessage.body");
|
||||
break;
|
||||
case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
|
||||
is(aMessage.body,
|
||||
aDcsInfo.indicator ? DUMMY_BODY_UCS2_IND : DUMMY_BODY_UCS2,
|
||||
"aMessage.body");
|
||||
break;
|
||||
}
|
||||
|
||||
is(aMessage.messageClass, aDcsInfo.messageClass, "aMessage.messageClass");
|
||||
};
|
||||
|
||||
testDcs.forEach(function(aDcsInfo) {
|
||||
let pdu = buildHexStr(CB_UMTS_MESSAGE_TYPE_CBS, 2) // msg_type
|
||||
+ buildHexStr(0, 4) // skip msg_id
|
||||
+ buildHexStr(0, 4) // skip SN
|
||||
+ buildHexStr(aDcsInfo.dcs, 2) // set dcs
|
||||
+ buildHexStr(1, 2) // set num_of_pages to 1
|
||||
+ buildHexStr(0, CB_UMTS_MESSAGE_PAGE_SIZE * 2)
|
||||
+ buildHexStr(CB_UMTS_MESSAGE_PAGE_SIZE, 2); // msg_info_length
|
||||
promise = promise
|
||||
.then(() => sendMultipleRawCbsToEmulatorAndWait([pdu]))
|
||||
.then((aMessage) => verifyCBMessage(aMessage, aDcsInfo));
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
function testReceiving_UMTS_Timestamp() {
|
||||
log("Test receiving UMTS Cell Broadcast - Timestamp");
|
||||
|
||||
|
@ -441,7 +377,6 @@ startTestCommon(function testCaseMain() {
|
|||
.then(() => testReceiving_UMTS_GeographicalScope())
|
||||
.then(() => testReceiving_UMTS_MessageCode())
|
||||
.then(() => testReceiving_UMTS_MessageId())
|
||||
.then(() => testReceiving_UMTS_Language_and_Body())
|
||||
.then(() => testReceiving_UMTS_Timestamp())
|
||||
.then(() => testReceiving_UMTS_WarningType())
|
||||
.then(() => testReceiving_UMTS_EmergencyUserAlert())
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
MARIONETTE_TIMEOUT = 90000;
|
||||
MARIONETTE_HEAD_JS = 'head.js';
|
||||
|
||||
function testReceiving_UMTS_Language_and_Body() {
|
||||
log("Test receiving UMTS Cell Broadcast - Language & Body");
|
||||
|
||||
let promise = Promise.resolve();
|
||||
|
||||
let testDcs = [];
|
||||
let dcs = 0;
|
||||
while (dcs <= 0xFF) {
|
||||
try {
|
||||
let dcsInfo = { dcs: dcs };
|
||||
[ dcsInfo.encoding, dcsInfo.language,
|
||||
dcsInfo.indicator, dcsInfo.messageClass ] = decodeGsmDataCodingScheme(dcs);
|
||||
testDcs.push(dcsInfo);
|
||||
} catch (e) {
|
||||
// Unsupported coding group, skip.
|
||||
dcs = (dcs & PDU_DCS_CODING_GROUP_BITS) + 0x10;
|
||||
}
|
||||
dcs++;
|
||||
}
|
||||
|
||||
let verifyCBMessage = (aMessage, aDcsInfo) => {
|
||||
if (aDcsInfo.language) {
|
||||
is(aMessage.language, aDcsInfo.language, "aMessage.language");
|
||||
} else if (aDcsInfo.indicator) {
|
||||
is(aMessage.language, "@@", "aMessage.language");
|
||||
} else {
|
||||
ok(aMessage.language == null, "aMessage.language");
|
||||
}
|
||||
|
||||
switch (aDcsInfo.encoding) {
|
||||
case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
|
||||
is(aMessage.body,
|
||||
aDcsInfo.indicator ? DUMMY_BODY_7BITS_IND : DUMMY_BODY_7BITS,
|
||||
"aMessage.body");
|
||||
break;
|
||||
case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
|
||||
ok(aMessage.body == null, "aMessage.body");
|
||||
break;
|
||||
case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
|
||||
is(aMessage.body,
|
||||
aDcsInfo.indicator ? DUMMY_BODY_UCS2_IND : DUMMY_BODY_UCS2,
|
||||
"aMessage.body");
|
||||
break;
|
||||
}
|
||||
|
||||
is(aMessage.messageClass, aDcsInfo.messageClass, "aMessage.messageClass");
|
||||
};
|
||||
|
||||
testDcs.forEach(function(aDcsInfo) {
|
||||
let pdu = buildHexStr(CB_UMTS_MESSAGE_TYPE_CBS, 2) // msg_type
|
||||
+ buildHexStr(0, 4) // skip msg_id
|
||||
+ buildHexStr(0, 4) // skip SN
|
||||
+ buildHexStr(aDcsInfo.dcs, 2) // set dcs
|
||||
+ buildHexStr(1, 2) // set num_of_pages to 1
|
||||
+ buildHexStr(0, CB_UMTS_MESSAGE_PAGE_SIZE * 2)
|
||||
+ buildHexStr(CB_UMTS_MESSAGE_PAGE_SIZE, 2); // msg_info_length
|
||||
promise = promise
|
||||
.then(() => sendMultipleRawCbsToEmulatorAndWait([pdu]))
|
||||
.then((aMessage) => verifyCBMessage(aMessage, aDcsInfo));
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
startTestCommon(() => testReceiving_UMTS_Language_and_Body());
|
|
@ -54,8 +54,8 @@ xn--wgbh1c=windows-1256
|
|||
|
||||
gr=ISO-8859-7
|
||||
|
||||
hk=Big5-HKSCS
|
||||
xn--j6w193g=Big5-HKSCS
|
||||
hk=Big5
|
||||
xn--j6w193g=Big5
|
||||
|
||||
hr=windows-1250
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
# x-unicode is assumed for encodings not listed here
|
||||
|
||||
Big5=zh-TW
|
||||
Big5-HKSCS=zh=HK
|
||||
EUC-JP=ja
|
||||
EUC-KR=ko
|
||||
gb18030=zh-CN
|
||||
|
|
|
@ -189,7 +189,7 @@ x-gbk=gbk
|
|||
gb18030=gb18030
|
||||
hz-gb-2312=replacement
|
||||
big5=Big5
|
||||
big5-hkscs=Big5-HKSCS
|
||||
big5-hkscs=Big5
|
||||
cn-big5=Big5
|
||||
csbig5=Big5
|
||||
x-x-big5=Big5
|
||||
|
|
|
@ -44,6 +44,7 @@ function runTextDecoderOptions()
|
|||
}, "testDecodeABVOption");
|
||||
test(testDecoderForThaiEncoding, "testDecoderForThaiEncoding");
|
||||
test(testInvalid2022JP, "testInvalid2022JP");
|
||||
test(testDecoderForBig5, "testDecoderForBig5");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -355,8 +356,7 @@ function testDecoderGetEncoding()
|
|||
{encoding: "x-mac-cyrillic", labels: ["x-mac-cyrillic", "x-mac-ukrainian"]},
|
||||
{encoding: "gbk", labels: ["chinese", "csgb2312", "csiso58gb231280", "gb2312", "gb_2312", "gb_2312-80", "gbk", "iso-ir-58", "x-gbk"]},
|
||||
{encoding: "gb18030", labels: ["gb18030"]},
|
||||
{encoding: "big5", labels: ["big5", "cn-big5", "csbig5", "x-x-big5"]},
|
||||
{encoding: "big5-hkscs", labels: ["big5-hkscs"]},
|
||||
{encoding: "big5", labels: ["big5", "cn-big5", "csbig5", "x-x-big5", "big5-hkscs"]},
|
||||
{encoding: "euc-jp", labels: ["cseucpkdfmtjapanese", "euc-jp", "x-euc-jp"]},
|
||||
{encoding: "iso-2022-jp", labels: ["csiso2022jp", "iso-2022-jp"]},
|
||||
{encoding: "shift_jis", labels: ["csshiftjis", "ms_kanji", "shift-jis", "shift_jis", "sjis", "windows-31j", "x-sjis"]},
|
||||
|
@ -463,3 +463,78 @@ function testInvalid2022JP()
|
|||
});
|
||||
assert_equals(failureCount, 0, failureCount + " of " + inputs.length + " tests failed");
|
||||
}
|
||||
|
||||
function testDecoderForBig5()
|
||||
{
|
||||
const inputs = [
|
||||
[ 0x61, 0x62 ],
|
||||
[ 0x87, 0x40 ],
|
||||
[ 0xFE, 0xFE ],
|
||||
[ 0xFE, 0xFD ],
|
||||
[ 0x88, 0x62 ],
|
||||
[ 0x88, 0x64 ],
|
||||
[ 0x88, 0x66 ],
|
||||
[ 0x88, 0xA3 ],
|
||||
[ 0x88, 0xA5 ],
|
||||
[ 0x88, 0xA7 ],
|
||||
[ 0x99, 0xD4 ],
|
||||
[ 0x99, 0xD5 ],
|
||||
[ 0x99, 0xD6 ],
|
||||
[ 0x61, 0x87, 0x40, 0x62 ],
|
||||
[ 0x61, 0xFE, 0xFE, 0x62 ],
|
||||
[ 0x61, 0xFE, 0xFD, 0x62 ],
|
||||
[ 0x61, 0x88, 0x62, 0x62 ],
|
||||
[ 0x61, 0x88, 0x64, 0x62 ],
|
||||
[ 0x61, 0x88, 0x66, 0x62 ],
|
||||
[ 0x61, 0x88, 0xA3, 0x62 ],
|
||||
[ 0x61, 0x88, 0xA5, 0x62 ],
|
||||
[ 0x61, 0x88, 0xA7, 0x62 ],
|
||||
[ 0x61, 0x99, 0xD4, 0x62 ],
|
||||
[ 0x61, 0x99, 0xD5, 0x62 ],
|
||||
[ 0x61, 0x99, 0xD6, 0x62 ],
|
||||
[ 0x80, 0x61 ],
|
||||
[ 0xFF, 0x61 ],
|
||||
[ 0xFE, 0x39 ],
|
||||
[ 0x87, 0x66 ],
|
||||
[ 0x81, 0x40 ],
|
||||
[ 0x61, 0x81 ],
|
||||
];
|
||||
const expectations = [
|
||||
"\u0061\u0062",
|
||||
"\u43F0",
|
||||
"\u79D4",
|
||||
"\uD864\uDD0D",
|
||||
"\u00CA\u0304",
|
||||
"\u00CA\u030C",
|
||||
"\u00CA",
|
||||
"\u00EA\u0304",
|
||||
"\u00EA\u030C",
|
||||
"\u00EA",
|
||||
"\u8991",
|
||||
"\uD85E\uDD67",
|
||||
"\u8A29",
|
||||
"\u0061\u43F0\u0062",
|
||||
"\u0061\u79D4\u0062",
|
||||
"\u0061\uD864\uDD0D\u0062",
|
||||
"\u0061\u00CA\u0304\u0062",
|
||||
"\u0061\u00CA\u030C\u0062",
|
||||
"\u0061\u00CA\u0062",
|
||||
"\u0061\u00EA\u0304\u0062",
|
||||
"\u0061\u00EA\u030C\u0062",
|
||||
"\u0061\u00EA\u0062",
|
||||
"\u0061\u8991\u0062",
|
||||
"\u0061\uD85E\uDD67\u0062",
|
||||
"\u0061\u8A29\u0062",
|
||||
"\uFFFD\u0061",
|
||||
"\uFFFD\u0061",
|
||||
"\uFFFD\u0039",
|
||||
"\uFFFD\u0066",
|
||||
"\uFFFD\u0040",
|
||||
"\u0061\uFFFD",
|
||||
];
|
||||
|
||||
for (var i = 0; i < inputs.length; i++) {
|
||||
testCharset({encoding: "big5", input: inputs[i], expected: expectations[i],
|
||||
msg: "decoder test #" + i + " for big5."});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -796,23 +796,23 @@ nsresult
|
|||
ContentEventHandler::HandleQueryContentEvent(WidgetQueryContentEvent* aEvent)
|
||||
{
|
||||
switch (aEvent->mMessage) {
|
||||
case NS_QUERY_SELECTED_TEXT:
|
||||
case eQuerySelectedText:
|
||||
return OnQuerySelectedText(aEvent);
|
||||
case NS_QUERY_TEXT_CONTENT:
|
||||
case eQueryTextContent:
|
||||
return OnQueryTextContent(aEvent);
|
||||
case NS_QUERY_CARET_RECT:
|
||||
case eQueryCaretRect:
|
||||
return OnQueryCaretRect(aEvent);
|
||||
case NS_QUERY_TEXT_RECT:
|
||||
return OnQueryTextRect(aEvent);
|
||||
case NS_QUERY_EDITOR_RECT:
|
||||
case eQueryEditorRect:
|
||||
return OnQueryEditorRect(aEvent);
|
||||
case NS_QUERY_CONTENT_STATE:
|
||||
case eQueryContentState:
|
||||
return OnQueryContentState(aEvent);
|
||||
case NS_QUERY_SELECTION_AS_TRANSFERABLE:
|
||||
case eQuerySelectionAsTransferable:
|
||||
return OnQuerySelectionAsTransferable(aEvent);
|
||||
case NS_QUERY_CHARACTER_AT_POINT:
|
||||
case eQueryCharacterAtPoint:
|
||||
return OnQueryCharacterAtPoint(aEvent);
|
||||
case NS_QUERY_DOM_WIDGET_HITTEST:
|
||||
case eQueryDOMWidgetHittest:
|
||||
return OnQueryDOMWidgetHittest(aEvent);
|
||||
default:
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
@ -1267,7 +1267,7 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
|
|||
NS_ENSURE_TRUE(rootWidget, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
WidgetQueryContentEvent eventOnRoot(true, NS_QUERY_CHARACTER_AT_POINT,
|
||||
WidgetQueryContentEvent eventOnRoot(true, eQueryCharacterAtPoint,
|
||||
rootWidget);
|
||||
eventOnRoot.mUseNativeLineBreak = aEvent->mUseNativeLineBreak;
|
||||
eventOnRoot.refPoint = aEvent->refPoint;
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче