mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to b2g-inbound
This commit is contained in:
commit
7a601d0b6d
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1095234 - Bug 1091260 stopped packaging a devtools file with EXTRA_JS_MODULES while making it require pre-processing.
|
||||
Bug 1084498 - Android build tools dependency.
|
||||
|
@ -44,3 +44,4 @@ support-files =
|
||||
[browser_newtab_undo.js]
|
||||
[browser_newtab_unpin.js]
|
||||
[browser_newtab_update.js]
|
||||
skip-if = true # Bug 1008029
|
||||
|
@ -697,6 +697,38 @@ html, .fx-embedded, #main,
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.standalone .room-conversation-wrapper {
|
||||
height: calc(100% - 50px - 60px);
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.room-conversation-wrapper header {
|
||||
background: #000;
|
||||
height: 50px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.room-conversation-wrapper header h1 {
|
||||
font-size: 1.5em;
|
||||
color: #fff;
|
||||
line-height: 50px;
|
||||
text-indent: 50px;
|
||||
background-image: url("../img/firefox-logo.png");
|
||||
background-size: 30px;
|
||||
background-position: 10px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.room-conversation-wrapper footer {
|
||||
background: #000;
|
||||
height: 60px;
|
||||
margin-top: -12px;
|
||||
}
|
||||
|
||||
.room-conversation-wrapper footer a {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the hangup button for room conversations.
|
||||
*/
|
||||
@ -745,7 +777,7 @@ html, .fx-embedded, #main,
|
||||
|
||||
.standalone .room-inner-info-area {
|
||||
position: absolute;
|
||||
top: 35%;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
right: 25%;
|
||||
z-index: 1000;
|
||||
@ -767,6 +799,7 @@ html, .fx-embedded, #main,
|
||||
padding: .5em 3em .3em 3em;
|
||||
border-radius: 3px;
|
||||
font-weight: normal;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.standalone .room-conversation h2.room-name {
|
||||
@ -796,7 +829,7 @@ html, .fx-embedded, #main,
|
||||
|
||||
.standalone .room-conversation .conversation-toolbar {
|
||||
background: #000;
|
||||
border-top: none;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.standalone .room-conversation .conversation-toolbar .btn-hangup-entry {
|
||||
|
@ -10,6 +10,15 @@ loop.store.ActiveRoomStore = (function() {
|
||||
"use strict";
|
||||
|
||||
var sharedActions = loop.shared.actions;
|
||||
var FAILURE_REASONS = loop.shared.utils.FAILURE_REASONS;
|
||||
|
||||
// Error numbers taken from
|
||||
// https://github.com/mozilla-services/loop-server/blob/master/loop/errno.json
|
||||
var SERVER_CODES = loop.store.SERVER_CODES = {
|
||||
INVALID_TOKEN: 105,
|
||||
EXPIRED: 111,
|
||||
ROOM_FULL: 202
|
||||
};
|
||||
|
||||
var ROOM_STATES = loop.store.ROOM_STATES = {
|
||||
// The initial state of the room
|
||||
@ -84,7 +93,8 @@ loop.store.ActiveRoomStore = (function() {
|
||||
this._storeState = {
|
||||
roomState: ROOM_STATES.INIT,
|
||||
audioMuted: false,
|
||||
videoMuted: false
|
||||
videoMuted: false,
|
||||
failureReason: undefined
|
||||
};
|
||||
}
|
||||
|
||||
@ -112,13 +122,24 @@ loop.store.ActiveRoomStore = (function() {
|
||||
* @param {sharedActions.RoomFailure} actionData
|
||||
*/
|
||||
roomFailure: function(actionData) {
|
||||
function getReason(serverCode) {
|
||||
switch (serverCode) {
|
||||
case SERVER_CODES.INVALID_TOKEN:
|
||||
case SERVER_CODES.EXPIRED:
|
||||
return FAILURE_REASONS.EXPIRED_OR_INVALID;
|
||||
default:
|
||||
return FAILURE_REASONS.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
console.error("Error in state `" + this._storeState.roomState + "`:",
|
||||
actionData.error);
|
||||
|
||||
this.setStoreState({
|
||||
error: actionData.error,
|
||||
roomState: actionData.error.errno === 202 ? ROOM_STATES.FULL
|
||||
: ROOM_STATES.FAILED
|
||||
failureReason: getReason(actionData.error.errno),
|
||||
roomState: actionData.error.errno === SERVER_CODES.ROOM_FULL ?
|
||||
ROOM_STATES.FULL : ROOM_STATES.FAILED
|
||||
});
|
||||
},
|
||||
|
||||
@ -228,6 +249,11 @@ loop.store.ActiveRoomStore = (function() {
|
||||
* Handles the action to join to a room.
|
||||
*/
|
||||
joinRoom: function() {
|
||||
// Reset the failure reason if necessary.
|
||||
if (this.getStoreState().failureReason) {
|
||||
this.setStoreState({failureReason: undefined});
|
||||
}
|
||||
|
||||
this._mozLoop.rooms.join(this._storeState.roomToken,
|
||||
function(error, responseData) {
|
||||
if (error) {
|
||||
@ -275,11 +301,17 @@ loop.store.ActiveRoomStore = (function() {
|
||||
|
||||
/**
|
||||
* Handles disconnection of this local client from the sdk servers.
|
||||
*
|
||||
* @param {sharedActions.ConnectionFailure} actionData
|
||||
*/
|
||||
connectionFailure: function() {
|
||||
connectionFailure: function(actionData) {
|
||||
// Treat all reasons as something failed. In theory, clientDisconnected
|
||||
// could be a success case, but there's no way we should be intentionally
|
||||
// sending that and still have the window open.
|
||||
this.setStoreState({
|
||||
failureReason: actionData.reason
|
||||
});
|
||||
|
||||
this._leaveRoom(ROOM_STATES.FAILED);
|
||||
},
|
||||
|
||||
|
@ -8,6 +8,7 @@ var loop = loop || {};
|
||||
loop.OTSdkDriver = (function() {
|
||||
|
||||
var sharedActions = loop.shared.actions;
|
||||
var FAILURE_REASONS = loop.shared.utils.FAILURE_REASONS;
|
||||
|
||||
/**
|
||||
* This is a wrapper for the OT sdk. It is used to translate the SDK events into
|
||||
@ -47,8 +48,11 @@ loop.OTSdkDriver = (function() {
|
||||
// the initial connect of the session. This saves time when setting up
|
||||
// the media.
|
||||
this.publisher = this.sdk.initPublisher(this.getLocalElement(),
|
||||
this.publisherConfig,
|
||||
this._onPublishComplete.bind(this));
|
||||
this.publisherConfig);
|
||||
this.publisher.on("accessAllowed", this._onPublishComplete.bind(this));
|
||||
this.publisher.on("accessDenied", this._onPublishDenied.bind(this));
|
||||
this.publisher.on("accessDialogOpened",
|
||||
this._onAccessDialogOpened.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
@ -96,16 +100,12 @@ loop.OTSdkDriver = (function() {
|
||||
*/
|
||||
disconnectSession: function() {
|
||||
if (this.session) {
|
||||
this.session.off("streamCreated", this._onRemoteStreamCreated.bind(this));
|
||||
this.session.off("connectionDestroyed",
|
||||
this._onConnectionDestroyed.bind(this));
|
||||
this.session.off("sessionDisconnected",
|
||||
this._onSessionDisconnected.bind(this));
|
||||
|
||||
this.session.off("streamCreated connectionDestroyed sessionDisconnected");
|
||||
this.session.disconnect();
|
||||
delete this.session;
|
||||
}
|
||||
if (this.publisher) {
|
||||
this.publisher.off("accessAllowed accessDenied accessDialogOpened");
|
||||
this.publisher.destroy();
|
||||
delete this.publisher;
|
||||
}
|
||||
@ -126,7 +126,7 @@ loop.OTSdkDriver = (function() {
|
||||
if (error) {
|
||||
console.error("Failed to complete connection", error);
|
||||
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
|
||||
reason: "couldNotConnect"
|
||||
reason: FAILURE_REASONS.COULD_NOT_CONNECT
|
||||
}));
|
||||
return;
|
||||
}
|
||||
@ -159,7 +159,7 @@ loop.OTSdkDriver = (function() {
|
||||
// We only need to worry about the network disconnected reason here.
|
||||
if (event.reason === "networkDisconnected") {
|
||||
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
|
||||
reason: "networkDisconnected"
|
||||
reason: FAILURE_REASONS.NETWORK_DISCONNECTED
|
||||
}));
|
||||
}
|
||||
},
|
||||
@ -188,24 +188,42 @@ loop.OTSdkDriver = (function() {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called from the sdk when the media access dialog is opened.
|
||||
* Prevents the default action, to prevent the SDK's "allow access"
|
||||
* dialog from being shown.
|
||||
*
|
||||
* @param {OT.Event} event
|
||||
*/
|
||||
_onAccessDialogOpened: function(event) {
|
||||
event.preventDefault();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles the publishing being complete.
|
||||
*
|
||||
* @param {Error} error An OT error object, null if there was no error.
|
||||
* @param {OT.Event} event
|
||||
*/
|
||||
_onPublishComplete: function(error) {
|
||||
if (error) {
|
||||
console.error("Failed to initialize publisher", error);
|
||||
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
|
||||
reason: "noMedia"
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
_onPublishComplete: function(event) {
|
||||
event.preventDefault();
|
||||
this._publisherReady = true;
|
||||
this._maybePublishLocalStream();
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles publishing of media being denied.
|
||||
*
|
||||
* @param {OT.Event} event
|
||||
*/
|
||||
_onPublishDenied: function(event) {
|
||||
// This prevents the SDK's "access denied" dialog showing.
|
||||
event.preventDefault();
|
||||
|
||||
this.dispatcher.dispatch(new sharedActions.ConnectionFailure({
|
||||
reason: FAILURE_REASONS.MEDIA_DENIED
|
||||
}));
|
||||
},
|
||||
|
||||
/**
|
||||
* Publishes the local stream if the session is connected
|
||||
* and the publisher is ready.
|
||||
|
@ -17,6 +17,14 @@ loop.shared.utils = (function(mozL10n) {
|
||||
AUDIO_ONLY: "audio"
|
||||
};
|
||||
|
||||
var FAILURE_REASONS = {
|
||||
MEDIA_DENIED: "reason-media-denied",
|
||||
COULD_NOT_CONNECT: "reason-could-not-connect",
|
||||
NETWORK_DISCONNECTED: "reason-network-disconnected",
|
||||
EXPIRED_OR_INVALID: "reason-expired-or-invalid",
|
||||
UNKNOWN: "reason-unknown"
|
||||
};
|
||||
|
||||
/**
|
||||
* Format a given date into an l10n-friendly string.
|
||||
*
|
||||
@ -110,6 +118,7 @@ loop.shared.utils = (function(mozL10n) {
|
||||
|
||||
return {
|
||||
CALL_TYPES: CALL_TYPES,
|
||||
FAILURE_REASONS: FAILURE_REASONS,
|
||||
Helper: Helper,
|
||||
composeCallUrlEmail: composeCallUrlEmail,
|
||||
formatDate: formatDate,
|
||||
|
@ -18,6 +18,13 @@ body,
|
||||
font-family: Open Sans,sans-serif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: the is-standalone-room class is dynamically set by the StandaloneRoomView.
|
||||
*/
|
||||
.standalone.is-standalone-room {
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.standalone-header {
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
|
@ -11,8 +11,10 @@ var loop = loop || {};
|
||||
loop.standaloneRoomViews = (function(mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var FAILURE_REASONS = loop.shared.utils.FAILURE_REASONS;
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedMixins = loop.shared.mixins;
|
||||
var sharedViews = loop.shared.views;
|
||||
|
||||
var StandaloneRoomInfoArea = React.createClass({displayName: 'StandaloneRoomInfoArea',
|
||||
@ -39,6 +41,20 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return String An appropriate string according to the failureReason.
|
||||
*/
|
||||
_getFailureString: function() {
|
||||
switch(this.props.failureReason) {
|
||||
case FAILURE_REASONS.MEDIA_DENIED:
|
||||
return mozL10n.get("rooms_media_denied_message");
|
||||
case FAILURE_REASONS.EXPIRED_OR_INVALID:
|
||||
return mozL10n.get("rooms_unavailable_notification_message");
|
||||
default:
|
||||
return mozL10n.get("status_error");
|
||||
};
|
||||
},
|
||||
|
||||
_renderContent: function() {
|
||||
switch(this.props.roomState) {
|
||||
case ROOM_STATES.INIT:
|
||||
@ -67,6 +83,12 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
React.DOM.p(null, this._renderCallToActionLink())
|
||||
)
|
||||
);
|
||||
case ROOM_STATES.FAILED:
|
||||
return (
|
||||
React.DOM.p({className: "failed-room-message"},
|
||||
this._getFailureString()
|
||||
)
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -81,6 +103,43 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
}
|
||||
});
|
||||
|
||||
var StandaloneRoomHeader = React.createClass({displayName: 'StandaloneRoomHeader',
|
||||
render: function() {
|
||||
return (
|
||||
React.DOM.header(null,
|
||||
React.DOM.h1(null, mozL10n.get("clientShortname2"))
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var StandaloneRoomFooter = React.createClass({displayName: 'StandaloneRoomFooter',
|
||||
_getContent: function() {
|
||||
return mozL10n.get("legal_text_and_links", {
|
||||
"clientShortname": mozL10n.get("clientShortname2"),
|
||||
"terms_of_use_url": React.renderComponentToStaticMarkup(
|
||||
React.DOM.a({href: loop.config.legalWebsiteUrl, target: "_blank"},
|
||||
mozL10n.get("terms_of_use_link_text")
|
||||
)
|
||||
),
|
||||
"privacy_notice_url": React.renderComponentToStaticMarkup(
|
||||
React.DOM.a({href: loop.config.privacyWebsiteUrl, target: "_blank"},
|
||||
mozL10n.get("privacy_notice_link_text")
|
||||
)
|
||||
),
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
React.DOM.footer(null,
|
||||
React.DOM.p({dangerouslySetInnerHTML: {__html: this._getContent()}}),
|
||||
React.DOM.div({className: "footer-logo"})
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var StandaloneRoomView = React.createClass({displayName: 'StandaloneRoomView',
|
||||
mixins: [Backbone.Events],
|
||||
|
||||
@ -144,6 +203,11 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
// Adding a class to the document body element from here to ease styling it.
|
||||
document.body.classList.add("is-standalone-room");
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this.stopListening(this.props.activeRoomStore);
|
||||
},
|
||||
@ -207,7 +271,9 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
|
||||
return (
|
||||
React.DOM.div({className: "room-conversation-wrapper"},
|
||||
StandaloneRoomHeader(null),
|
||||
StandaloneRoomInfoArea({roomState: this.state.roomState,
|
||||
failureReason: this.state.failureReason,
|
||||
joinRoom: this.joinRoom,
|
||||
helper: this.props.helper}),
|
||||
React.DOM.div({className: "video-layout-wrapper"},
|
||||
@ -229,7 +295,8 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
hangupButtonLabel: mozL10n.get("rooms_leave_button_label"),
|
||||
enableHangup: this._roomIsActive()})
|
||||
)
|
||||
)
|
||||
),
|
||||
StandaloneRoomFooter(null)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -11,8 +11,10 @@ var loop = loop || {};
|
||||
loop.standaloneRoomViews = (function(mozL10n) {
|
||||
"use strict";
|
||||
|
||||
var FAILURE_REASONS = loop.shared.utils.FAILURE_REASONS;
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var sharedActions = loop.shared.actions;
|
||||
var sharedMixins = loop.shared.mixins;
|
||||
var sharedViews = loop.shared.views;
|
||||
|
||||
var StandaloneRoomInfoArea = React.createClass({
|
||||
@ -39,6 +41,20 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* @return String An appropriate string according to the failureReason.
|
||||
*/
|
||||
_getFailureString: function() {
|
||||
switch(this.props.failureReason) {
|
||||
case FAILURE_REASONS.MEDIA_DENIED:
|
||||
return mozL10n.get("rooms_media_denied_message");
|
||||
case FAILURE_REASONS.EXPIRED_OR_INVALID:
|
||||
return mozL10n.get("rooms_unavailable_notification_message");
|
||||
default:
|
||||
return mozL10n.get("status_error");
|
||||
};
|
||||
},
|
||||
|
||||
_renderContent: function() {
|
||||
switch(this.props.roomState) {
|
||||
case ROOM_STATES.INIT:
|
||||
@ -67,6 +83,12 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
<p>{this._renderCallToActionLink()}</p>
|
||||
</div>
|
||||
);
|
||||
case ROOM_STATES.FAILED:
|
||||
return (
|
||||
<p className="failed-room-message">
|
||||
{this._getFailureString()}
|
||||
</p>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -81,6 +103,43 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
}
|
||||
});
|
||||
|
||||
var StandaloneRoomHeader = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<header>
|
||||
<h1>{mozL10n.get("clientShortname2")}</h1>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var StandaloneRoomFooter = React.createClass({
|
||||
_getContent: function() {
|
||||
return mozL10n.get("legal_text_and_links", {
|
||||
"clientShortname": mozL10n.get("clientShortname2"),
|
||||
"terms_of_use_url": React.renderComponentToStaticMarkup(
|
||||
<a href={loop.config.legalWebsiteUrl} target="_blank">
|
||||
{mozL10n.get("terms_of_use_link_text")}
|
||||
</a>
|
||||
),
|
||||
"privacy_notice_url": React.renderComponentToStaticMarkup(
|
||||
<a href={loop.config.privacyWebsiteUrl} target="_blank">
|
||||
{mozL10n.get("privacy_notice_link_text")}
|
||||
</a>
|
||||
),
|
||||
});
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<footer>
|
||||
<p dangerouslySetInnerHTML={{__html: this._getContent()}}></p>
|
||||
<div className="footer-logo" />
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var StandaloneRoomView = React.createClass({
|
||||
mixins: [Backbone.Events],
|
||||
|
||||
@ -144,6 +203,11 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
// Adding a class to the document body element from here to ease styling it.
|
||||
document.body.classList.add("is-standalone-room");
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this.stopListening(this.props.activeRoomStore);
|
||||
},
|
||||
@ -207,7 +271,9 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
|
||||
return (
|
||||
<div className="room-conversation-wrapper">
|
||||
<StandaloneRoomHeader />
|
||||
<StandaloneRoomInfoArea roomState={this.state.roomState}
|
||||
failureReason={this.state.failureReason}
|
||||
joinRoom={this.joinRoom}
|
||||
helper={this.props.helper} />
|
||||
<div className="video-layout-wrapper">
|
||||
@ -230,6 +296,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
enableHangup={this._roomIsActive()} />
|
||||
</div>
|
||||
</div>
|
||||
<StandaloneRoomFooter />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -116,6 +116,8 @@ rooms_room_full_call_to_action_label=Learn more about {{clientShortname}} »
|
||||
rooms_room_joined_label=Someone has joined the conversation!
|
||||
rooms_room_join_label=Join the conversation
|
||||
rooms_display_name_guest=Guest
|
||||
rooms_unavailable_notification_message=Sorry, you cannot join this conversation. The link may be expired or invalid.
|
||||
rooms_media_denied_message=We could not get access to your microphone or camera. Please reload the page to try again.
|
||||
|
||||
## LOCALIZATION_NOTE(standalone_title_with_status): {{clientShortname}} will be
|
||||
## replaced by the brand name and {{currentStatus}} will be replaced
|
||||
|
@ -65,6 +65,7 @@ describe("loop.roomViews", function () {
|
||||
roomState: ROOM_STATES.INIT,
|
||||
audioMuted: false,
|
||||
videoMuted: false,
|
||||
failureReason: undefined,
|
||||
foo: "bar"
|
||||
});
|
||||
});
|
||||
|
@ -6,7 +6,9 @@ var sharedActions = loop.shared.actions;
|
||||
describe("loop.store.ActiveRoomStore", function () {
|
||||
"use strict";
|
||||
|
||||
var SERVER_CODES = loop.store.SERVER_CODES;
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var FAILURE_REASONS = loop.shared.utils.FAILURE_REASONS;
|
||||
var sandbox, dispatcher, store, fakeMozLoop, fakeSdkDriver;
|
||||
var fakeMultiplexGum;
|
||||
|
||||
@ -91,8 +93,8 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
sinon.match(ROOM_STATES.READY), fakeError);
|
||||
});
|
||||
|
||||
it("should set the state to `FULL` on server errno 202", function() {
|
||||
fakeError.errno = 202;
|
||||
it("should set the state to `FULL` on server error room full", function() {
|
||||
fakeError.errno = SERVER_CODES.ROOM_FULL;
|
||||
|
||||
store.roomFailure({error: fakeError});
|
||||
|
||||
@ -103,7 +105,28 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
store.roomFailure({error: fakeError});
|
||||
|
||||
expect(store._storeState.roomState).eql(ROOM_STATES.FAILED);
|
||||
expect(store._storeState.failureReason).eql(FAILURE_REASONS.UNKNOWN);
|
||||
});
|
||||
|
||||
it("should set the failureReason to EXPIRED_OR_INVALID on server error: " +
|
||||
"invalid token", function() {
|
||||
fakeError.errno = SERVER_CODES.INVALID_TOKEN;
|
||||
|
||||
store.roomFailure({error: fakeError});
|
||||
|
||||
expect(store._storeState.roomState).eql(ROOM_STATES.FAILED);
|
||||
expect(store._storeState.failureReason).eql(FAILURE_REASONS.EXPIRED_OR_INVALID);
|
||||
});
|
||||
|
||||
it("should set the failureReason to EXPIRED_OR_INVALID on server error: " +
|
||||
"expired", function() {
|
||||
fakeError.errno = SERVER_CODES.EXPIRED;
|
||||
|
||||
store.roomFailure({error: fakeError});
|
||||
|
||||
expect(store._storeState.roomState).eql(ROOM_STATES.FAILED);
|
||||
expect(store._storeState.failureReason).eql(FAILURE_REASONS.EXPIRED_OR_INVALID);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#setupWindowData", function() {
|
||||
@ -244,6 +267,14 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
store.setStoreState({roomToken: "tokenFake"});
|
||||
});
|
||||
|
||||
it("should reset failureReason", function() {
|
||||
store.setStoreState({failureReason: "Test"});
|
||||
|
||||
store.joinRoom();
|
||||
|
||||
expect(store.getStoreState().failureReason).eql(undefined);
|
||||
});
|
||||
|
||||
it("should call rooms.join on mozLoop", function() {
|
||||
store.joinRoom();
|
||||
|
||||
@ -380,22 +411,34 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
});
|
||||
|
||||
describe("#connectionFailure", function() {
|
||||
var connectionFailureAction;
|
||||
|
||||
beforeEach(function() {
|
||||
store.setStoreState({
|
||||
roomState: ROOM_STATES.JOINED,
|
||||
roomToken: "fakeToken",
|
||||
sessionToken: "1627384950"
|
||||
});
|
||||
|
||||
connectionFailureAction = new sharedActions.ConnectionFailure({
|
||||
reason: "FAIL"
|
||||
});
|
||||
});
|
||||
|
||||
it("should store the failure reason", function() {
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
|
||||
expect(store.getStoreState().failureReason).eql("FAIL");
|
||||
});
|
||||
|
||||
it("should reset the multiplexGum", function() {
|
||||
store.leaveRoom();
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
|
||||
sinon.assert.calledOnce(fakeMultiplexGum.reset);
|
||||
});
|
||||
|
||||
it("should disconnect from the servers via the sdk", function() {
|
||||
store.connectionFailure();
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
|
||||
sinon.assert.calledOnce(fakeSdkDriver.disconnectSession);
|
||||
});
|
||||
@ -404,13 +447,13 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
sandbox.stub(window, "clearTimeout");
|
||||
store._timeout = {};
|
||||
|
||||
store.connectionFailure();
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
|
||||
sinon.assert.calledOnce(clearTimeout);
|
||||
});
|
||||
|
||||
it("should call mozLoop.rooms.leave", function() {
|
||||
store.connectionFailure();
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
|
||||
sinon.assert.calledOnce(fakeMozLoop.rooms.leave);
|
||||
sinon.assert.calledWithExactly(fakeMozLoop.rooms.leave,
|
||||
@ -418,7 +461,7 @@ describe("loop.store.ActiveRoomStore", function () {
|
||||
});
|
||||
|
||||
it("should set the state to `FAILED`", function() {
|
||||
store.connectionFailure();
|
||||
store.connectionFailure(connectionFailureAction);
|
||||
|
||||
expect(store.getStoreState().roomState).eql(ROOM_STATES.FAILED);
|
||||
});
|
||||
|
@ -7,16 +7,19 @@ describe("loop.OTSdkDriver", function () {
|
||||
"use strict";
|
||||
|
||||
var sharedActions = loop.shared.actions;
|
||||
|
||||
var FAILURE_REASONS = loop.shared.utils.FAILURE_REASONS;
|
||||
var sandbox;
|
||||
var dispatcher, driver, publisher, sdk, session, sessionData;
|
||||
var fakeLocalElement, fakeRemoteElement, publisherConfig;
|
||||
var fakeLocalElement, fakeRemoteElement, publisherConfig, fakeEvent;
|
||||
|
||||
beforeEach(function() {
|
||||
sandbox = sinon.sandbox.create();
|
||||
|
||||
fakeLocalElement = {fake: 1};
|
||||
fakeRemoteElement = {fake: 2};
|
||||
fakeEvent = {
|
||||
preventDefault: sinon.stub()
|
||||
};
|
||||
publisherConfig = {
|
||||
fake: "config"
|
||||
};
|
||||
@ -34,14 +37,14 @@ describe("loop.OTSdkDriver", function () {
|
||||
subscribe: sinon.stub()
|
||||
}, Backbone.Events);
|
||||
|
||||
publisher = {
|
||||
publisher = _.extend({
|
||||
destroy: sinon.stub(),
|
||||
publishAudio: sinon.stub(),
|
||||
publishVideo: sinon.stub()
|
||||
};
|
||||
}, Backbone.Events);
|
||||
|
||||
sdk = {
|
||||
initPublisher: sinon.stub(),
|
||||
initPublisher: sinon.stub().returns(publisher),
|
||||
initSession: sinon.stub().returns(session)
|
||||
};
|
||||
|
||||
@ -80,51 +83,6 @@ describe("loop.OTSdkDriver", function () {
|
||||
sinon.assert.calledOnce(sdk.initPublisher);
|
||||
sinon.assert.calledWith(sdk.initPublisher, fakeLocalElement, publisherConfig);
|
||||
});
|
||||
|
||||
describe("On Publisher Complete", function() {
|
||||
it("should publish the stream if the connection is ready", function() {
|
||||
sdk.initPublisher.callsArgWith(2, null);
|
||||
|
||||
driver.session = session;
|
||||
driver._sessionConnected = true;
|
||||
|
||||
dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
||||
getLocalElementFunc: function() {return fakeLocalElement;},
|
||||
getRemoteElementFunc: function() {return fakeRemoteElement;},
|
||||
publisherConfig: publisherConfig
|
||||
}));
|
||||
|
||||
sinon.assert.calledOnce(session.publish);
|
||||
});
|
||||
|
||||
it("should dispatch connectionFailure if connecting failed", function() {
|
||||
sdk.initPublisher.callsArgWith(2, new Error("Failure"));
|
||||
|
||||
// Special stub, as we want to use the dispatcher, but also know that
|
||||
// we've been called correctly for the second dispatch.
|
||||
var dispatchStub = (function() {
|
||||
var originalDispatch = dispatcher.dispatch.bind(dispatcher);
|
||||
return sandbox.stub(dispatcher, "dispatch", function(action) {
|
||||
originalDispatch(action);
|
||||
});
|
||||
}());
|
||||
|
||||
driver.session = session;
|
||||
driver._sessionConnected = true;
|
||||
|
||||
dispatcher.dispatch(new sharedActions.SetupStreamElements({
|
||||
getLocalElementFunc: function() {return fakeLocalElement;},
|
||||
getRemoteElementFunc: function() {return fakeRemoteElement;},
|
||||
publisherConfig: publisherConfig
|
||||
}));
|
||||
|
||||
sinon.assert.called(dispatcher.dispatch);
|
||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||
sinon.match.hasOwn("name", "connectionFailure"));
|
||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||
sinon.match.hasOwn("reason", "noMedia"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("#setMute", function() {
|
||||
@ -194,7 +152,7 @@ describe("loop.OTSdkDriver", function () {
|
||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||
sinon.match.hasOwn("name", "connectionFailure"));
|
||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||
sinon.match.hasOwn("reason", "couldNotConnect"));
|
||||
sinon.match.hasOwn("reason", FAILURE_REASONS.COULD_NOT_CONNECT));
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -269,7 +227,7 @@ describe("loop.OTSdkDriver", function () {
|
||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||
sinon.match.hasOwn("name", "connectionFailure"));
|
||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||
sinon.match.hasOwn("reason", "networkDisconnected"));
|
||||
sinon.match.hasOwn("reason", FAILURE_REASONS.NETWORK_DISCONNECTED));
|
||||
});
|
||||
});
|
||||
|
||||
@ -328,5 +286,41 @@ describe("loop.OTSdkDriver", function () {
|
||||
sinon.assert.notCalled(dispatcher.dispatch);
|
||||
});
|
||||
});
|
||||
|
||||
describe("accessAllowed", function() {
|
||||
it("should publish the stream if the connection is ready", function() {
|
||||
driver._sessionConnected = true;
|
||||
|
||||
publisher.trigger("accessAllowed", fakeEvent);
|
||||
|
||||
sinon.assert.calledOnce(session.publish);
|
||||
});
|
||||
});
|
||||
|
||||
describe("accessDenied", function() {
|
||||
it("should prevent the default event behavior", function() {
|
||||
publisher.trigger("accessDenied", fakeEvent);
|
||||
|
||||
sinon.assert.calledOnce(fakeEvent.preventDefault);
|
||||
});
|
||||
|
||||
it("should dispatch connectionFailure", function() {
|
||||
publisher.trigger("accessDenied", fakeEvent);
|
||||
|
||||
sinon.assert.called(dispatcher.dispatch);
|
||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||
sinon.match.hasOwn("name", "connectionFailure"));
|
||||
sinon.assert.calledWithMatch(dispatcher.dispatch,
|
||||
sinon.match.hasOwn("reason", FAILURE_REASONS.MEDIA_DENIED));
|
||||
});
|
||||
});
|
||||
|
||||
describe("accessDialogOpened", function() {
|
||||
it("should prevent the default event behavior", function() {
|
||||
publisher.trigger("accessDialogOpened", fakeEvent);
|
||||
|
||||
sinon.assert.calledOnce(fakeEvent.preventDefault);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -139,6 +139,16 @@ describe("loop.standaloneRoomViews", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Failed room message", function() {
|
||||
it("should display a failed room message on FAILED",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.FAILED});
|
||||
|
||||
expect(view.getDOMNode().querySelector(".failed-room-message"))
|
||||
.not.eql(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Join button", function() {
|
||||
function getJoinButton(view) {
|
||||
return view.getDOMNode().querySelector(".btn-join");
|
||||
|
@ -608,6 +608,16 @@
|
||||
roomState: ROOM_STATES.FULL,
|
||||
helper: {isFirefox: returnFalse}})
|
||||
)
|
||||
),
|
||||
|
||||
Example({summary: "Standalone room conversation (failed)"},
|
||||
React.DOM.div({className: "standalone"},
|
||||
StandaloneRoomView({
|
||||
dispatcher: dispatcher,
|
||||
activeRoomStore: activeRoomStore,
|
||||
roomState: ROOM_STATES.FAILED,
|
||||
helper: {isFirefox: returnFalse}})
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
|
@ -609,6 +609,16 @@
|
||||
helper={{isFirefox: returnFalse}} />
|
||||
</div>
|
||||
</Example>
|
||||
|
||||
<Example summary="Standalone room conversation (failed)">
|
||||
<div className="standalone">
|
||||
<StandaloneRoomView
|
||||
dispatcher={dispatcher}
|
||||
activeRoomStore={activeRoomStore}
|
||||
roomState={ROOM_STATES.FAILED}
|
||||
helper={{isFirefox: returnFalse}} />
|
||||
</div>
|
||||
</Example>
|
||||
</Section>
|
||||
|
||||
<Section name="SVG icons preview">
|
||||
|
@ -9,11 +9,6 @@ function test() {
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
// Request a longer timeout because the test takes quite a while
|
||||
// to complete on slow Windows debug machines and we would otherwise
|
||||
// see a lot of (not so) intermittent test failures.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, true);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(PREF_RESTORE_ON_DEMAND);
|
||||
@ -29,112 +24,31 @@ function runTests() {
|
||||
{ entries: [{ url: "http://example.org/#7" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#8" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#9" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#10" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#11" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#12" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#13" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#14" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#15" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#16" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#17" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.org/#18" }], extData: { "uniq": r() } }
|
||||
], selected: 1 }] };
|
||||
|
||||
let loadCount = 0;
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
loadCount++;
|
||||
is(aBrowser.currentURI.spec, state.windows[0].tabs[loadCount - 1].entries[0].url,
|
||||
gBrowser.tabContainer.addEventListener("SSTabRestored", function onRestored(event) {
|
||||
let tab = event.target;
|
||||
let browser = tab.linkedBrowser;
|
||||
let tabData = state.windows[0].tabs[loadCount++];
|
||||
|
||||
// double check that this tab was the right one
|
||||
is(browser.currentURI.spec, tabData.entries[0].url,
|
||||
"load " + loadCount + " - browser loaded correct url");
|
||||
is(ss.getTabValue(tab, "uniq"), tabData.extData.uniq,
|
||||
"load " + loadCount + " - correct tab was restored");
|
||||
|
||||
if (loadCount <= state.windows[0].tabs.length) {
|
||||
// double check that this tab was the right one
|
||||
let expectedData = state.windows[0].tabs[loadCount - 1].extData.uniq;
|
||||
let tab;
|
||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||
if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
|
||||
tab = window.gBrowser.tabs[i];
|
||||
}
|
||||
is(ss.getTabValue(tab, "uniq"), expectedData,
|
||||
"load " + loadCount + " - correct tab was restored");
|
||||
if (loadCount == state.windows[0].tabs.length) {
|
||||
gBrowser.tabContainer.removeEventListener("SSTabRestored", onRestored);
|
||||
|
||||
if (loadCount == state.windows[0].tabs.length) {
|
||||
gProgressListener.unsetCallback();
|
||||
executeSoon(function () {
|
||||
reloadAllTabs(state, function () {
|
||||
waitForBrowserState(TestRunner.backupState, testCascade);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// reload the next tab
|
||||
window.gBrowser.reloadTab(window.gBrowser.tabs[loadCount]);
|
||||
}
|
||||
executeSoon(function () {
|
||||
waitForBrowserState(TestRunner.backupState, finish);
|
||||
});
|
||||
} else {
|
||||
// reload the next tab
|
||||
gBrowser.browsers[loadCount].reload();
|
||||
}
|
||||
});
|
||||
|
||||
yield ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
function testCascade() {
|
||||
Services.prefs.setBoolPref(PREF_RESTORE_ON_DEMAND, false);
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.com/#1" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com/#2" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com/#3" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com/#4" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com/#5" }], extData: { "uniq": r() } },
|
||||
{ entries: [{ url: "http://example.com/#6" }], extData: { "uniq": r() } }
|
||||
] }] };
|
||||
|
||||
let loadCount = 0;
|
||||
gProgressListener.setCallback(function (aBrowser, aNeedRestore, aRestoring, aRestored) {
|
||||
if (++loadCount < state.windows[0].tabs.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
gProgressListener.unsetCallback();
|
||||
executeSoon(function () {
|
||||
reloadAllTabs(state, next);
|
||||
});
|
||||
});
|
||||
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
function reloadAllTabs(aState, aCallback) {
|
||||
// Simulate a left mouse button click with no modifiers, which is what
|
||||
// Command-R, or clicking reload does.
|
||||
let fakeEvent = {
|
||||
button: 0,
|
||||
metaKey: false,
|
||||
altKey: false,
|
||||
ctrlKey: false,
|
||||
shiftKey: false
|
||||
};
|
||||
|
||||
let loadCount = 0;
|
||||
gWebProgressListener.setCallback(function (aBrowser) {
|
||||
if (++loadCount <= aState.windows[0].tabs.length) {
|
||||
// double check that this tab was the right one
|
||||
let expectedData = aState.windows[0].tabs[loadCount - 1].extData.uniq;
|
||||
let tab;
|
||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||
if (!tab && window.gBrowser.tabs[i].linkedBrowser == aBrowser)
|
||||
tab = window.gBrowser.tabs[i];
|
||||
}
|
||||
is(ss.getTabValue(tab, "uniq"), expectedData,
|
||||
"load " + loadCount + " - correct tab was reloaded");
|
||||
|
||||
if (loadCount == aState.windows[0].tabs.length) {
|
||||
gWebProgressListener.unsetCallback();
|
||||
executeSoon(aCallback);
|
||||
} else {
|
||||
// reload the next tab
|
||||
window.gBrowser.selectTabAtIndex(loadCount);
|
||||
BrowserReloadOrDuplicate(fakeEvent);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
BrowserReloadOrDuplicate(fakeEvent);
|
||||
}
|
||||
|
@ -152,33 +152,33 @@ skip-if = e10s || os == "mac" || e10s # Bug 895426
|
||||
[browser_dbg_break-on-dom-event-02.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_breakpoints-actual-location.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-actual-location2.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s # Bug 1093535
|
||||
[browser_dbg_breakpoints-button-01.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-button-02.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-contextmenu-add.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-contextmenu.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-disabled-reload.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s # Bug 1093535
|
||||
[browser_dbg_breakpoints-editor.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-highlight.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-new-script.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-other-tabs.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-pane.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-reload.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_chrome-create.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_chrome-debugging.js]
|
||||
@ -458,21 +458,21 @@ skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-accessibility.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-data.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-cancel.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-click.js]
|
||||
skip-if = e10s || (os == 'mac' || os == 'win') && (debug == false) # Bug 986166
|
||||
[browser_dbg_variables-view-edit-getset-01.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-getset-02.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-value.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-watch.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-02.js]
|
||||
@ -484,27 +484,27 @@ skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-pref.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-searchbox.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frame-parameters-01.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frame-parameters-02.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frame-parameters-03.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frame-with.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frozen-sealed-nonext.js]
|
||||
skip-if = e10s || buildapp == 'mulet'
|
||||
skip-if = e10s && debug || buildapp == 'mulet'
|
||||
[browser_dbg_variables-view-hide-non-enums.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-large-array-buffer.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-override-01.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-override-02.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-02.js]
|
||||
@ -532,20 +532,20 @@ skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-13.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-14.js]
|
||||
skip-if = e10s && debug
|
||||
skip-if = (e10s && debug) || (e10s && os == 'linux') # Linux e10s - bug 1029545
|
||||
[browser_dbg_variables-view-popup-15.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-16.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-reexpand-01.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-reexpand-02.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-reexpand-03.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-webidl.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_watch-expressions-01.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_watch-expressions-02.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
|
@ -9,12 +9,11 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
@ -24,7 +23,7 @@ function test() {
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest);
|
||||
gDebuggee.firstCall();
|
||||
callInTab(gTab, "firstCall");
|
||||
});
|
||||
|
||||
function performTest() {
|
||||
|
@ -10,12 +10,11 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_breakpoint-move.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
@ -25,7 +24,7 @@ function test() {
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 1).then(performTest);
|
||||
gDebuggee.ermahgerd();
|
||||
callInTab(gTab, "ermahgerd");
|
||||
});
|
||||
|
||||
function performTest() {
|
||||
@ -62,7 +61,7 @@ function test() {
|
||||
yield resumeAndTestBreakpoint(20);
|
||||
yield doResume(gPanel);
|
||||
|
||||
executeSoon(() => gDebuggee.ermahgerd());
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
|
||||
|
||||
yield resumeAndTestBreakpoint(20);
|
||||
|
@ -15,7 +15,7 @@ function test() {
|
||||
|
||||
let gPanel, gDebugger, gThreadClient, gEvents;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gThreadClient = gDebugger.gThreadClient;
|
||||
|
@ -8,12 +8,11 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gSources, gBreakpoints;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
@ -9,12 +9,11 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gSources, gBreakpoints;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
@ -8,12 +8,11 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor, gSources, gContextMenu, gBreakpoints, gBreakpointsAdded;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
@ -29,7 +28,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
gDebuggee.firstCall();
|
||||
callInTab(gTab, "firstCall");
|
||||
});
|
||||
|
||||
function performTest() {
|
||||
|
@ -11,12 +11,11 @@ function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gSources, gBreakpoints;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
@ -95,13 +94,7 @@ function test() {
|
||||
ok(isCaretPos(gPanel, 9),
|
||||
"The editor location is correct before pausing.");
|
||||
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
});
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
@ -8,7 +8,8 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
let gTab = aTab;
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gEvents = gDebugger.EVENTS;
|
||||
let gEditor = gDebugger.DebuggerView.editor;
|
||||
@ -66,7 +67,7 @@ function test() {
|
||||
yield ensureSourceIs(aPanel, "-01.js");
|
||||
yield verifyView({ disabled: false, visible: true });
|
||||
|
||||
executeSoon(() => aDebuggee.firstCall());
|
||||
callInTab(gTab, "firstCall");
|
||||
yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES);
|
||||
yield ensureSourceIs(aPanel, "-01.js");
|
||||
yield ensureCaretAt(aPanel, 5);
|
||||
@ -83,7 +84,7 @@ function test() {
|
||||
yield ensureSourceIs(aPanel, "-02.js", true);
|
||||
yield verifyView({ disabled: false, visible: false });
|
||||
|
||||
executeSoon(() => aDebuggee.firstCall());
|
||||
callInTab(gTab, "firstCall");
|
||||
yield waitForSourceAndCaretAndScopes(aPanel, "-01.js", 1);
|
||||
yield verifyView({ disabled: false, visible: true });
|
||||
|
||||
@ -98,7 +99,7 @@ function test() {
|
||||
yield ensureSourceIs(aPanel, "-02.js", true);
|
||||
yield verifyView({ disabled: true, visible: false });
|
||||
|
||||
executeSoon(() => aDebuggee.firstCall());
|
||||
callInTab(gTab, "firstCall");
|
||||
yield waitForDebuggerEvents(aPanel, gEvents.FETCHED_SCOPES);
|
||||
yield ensureSourceIs(aPanel, "-02.js");
|
||||
yield ensureCaretAt(aPanel, 1);
|
||||
|
@ -9,12 +9,11 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
@ -24,7 +23,7 @@ function test() {
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest);
|
||||
gDebuggee.firstCall();
|
||||
callInTab(gTab, "firstCall");
|
||||
});
|
||||
|
||||
function performTest() {
|
||||
|
@ -8,12 +8,11 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor, gSources;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
|
@ -8,12 +8,11 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-script.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
@ -33,7 +32,7 @@ function addBreakpoint() {
|
||||
});
|
||||
});
|
||||
|
||||
gDebuggee.runDebuggerStatement();
|
||||
callInTab(gTab, "runDebuggerStatement");
|
||||
}
|
||||
|
||||
function testResume() {
|
||||
@ -54,9 +53,7 @@ function testResume() {
|
||||
});
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -84,7 +81,6 @@ function testBreakpointHit() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
@ -9,8 +9,8 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_breakpoints-other-tabs.html";
|
||||
|
||||
let test = Task.async(function* () {
|
||||
const [tab1, debuggee1, panel1] = yield initDebugger(TAB_URL);
|
||||
const [tab2, debuggee2, panel2] = yield initDebugger(TAB_URL);
|
||||
const [tab1,, panel1] = yield initDebugger(TAB_URL);
|
||||
const [tab2,, panel2] = yield initDebugger(TAB_URL);
|
||||
|
||||
yield ensureSourceIs(panel1, "code_breakpoints-other-tabs.js", true);
|
||||
|
||||
@ -22,7 +22,7 @@ let test = Task.async(function* () {
|
||||
});
|
||||
|
||||
const paused = waitForThreadEvents(panel2, "paused");
|
||||
executeSoon(() => debuggee2.testCase());
|
||||
callInTab(tab2, "testCase");
|
||||
const packet = yield paused;
|
||||
|
||||
is(packet.why.type, "debuggerStatement",
|
||||
|
@ -9,12 +9,11 @@
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor, gSources, gBreakpoints, gBreakpointsAdded, gBreakpointsRemoving;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
@ -24,7 +23,7 @@ function test() {
|
||||
gBreakpointsRemoving = gBreakpoints._removing;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1).then(performTest);
|
||||
gDebuggee.firstCall();
|
||||
callInTab(gTab, "firstCall");
|
||||
});
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
|
@ -11,7 +11,7 @@ const TAB_URL = EXAMPLE_URL + "doc_breakpoints-reload.html";
|
||||
let test = Task.async(function* () {
|
||||
requestLongerTimeout(4);
|
||||
|
||||
const [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
const [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
|
||||
yield ensureSourceIs(panel, "doc_breakpoints-reload.html", true);
|
||||
|
||||
|
@ -5,13 +5,12 @@
|
||||
* Make sure that the variables view is keyboard accessible.
|
||||
*/
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariablesView;
|
||||
|
||||
function test() {
|
||||
initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger("about:blank").then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariablesView = gDebugger.DebuggerView.Variables;
|
||||
@ -504,7 +503,6 @@ function performTest() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariablesView = null;
|
||||
|
@ -6,13 +6,12 @@
|
||||
* when given some raw data.
|
||||
*/
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariablesView, gScope, gVariable;
|
||||
|
||||
function test() {
|
||||
initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger("about:blank").then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariablesView = gDebugger.DebuggerView.Variables;
|
||||
@ -602,7 +601,6 @@ function testClearHierarchy() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariablesView = null;
|
||||
|
@ -10,14 +10,13 @@ const TAB_URL = EXAMPLE_URL + "doc_watch-expressions.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function*() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let vars = win.DebuggerView.Variables;
|
||||
|
||||
win.DebuggerView.WatchExpressions.addExpression("this");
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.ermahgerd());
|
||||
callInTab(tab, "ermahgerd");
|
||||
yield waitForDebuggerEvents(panel, win.EVENTS.FETCHED_WATCH_EXPRESSIONS);
|
||||
|
||||
let exprScope = vars.getScopeAtIndex(0);
|
||||
|
@ -7,16 +7,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gL10N, gEditor, gVars, gWatch;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gL10N = gDebugger.L10N;
|
||||
@ -115,9 +114,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -288,7 +285,6 @@ function testWatchExpressionsRemoved() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gL10N = null;
|
||||
|
@ -8,16 +8,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gL10N, gEditor, gVars, gWatch;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gL10N = gDebugger.L10N;
|
||||
@ -36,9 +35,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -94,7 +91,6 @@ function testEdit(aString, aExpected) {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gL10N = null;
|
||||
|
@ -7,13 +7,12 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVars;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVars = gDebugger.DebuggerView.Variables;
|
||||
@ -38,9 +37,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -82,7 +79,6 @@ function testModification(aNewValue, aNewResult) {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVars = null;
|
||||
|
@ -7,13 +7,12 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_watch-expressions.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gL10N, gEditor, gVars, gWatch;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gL10N = gDebugger.L10N;
|
||||
@ -44,7 +43,7 @@ function test() {
|
||||
});
|
||||
|
||||
addExpressions();
|
||||
gDebuggee.ermahgerd();
|
||||
callInTab(gTab, "ermahgerd");
|
||||
});
|
||||
}
|
||||
|
||||
@ -494,7 +493,6 @@ function addCmdExpression(aString) {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gL10N = null;
|
||||
|
@ -7,13 +7,12 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gPrefs, gOptions, gVariables;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gPrefs = gDebugger.Prefs;
|
||||
@ -72,7 +71,6 @@ function performTest() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gPrefs = null;
|
||||
|
@ -8,13 +8,12 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
@ -139,7 +138,6 @@ function performTest() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
@ -8,16 +8,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
@ -30,9 +29,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -253,7 +250,6 @@ function testExpandVariables() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
@ -8,16 +8,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
@ -35,9 +34,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -543,7 +540,6 @@ function testGetterSetterObject() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
@ -8,16 +8,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
@ -32,9 +31,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -148,7 +145,6 @@ function testWindowVariable() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
@ -7,13 +7,12 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
@ -34,9 +33,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -204,7 +201,6 @@ function testFunctionScope() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
@ -8,12 +8,11 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
@ -24,7 +23,7 @@ function test() {
|
||||
function prepareTest() {
|
||||
gDebugger.once(gDebugger.EVENTS.FETCHED_SCOPES, runTest);
|
||||
|
||||
gDebuggee.eval("(" + function() {
|
||||
evalInTab(gTab, "(" + function() {
|
||||
var frozen = Object.freeze({});
|
||||
var sealed = Object.seal({});
|
||||
var nonExtensible = Object.preventExtensions({});
|
||||
@ -83,7 +82,6 @@ function runTest() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
@ -8,17 +8,16 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest);
|
||||
gDebuggee.simpleCall();
|
||||
callInTab(gTab, "simpleCall");
|
||||
});
|
||||
}
|
||||
|
||||
@ -101,7 +100,6 @@ function performTest() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
@ -8,13 +8,12 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_large-array-buffer.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables, gEllipsis;
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
@ -29,9 +28,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -235,7 +232,6 @@ function verifyNextLevels() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
@ -10,13 +10,12 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable-2.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let events = win.EVENTS;
|
||||
let variables = win.DebuggerView.Variables;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.test());
|
||||
callInTab(tab, "test");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 23);
|
||||
|
||||
let firstScope = variables.getScopeAtIndex(0);
|
||||
|
@ -9,7 +9,7 @@ const TAB_URL = EXAMPLE_URL + "doc_scope-variable-2.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function() {
|
||||
let [tab, debuggee, panel] = yield initDebugger(TAB_URL);
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL);
|
||||
let win = panel.panelWin;
|
||||
let events = win.EVENTS;
|
||||
let variables = win.DebuggerView.Variables;
|
||||
@ -18,8 +18,7 @@ function test() {
|
||||
let committedLocalScopeHierarchy = promise.defer();
|
||||
variables.oncommit = committedLocalScopeHierarchy.resolve;
|
||||
|
||||
// Allow this generator function to yield first.
|
||||
executeSoon(() => debuggee.test());
|
||||
callInTab(tab, "test");
|
||||
yield waitForSourceAndCaretAndScopes(panel, ".html", 23);
|
||||
yield committedLocalScopeHierarchy.promise;
|
||||
|
||||
|
@ -7,16 +7,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gBreakpoints, gSources, gVariables;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(4);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
@ -45,13 +44,7 @@ function addBreakpoint() {
|
||||
}
|
||||
|
||||
function pauseDebuggee() {
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
});
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
|
||||
// The first 'with' scope should be expanded by default, but the
|
||||
// variables haven't been fetched yet. This is how 'with' scopes work.
|
||||
@ -200,7 +193,6 @@ function prepareVariablesAndProperties() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gBreakpoints = null;
|
||||
|
@ -8,16 +8,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gBreakpoints, gSources, gVariables;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(4);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
@ -46,13 +45,7 @@ function addBreakpoint() {
|
||||
}
|
||||
|
||||
function pauseDebuggee() {
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
});
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
|
||||
// The first 'with' scope should be expanded by default, but the
|
||||
// variables haven't been fetched yet. This is how 'with' scopes work.
|
||||
@ -215,7 +208,6 @@ function prepareVariablesAndProperties() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gBreakpoints = null;
|
||||
|
@ -7,16 +7,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_scope-variable-4.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gBreakpoints, gSources, gVariables;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(4);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
|
||||
@ -45,11 +44,7 @@ function addBreakpoint() {
|
||||
}
|
||||
|
||||
function pauseDebuggee() {
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => {
|
||||
gDebuggee.test();
|
||||
});
|
||||
callInTab(gTab, "test");
|
||||
|
||||
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
|
||||
}
|
||||
@ -120,7 +115,6 @@ function prepareScopes() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gBreakpoints = null;
|
||||
|
@ -8,16 +8,15 @@
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
@ -30,9 +29,7 @@ function test() {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebuggee.document.querySelector("button"),
|
||||
gDebuggee);
|
||||
sendMouseClickToTab(gTab, content.document.querySelector("button"));
|
||||
});
|
||||
}
|
||||
|
||||
@ -253,7 +250,6 @@ function performTest() {
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
@ -11,12 +11,11 @@ function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor, gWatch, gVariables;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
|
@ -11,12 +11,11 @@ function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gWatch, gVariables;
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gWatch = gDebugger.DebuggerView.WatchExpressions;
|
||||
@ -113,7 +112,7 @@ function test() {
|
||||
aCallback();
|
||||
});
|
||||
|
||||
gDebuggee.test();
|
||||
callInTab(gTab, "test");
|
||||
}
|
||||
|
||||
function test2(aCallback) {
|
||||
|
@ -24,3 +24,10 @@ addMessageListener("test:click", function (message) {
|
||||
EventUtils.synthesizeMouseAtCenter(target, {},
|
||||
target.ownerDocument.defaultView);
|
||||
});
|
||||
|
||||
addMessageListener("test:eval", function (message) {
|
||||
dump("Evalling string " + message.data.string + ".\n");
|
||||
|
||||
content.eval(message.data.string);
|
||||
sendAsyncMessage("test:eval");
|
||||
});
|
||||
|
@ -970,6 +970,15 @@ function callInTab(tab, name) {
|
||||
waitForMessageFromTab(tab, "test:call");
|
||||
}
|
||||
|
||||
function evalInTab(tab, string) {
|
||||
info("Evalling string " + string + " in tab.");
|
||||
|
||||
sendMessageToTab(tab, "test:eval", {
|
||||
string: string,
|
||||
});
|
||||
waitForMessageFromTab(tab, "test:eval");
|
||||
}
|
||||
|
||||
function sendMouseClickToTab(tab, target) {
|
||||
info("Sending mouse click to tab.");
|
||||
|
||||
|
@ -13,6 +13,8 @@ var gRGB_TO_HSL = {
|
||||
"rgb(96, 201, 58)": "hsl(104,57%,51%)",
|
||||
"rgb(240, 195, 111)": "hsl(39,82%,69%)",
|
||||
"rgb(227, 155, 22)": "hsl(39,82%,49%)",
|
||||
"rgb(204, 204, 204)": "hsl(0,0%,80%)",
|
||||
"rgb(153, 153, 153)": "hsl(0,0%,60%)",
|
||||
};
|
||||
|
||||
let test = Task.async(function*() {
|
||||
|
@ -55,7 +55,13 @@ const TIMELINE_BLUEPRINT = {
|
||||
fill: "hsl(0,0%,80%)",
|
||||
stroke: "hsl(0,0%,60%)",
|
||||
label: L10N.getStr("timeline.label.consoleTime")
|
||||
}
|
||||
},
|
||||
"Javascript": {
|
||||
group: 4,
|
||||
fill: "hsl(0,0%,80%)",
|
||||
stroke: "hsl(0,0%,60%)",
|
||||
label: L10N.getStr("timeline.label.javascript")
|
||||
},
|
||||
};
|
||||
|
||||
// Exported symbols.
|
||||
|
@ -8,9 +8,8 @@ include $(topsrcdir)/config/rules.mk
|
||||
addondir = $(srcdir)/test/addons
|
||||
testdir = $(abspath $(DEPTH)/_tests/xpcshell/browser/experiments/test/xpcshell)
|
||||
|
||||
libs::
|
||||
misc:: $(call mkdir_deps,$(testdir))
|
||||
$(EXIT_ON_ERROR) \
|
||||
$(NSINSTALL) -D $(testdir); \
|
||||
for dir in $(addondir)/*; do \
|
||||
base=`basename $$dir`; \
|
||||
(cd $$dir && zip -qr $(testdir)/$$base.xpi *); \
|
||||
|
@ -2,6 +2,8 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
HAS_MISC_RULE = True
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'Experiments.manifest',
|
||||
'ExperimentsService.js',
|
||||
|
@ -1,2 +1,6 @@
|
||||
title=You're browsing privately
|
||||
title.normal=Open a private window?
|
||||
# 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/.
|
||||
|
||||
title=You're browsing privately
|
||||
title.normal=Open a private window?
|
||||
|
@ -38,6 +38,7 @@ timeline.records=RECORDS
|
||||
timeline.label.styles=Styles
|
||||
timeline.label.reflow=Reflow
|
||||
timeline.label.paint=Paint
|
||||
timeline.label.javascript=Javascript
|
||||
timeline.label.domevent=DOM Event
|
||||
timeline.label.consoleTime=Console
|
||||
|
||||
|
@ -12,12 +12,19 @@ public class AnnotationInfo {
|
||||
public final boolean isMultithreaded;
|
||||
public final boolean noThrow;
|
||||
public final boolean narrowChars;
|
||||
public final boolean catchException;
|
||||
|
||||
public AnnotationInfo(String aWrapperName, boolean aIsMultithreaded,
|
||||
boolean aNoThrow, boolean aNarrowChars) {
|
||||
boolean aNoThrow, boolean aNarrowChars, boolean aCatchException) {
|
||||
wrapperName = aWrapperName;
|
||||
isMultithreaded = aIsMultithreaded;
|
||||
noThrow = aNoThrow;
|
||||
narrowChars = aNarrowChars;
|
||||
catchException = aCatchException;
|
||||
|
||||
if (!noThrow && catchException) {
|
||||
// It doesn't make sense to have these together
|
||||
throw new IllegalArgumentException("noThrow and catchException are not allowed together");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ public class AnnotationProcessor {
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"namespace android {\n" +
|
||||
"void InitStubs(JNIEnv *jEnv);\n\n");
|
||||
"void InitStubs(JNIEnv *env);\n\n");
|
||||
|
||||
StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
|
||||
implementationFile.append("#include \"GeneratedJNIWrappers.h\"\n" +
|
||||
@ -66,7 +66,7 @@ public class AnnotationProcessor {
|
||||
|
||||
// Used to track the calls to the various class-specific initialisation functions.
|
||||
StringBuilder stubInitialiser = new StringBuilder();
|
||||
stubInitialiser.append("void InitStubs(JNIEnv *jEnv) {\n");
|
||||
stubInitialiser.append("void InitStubs(JNIEnv *env) {\n");
|
||||
|
||||
while (jarClassIterator.hasNext()) {
|
||||
ClassWithOptions aClassTuple = jarClassIterator.next();
|
||||
@ -81,7 +81,7 @@ public class AnnotationProcessor {
|
||||
}
|
||||
generatorInstance = new CodeGenerator(aClassTuple.wrappedClass, aClassTuple.generatedName);
|
||||
|
||||
stubInitialiser.append(" ").append(aClassTuple.generatedName).append("::InitStubs(jEnv);\n");
|
||||
stubInitialiser.append(" ").append(aClassTuple.generatedName).append("::InitStubs(env);\n");
|
||||
|
||||
// Iterate all annotated members in this class..
|
||||
while (methodIterator.hasNext()) {
|
||||
|
@ -12,6 +12,7 @@ import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
@ -40,21 +41,27 @@ public class CodeGenerator {
|
||||
private final HashSet<String> mTakenMemberNames = new HashSet<String>();
|
||||
private int mNameMunger;
|
||||
|
||||
private final boolean mLazyInit;
|
||||
|
||||
public CodeGenerator(Class<?> aClass, String aGeneratedName) {
|
||||
this(aClass, aGeneratedName, false);
|
||||
}
|
||||
|
||||
public CodeGenerator(Class<?> aClass, String aGeneratedName, boolean aLazyInit) {
|
||||
mClassToWrap = aClass;
|
||||
mCClassName = aGeneratedName;
|
||||
mLazyInit = aLazyInit;
|
||||
|
||||
// Write the file header things. Includes and so forth.
|
||||
// GeneratedJNIWrappers.cpp is generated as the concatenation of wrapperStartupCode with
|
||||
// wrapperMethodBodies. Similarly, GeneratedJNIWrappers.h is the concatenation of headerPublic
|
||||
// with headerProtected.
|
||||
wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *jEnv) {\n" +
|
||||
" initInit();\n");
|
||||
wrapperStartupCode.append("void ").append(mCClassName).append("::InitStubs(JNIEnv *env) {\n");
|
||||
|
||||
// Now we write the various GetStaticMethodID calls here...
|
||||
headerPublic.append("class ").append(mCClassName).append(" : public AutoGlobalWrappedJavaObject {\n" +
|
||||
"public:\n" +
|
||||
" static void InitStubs(JNIEnv *jEnv);\n");
|
||||
" static void InitStubs(JNIEnv *env);\n");
|
||||
headerProtected.append("protected:");
|
||||
|
||||
generateWrapperMethod();
|
||||
@ -79,7 +86,10 @@ public class CodeGenerator {
|
||||
private void generateMemberCommon(Member theMethod, String aCMethodName, Class<?> aClass) {
|
||||
ensureClassHeaderAndStartup(aClass);
|
||||
writeMemberIdField(theMethod, aCMethodName);
|
||||
writeStartupCode(theMethod);
|
||||
|
||||
if (!mLazyInit) {
|
||||
writeMemberInit(theMethod, wrapperStartupCode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,8 +111,10 @@ public class CodeGenerator {
|
||||
Class<?> returnType = theMethod.getReturnType();
|
||||
|
||||
// Get the C++ method signature for this method.
|
||||
String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName, mCClassName, aMethodTuple.mAnnotationInfo.narrowChars);
|
||||
String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType, CMethodName, mCClassName, isFieldStatic, aMethodTuple.mAnnotationInfo.narrowChars);
|
||||
String implementationSignature = Utils.getCImplementationMethodSignature(parameterTypes, returnType, CMethodName,
|
||||
mCClassName, aMethodTuple.mAnnotationInfo.narrowChars, aMethodTuple.mAnnotationInfo.catchException);
|
||||
String headerSignature = Utils.getCHeaderMethodSignature(parameterTypes, theMethod.getParameterAnnotations(), returnType,
|
||||
CMethodName, mCClassName, isFieldStatic, aMethodTuple.mAnnotationInfo.narrowChars, aMethodTuple.mAnnotationInfo.catchException);
|
||||
|
||||
// Add the header signature to the header file.
|
||||
writeSignatureToHeader(headerSignature);
|
||||
@ -111,19 +123,25 @@ public class CodeGenerator {
|
||||
writeMethodBody(implementationSignature, theMethod, mClassToWrap,
|
||||
aMethodTuple.mAnnotationInfo.isMultithreaded,
|
||||
aMethodTuple.mAnnotationInfo.noThrow,
|
||||
aMethodTuple.mAnnotationInfo.narrowChars);
|
||||
aMethodTuple.mAnnotationInfo.narrowChars,
|
||||
aMethodTuple.mAnnotationInfo.catchException);
|
||||
}
|
||||
|
||||
private void generateGetterOrSetterBody(Class<?> aFieldType, String aFieldName, boolean aIsFieldStatic, boolean isSetter, boolean aNarrowChars) {
|
||||
private void generateGetterOrSetterBody(Field aField, String aFieldName, boolean aIsFieldStatic, boolean isSetter, boolean aNarrowChars) {
|
||||
StringBuilder argumentContent = null;
|
||||
Class<?> fieldType = aField.getType();
|
||||
|
||||
if (isSetter) {
|
||||
Class<?>[] setterArguments = new Class<?>[]{aFieldType};
|
||||
Class<?>[] setterArguments = new Class<?>[]{fieldType};
|
||||
// Marshall the argument..
|
||||
argumentContent = getArgumentMarshalling(setterArguments);
|
||||
}
|
||||
|
||||
boolean isObjectReturningMethod = Utils.isObjectType(aFieldType);
|
||||
if (mLazyInit) {
|
||||
writeMemberInit(aField, wrapperMethodBodies);
|
||||
}
|
||||
|
||||
boolean isObjectReturningMethod = Utils.isObjectType(fieldType);
|
||||
wrapperMethodBodies.append(" ");
|
||||
if (isSetter) {
|
||||
wrapperMethodBodies.append("env->Set");
|
||||
@ -131,7 +149,7 @@ public class CodeGenerator {
|
||||
wrapperMethodBodies.append("return ");
|
||||
|
||||
if (isObjectReturningMethod) {
|
||||
wrapperMethodBodies.append("static_cast<").append(Utils.getCReturnType(aFieldType, aNarrowChars)).append(">(");
|
||||
wrapperMethodBodies.append("static_cast<").append(Utils.getCReturnType(fieldType, aNarrowChars)).append(">(");
|
||||
}
|
||||
|
||||
wrapperMethodBodies.append("env->Get");
|
||||
@ -140,7 +158,7 @@ public class CodeGenerator {
|
||||
if (aIsFieldStatic) {
|
||||
wrapperMethodBodies.append("Static");
|
||||
}
|
||||
wrapperMethodBodies.append(Utils.getFieldType(aFieldType))
|
||||
wrapperMethodBodies.append(Utils.getFieldType(fieldType))
|
||||
.append("Field(");
|
||||
|
||||
// Static will require the class and the field id. Nonstatic, the object and the field id.
|
||||
@ -181,14 +199,14 @@ public class CodeGenerator {
|
||||
boolean isFieldFinal = Utils.isMemberFinal(theField);
|
||||
|
||||
String getterName = "get" + CFieldName;
|
||||
String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars);
|
||||
String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars);
|
||||
String getterSignature = Utils.getCImplementationMethodSignature(EMPTY_CLASS_ARRAY, fieldType, getterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars, false);
|
||||
String getterHeaderSignature = Utils.getCHeaderMethodSignature(EMPTY_CLASS_ARRAY, GETTER_ARGUMENT_ANNOTATIONS, fieldType, getterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars, false);
|
||||
|
||||
writeSignatureToHeader(getterHeaderSignature);
|
||||
|
||||
writeFunctionStartupBoilerPlate(getterSignature, true);
|
||||
|
||||
generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, false, aFieldTuple.mAnnotationInfo.narrowChars);
|
||||
generateGetterOrSetterBody(theField, CFieldName, isFieldStatic, false, aFieldTuple.mAnnotationInfo.narrowChars);
|
||||
|
||||
// If field not final, also generate a setter function.
|
||||
if (!isFieldFinal) {
|
||||
@ -196,14 +214,14 @@ public class CodeGenerator {
|
||||
|
||||
Class<?>[] setterArguments = new Class<?>[]{fieldType};
|
||||
|
||||
String setterSignature = Utils.getCImplementationMethodSignature(setterArguments, Void.class, setterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars);
|
||||
String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars);
|
||||
String setterSignature = Utils.getCImplementationMethodSignature(setterArguments, Void.class, setterName, mCClassName, aFieldTuple.mAnnotationInfo.narrowChars, false);
|
||||
String setterHeaderSignature = Utils.getCHeaderMethodSignature(setterArguments, SETTER_ARGUMENT_ANNOTATIONS, Void.class, setterName, mCClassName, isFieldStatic, aFieldTuple.mAnnotationInfo.narrowChars, false);
|
||||
|
||||
writeSignatureToHeader(setterHeaderSignature);
|
||||
|
||||
writeFunctionStartupBoilerPlate(setterSignature, true);
|
||||
|
||||
generateGetterOrSetterBody(fieldType, CFieldName, isFieldStatic, true, aFieldTuple.mAnnotationInfo.narrowChars);
|
||||
generateGetterOrSetterBody(theField, CFieldName, isFieldStatic, true, aFieldTuple.mAnnotationInfo.narrowChars);
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,8 +232,10 @@ public class CodeGenerator {
|
||||
|
||||
generateMemberCommon(theCtor, mCClassName, mClassToWrap);
|
||||
|
||||
String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName, mCClassName, aCtorTuple.mAnnotationInfo.narrowChars);
|
||||
String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName, mCClassName, false, aCtorTuple.mAnnotationInfo.narrowChars);
|
||||
String implementationSignature = Utils.getCImplementationMethodSignature(theCtor.getParameterTypes(), Void.class, CMethodName,
|
||||
mCClassName, aCtorTuple.mAnnotationInfo.narrowChars, aCtorTuple.mAnnotationInfo.catchException);
|
||||
String headerSignature = Utils.getCHeaderMethodSignature(theCtor.getParameterTypes(), theCtor.getParameterAnnotations(), Void.class, CMethodName,
|
||||
mCClassName, false, aCtorTuple.mAnnotationInfo.narrowChars, aCtorTuple.mAnnotationInfo.catchException);
|
||||
|
||||
// Slice off the "void " from the start of the constructor declaration.
|
||||
headerSignature = headerSignature.substring(5);
|
||||
@ -227,13 +247,37 @@ public class CodeGenerator {
|
||||
// Use the implementation signature to generate the method body...
|
||||
writeCtorBody(implementationSignature, theCtor,
|
||||
aCtorTuple.mAnnotationInfo.isMultithreaded,
|
||||
aCtorTuple.mAnnotationInfo.noThrow);
|
||||
aCtorTuple.mAnnotationInfo.noThrow,
|
||||
aCtorTuple.mAnnotationInfo.catchException);
|
||||
|
||||
if (theCtor.getParameterTypes().length == 0) {
|
||||
mHasEncounteredDefaultConstructor = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void generateMembers(Member[] members) {
|
||||
for (Member m : members) {
|
||||
if (!Modifier.isPublic(m.getModifiers())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = m.getName();
|
||||
name = name.substring(0, 1).toUpperCase() + name.substring(1);
|
||||
|
||||
AnnotationInfo info = new AnnotationInfo(name, true, true, true, true);
|
||||
AnnotatableEntity entity = new AnnotatableEntity(m, info);
|
||||
if (m instanceof Constructor) {
|
||||
generateConstructor(entity);
|
||||
} else if (m instanceof Method) {
|
||||
generateMethod(entity);
|
||||
} else if (m instanceof Field) {
|
||||
generateField(entity);
|
||||
} else {
|
||||
throw new IllegalArgumentException("expected member to be Constructor, Method, or Field");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the appropriate header and startup code to ensure the existence of a reference to the
|
||||
* class specified. If this is already done, does nothing.
|
||||
@ -258,8 +302,7 @@ public class CodeGenerator {
|
||||
.append(";\n");
|
||||
|
||||
// Add startup code to populate it..
|
||||
wrapperStartupCode.append('\n')
|
||||
.append(Utils.getStartupLineForClass(aClass));
|
||||
wrapperStartupCode.append(Utils.getStartupLineForClass(aClass));
|
||||
|
||||
seenClasses.add(className);
|
||||
}
|
||||
@ -371,14 +414,30 @@ public class CodeGenerator {
|
||||
return argumentContent;
|
||||
}
|
||||
|
||||
private void writeCatchException() {
|
||||
wrapperMethodBodies.append(
|
||||
" if (env->ExceptionCheck()) {\n" +
|
||||
" env->ExceptionClear();\n" +
|
||||
" if (aResult) {\n" +
|
||||
" *aResult = NS_ERROR_FAILURE;\n" +
|
||||
" }\n" +
|
||||
" } else if (aResult) {\n" +
|
||||
" *aResult = NS_OK;\n" +
|
||||
" }\n\n");
|
||||
}
|
||||
|
||||
private void writeCtorBody(String implementationSignature, Constructor<?> theCtor,
|
||||
boolean aIsThreaded, boolean aNoThrow) {
|
||||
boolean aIsThreaded, boolean aNoThrow, boolean aCatchException) {
|
||||
Class<?>[] argumentTypes = theCtor.getParameterTypes();
|
||||
|
||||
writeFunctionStartupBoilerPlate(implementationSignature, aIsThreaded);
|
||||
|
||||
writeFramePushBoilerplate(theCtor, false, aNoThrow);
|
||||
|
||||
if (mLazyInit) {
|
||||
writeMemberInit(theCtor, wrapperMethodBodies);
|
||||
}
|
||||
|
||||
// Marshall arguments for this constructor, if any...
|
||||
boolean hasArguments = argumentTypes.length != 0;
|
||||
|
||||
@ -402,9 +461,14 @@ public class CodeGenerator {
|
||||
wrapperMethodBodies.append(mMembersToIds.get(theCtor))
|
||||
// Tack on the arguments, if any..
|
||||
.append(argumentContent)
|
||||
.append("), env);\n" +
|
||||
" env->PopLocalFrame(nullptr);\n" +
|
||||
"}\n");
|
||||
.append("), env);\n");
|
||||
|
||||
// Check for exception and set aResult
|
||||
if (aCatchException) {
|
||||
writeCatchException();
|
||||
}
|
||||
|
||||
wrapperMethodBodies.append(" env->PopLocalFrame(nullptr);\n}\n");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -417,7 +481,8 @@ public class CodeGenerator {
|
||||
*/
|
||||
private void writeMethodBody(String methodSignature, Method aMethod,
|
||||
Class<?> aClass, boolean aIsMultithreaded,
|
||||
boolean aNoThrow, boolean aNarrowChars) {
|
||||
boolean aNoThrow, boolean aNarrowChars,
|
||||
boolean aCatchException) {
|
||||
Class<?>[] argumentTypes = aMethod.getParameterTypes();
|
||||
Class<?> returnType = aMethod.getReturnType();
|
||||
|
||||
@ -427,6 +492,10 @@ public class CodeGenerator {
|
||||
|
||||
writeFramePushBoilerplate(aMethod, isObjectReturningMethod, aNoThrow);
|
||||
|
||||
if (mLazyInit) {
|
||||
writeMemberInit(aMethod, wrapperMethodBodies);
|
||||
}
|
||||
|
||||
// Marshall arguments, if we have any.
|
||||
boolean hasArguments = argumentTypes.length != 0;
|
||||
|
||||
@ -481,6 +550,11 @@ public class CodeGenerator {
|
||||
wrapperMethodBodies.append(" AndroidBridge::HandleUncaughtException(env);\n");
|
||||
}
|
||||
|
||||
// Check for exception and set aResult
|
||||
if (aCatchException) {
|
||||
writeCatchException();
|
||||
}
|
||||
|
||||
// If we're returning an object, pop the callee's stack frame extracting our ref as the return
|
||||
// value.
|
||||
if (isObjectReturningMethod) {
|
||||
@ -501,33 +575,41 @@ public class CodeGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the code to get the id of the given member on startup.
|
||||
* Generates the code to get the id of the given member on startup or in the member body if lazy init
|
||||
* is requested.
|
||||
*
|
||||
* @param aMember The Java member being wrapped.
|
||||
*/
|
||||
private void writeStartupCode(Member aMember) {
|
||||
wrapperStartupCode.append(" ")
|
||||
.append(mMembersToIds.get(aMember))
|
||||
.append(" = get");
|
||||
private void writeMemberInit(Member aMember, StringBuilder aOutput) {
|
||||
if (mLazyInit) {
|
||||
aOutput.append(" if (!" + mMembersToIds.get(aMember) + ") {\n ");
|
||||
}
|
||||
|
||||
aOutput.append(" " + mMembersToIds.get(aMember)).append(" = AndroidBridge::Get");
|
||||
if (Utils.isMemberStatic(aMember)) {
|
||||
wrapperStartupCode.append("Static");
|
||||
aOutput.append("Static");
|
||||
}
|
||||
|
||||
boolean isField = aMember instanceof Field;
|
||||
if (isField) {
|
||||
wrapperStartupCode.append("Field(\"");
|
||||
aOutput.append("FieldID(env, " + Utils.getClassReferenceName(aMember.getDeclaringClass()) + ", \"");
|
||||
} else {
|
||||
wrapperStartupCode.append("Method(\"");
|
||||
}
|
||||
if (aMember instanceof Constructor) {
|
||||
wrapperStartupCode.append("<init>");
|
||||
} else {
|
||||
wrapperStartupCode.append(aMember.getName());
|
||||
aOutput.append("MethodID(env, " + Utils.getClassReferenceName(aMember.getDeclaringClass()) + ", \"");
|
||||
}
|
||||
|
||||
wrapperStartupCode.append("\", \"")
|
||||
if (aMember instanceof Constructor) {
|
||||
aOutput.append("<init>");
|
||||
} else {
|
||||
aOutput.append(aMember.getName());
|
||||
}
|
||||
|
||||
aOutput.append("\", \"")
|
||||
.append(Utils.getTypeSignatureStringForMember(aMember))
|
||||
.append("\");\n");
|
||||
|
||||
if (mLazyInit) {
|
||||
aOutput.append(" }\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeZeroingFor(Member aMember, final String aMemberName) {
|
||||
|
@ -4,9 +4,9 @@
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar
|
||||
JAVA_CLASSPATH := $(ANDROID_SDK)/android.jar:$(ANDROID_SDK)/../../tools/lib/lint.jar:$(ANDROID_SDK)/../../tools/lib/lint-checks.jar
|
||||
|
||||
# Include Android specific java flags, instead of what's in rules.mk.
|
||||
include $(topsrcdir)/config/android-common.mk
|
||||
|
||||
libs:: annotationProcessors.jar
|
||||
export:: annotationProcessors.jar
|
||||
|
255
build/annotationProcessors/SDKProcessor.java
Normal file
255
build/annotationProcessors/SDKProcessor.java
Normal file
@ -0,0 +1,255 @@
|
||||
/* 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/. */
|
||||
|
||||
package org.mozilla.gecko.annotationProcessors;
|
||||
|
||||
import com.android.tools.lint.checks.ApiLookup;
|
||||
import com.android.tools.lint.LintCliClient;
|
||||
|
||||
import org.mozilla.gecko.annotationProcessors.classloader.AnnotatableEntity;
|
||||
import org.mozilla.gecko.annotationProcessors.classloader.ClassWithOptions;
|
||||
import org.mozilla.gecko.annotationProcessors.classloader.IterableJarLoadingURLClassLoader;
|
||||
import org.mozilla.gecko.annotationProcessors.utils.GeneratableElementIterator;
|
||||
import org.mozilla.gecko.annotationProcessors.utils.Utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.Properties;
|
||||
import java.util.Scanner;
|
||||
import java.util.Vector;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class SDKProcessor {
|
||||
public static final String GENERATED_COMMENT =
|
||||
"// GENERATED CODE\n" +
|
||||
"// Generated by the Java program at /build/annotationProcessors at compile time from\n" +
|
||||
"// annotations on Java methods. To update, change the annotations on the corresponding Java\n" +
|
||||
"// methods and rerun the build. Manually updating this file will cause your build to fail.\n\n";
|
||||
|
||||
private static ApiLookup sApiLookup;
|
||||
private static int sMaxSdkVersion;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// We expect a list of jars on the commandline. If missing, whinge about it.
|
||||
if (args.length < 5) {
|
||||
System.err.println("Usage: java SDKProcessor sdkjar classlistfile outdir fileprefix max-sdk-version");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
System.out.println("Processing platform bindings...");
|
||||
|
||||
String sdkJar = args[0];
|
||||
Vector classes = getClassList(args[1]);
|
||||
String outdir = args[2];
|
||||
String generatedFilePrefix = args[3];
|
||||
sMaxSdkVersion = Integer.parseInt(args[4]);
|
||||
|
||||
Properties props = System.getProperties();
|
||||
props.setProperty("com.android.tools.lint.bindir",
|
||||
new File(new File(sdkJar).getParentFile(), "../../tools").toString());
|
||||
|
||||
LintCliClient lintClient = new LintCliClient();
|
||||
sApiLookup = ApiLookup.get(lintClient);
|
||||
|
||||
// Start the clock!
|
||||
long s = System.currentTimeMillis();
|
||||
|
||||
// Get an iterator over the classes in the jar files given...
|
||||
// Iterator<ClassWithOptions> jarClassIterator = IterableJarLoadingURLClassLoader.getIteratorOverJars(args);
|
||||
|
||||
StringBuilder headerFile = new StringBuilder(GENERATED_COMMENT);
|
||||
headerFile.append("#ifndef " + generatedFilePrefix + "_h__\n" +
|
||||
"#define " + generatedFilePrefix + "_h__\n" +
|
||||
"#include \"nsXPCOMStrings.h\"\n" +
|
||||
"#include \"AndroidJavaWrappers.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"namespace android {\n" +
|
||||
"namespace sdk {\n" +
|
||||
"void Init" + generatedFilePrefix + "Stubs(JNIEnv *jEnv);\n\n");
|
||||
|
||||
StringBuilder implementationFile = new StringBuilder(GENERATED_COMMENT);
|
||||
implementationFile.append("#include \"" + generatedFilePrefix + ".h\"\n" +
|
||||
"#include \"AndroidBridgeUtilities.h\"\n" +
|
||||
"#include \"nsXPCOMStrings.h\"\n" +
|
||||
"#include \"AndroidBridge.h\"\n" +
|
||||
"\n" +
|
||||
"namespace mozilla {\n" +
|
||||
"namespace widget {\n" +
|
||||
"namespace android {\n" +
|
||||
"namespace sdk {\n");
|
||||
|
||||
// Used to track the calls to the various class-specific initialisation functions.
|
||||
StringBuilder stubInitializer = new StringBuilder();
|
||||
stubInitializer.append("void Init" + generatedFilePrefix + "Stubs(JNIEnv *jEnv) {\n");
|
||||
|
||||
ClassLoader loader = null;
|
||||
try {
|
||||
loader = URLClassLoader.newInstance(new URL[] { new URL("file://" + sdkJar) },
|
||||
SDKProcessor.class.getClassLoader());
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
|
||||
for (Iterator<String> i = classes.iterator(); i.hasNext(); ) {
|
||||
String className = i.next();
|
||||
System.out.println("Looking up: " + className);
|
||||
|
||||
try {
|
||||
Class<?> c = Class.forName(className, true, loader);
|
||||
|
||||
generateClass(Class.forName(className, true, loader),
|
||||
stubInitializer,
|
||||
implementationFile,
|
||||
headerFile);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Failed to generate class " + className + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
implementationFile.append('\n');
|
||||
stubInitializer.append("}");
|
||||
implementationFile.append(stubInitializer);
|
||||
|
||||
implementationFile.append("\n} /* sdk */\n" +
|
||||
"} /* android */\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n");
|
||||
|
||||
headerFile.append("\n} /* sdk */\n" +
|
||||
"} /* android */\n" +
|
||||
"} /* widget */\n" +
|
||||
"} /* mozilla */\n" +
|
||||
"#endif\n");
|
||||
|
||||
writeOutputFiles(outdir, generatedFilePrefix, headerFile, implementationFile);
|
||||
long e = System.currentTimeMillis();
|
||||
System.out.println("SDK processing complete in " + (e - s) + "ms");
|
||||
}
|
||||
|
||||
private static Member[] sortAndFilterMembers(Member[] members) {
|
||||
Arrays.sort(members, new Comparator<Member>() {
|
||||
@Override
|
||||
public int compare(Member a, Member b) {
|
||||
return a.getName().compareTo(b.getName());
|
||||
}
|
||||
});
|
||||
|
||||
ArrayList<Member> list = new ArrayList<>();
|
||||
for (Member m : members) {
|
||||
int version = 0;
|
||||
|
||||
if (m instanceof Method || m instanceof Constructor) {
|
||||
version = sApiLookup.getCallVersion(Utils.getTypeSignatureStringForClass(m.getDeclaringClass()),
|
||||
m.getName(),
|
||||
Utils.getTypeSignatureStringForMember(m));
|
||||
} else if (m instanceof Field) {
|
||||
version = sApiLookup.getFieldVersion(Utils.getTypeSignatureStringForClass(m.getDeclaringClass()),
|
||||
m.getName());
|
||||
} else {
|
||||
throw new IllegalArgumentException("expected member to be Method, Constructor, or Field");
|
||||
}
|
||||
|
||||
if (version > sMaxSdkVersion) {
|
||||
System.out.println("Skipping " + m.getDeclaringClass().getName() + "." + m.getName() +
|
||||
", version " + version + " > " + sMaxSdkVersion);
|
||||
continue;
|
||||
}
|
||||
|
||||
list.add(m);
|
||||
}
|
||||
|
||||
return list.toArray(new Member[list.size()]);
|
||||
}
|
||||
|
||||
private static void generateClass(Class<?> clazz,
|
||||
StringBuilder stubInitializer,
|
||||
StringBuilder implementationFile,
|
||||
StringBuilder headerFile) {
|
||||
String generatedName = clazz.getSimpleName();
|
||||
|
||||
CodeGenerator generator = new CodeGenerator(clazz, generatedName, true);
|
||||
stubInitializer.append(" ").append(generatedName).append("::InitStubs(jEnv);\n");
|
||||
|
||||
generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredConstructors()));
|
||||
generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredMethods()));
|
||||
generator.generateMembers(sortAndFilterMembers(clazz.getDeclaredFields()));
|
||||
|
||||
headerFile.append(generator.getHeaderFileContents());
|
||||
implementationFile.append(generator.getWrapperFileContents());
|
||||
}
|
||||
|
||||
private static Vector<String> getClassList(String path) {
|
||||
Scanner scanner = null;
|
||||
try {
|
||||
scanner = new Scanner(new FileInputStream(path));
|
||||
|
||||
Vector lines = new Vector();
|
||||
while (scanner.hasNextLine()) {
|
||||
lines.add(scanner.nextLine());
|
||||
}
|
||||
return lines;
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.toString());
|
||||
return null;
|
||||
} finally {
|
||||
if (scanner != null) {
|
||||
scanner.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeOutputFiles(String aOutputDir, String aPrefix, StringBuilder aHeaderFile,
|
||||
StringBuilder aImplementationFile) {
|
||||
FileOutputStream implStream = null;
|
||||
try {
|
||||
implStream = new FileOutputStream(new File(aOutputDir, aPrefix + ".cpp"));
|
||||
implStream.write(aImplementationFile.toString().getBytes());
|
||||
} catch (IOException e) {
|
||||
System.err.println("Unable to write " + aOutputDir + ". Perhaps a permissions issue?");
|
||||
e.printStackTrace(System.err);
|
||||
} finally {
|
||||
if (implStream != null) {
|
||||
try {
|
||||
implStream.close();
|
||||
} catch (IOException e) {
|
||||
System.err.println("Unable to close implStream due to "+e);
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileOutputStream headerStream = null;
|
||||
try {
|
||||
headerStream = new FileOutputStream(new File(aOutputDir, aPrefix + ".h"));
|
||||
headerStream.write(aHeaderFile.toString().getBytes());
|
||||
} catch (IOException e) {
|
||||
System.err.println("Unable to write " + aOutputDir + ". Perhaps a permissions issue?");
|
||||
e.printStackTrace(System.err);
|
||||
} finally {
|
||||
if (headerStream != null) {
|
||||
try {
|
||||
headerStream.close();
|
||||
} catch (IOException e) {
|
||||
System.err.println("Unable to close headerStream due to "+e);
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ jar.sources += [
|
||||
'classloader/IterableJarLoadingURLClassLoader.java',
|
||||
'classloader/JarClassIterator.java',
|
||||
'CodeGenerator.java',
|
||||
'SDKProcessor.java',
|
||||
'utils/AlphabeticAnnotatableEntityComparator.java',
|
||||
'utils/GeneratableElementIterator.java',
|
||||
'utils/Utils.java',
|
||||
|
@ -76,6 +76,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
boolean isMultithreadedStub = false;
|
||||
boolean noThrow = false;
|
||||
boolean narrowChars = false;
|
||||
boolean catchException = false;
|
||||
try {
|
||||
// Determine the explicitly-given name of the stub to generate, if any.
|
||||
final Method stubNameMethod = annotationType.getDeclaredMethod("stubName");
|
||||
@ -97,6 +98,11 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
narrowCharsMethod.setAccessible(true);
|
||||
narrowChars = (Boolean) narrowCharsMethod.invoke(annotation);
|
||||
|
||||
// Determine if we should catch exceptions
|
||||
final Method catchExceptionMethod = annotationType.getDeclaredMethod("catchException");
|
||||
catchExceptionMethod.setAccessible(true);
|
||||
catchException = (Boolean) catchExceptionMethod.invoke(annotation);
|
||||
|
||||
} catch (NoSuchMethodException e) {
|
||||
System.err.println("Unable to find expected field on WrapElementForJNI annotation. Did the signature change?");
|
||||
e.printStackTrace(System.err);
|
||||
@ -118,7 +124,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
}
|
||||
|
||||
AnnotationInfo annotationInfo = new AnnotationInfo(
|
||||
stubName, isMultithreadedStub, noThrow, narrowChars);
|
||||
stubName, isMultithreadedStub, noThrow, narrowChars, catchException);
|
||||
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
|
||||
return;
|
||||
}
|
||||
@ -128,7 +134,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
|
||||
// thanks to the "Generate everything" annotation.
|
||||
if (mIterateEveryEntry) {
|
||||
AnnotationInfo annotationInfo = new AnnotationInfo(
|
||||
candidateElement.getName(), false, false, false);
|
||||
candidateElement.getName(), false, false, false, false);
|
||||
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
|
||||
return;
|
||||
}
|
||||
|
@ -318,6 +318,10 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getTypeSignatureStringForClass(Class<?> clazz) {
|
||||
return clazz.getCanonicalName().replace('.', '/');
|
||||
}
|
||||
|
||||
public static String getTypeSignatureString(Constructor<?> aConstructor) {
|
||||
Class<?>[] arguments = aConstructor.getParameterTypes();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -341,7 +345,7 @@ public class Utils {
|
||||
* @param c The type of the element to write the subsignature of.
|
||||
*/
|
||||
private static void writeTypeSignature(StringBuilder sb, Class<?> c) {
|
||||
String name = c.getCanonicalName().replaceAll("\\.", "/");
|
||||
String name = Utils.getTypeSignatureStringForClass(c);
|
||||
|
||||
// Determine if this is an array type and, if so, peel away the array operators..
|
||||
int len = name.length();
|
||||
@ -384,7 +388,8 @@ public class Utils {
|
||||
* @param aCClassName Name of the C++ class into which the method is declared.
|
||||
* @return The C++ method implementation signature for the method described.
|
||||
*/
|
||||
public static String getCImplementationMethodSignature(Class<?>[] aArgumentTypes, Class<?> aReturnType, String aCMethodName, String aCClassName, boolean aNarrowChars) {
|
||||
public static String getCImplementationMethodSignature(Class<?>[] aArgumentTypes, Class<?> aReturnType,
|
||||
String aCMethodName, String aCClassName, boolean aNarrowChars, boolean aCatchException) {
|
||||
StringBuilder retBuffer = new StringBuilder();
|
||||
|
||||
retBuffer.append(getCReturnType(aReturnType, aNarrowChars));
|
||||
@ -406,6 +411,14 @@ public class Utils {
|
||||
retBuffer.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (aCatchException) {
|
||||
if (aArgumentTypes.length > 0) {
|
||||
retBuffer.append(", ");
|
||||
}
|
||||
retBuffer.append("nsresult* aResult");
|
||||
}
|
||||
|
||||
retBuffer.append(')');
|
||||
return retBuffer.toString();
|
||||
}
|
||||
@ -423,7 +436,8 @@ public class Utils {
|
||||
* @param aIsStaticStub true if the generated C++ method should be static, false otherwise.
|
||||
* @return The generated C++ header method signature for the method described.
|
||||
*/
|
||||
public static String getCHeaderMethodSignature(Class<?>[] aArgumentTypes, Annotation[][] aArgumentAnnotations, Class<?> aReturnType, String aCMethodName, String aCClassName, boolean aIsStaticStub, boolean aNarrowChars) {
|
||||
public static String getCHeaderMethodSignature(Class<?>[] aArgumentTypes, Annotation[][] aArgumentAnnotations, Class<?> aReturnType,
|
||||
String aCMethodName, String aCClassName, boolean aIsStaticStub, boolean aNarrowChars, boolean aCatchException) {
|
||||
StringBuilder retBuffer = new StringBuilder();
|
||||
|
||||
// Add the static keyword, if applicable.
|
||||
@ -453,6 +467,14 @@ public class Utils {
|
||||
retBuffer.append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
if (aCatchException) {
|
||||
if (aArgumentTypes.length > 0) {
|
||||
retBuffer.append(", ");
|
||||
}
|
||||
retBuffer.append("nsresult* aResult = nullptr");
|
||||
}
|
||||
|
||||
retBuffer.append(')');
|
||||
return retBuffer.toString();
|
||||
}
|
||||
@ -587,9 +609,9 @@ public class Utils {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(" ");
|
||||
sb.append(getClassReferenceName(aClass));
|
||||
sb.append(" = getClassGlobalRef(\"");
|
||||
sb.append(" = AndroidBridge::GetClassGlobalRef(env, \"");
|
||||
|
||||
String name = aClass.getCanonicalName().replaceAll("\\.", "/");
|
||||
String name = Utils.getTypeSignatureStringForClass(aClass);
|
||||
Class<?> containerClass = aClass.getDeclaringClass();
|
||||
if (containerClass != null) {
|
||||
// Is an inner class. Add the $ symbol.
|
||||
|
@ -41,7 +41,7 @@ public class FennecNativeActions implements Actions {
|
||||
}
|
||||
|
||||
class GeckoEventExpecter implements RepeatedEventExpecter {
|
||||
private static final int MAX_WAIT_MS = 90000;
|
||||
private static final int MAX_WAIT_MS = 180000;
|
||||
|
||||
private volatile boolean mIsRegistered;
|
||||
|
||||
|
@ -141,6 +141,10 @@ ifeq (.,$(DEPTH))
|
||||
# Interdependencies for parallel export.
|
||||
js/xpconnect/src/export: dom/bindings/export xpcom/xpidl/export
|
||||
accessible/xpcom/export: xpcom/xpidl/export
|
||||
|
||||
# The widget binding generator code is part of the annotationProcessors.
|
||||
widget/android/bindings/export: build/annotationProcessors/export
|
||||
|
||||
ifdef ENABLE_CLANG_PLUGIN
|
||||
$(filter-out build/clang-plugin/%,$(compile_targets)): build/clang-plugin/target build/clang-plugin/tests/target
|
||||
build/clang-plugin/tests/target: build/clang-plugin/target
|
||||
|
@ -1459,6 +1459,7 @@ if test "$GNU_CC"; then
|
||||
# -Wignored-qualifiers - catches returns types with qualifiers like const
|
||||
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
|
||||
# -Wmultichar - catches multicharacter integer constants like 'THIS'
|
||||
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
|
||||
# -Wnonnull - catches NULL used with functions arguments marked as non-null
|
||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||
# -Wpointer-sign - catches mixing pointers to signed and unsigned types
|
||||
@ -1493,6 +1494,8 @@ if test "$GNU_CC"; then
|
||||
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=sequence-point"
|
||||
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs"
|
||||
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas"
|
||||
|
||||
MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_werror_non_literal_null_conversion)
|
||||
fi
|
||||
|
||||
# Turn off the following warnings that -Wall turns on:
|
||||
@ -1552,6 +1555,7 @@ if test "$GNU_CXX"; then
|
||||
# -Wendif-labels - catches `#else FOO` and `#endif FOO` not in comment
|
||||
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
|
||||
# -Wmissing-braces - catches aggregate initializers missing nested braces
|
||||
# -Wnon-literal-null-conversion - catches expressions used as a null pointer constant
|
||||
# -Woverloaded-virtual - function declaration hides virtual function from base class
|
||||
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
|
||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||
@ -1583,6 +1587,8 @@ if test "$GNU_CXX"; then
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
|
||||
|
||||
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion)
|
||||
fi
|
||||
|
||||
# Turn off the following warnings that -Wall turns on:
|
||||
|
@ -854,7 +854,8 @@ nsDocShell::nsDocShell():
|
||||
mDefaultLoadFlags(nsIRequest::LOAD_NORMAL),
|
||||
mFrameType(eFrameTypeRegular),
|
||||
mOwnOrContainingAppId(nsIScriptSecurityManager::UNKNOWN_APP_ID),
|
||||
mParentCharsetSource(0)
|
||||
mParentCharsetSource(0),
|
||||
mJSRunToCompletionDepth(0)
|
||||
{
|
||||
mHistoryID = ++gDocshellIDCounter;
|
||||
if (gDocShellCount++ == 0) {
|
||||
@ -890,6 +891,8 @@ nsDocShell::nsDocShell():
|
||||
|
||||
nsDocShell::~nsDocShell()
|
||||
{
|
||||
MOZ_ASSERT(!mProfileTimelineRecording);
|
||||
|
||||
Destroy();
|
||||
|
||||
nsCOMPtr<nsISHistoryInternal>
|
||||
@ -2829,14 +2832,15 @@ NS_IMETHODIMP
|
||||
nsDocShell::SetRecordProfileTimelineMarkers(bool aValue)
|
||||
{
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
bool currentValue;
|
||||
GetRecordProfileTimelineMarkers(¤tValue);
|
||||
bool currentValue = nsIDocShell::GetRecordProfileTimelineMarkers();
|
||||
if (currentValue != aValue) {
|
||||
if (aValue) {
|
||||
++gProfileTimelineRecordingsCount;
|
||||
UseEntryScriptProfiling();
|
||||
mProfileTimelineRecording = true;
|
||||
} else {
|
||||
--gProfileTimelineRecordingsCount;
|
||||
UnuseEntryScriptProfiling();
|
||||
mProfileTimelineRecording = false;
|
||||
ClearProfileTimelineMarkers();
|
||||
}
|
||||
@ -4243,15 +4247,17 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
|
||||
int32_t aChildOffset, uint32_t loadType,
|
||||
bool aCloneChildren)
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (mLSHE && loadType != LOAD_PUSHSTATE && !aCloneRef) {
|
||||
if (mLSHE && loadType != LOAD_PUSHSTATE) {
|
||||
/* You get here if you are currently building a
|
||||
* hierarchy ie.,you just visited a frameset page
|
||||
*/
|
||||
nsCOMPtr<nsISHContainer> container(do_QueryInterface(mLSHE, &rv));
|
||||
if (container) {
|
||||
rv = container->AddChild(aNewEntry, aChildOffset);
|
||||
if (NS_FAILED(container->ReplaceChild(aNewEntry))) {
|
||||
rv = container->AddChild(aNewEntry, aChildOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!aCloneRef) {
|
||||
@ -4260,8 +4266,22 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
|
||||
if (container) {
|
||||
rv = container->AddChild(aNewEntry, aChildOffset);
|
||||
}
|
||||
} else {
|
||||
rv = AddChildSHEntryInternal(aCloneRef, aNewEntry, aChildOffset,
|
||||
loadType, aCloneChildren);
|
||||
}
|
||||
else if (mSessionHistory) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::AddChildSHEntryInternal(nsISHEntry* aCloneRef,
|
||||
nsISHEntry* aNewEntry,
|
||||
int32_t aChildOffset,
|
||||
uint32_t aLoadType,
|
||||
bool aCloneChildren)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (mSessionHistory) {
|
||||
/* You are currently in the rootDocShell.
|
||||
* You will get here when a subframe has a new url
|
||||
* to load and you have walked up the tree all the
|
||||
@ -4300,16 +4320,17 @@ nsDocShell::AddChildSHEntry(nsISHEntry * aCloneRef, nsISHEntry * aNewEntry,
|
||||
nsCOMPtr<nsIDocShell> parent =
|
||||
do_QueryInterface(GetAsSupports(mParent), &rv);
|
||||
if (parent) {
|
||||
rv = parent->AddChildSHEntry(aCloneRef, aNewEntry, aChildOffset,
|
||||
loadType, aCloneChildren);
|
||||
}
|
||||
rv = static_cast<nsDocShell*>(parent.get())->
|
||||
AddChildSHEntryInternal(aCloneRef, aNewEntry, aChildOffset,
|
||||
aLoadType, aCloneChildren);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::DoAddChildSHEntry(nsISHEntry* aNewEntry, int32_t aChildOffset,
|
||||
bool aCloneChildren)
|
||||
nsDocShell::AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset,
|
||||
bool aCloneChildren)
|
||||
{
|
||||
/* You will get here when you are in a subframe and
|
||||
* a new url has been loaded on you.
|
||||
@ -11653,7 +11674,7 @@ nsDocShell::AddToSessionHistory(nsIURI * aURI, nsIChannel * aChannel,
|
||||
// This is a subframe.
|
||||
if (!mOSHE || !LOAD_TYPE_HAS_FLAGS(mLoadType,
|
||||
LOAD_FLAGS_REPLACE_HISTORY))
|
||||
rv = DoAddChildSHEntry(entry, mChildOffset, aCloneChildren);
|
||||
rv = AddChildSHEntryToParent(entry, mChildOffset, aCloneChildren);
|
||||
}
|
||||
|
||||
// Return the new SH entry...
|
||||
@ -13591,6 +13612,30 @@ nsDocShell::GetURLSearchParams()
|
||||
return mURLSearchParams;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::NotifyJSRunToCompletionStart()
|
||||
{
|
||||
bool timelineOn = nsIDocShell::GetRecordProfileTimelineMarkers();
|
||||
|
||||
// If first start, mark interval start.
|
||||
if (timelineOn && mJSRunToCompletionDepth == 0) {
|
||||
AddProfileTimelineMarker("Javascript", TRACING_INTERVAL_START);
|
||||
}
|
||||
mJSRunToCompletionDepth++;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::NotifyJSRunToCompletionStop()
|
||||
{
|
||||
bool timelineOn = nsIDocShell::GetRecordProfileTimelineMarkers();
|
||||
|
||||
// If last stop, mark interval end.
|
||||
mJSRunToCompletionDepth--;
|
||||
if (timelineOn && mJSRunToCompletionDepth == 0) {
|
||||
AddProfileTimelineMarker("Javascript", TRACING_INTERVAL_END);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::MaybeNotifyKeywordSearchLoading(const nsString &aProvider,
|
||||
const nsString &aKeyword) {
|
||||
|
@ -371,8 +371,12 @@ protected:
|
||||
nsISupports* aOwner,
|
||||
bool aCloneChildren,
|
||||
nsISHEntry ** aNewEntry);
|
||||
nsresult DoAddChildSHEntry(nsISHEntry* aNewEntry, int32_t aChildOffset,
|
||||
bool aCloneChildren);
|
||||
nsresult AddChildSHEntryToParent(nsISHEntry* aNewEntry, int32_t aChildOffset,
|
||||
bool aCloneChildren);
|
||||
|
||||
nsresult AddChildSHEntryInternal(nsISHEntry* aCloneRef, nsISHEntry* aNewEntry,
|
||||
int32_t aChildOffset, uint32_t loadType,
|
||||
bool aCloneChildren);
|
||||
|
||||
NS_IMETHOD LoadHistoryEntry(nsISHEntry * aEntry, uint32_t aLoadType);
|
||||
NS_IMETHOD PersistLayoutHistoryState();
|
||||
@ -946,6 +950,10 @@ private:
|
||||
nsWeakPtr mOpener;
|
||||
nsWeakPtr mOpenedRemote;
|
||||
|
||||
// A depth count of how many times NotifyRunToCompletionStart
|
||||
// has been called without a matching NotifyRunToCompletionStop.
|
||||
uint32_t mJSRunToCompletionDepth;
|
||||
|
||||
// True if recording profiles.
|
||||
bool mProfileTimelineRecording;
|
||||
|
||||
|
@ -54,7 +54,7 @@ interface nsITabParent;
|
||||
|
||||
typedef unsigned long nsLoadFlags;
|
||||
|
||||
[scriptable, builtinclass, uuid(da8f78f1-8f20-4d6d-be56-fe53e177b630)]
|
||||
[scriptable, builtinclass, uuid(4e3de242-0b2a-4cf0-81b5-a5fe8628431c)]
|
||||
interface nsIDocShell : nsIDocShellTreeItem
|
||||
{
|
||||
/**
|
||||
@ -1026,6 +1026,14 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
// URLSearchParams for the window.location is owned by the docShell.
|
||||
[noscript,notxpcom] URLSearchParams getURLSearchParams();
|
||||
|
||||
/**
|
||||
* Notify DocShell when the browser is about to start executing JS, and after
|
||||
* that execution has stopped. This only occurs when the Timeline devtool
|
||||
* is collecting information.
|
||||
*/
|
||||
[noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStart();
|
||||
[noscript,notxpcom,nostdcall] void notifyJSRunToCompletionStop();
|
||||
|
||||
/**
|
||||
* This attribute determines whether a document which is not about:blank has
|
||||
* already be loaded by this docShell.
|
||||
|
@ -14,7 +14,7 @@ interface nsISHEntry;
|
||||
*
|
||||
*/
|
||||
|
||||
[scriptable, uuid(65281BA2-988A-11d3-BDC7-0050040A9B44)]
|
||||
[scriptable, uuid(67dd0357-8372-4122-bff6-217435e8b7e4)]
|
||||
interface nsISHContainer : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -38,5 +38,12 @@ interface nsISHContainer : nsISupports
|
||||
*/
|
||||
nsISHEntry GetChildAt(in long index);
|
||||
|
||||
/**
|
||||
* Replaces a child which is for the same docshell as aNewChild
|
||||
* with aNewChild.
|
||||
* @throw if nothing was replaced.
|
||||
*/
|
||||
void ReplaceChild(in nsISHEntry aNewChild);
|
||||
|
||||
};
|
||||
|
||||
|
@ -690,6 +690,27 @@ nsSHEntry::GetChildAt(int32_t aIndex, nsISHEntry ** aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::ReplaceChild(nsISHEntry* aNewEntry)
|
||||
{
|
||||
NS_ENSURE_STATE(aNewEntry);
|
||||
|
||||
uint64_t docshellID;
|
||||
aNewEntry->GetDocshellID(&docshellID);
|
||||
|
||||
uint64_t otherID;
|
||||
for (int32_t i = 0; i < mChildren.Count(); ++i) {
|
||||
if (mChildren[i] && NS_SUCCEEDED(mChildren[i]->GetDocshellID(&otherID)) &&
|
||||
docshellID == otherID) {
|
||||
mChildren[i]->SetParent(nullptr);
|
||||
if (mChildren.ReplaceObjectAt(aNewEntry, i)) {
|
||||
return aNewEntry->SetParent(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::AddChildShell(nsIDocShellTreeItem *aShell)
|
||||
{
|
||||
|
28
docshell/test/navigation/file_nested_frames.html
Normal file
28
docshell/test/navigation/file_nested_frames.html
Normal file
@ -0,0 +1,28 @@
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function nestedIframeLoaded() {
|
||||
var tf = document.getElementById("testframe");
|
||||
var innerf = tf.contentDocument.getElementsByTagName("iframe")[0];
|
||||
if (innerf.contentDocument.documentURI.indexOf("frame0") < 0) {
|
||||
innerf.contentWindow.location.href = "http://mochi.test:8888/tests/docshell/test/navigation/frame0.html";
|
||||
return;
|
||||
}
|
||||
innerf.onload = null;
|
||||
innerf.src = "about:blank";
|
||||
var d = innerf.contentDocument;
|
||||
d.open();
|
||||
d.write("test");
|
||||
d.close();
|
||||
opener.is(window.history.length, 1, "Unexpected history length");
|
||||
opener.nextTest();
|
||||
window.close();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="testframe" src="data:text/html,<iframe onload='parent.nestedIframeLoaded();'></iframe>" onload="frameLoaded()"></iframe>
|
||||
<script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -9,6 +9,7 @@ support-files =
|
||||
file_bug534178.html
|
||||
file_document_write_1.html
|
||||
file_fragment_handling_during_load.html
|
||||
file_nested_frames.html
|
||||
file_static_and_dynamic_1.html
|
||||
frame0.html
|
||||
frame1.html
|
||||
|
@ -27,7 +27,8 @@ var testFiles =
|
||||
"file_document_write_1.html", // Session history + document.write
|
||||
//"file_static_and_dynamic_1.html",// Static and dynamic frames and forward-back
|
||||
"file_bug534178.html", // Session history transaction clean-up.
|
||||
"file_fragment_handling_during_load.html"
|
||||
"file_fragment_handling_during_load.html",
|
||||
"file_nested_frames.html"
|
||||
];
|
||||
var testCount = 0; // Used by the test files.
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "xpcprivate.h" // For AutoCxPusher guts
|
||||
#include "xpcpublic.h"
|
||||
#include "nsIGlobalObject.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -70,8 +71,26 @@ public:
|
||||
ScriptSettingsStackEntry *entry = EntryPoint();
|
||||
return entry ? entry->mGlobalObject : nullptr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static unsigned long gRunToCompletionListeners = 0;
|
||||
|
||||
void
|
||||
UseEntryScriptProfiling()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
++gRunToCompletionListeners;
|
||||
}
|
||||
|
||||
void
|
||||
UnuseEntryScriptProfiling()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(gRunToCompletionListeners > 0);
|
||||
--gRunToCompletionListeners;
|
||||
}
|
||||
|
||||
void
|
||||
InitScriptSettings()
|
||||
{
|
||||
@ -122,10 +141,44 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry()
|
||||
ScriptSettingsStack::Pop(this);
|
||||
}
|
||||
|
||||
// If the entry or incumbent global ends up being something that the subject
|
||||
// principal doesn't subsume, we don't want to use it. This never happens on
|
||||
// the web, but can happen with asymmetric privilege relationships (i.e.
|
||||
// nsExpandedPrincipal and System Principal).
|
||||
//
|
||||
// The most correct thing to use instead would be the topmost global on the
|
||||
// callstack whose principal is subsumed by the subject principal. But that's
|
||||
// hard to compute, so we just substitute the global of the current
|
||||
// compartment. In practice, this is fine.
|
||||
//
|
||||
// Note that in particular things like:
|
||||
//
|
||||
// |SpecialPowers.wrap(crossOriginWindow).eval(open())|
|
||||
//
|
||||
// trigger this case. Although both the entry global and the current global
|
||||
// have normal principals, the use of Gecko-specific System-Principaled JS
|
||||
// puts the code from two different origins on the callstack at once, which
|
||||
// doesn't happen normally on the web.
|
||||
static nsIGlobalObject*
|
||||
ClampToSubject(nsIGlobalObject* aGlobalOrNull)
|
||||
{
|
||||
if (!aGlobalOrNull || !NS_IsMainThread()) {
|
||||
return aGlobalOrNull;
|
||||
}
|
||||
|
||||
nsIPrincipal* globalPrin = aGlobalOrNull->PrincipalOrNull();
|
||||
NS_ENSURE_TRUE(globalPrin, GetCurrentGlobal());
|
||||
if (!nsContentUtils::SubjectPrincipal()->SubsumesConsideringDomain(globalPrin)) {
|
||||
return GetCurrentGlobal();
|
||||
}
|
||||
|
||||
return aGlobalOrNull;
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
GetEntryGlobal()
|
||||
{
|
||||
return ScriptSettingsStack::EntryGlobal();
|
||||
return ClampToSubject(ScriptSettingsStack::EntryGlobal());
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
@ -163,12 +216,12 @@ GetIncumbentGlobal()
|
||||
// there's nothing on the JS stack, which will cause us to check the
|
||||
// incumbent script stack below.
|
||||
if (JSObject *global = JS::GetScriptedCallerGlobal(cx)) {
|
||||
return xpc::NativeGlobal(global);
|
||||
return ClampToSubject(xpc::NativeGlobal(global));
|
||||
}
|
||||
|
||||
// Ok, nothing from the JS engine. Let's use whatever's on the
|
||||
// explicit stack.
|
||||
return ScriptSettingsStack::IncumbentGlobal();
|
||||
return ClampToSubject(ScriptSettingsStack::IncumbentGlobal());
|
||||
}
|
||||
|
||||
nsIGlobalObject*
|
||||
@ -463,14 +516,30 @@ AutoEntryScript::AutoEntryScript(nsIGlobalObject* aGlobalObject,
|
||||
aCx ? aCx : FindJSContext(aGlobalObject))
|
||||
, ScriptSettingsStackEntry(aGlobalObject, /* aCandidate = */ true)
|
||||
, mWebIDLCallerPrincipal(nullptr)
|
||||
, mDocShellForJSRunToCompletion(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aGlobalObject);
|
||||
MOZ_ASSERT_IF(!aCx, aIsMainThread); // cx is mandatory off-main-thread.
|
||||
MOZ_ASSERT_IF(aCx && aIsMainThread, aCx == FindJSContext(aGlobalObject));
|
||||
|
||||
if (aIsMainThread && gRunToCompletionListeners > 0) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobalObject);
|
||||
if (window) {
|
||||
mDocShellForJSRunToCompletion = window->GetDocShell();
|
||||
}
|
||||
}
|
||||
|
||||
if (mDocShellForJSRunToCompletion) {
|
||||
mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStart();
|
||||
}
|
||||
}
|
||||
|
||||
AutoEntryScript::~AutoEntryScript()
|
||||
{
|
||||
if (mDocShellForJSRunToCompletion) {
|
||||
mDocShellForJSRunToCompletion->NotifyJSRunToCompletionStop();
|
||||
}
|
||||
|
||||
// GC when we pop a script entry point. This is a useful heuristic that helps
|
||||
// us out on certain (flawed) benchmarks like sunspider, because it lets us
|
||||
// avoid GCing during the timing loop.
|
||||
|
@ -21,6 +21,7 @@ class nsPIDOMWindow;
|
||||
class nsGlobalWindow;
|
||||
class nsIScriptContext;
|
||||
class nsIDocument;
|
||||
class nsIDocShell;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -63,6 +64,16 @@ private:
|
||||
void InitScriptSettings();
|
||||
void DestroyScriptSettings();
|
||||
|
||||
/*
|
||||
* Static helpers in ScriptSettings which track the number of listeners
|
||||
* of Javascript RunToCompletion events. These should be used by the code in
|
||||
* nsDocShell::SetRecordProfileTimelineMarkers to indicate to script
|
||||
* settings that script run-to-completion needs to be monitored.
|
||||
* SHOULD BE CALLED ONLY BY MAIN THREAD.
|
||||
*/
|
||||
void UseEntryScriptProfiling();
|
||||
void UnuseEntryScriptProfiling();
|
||||
|
||||
// To implement a web-compatible browser, it is often necessary to obtain the
|
||||
// global object that is "associated" with the currently-running code. This
|
||||
// process is made more complicated by the fact that, historically, different
|
||||
@ -331,6 +342,8 @@ private:
|
||||
// can't go away until then either.
|
||||
nsIPrincipal* mWebIDLCallerPrincipal;
|
||||
friend nsIPrincipal* GetWebIDLCallerPrincipal();
|
||||
|
||||
nsIDocShell* mDocShellForJSRunToCompletion;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -415,8 +415,6 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
|
||||
float aTopMargin,
|
||||
float aRightMargin,
|
||||
float aBottomMargin,
|
||||
uint32_t aAlignmentX,
|
||||
uint32_t aAlignmentY,
|
||||
nsIDOMElement* aElement,
|
||||
uint32_t aPriority)
|
||||
{
|
||||
@ -451,7 +449,7 @@ nsDOMWindowUtils::SetDisplayPortMarginsForElement(float aLeftMargin,
|
||||
aLeftMargin);
|
||||
|
||||
nsLayoutUtils::SetDisplayPortMargins(content, presShell, displayportMargins,
|
||||
aAlignmentX, aAlignmentY, aPriority);
|
||||
aPriority);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2412,9 +2412,10 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
|
||||
bool thisChrome = IsChromeWindow();
|
||||
|
||||
// Check if we're near the stack limit before we get anywhere near the
|
||||
// transplanting code. We use a conservative check since we'll use a little
|
||||
// more space before we actually hit the critical "can't fail" path.
|
||||
// Check if we're anywhere near the stack limit before we reach the
|
||||
// transplanting code, since it has no good way to handle errors. This uses
|
||||
// the untrusted script limit, which is not strictly necessary since no
|
||||
// actual script should run.
|
||||
JS_CHECK_RECURSION_CONSERVATIVE(cx, return NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<WindowStateHolder> wsh = do_QueryInterface(aState);
|
||||
@ -7783,46 +7784,15 @@ nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames)
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
|
||||
JSObject* nsGlobalWindow::CallerGlobal()
|
||||
{
|
||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||
if (!cx) {
|
||||
NS_ERROR("Please don't call this method from C++!");
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// If somebody does sameOriginIframeWindow.postMessage(...), they probably
|
||||
// expect the .source attribute of the resulting message event to be |window|
|
||||
// rather than |sameOriginIframeWindow|, even though the transparent wrapper
|
||||
// semantics of same-origin access will cause us to be in the iframe's
|
||||
// compartment at the time of the call. This means that we want the incumbent
|
||||
// global here, rather than the global of the current compartment.
|
||||
//
|
||||
// There are various edge cases in which the incumbent global and the current
|
||||
// global would not be same-origin. They include:
|
||||
// * A privileged caller (System Principal or Expanded Principal) manipulating
|
||||
// less-privileged content via Xray Waivers.
|
||||
// * An unprivileged caller invoking a cross-origin function that was exposed
|
||||
// to it by privileged code (i.e. Sandbox.importFunction).
|
||||
//
|
||||
// In these cases, we probably don't want the privileged global appearing in the
|
||||
// .source attribute. So we fall back to the compartment global there.
|
||||
JS::Rooted<JSObject*> incumbentGlobal(cx, &IncumbentJSGlobal());
|
||||
JS::Rooted<JSObject*> compartmentGlobal(cx, JS::CurrentGlobalOrNull(cx));
|
||||
nsIPrincipal* incumbentPrin = nsContentUtils::ObjectPrincipal(incumbentGlobal);
|
||||
nsIPrincipal* compartmentPrin = nsContentUtils::ObjectPrincipal(compartmentGlobal);
|
||||
return incumbentPrin->EqualsConsideringDomain(compartmentPrin) ? incumbentGlobal
|
||||
: compartmentGlobal;
|
||||
}
|
||||
|
||||
|
||||
nsGlobalWindow*
|
||||
nsGlobalWindow::CallerInnerWindow()
|
||||
{
|
||||
JSContext *cx = nsContentUtils::GetCurrentJSContext();
|
||||
NS_ENSURE_TRUE(cx, nullptr);
|
||||
JS::Rooted<JSObject*> scope(cx, CallerGlobal());
|
||||
nsIGlobalObject* global = GetIncumbentGlobal();
|
||||
NS_ENSURE_TRUE(global, nullptr);
|
||||
JS::Rooted<JSObject*> scope(cx, global->GetGlobalJSObject());
|
||||
NS_ENSURE_TRUE(scope, nullptr);
|
||||
|
||||
// When Jetpack runs content scripts inside a sandbox, it uses
|
||||
// sandboxPrototype to make them appear as though they're running in the
|
||||
@ -7830,7 +7800,7 @@ nsGlobalWindow::CallerInnerWindow()
|
||||
// the |source| of the received message to be the window set as the
|
||||
// sandboxPrototype. This used to work incidentally for unrelated reasons, but
|
||||
// now we need to do some special handling to support it.
|
||||
{
|
||||
if (xpc::IsSandbox(scope)) {
|
||||
JSAutoCompartment ac(cx, scope);
|
||||
JS::Rooted<JSObject*> scopeProto(cx);
|
||||
bool ok = JS_GetPrototype(cx, scope, &scopeProto);
|
||||
@ -7838,26 +7808,14 @@ nsGlobalWindow::CallerInnerWindow()
|
||||
if (scopeProto && xpc::IsSandboxPrototypeProxy(scopeProto) &&
|
||||
(scopeProto = js::CheckedUnwrap(scopeProto, /* stopAtOuter = */ false)))
|
||||
{
|
||||
scope = scopeProto;
|
||||
global = xpc::NativeGlobal(scopeProto);
|
||||
NS_ENSURE_TRUE(global, nullptr);
|
||||
}
|
||||
}
|
||||
JSAutoCompartment ac(cx, scope);
|
||||
|
||||
// We don't use xpc::WindowOrNull here because we want to be able to tell
|
||||
// apart the cases of "scope is not an nsISupports at all" and "scope is an
|
||||
// nsISupports that's not a window". It's not clear whether that's desirable,
|
||||
// see bug 984467.
|
||||
nsISupports* native =
|
||||
nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, scope);
|
||||
if (!native)
|
||||
return nullptr;
|
||||
|
||||
// The calling window must be holding a reference, so we can just return a
|
||||
// raw pointer here and let the QI's addref be balanced by the nsCOMPtr
|
||||
// destructor's release.
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(native);
|
||||
if (!win)
|
||||
return GetCurrentInnerWindowInternal();
|
||||
// The calling window must be holding a reference, so we can return a weak
|
||||
// pointer.
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(global);
|
||||
return static_cast<nsGlobalWindow*>(win.get());
|
||||
}
|
||||
|
||||
@ -8258,10 +8216,9 @@ nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
else {
|
||||
// In case the global is not a window, it can be a sandbox, and the sandbox's
|
||||
// principal can be used for the security check.
|
||||
JSObject *global = CallerGlobal();
|
||||
nsIGlobalObject* global = GetIncumbentGlobal();
|
||||
NS_ASSERTION(global, "Why is there no global object?");
|
||||
JSCompartment *compartment = js::GetObjectCompartment(global);
|
||||
callerPrin = xpc::GetCompartmentPrincipal(compartment);
|
||||
callerPrin = global->PrincipalOrNull();
|
||||
}
|
||||
if (!callerPrin) {
|
||||
return;
|
||||
@ -12023,6 +11980,9 @@ nsGlobalWindow::InnerForSetTimeoutOrInterval(ErrorResult& aError)
|
||||
// inner window that's calling window.setTimeout().
|
||||
|
||||
forwardTo = CallerInnerWindow();
|
||||
if (!forwardTo && nsContentUtils::IsCallerChrome()) {
|
||||
forwardTo = currentInner;
|
||||
}
|
||||
if (!forwardTo) {
|
||||
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
@ -12241,14 +12201,15 @@ nsGlobalWindow::SetTimeoutOrInterval(bool aIsInterval, int32_t *aReturn)
|
||||
|
||||
if (IsOuterWindow()) {
|
||||
nsGlobalWindow* callerInner = CallerInnerWindow();
|
||||
NS_ENSURE_TRUE(callerInner, NS_ERROR_NOT_AVAILABLE);
|
||||
NS_ENSURE_TRUE(callerInner || nsContentUtils::IsCallerChrome(), NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// If the caller and the callee share the same outer window,
|
||||
// forward to the callee inner. Else, we forward to the current
|
||||
// inner (e.g. someone is calling setTimeout() on a reference to
|
||||
// some other window).
|
||||
|
||||
if (callerInner->GetOuterWindow() == this &&
|
||||
if (callerInner &&
|
||||
callerInner->GetOuterWindow() == this &&
|
||||
callerInner->IsInnerWindow()) {
|
||||
return callerInner->SetTimeoutOrInterval(aIsInterval, aReturn);
|
||||
}
|
||||
|
@ -1092,7 +1092,6 @@ protected:
|
||||
}
|
||||
|
||||
void FreeInnerObjects();
|
||||
JSObject *CallerGlobal();
|
||||
nsGlobalWindow *CallerInnerWindow();
|
||||
|
||||
// Only to be called on an inner window.
|
||||
|
@ -1984,6 +1984,11 @@ ToCanonicalSupports(nsINode* aPointer)
|
||||
aLocalName = nsINode::LocalName(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD UnusedPlaceholder(bool* aResult) __VA_ARGS__ \
|
||||
{ \
|
||||
*aResult = false; \
|
||||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ \
|
||||
{ \
|
||||
nsINode::GetBaseURI(aBaseURI); \
|
||||
|
@ -1698,9 +1698,10 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
|
||||
{
|
||||
js::AssertSameCompartment(aCx, aObjArg);
|
||||
|
||||
// Check if we're near the stack limit before we get anywhere near the
|
||||
// transplanting code. We use a conservative check since we'll use a little
|
||||
// more space before we actually hit the critical "can't fail" path.
|
||||
// Check if we're anywhere near the stack limit before we reach the
|
||||
// transplanting code, since it has no good way to handle errors. This uses
|
||||
// the untrusted script limit, which is not strictly necessary since no
|
||||
// actual script should run.
|
||||
JS_CHECK_RECURSION_CONSERVATIVE(aCx, return NS_ERROR_FAILURE);
|
||||
|
||||
JS::Rooted<JSObject*> aObj(aCx, aObjArg);
|
||||
|
@ -66,10 +66,10 @@ ToJSValue(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue)
|
||||
{
|
||||
MOZ_ASSERT(aArgument.Failed());
|
||||
ThrowMethodFailedWithDetails(aCx, aArgument, "", "");
|
||||
if (!JS_GetPendingException(aCx, aValue)) {
|
||||
return false;
|
||||
}
|
||||
DebugOnly<bool> throwResult = ThrowMethodFailedWithDetails(aCx, aArgument, "", "");
|
||||
MOZ_ASSERT(!throwResult);
|
||||
DebugOnly<bool> getPendingResult = JS_GetPendingException(aCx, aValue);
|
||||
MOZ_ASSERT(getPendingResult);
|
||||
JS_ClearPendingException(aCx);
|
||||
return true;
|
||||
}
|
||||
|
@ -767,7 +767,7 @@ skip-if = (os == 'android') || (os == 'b2g') || (os == 'linux')
|
||||
[webgl-conformance/_wrappers/test_conformance__textures__texture-formats-test.html]
|
||||
[webgl-conformance/_wrappers/test_conformance__textures__texture-mips.html]
|
||||
[webgl-conformance/_wrappers/test_conformance__textures__texture-npot-video.html]
|
||||
skip-if = os == 'win'
|
||||
skip-if = os == 'win' || buildapp == 'mulet' # Mulet - bug 1089453 (crashes in libLLVM-3.0.so)
|
||||
[webgl-conformance/_wrappers/test_conformance__textures__texture-npot.html]
|
||||
[webgl-conformance/_wrappers/test_conformance__textures__texture-size.html]
|
||||
skip-if = os == 'android'
|
||||
|
@ -12,7 +12,7 @@ fail-if = (os == 'b2g')
|
||||
[webgl-mochitest/test_fb_param.html]
|
||||
[webgl-mochitest/test_fb_param_crash.html]
|
||||
[webgl-mochitest/test_hidden_alpha.html]
|
||||
fail-if = (os == 'b2g')
|
||||
skip-if = (os == 'b2g') || buildapp == 'mulet' # Mulet - bug 1093639 (crashes in libLLVM-3.0.so)
|
||||
[webgl-mochitest/test_highp_fs.html]
|
||||
[webgl-mochitest/test_no_arr_points.html]
|
||||
skip-if = android_version == '10' #Android 2.3 aws only; bug 1030942
|
||||
|
@ -1032,11 +1032,12 @@ UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc,
|
||||
nsCOMPtr<nsIContentPrefCallback2> prefCallback =
|
||||
new UploadLastDir::ContentPrefCallback(aFilePicker, aFpCallback);
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
// FIXME (bug 949666): Run this code in the parent process.
|
||||
prefCallback->HandleCompletion(nsIContentPrefCallback2::COMPLETE_ERROR);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Attempt to get the CPS, if it's not present we'll fallback to use the Desktop folder
|
||||
nsCOMPtr<nsIContentPrefService2> contentPrefService =
|
||||
@ -1062,10 +1063,11 @@ UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_B2G
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
// FIXME (bug 949666): Run this code in the parent process.
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI();
|
||||
NS_PRECONDITION(docURI, "docURI is null");
|
||||
|
@ -51,7 +51,7 @@ interface nsITranslationNodeList;
|
||||
interface nsIJSRAIIHelper;
|
||||
interface nsIContentPermissionRequest;
|
||||
|
||||
[scriptable, uuid(e293355b-ae7f-4ef7-9237-452bcf3e9e6b)]
|
||||
[scriptable, uuid(9621eb05-b498-4e87-a012-95d817987624)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -188,8 +188,6 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
in float aTopMargin,
|
||||
in float aRightMargin,
|
||||
in float aBottomMargin,
|
||||
in uint32_t aAlignmentX,
|
||||
in uint32_t aAlignmentY,
|
||||
in nsIDOMElement aElement,
|
||||
in uint32_t aPriority);
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* http://www.w3.org/TR/DOM-Level-2-Core/
|
||||
*/
|
||||
|
||||
[builtinclass, uuid(7d0582bd-09a7-430e-969b-054abbea19fe)]
|
||||
[builtinclass, uuid(7db491e8-a3a3-4432-ad67-e6c33e24ac6d)]
|
||||
interface nsIDOMAttr : nsIDOMNode
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
|
@ -15,7 +15,7 @@
|
||||
* http://www.w3.org/TR/DOM-Level-2-Core/
|
||||
*/
|
||||
|
||||
[uuid(4ac42d40-69b7-4506-b730-c41ec74b74bd)]
|
||||
[uuid(e14ef131-34cc-40c8-9c99-a403c001184a)]
|
||||
interface nsIDOMCDATASection : nsIDOMText
|
||||
{
|
||||
};
|
||||
|
@ -13,7 +13,7 @@
|
||||
* http://www.w3.org/TR/DOM-Level-2-Core/
|
||||
*/
|
||||
|
||||
[uuid(844b8e7e-6d37-4fa1-8196-86e3afdfa0ca)]
|
||||
[uuid(4109a2d2-e7af-445d-bb72-c7c9b875f35e)]
|
||||
interface nsIDOMCharacterData : nsIDOMNode
|
||||
{
|
||||
attribute DOMString data;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* http://www.w3.org/TR/DOM-Level-2-Core/
|
||||
*/
|
||||
|
||||
[uuid(c1a1d2ea-e106-4ee8-806d-2633468e8098)]
|
||||
[uuid(e7866ff8-b7fc-494f-87c0-fb017d8a4d30)]
|
||||
interface nsIDOMComment : nsIDOMCharacterData
|
||||
{
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ interface nsIDOMLocation;
|
||||
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
|
||||
*/
|
||||
|
||||
[uuid(08c6400b-0b6d-4ce6-b88d-e7a15a9c7c03)]
|
||||
[uuid(35dc5030-dc83-4291-88a2-0906c549788e)]
|
||||
interface nsIDOMDocument : nsIDOMNode
|
||||
{
|
||||
readonly attribute nsIDOMDocumentType doctype;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user