зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound a=merge
This commit is contained in:
Коммит
b0f3436ee5
|
@ -18,7 +18,7 @@ loop.conversation = (function(mozL10n) {
|
|||
|
||||
var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
|
||||
var CallIdentifierView = loop.conversationViews.CallIdentifierView;
|
||||
var DesktopRoomView = loop.roomViews.DesktopRoomView;
|
||||
var DesktopRoomControllerView = loop.roomViews.DesktopRoomControllerView;
|
||||
|
||||
var IncomingCallView = React.createClass({displayName: 'IncomingCallView',
|
||||
mixins: [sharedMixins.DropdownMenuMixin, sharedMixins.AudioMixin],
|
||||
|
@ -584,8 +584,9 @@ loop.conversation = (function(mozL10n) {
|
|||
));
|
||||
}
|
||||
case "room": {
|
||||
return (DesktopRoomView({
|
||||
return (DesktopRoomControllerView({
|
||||
mozLoop: navigator.mozLoop,
|
||||
dispatcher: this.props.dispatcher,
|
||||
roomStore: this.props.roomStore}
|
||||
));
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ loop.conversation = (function(mozL10n) {
|
|||
|
||||
var OutgoingConversationView = loop.conversationViews.OutgoingConversationView;
|
||||
var CallIdentifierView = loop.conversationViews.CallIdentifierView;
|
||||
var DesktopRoomView = loop.roomViews.DesktopRoomView;
|
||||
var DesktopRoomControllerView = loop.roomViews.DesktopRoomControllerView;
|
||||
|
||||
var IncomingCallView = React.createClass({
|
||||
mixins: [sharedMixins.DropdownMenuMixin, sharedMixins.AudioMixin],
|
||||
|
@ -584,8 +584,9 @@ loop.conversation = (function(mozL10n) {
|
|||
/>);
|
||||
}
|
||||
case "room": {
|
||||
return (<DesktopRoomView
|
||||
return (<DesktopRoomControllerView
|
||||
mozLoop={navigator.mozLoop}
|
||||
dispatcher={this.props.dispatcher}
|
||||
roomStore={this.props.roomStore}
|
||||
/>);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* 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/. */
|
||||
|
||||
/* jshint newcap:false */
|
||||
/* global loop:true, React */
|
||||
|
||||
var loop = loop || {};
|
||||
|
@ -11,17 +12,19 @@ loop.roomViews = (function(mozL10n) {
|
|||
"use strict";
|
||||
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var sharedViews = loop.shared.views;
|
||||
|
||||
var DesktopRoomView = React.createClass({displayName: 'DesktopRoomView',
|
||||
mixins: [Backbone.Events, loop.shared.mixins.DocumentTitleMixin],
|
||||
function noop() {}
|
||||
|
||||
/**
|
||||
* ActiveRoomStore mixin.
|
||||
* @type {Object}
|
||||
*/
|
||||
var ActiveRoomStoreMixin = {
|
||||
mixins: [Backbone.Events],
|
||||
|
||||
propTypes: {
|
||||
mozLoop: React.PropTypes.object.isRequired,
|
||||
roomStore: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return this.props.roomStore.getStoreState("activeRoom");
|
||||
roomStore: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
|
@ -29,48 +32,175 @@ loop.roomViews = (function(mozL10n) {
|
|||
this._onActiveRoomStateChanged);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles a "change" event on the roomStore, and updates this.state
|
||||
* to match the store.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onActiveRoomStateChanged: function() {
|
||||
this.setState(this.props.roomStore.getStoreState("activeRoom"));
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this.stopListening(this.props.roomStore);
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes the window if the cancel button is pressed in the generic failure view.
|
||||
*/
|
||||
_onActiveRoomStateChanged: function() {
|
||||
this.setState(this.props.roomStore.getStoreState("activeRoom"));
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return this.props.roomStore.getStoreState("activeRoom");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Desktop room invitation view (overlay).
|
||||
*/
|
||||
var DesktopRoomInvitationView = React.createClass({displayName: 'DesktopRoomInvitationView',
|
||||
mixins: [ActiveRoomStoreMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
|
||||
},
|
||||
|
||||
handleFormSubmit: function(event) {
|
||||
event.preventDefault();
|
||||
// XXX
|
||||
},
|
||||
|
||||
handleEmailButtonClick: function(event) {
|
||||
event.preventDefault();
|
||||
// XXX
|
||||
},
|
||||
|
||||
handleCopyButtonClick: function(event) {
|
||||
event.preventDefault();
|
||||
// XXX
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
React.DOM.div({className: "room-conversation-wrapper"},
|
||||
React.DOM.div({className: "room-invitation-overlay"},
|
||||
React.DOM.form({onSubmit: this.handleFormSubmit},
|
||||
React.DOM.input({type: "text", ref: "roomName",
|
||||
placeholder: mozL10n.get("rooms_name_this_room_label")})
|
||||
),
|
||||
React.DOM.p(null, mozL10n.get("invite_header_text")),
|
||||
React.DOM.div({className: "btn-group call-action-group"},
|
||||
React.DOM.button({className: "btn btn-info btn-email",
|
||||
onClick: this.handleEmailButtonClick},
|
||||
mozL10n.get("share_button2")
|
||||
),
|
||||
React.DOM.button({className: "btn btn-info btn-copy",
|
||||
onClick: this.handleCopyButtonClick},
|
||||
mozL10n.get("copy_url_button2")
|
||||
)
|
||||
)
|
||||
),
|
||||
DesktopRoomConversationView({roomStore: this.props.roomStore})
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Desktop room conversation view.
|
||||
*/
|
||||
var DesktopRoomConversationView = React.createClass({displayName: 'DesktopRoomConversationView',
|
||||
mixins: [ActiveRoomStoreMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
video: React.PropTypes.object,
|
||||
audio: React.PropTypes.object,
|
||||
displayInvitation: React.PropTypes.bool
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
video: {enabled: true, visible: true},
|
||||
audio: {enabled: true, visible: true}
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var localStreamClasses = React.addons.classSet({
|
||||
local: true,
|
||||
"local-stream": true,
|
||||
"local-stream-audio": !this.props.video.enabled
|
||||
});
|
||||
return (
|
||||
React.DOM.div({className: "room-conversation-wrapper"},
|
||||
React.DOM.div({className: "video-layout-wrapper"},
|
||||
React.DOM.div({className: "conversation room-conversation"},
|
||||
React.DOM.div({className: "media nested"},
|
||||
React.DOM.div({className: "video_wrapper remote_wrapper"},
|
||||
React.DOM.div({className: "video_inner remote"})
|
||||
),
|
||||
React.DOM.div({className: localStreamClasses})
|
||||
),
|
||||
sharedViews.ConversationToolbar({
|
||||
video: this.props.video,
|
||||
audio: this.props.audio,
|
||||
publishStream: noop,
|
||||
hangup: noop})
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Desktop room controller view.
|
||||
*/
|
||||
var DesktopRoomControllerView = React.createClass({displayName: 'DesktopRoomControllerView',
|
||||
mixins: [ActiveRoomStoreMixin, loop.shared.mixins.DocumentTitleMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
|
||||
},
|
||||
|
||||
closeWindow: function() {
|
||||
window.close();
|
||||
},
|
||||
|
||||
_renderRoomView: function(roomState) {
|
||||
switch (roomState) {
|
||||
case ROOM_STATES.FAILED: {
|
||||
return loop.conversation.GenericFailureView({
|
||||
cancelCall: this.closeWindow}
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.INIT:
|
||||
case ROOM_STATES.GATHER:
|
||||
case ROOM_STATES.READY:
|
||||
case ROOM_STATES.JOINED: {
|
||||
return DesktopRoomInvitationView({
|
||||
dispatcher: this.props.dispatcher,
|
||||
roomStore: this.props.roomStore}
|
||||
);
|
||||
}
|
||||
// XXX needs bug 1074686/1074702
|
||||
case ROOM_STATES.HAS_PARTICIPANTS: {
|
||||
return DesktopRoomConversationView({
|
||||
dispatcher: this.props.dispatcher,
|
||||
roomStore: this.props.roomStore}
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.roomName) {
|
||||
this.setTitle(this.state.roomName);
|
||||
}
|
||||
|
||||
if (this.state.roomState === ROOM_STATES.FAILED) {
|
||||
return (loop.conversation.GenericFailureView({
|
||||
cancelCall: this.closeWindow}
|
||||
));
|
||||
}
|
||||
|
||||
return (
|
||||
React.DOM.div(null,
|
||||
React.DOM.div(null, mozL10n.get("invite_header_text"))
|
||||
React.DOM.div({className: "room-conversation-wrapper"},
|
||||
this._renderRoomView(this.state.roomState)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
DesktopRoomView: DesktopRoomView
|
||||
ActiveRoomStoreMixin: ActiveRoomStoreMixin,
|
||||
DesktopRoomControllerView: DesktopRoomControllerView,
|
||||
DesktopRoomConversationView: DesktopRoomConversationView,
|
||||
DesktopRoomInvitationView: DesktopRoomInvitationView
|
||||
};
|
||||
|
||||
})(document.mozL10n || navigator.mozL10n);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* 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/. */
|
||||
|
||||
/* jshint newcap:false */
|
||||
/* global loop:true, React */
|
||||
|
||||
var loop = loop || {};
|
||||
|
@ -11,17 +12,19 @@ loop.roomViews = (function(mozL10n) {
|
|||
"use strict";
|
||||
|
||||
var ROOM_STATES = loop.store.ROOM_STATES;
|
||||
var sharedViews = loop.shared.views;
|
||||
|
||||
var DesktopRoomView = React.createClass({
|
||||
mixins: [Backbone.Events, loop.shared.mixins.DocumentTitleMixin],
|
||||
function noop() {}
|
||||
|
||||
/**
|
||||
* ActiveRoomStore mixin.
|
||||
* @type {Object}
|
||||
*/
|
||||
var ActiveRoomStoreMixin = {
|
||||
mixins: [Backbone.Events],
|
||||
|
||||
propTypes: {
|
||||
mozLoop: React.PropTypes.object.isRequired,
|
||||
roomStore: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired,
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return this.props.roomStore.getStoreState("activeRoom");
|
||||
roomStore: React.PropTypes.instanceOf(loop.store.RoomStore).isRequired
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
|
@ -29,48 +32,175 @@ loop.roomViews = (function(mozL10n) {
|
|||
this._onActiveRoomStateChanged);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handles a "change" event on the roomStore, and updates this.state
|
||||
* to match the store.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onActiveRoomStateChanged: function() {
|
||||
this.setState(this.props.roomStore.getStoreState("activeRoom"));
|
||||
},
|
||||
|
||||
componentWillUnmount: function() {
|
||||
this.stopListening(this.props.roomStore);
|
||||
},
|
||||
|
||||
/**
|
||||
* Closes the window if the cancel button is pressed in the generic failure view.
|
||||
*/
|
||||
_onActiveRoomStateChanged: function() {
|
||||
this.setState(this.props.roomStore.getStoreState("activeRoom"));
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
return this.props.roomStore.getStoreState("activeRoom");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Desktop room invitation view (overlay).
|
||||
*/
|
||||
var DesktopRoomInvitationView = React.createClass({
|
||||
mixins: [ActiveRoomStoreMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
|
||||
},
|
||||
|
||||
handleFormSubmit: function(event) {
|
||||
event.preventDefault();
|
||||
// XXX
|
||||
},
|
||||
|
||||
handleEmailButtonClick: function(event) {
|
||||
event.preventDefault();
|
||||
// XXX
|
||||
},
|
||||
|
||||
handleCopyButtonClick: function(event) {
|
||||
event.preventDefault();
|
||||
// XXX
|
||||
},
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="room-conversation-wrapper">
|
||||
<div className="room-invitation-overlay">
|
||||
<form onSubmit={this.handleFormSubmit}>
|
||||
<input type="text" ref="roomName"
|
||||
placeholder={mozL10n.get("rooms_name_this_room_label")} />
|
||||
</form>
|
||||
<p>{mozL10n.get("invite_header_text")}</p>
|
||||
<div className="btn-group call-action-group">
|
||||
<button className="btn btn-info btn-email"
|
||||
onClick={this.handleEmailButtonClick}>
|
||||
{mozL10n.get("share_button2")}
|
||||
</button>
|
||||
<button className="btn btn-info btn-copy"
|
||||
onClick={this.handleCopyButtonClick}>
|
||||
{mozL10n.get("copy_url_button2")}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<DesktopRoomConversationView roomStore={this.props.roomStore} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Desktop room conversation view.
|
||||
*/
|
||||
var DesktopRoomConversationView = React.createClass({
|
||||
mixins: [ActiveRoomStoreMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
video: React.PropTypes.object,
|
||||
audio: React.PropTypes.object,
|
||||
displayInvitation: React.PropTypes.bool
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
video: {enabled: true, visible: true},
|
||||
audio: {enabled: true, visible: true}
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var localStreamClasses = React.addons.classSet({
|
||||
local: true,
|
||||
"local-stream": true,
|
||||
"local-stream-audio": !this.props.video.enabled
|
||||
});
|
||||
return (
|
||||
<div className="room-conversation-wrapper">
|
||||
<div className="video-layout-wrapper">
|
||||
<div className="conversation room-conversation">
|
||||
<div className="media nested">
|
||||
<div className="video_wrapper remote_wrapper">
|
||||
<div className="video_inner remote"></div>
|
||||
</div>
|
||||
<div className={localStreamClasses}></div>
|
||||
</div>
|
||||
<sharedViews.ConversationToolbar
|
||||
video={this.props.video}
|
||||
audio={this.props.audio}
|
||||
publishStream={noop}
|
||||
hangup={noop} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Desktop room controller view.
|
||||
*/
|
||||
var DesktopRoomControllerView = React.createClass({
|
||||
mixins: [ActiveRoomStoreMixin, loop.shared.mixins.DocumentTitleMixin],
|
||||
|
||||
propTypes: {
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired
|
||||
},
|
||||
|
||||
closeWindow: function() {
|
||||
window.close();
|
||||
},
|
||||
|
||||
_renderRoomView: function(roomState) {
|
||||
switch (roomState) {
|
||||
case ROOM_STATES.FAILED: {
|
||||
return <loop.conversation.GenericFailureView
|
||||
cancelCall={this.closeWindow}
|
||||
/>;
|
||||
}
|
||||
case ROOM_STATES.INIT:
|
||||
case ROOM_STATES.GATHER:
|
||||
case ROOM_STATES.READY:
|
||||
case ROOM_STATES.JOINED: {
|
||||
return <DesktopRoomInvitationView
|
||||
dispatcher={this.props.dispatcher}
|
||||
roomStore={this.props.roomStore}
|
||||
/>;
|
||||
}
|
||||
// XXX needs bug 1074686/1074702
|
||||
case ROOM_STATES.HAS_PARTICIPANTS: {
|
||||
return <DesktopRoomConversationView
|
||||
dispatcher={this.props.dispatcher}
|
||||
roomStore={this.props.roomStore}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.roomName) {
|
||||
this.setTitle(this.state.roomName);
|
||||
}
|
||||
|
||||
if (this.state.roomState === ROOM_STATES.FAILED) {
|
||||
return (<loop.conversation.GenericFailureView
|
||||
cancelCall={this.closeWindow}
|
||||
/>);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div>{mozL10n.get("invite_header_text")}</div>
|
||||
</div>
|
||||
<div className="room-conversation-wrapper">{
|
||||
this._renderRoomView(this.state.roomState)
|
||||
}</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
DesktopRoomView: DesktopRoomView
|
||||
ActiveRoomStoreMixin: ActiveRoomStoreMixin,
|
||||
DesktopRoomControllerView: DesktopRoomControllerView,
|
||||
DesktopRoomConversationView: DesktopRoomConversationView,
|
||||
DesktopRoomInvitationView: DesktopRoomInvitationView
|
||||
};
|
||||
|
||||
})(document.mozL10n || navigator.mozL10n);
|
||||
|
|
|
@ -677,3 +677,51 @@ html, .fx-embedded, #main,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rooms
|
||||
*/
|
||||
|
||||
.room-conversation-wrapper {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the hangup button for room conversations.
|
||||
*/
|
||||
.room-conversation .conversation-toolbar .btn-hangup-entry {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.room-invitation-overlay {
|
||||
position: absolute;
|
||||
background: rgba(0, 0, 0, .6);
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
z-index: 1010;
|
||||
}
|
||||
|
||||
.room-invitation-overlay form {
|
||||
padding: 8em 0 2.5em 0;
|
||||
}
|
||||
|
||||
.room-invitation-overlay input[type="text"] {
|
||||
display: block;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
color: #fff;
|
||||
font-size: 1.2em;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
padding: .5em;
|
||||
width: 200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.room-invitation-overlay .btn-group {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
|
|
@ -21,7 +21,9 @@ loop.store.ActiveRoomStore = (function() {
|
|||
// The room is known to be joined on the loop-server
|
||||
JOINED: "room-joined",
|
||||
// There was an issue with the room
|
||||
FAILED: "room-failed"
|
||||
FAILED: "room-failed",
|
||||
// XXX to be implemented in bug 1074686/1074702
|
||||
HAS_PARTICIPANTS: "room-has-participants"
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -144,7 +144,8 @@ loop.shared.mixins = (function() {
|
|||
_audioRequest: null,
|
||||
|
||||
_isLoopDesktop: function() {
|
||||
return typeof rootObject.navigator.mozLoop === "object";
|
||||
return rootObject.navigator &&
|
||||
typeof rootObject.navigator.mozLoop === "object";
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -108,7 +108,7 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
var cx = React.addons.classSet;
|
||||
return (
|
||||
React.DOM.ul({className: "conversation-toolbar"},
|
||||
React.DOM.li({className: "conversation-toolbar-btn-box"},
|
||||
React.DOM.li({className: "conversation-toolbar-btn-box btn-hangup-entry"},
|
||||
React.DOM.button({className: "btn btn-hangup", onClick: this.handleClickHangup,
|
||||
title: l10n.get("hangup_button_title")},
|
||||
l10n.get("hangup_button_caption2")
|
||||
|
|
|
@ -108,7 +108,7 @@ loop.shared.views = (function(_, OT, l10n) {
|
|||
var cx = React.addons.classSet;
|
||||
return (
|
||||
<ul className="conversation-toolbar">
|
||||
<li className="conversation-toolbar-btn-box">
|
||||
<li className="conversation-toolbar-btn-box btn-hangup-entry">
|
||||
<button className="btn btn-hangup" onClick={this.handleClickHangup}
|
||||
title={l10n.get("hangup_button_title")}>
|
||||
{l10n.get("hangup_button_caption2")}
|
||||
|
|
|
@ -214,7 +214,7 @@ describe("loop.conversation", function() {
|
|||
ccView = mountTestComponent();
|
||||
|
||||
TestUtils.findRenderedComponentWithType(ccView,
|
||||
loop.roomViews.DesktopRoomView);
|
||||
loop.roomViews.DesktopRoomControllerView);
|
||||
});
|
||||
|
||||
it("should display the GenericFailureView for failures", function() {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
var expect = chai.expect;
|
||||
|
||||
/* jshint newcap:false */
|
||||
|
||||
describe("loop.roomViews", function () {
|
||||
"use strict";
|
||||
|
||||
|
@ -28,7 +30,6 @@ describe("loop.roomViews", function () {
|
|||
return x;
|
||||
});
|
||||
|
||||
|
||||
activeRoomStore = new loop.store.ActiveRoomStore({
|
||||
dispatcher: dispatcher,
|
||||
mozLoop: {}
|
||||
|
@ -45,12 +46,47 @@ describe("loop.roomViews", function () {
|
|||
loop.shared.mixins.setRootObject(window);
|
||||
});
|
||||
|
||||
describe("DesktopRoomView", function() {
|
||||
describe("ActiveRoomStoreMixin", function() {
|
||||
it("should merge initial state", function() {
|
||||
var TestView = React.createClass({
|
||||
mixins: [loop.roomViews.ActiveRoomStoreMixin],
|
||||
getInitialState: function() {
|
||||
return {foo: "bar"};
|
||||
},
|
||||
render: function() { return React.DOM.div(); }
|
||||
});
|
||||
|
||||
var testView = TestUtils.renderIntoDocument(TestView({
|
||||
roomStore: activeRoomStore
|
||||
}));
|
||||
|
||||
expect(testView.state).eql({
|
||||
roomState: ROOM_STATES.INIT,
|
||||
foo: "bar"
|
||||
});
|
||||
});
|
||||
|
||||
it("should listen to store changes", function() {
|
||||
var TestView = React.createClass({
|
||||
mixins: [loop.roomViews.ActiveRoomStoreMixin],
|
||||
render: function() { return React.DOM.div(); }
|
||||
});
|
||||
var testView = TestUtils.renderIntoDocument(TestView({
|
||||
roomStore: activeRoomStore
|
||||
}));
|
||||
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.READY});
|
||||
|
||||
expect(testView.state).eql({roomState: ROOM_STATES.READY});
|
||||
});
|
||||
});
|
||||
|
||||
describe("DesktopRoomControllerView", function() {
|
||||
var view;
|
||||
|
||||
function mountTestComponent() {
|
||||
return TestUtils.renderIntoDocument(
|
||||
new loop.roomViews.DesktopRoomView({
|
||||
new loop.roomViews.DesktopRoomControllerView({
|
||||
mozLoop: {},
|
||||
roomStore: roomStore
|
||||
}));
|
||||
|
@ -65,17 +101,35 @@ describe("loop.roomViews", function () {
|
|||
expect(fakeWindow.document.title).to.equal("fakeName");
|
||||
});
|
||||
|
||||
it("should render the GenericFailureView if the roomState is `FAILED`", function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.FAILED});
|
||||
it("should render the GenericFailureView if the roomState is `FAILED`",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.FAILED});
|
||||
|
||||
view = mountTestComponent();
|
||||
view = mountTestComponent();
|
||||
|
||||
TestUtils.findRenderedComponentWithType(view,
|
||||
loop.conversation.GenericFailureView);
|
||||
});
|
||||
TestUtils.findRenderedComponentWithType(view,
|
||||
loop.conversation.GenericFailureView);
|
||||
});
|
||||
|
||||
// XXX Implement this when we do the rooms views in bug 1074686 and others.
|
||||
it("should display the main view");
|
||||
it("should render the DesktopRoomInvitationView if roomState is `JOINED`",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.JOINED});
|
||||
|
||||
view = mountTestComponent();
|
||||
|
||||
TestUtils.findRenderedComponentWithType(view,
|
||||
loop.roomViews.DesktopRoomInvitationView);
|
||||
});
|
||||
|
||||
it("should render the DesktopRoomConversationView if roomState is `HAS_PARTICIPANTS`",
|
||||
function() {
|
||||
activeRoomStore.setStoreState({roomState: ROOM_STATES.HAS_PARTICIPANTS});
|
||||
|
||||
view = mountTestComponent();
|
||||
|
||||
TestUtils.findRenderedComponentWithType(view,
|
||||
loop.roomViews.DesktopRoomConversationView);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
var IncomingCallView = loop.conversation.IncomingCallView;
|
||||
var DesktopPendingConversationView = loop.conversationViews.PendingConversationView;
|
||||
var CallFailedView = loop.conversationViews.CallFailedView;
|
||||
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
|
||||
var DesktopRoomInvitationView = loop.roomViews.DesktopRoomInvitationView;
|
||||
|
||||
// 2. Standalone webapp
|
||||
var HomeView = loop.webapp.HomeView;
|
||||
|
@ -57,6 +59,10 @@
|
|||
);
|
||||
|
||||
var dispatcher = new loop.Dispatcher();
|
||||
var activeRoomStore = new loop.store.ActiveRoomStore({
|
||||
dispatcher: dispatcher,
|
||||
mozLoop: navigator.mozLoop
|
||||
});
|
||||
var roomStore = new loop.store.RoomStore({
|
||||
dispatcher: dispatcher,
|
||||
mozLoop: navigator.mozLoop
|
||||
|
@ -527,6 +533,24 @@
|
|||
)
|
||||
),
|
||||
|
||||
Section({name: "DesktopRoomInvitationView"},
|
||||
Example({summary: "Desktop room invitation", dashed: "true",
|
||||
style: {width: "260px", height: "265px"}},
|
||||
React.DOM.div({className: "fx-embedded"},
|
||||
DesktopRoomInvitationView({roomStore: roomStore})
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
Section({name: "DesktopRoomConversationView"},
|
||||
Example({summary: "Desktop room conversation", dashed: "true",
|
||||
style: {width: "260px", height: "265px"}},
|
||||
React.DOM.div({className: "fx-embedded"},
|
||||
DesktopRoomConversationView({roomStore: roomStore})
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
Section({name: "SVG icons preview"},
|
||||
Example({summary: "16x16"},
|
||||
SVGIcons(null)
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
var IncomingCallView = loop.conversation.IncomingCallView;
|
||||
var DesktopPendingConversationView = loop.conversationViews.PendingConversationView;
|
||||
var CallFailedView = loop.conversationViews.CallFailedView;
|
||||
var DesktopRoomConversationView = loop.roomViews.DesktopRoomConversationView;
|
||||
var DesktopRoomInvitationView = loop.roomViews.DesktopRoomInvitationView;
|
||||
|
||||
// 2. Standalone webapp
|
||||
var HomeView = loop.webapp.HomeView;
|
||||
|
@ -57,6 +59,10 @@
|
|||
);
|
||||
|
||||
var dispatcher = new loop.Dispatcher();
|
||||
var activeRoomStore = new loop.store.ActiveRoomStore({
|
||||
dispatcher: dispatcher,
|
||||
mozLoop: navigator.mozLoop
|
||||
});
|
||||
var roomStore = new loop.store.RoomStore({
|
||||
dispatcher: dispatcher,
|
||||
mozLoop: navigator.mozLoop
|
||||
|
@ -527,6 +533,24 @@
|
|||
</Example>
|
||||
</Section>
|
||||
|
||||
<Section name="DesktopRoomInvitationView">
|
||||
<Example summary="Desktop room invitation" dashed="true"
|
||||
style={{width: "260px", height: "265px"}}>
|
||||
<div className="fx-embedded">
|
||||
<DesktopRoomInvitationView roomStore={roomStore} />
|
||||
</div>
|
||||
</Example>
|
||||
</Section>
|
||||
|
||||
<Section name="DesktopRoomConversationView">
|
||||
<Example summary="Desktop room conversation" dashed="true"
|
||||
style={{width: "260px", height: "265px"}}>
|
||||
<div className="fx-embedded">
|
||||
<DesktopRoomConversationView roomStore={roomStore} />
|
||||
</div>
|
||||
</Example>
|
||||
</Section>
|
||||
|
||||
<Section name="SVG icons preview">
|
||||
<Example summary="16x16">
|
||||
<SVGIcons />
|
||||
|
|
|
@ -186,7 +186,7 @@ skip-if = e10s
|
|||
[browser_dbg_clean-exit-window.js]
|
||||
skip-if = true # Bug 933950 (leaky test)
|
||||
[browser_dbg_clean-exit.js]
|
||||
skip-if = e10s
|
||||
skip-if = true # Bug 1044985 (racy test)
|
||||
[browser_dbg_closure-inspection.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_cmd-blackbox.js]
|
||||
|
@ -474,15 +474,15 @@ skip-if = e10s
|
|||
[browser_dbg_variables-view-edit-watch.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_variables-view-filter-01.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-02.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-03.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-04.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-05.js]
|
||||
skip-if = e10s
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-pref.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_variables-view-filter-searchbox.js]
|
||||
|
|
|
@ -7,16 +7,15 @@
|
|||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables, gSearchBox;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are quite 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;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
|
@ -37,9 +36,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"));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -214,7 +211,6 @@ function prepareVariablesAndProperties() {
|
|||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
|
|
@ -7,16 +7,15 @@
|
|||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables, gSearchBox;
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are quite 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;
|
||||
gVariables = gDebugger.DebuggerView.Variables;
|
||||
|
@ -37,9 +36,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"));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -221,7 +218,6 @@ function prepareVariablesAndProperties() {
|
|||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
|
|
@ -8,16 +8,15 @@
|
|||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables, gSearchBox;
|
||||
|
||||
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;
|
||||
|
@ -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"));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -153,7 +150,6 @@ function prepareVariablesAndProperties() {
|
|||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
|
|
@ -8,16 +8,15 @@
|
|||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor, gVariables, gSearchBox;
|
||||
|
||||
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;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
|
@ -37,9 +36,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"));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -220,7 +217,6 @@ function prepareVariablesAndProperties() {
|
|||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
|
|
|
@ -8,16 +8,15 @@
|
|||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
|
||||
|
||||
let gTab, gDebuggee, gPanel, gDebugger;
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gVariables, gSearchBox;
|
||||
|
||||
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;
|
||||
|
@ -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"));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -229,7 +226,6 @@ function prepareVariablesAndProperties() {
|
|||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gVariables = null;
|
||||
|
|
|
@ -370,7 +370,10 @@ ProfilerFront.prototype = {
|
|||
// for all toolboxes and interacts with the whole platform, so we don't want
|
||||
// to affect other clients by stopping (or restarting) it.
|
||||
if (!isActive) {
|
||||
yield this._request("profiler", "startProfiler", this._customProfilerOptions);
|
||||
// Make a copy of the options, because eventually _request wants
|
||||
// to freeze the packet.
|
||||
let localOptions = Cu.cloneInto(this._customProfilerOptions, {});
|
||||
yield this._request("profiler", "startProfiler", localOptions);
|
||||
this._profilingStartTime = 0;
|
||||
this.emit("profiler-activated");
|
||||
} else {
|
||||
|
|
|
@ -518,7 +518,7 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e1
|
|||
skip-if = toolkit == 'android' || (toolkit == 'gonk' && debug) #bug 871015, bug 881443
|
||||
[test_input_files_not_nsIFile.html]
|
||||
[test_ignoreuserfocus.html]
|
||||
skip-if = (toolkit == 'gonk' && debug) #debug-only failure
|
||||
skip-if = (toolkit == 'gonk' && debug) || (os == 'linux' && e10s && debug) # bug 942411
|
||||
[test_fragment_form_pointer.html]
|
||||
[test_bug1682.html]
|
||||
[test_bug1823.html]
|
||||
|
|
|
@ -341,11 +341,13 @@ GMPChild::PreLoadLibraries(const std::string& aPluginPath)
|
|||
// This must be in sorted order and lowercase!
|
||||
static const char* whitelist[] =
|
||||
{
|
||||
"bcrypt.dll", // Used for OutputProtectionManager handshake
|
||||
"crypt32.dll", // Used for OutputProtectionManager handshake
|
||||
"d3d9.dll", // Create an `IDirect3D9` to get adapter information
|
||||
"dxva2.dll", // Get monitor information
|
||||
"msauddecmft.dll", // H.264 decoder
|
||||
"msauddecmft.dll", // AAC decoder (on Windows 8)
|
||||
"msmpeg2adec.dll", // AAC decoder (on Windows 7)
|
||||
"msmpeg2vdec.dll", // AAC decoder (on Windows 8)
|
||||
"msmpeg2vdec.dll", // H.264 decoder
|
||||
};
|
||||
static const int whitelistLen = sizeof(whitelist) / sizeof(whitelist[0]);
|
||||
|
||||
|
|
|
@ -39,22 +39,11 @@ public:
|
|||
float aSampleRate)
|
||||
: AudioNodeEngine(aNode)
|
||||
, mWriteIndex(0)
|
||||
, mNumberOfChannels(aNumberOfChannels)
|
||||
, mLength(aLength)
|
||||
, mSampleRate(aSampleRate)
|
||||
, mBufferAllocated(false)
|
||||
{
|
||||
// These allocations might fail if content provides a huge number of
|
||||
// channels or size, but it's OK since we'll deal with the failure
|
||||
// gracefully.
|
||||
if (mInputChannels.SetLength(aNumberOfChannels)) {
|
||||
static const fallible_t fallible = fallible_t();
|
||||
for (uint32_t i = 0; i < aNumberOfChannels; ++i) {
|
||||
mInputChannels[i] = new(fallible) float[aLength];
|
||||
if (!mInputChannels[i]) {
|
||||
mInputChannels.Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ProcessBlock(AudioNodeStream* aStream,
|
||||
|
@ -66,6 +55,25 @@ public:
|
|||
// will not go anywhere.
|
||||
*aOutput = aInput;
|
||||
|
||||
// The output buffer is allocated lazily, on the rendering thread.
|
||||
if (!mBufferAllocated) {
|
||||
// These allocations might fail if content provides a huge number of
|
||||
// channels or size, but it's OK since we'll deal with the failure
|
||||
// gracefully.
|
||||
if (mInputChannels.SetLength(mNumberOfChannels)) {
|
||||
static const fallible_t fallible = fallible_t();
|
||||
for (uint32_t i = 0; i < mNumberOfChannels; ++i) {
|
||||
mInputChannels[i] = new(fallible) float[mLength];
|
||||
if (!mInputChannels[i]) {
|
||||
mInputChannels.Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mBufferAllocated = true;
|
||||
}
|
||||
|
||||
// Handle the case of allocation failure in the input buffer
|
||||
if (mInputChannels.IsEmpty()) {
|
||||
return;
|
||||
|
@ -169,9 +177,11 @@ private:
|
|||
InputChannels mInputChannels;
|
||||
// An index representing the next offset in mInputChannels to be written to.
|
||||
uint32_t mWriteIndex;
|
||||
uint32_t mNumberOfChannels;
|
||||
// How many frames the OfflineAudioContext intends to produce.
|
||||
uint32_t mLength;
|
||||
float mSampleRate;
|
||||
bool mBufferAllocated;
|
||||
};
|
||||
|
||||
class InputMutedRunnable : public nsRunnable
|
||||
|
|
|
@ -105,7 +105,7 @@ nsSVGPolyElement::GetMarkPoints(nsTArray<nsSVGMark> *aMarks)
|
|||
if (i == 1) {
|
||||
aMarks->ElementAt(0).angle = angle;
|
||||
} else {
|
||||
aMarks->ElementAt(aMarks->Length() - 2).angle =
|
||||
aMarks->ElementAt(aMarks->Length() - 1).angle =
|
||||
SVGContentUtils::AngleBisect(prevAngle, angle);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
if (!getBuildConfiguration().parallelJS)
|
||||
quit(0);
|
||||
|
||||
function f() {
|
||||
Function() * (function() {})()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<marker id="startMarker" markerUnits="userSpaceOnUse" orient="auto" markerWidth="30" markerHeight="45" refX="15" refY="22.5">
|
||||
<rect fill="red" x="0.5" y="0.5" width="29" height="44"/>
|
||||
</marker>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="lime"/>
|
||||
<polyline fill="none" marker-start="url(#startMarker)" points="190 40 220 40 310 190 340 190"/>
|
||||
<rect x="175" y="18" width="30" height="45" fill="lime" />
|
||||
|
||||
</svg>
|
После Ширина: | Высота: | Размер: 602 B |
|
@ -200,6 +200,7 @@ fuzzy-if(cocoaWidget,15,19679) fuzzy-if(winWidget,1,8800) fuzzy-if(!cocoaWidget&
|
|||
== marker-viewBox-01.svg marker-viewBox-01-ref.svg
|
||||
== marker-orientation-01.svg marker-orientation-01-ref.svg
|
||||
pref(svg.marker-improvements.enabled,true) == marker-orientation-02.svg marker-orientation-02-ref.svg
|
||||
== marker-orientation-03.svg pass.svg
|
||||
== mask-basic-01.svg pass.svg
|
||||
== mask-basic-02.svg mask-basic-02-ref.svg
|
||||
== mask-basic-03.svg pass.svg
|
||||
|
|
|
@ -3534,7 +3534,7 @@ Tab.prototype = {
|
|||
|
||||
setDisplayPort: function(aDisplayPort) {
|
||||
let zoom = this._zoom;
|
||||
let resolution = aDisplayPort.resolution;
|
||||
let resolution = this.restoredSessionZoom() || aDisplayPort.resolution;
|
||||
if (zoom <= 0 || resolution <= 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -133,15 +133,6 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
// First try to read the engine list from the jar.
|
||||
InputStream in = getInputStreamFromJar("list.txt");
|
||||
|
||||
// Fallback for standalone search activity.
|
||||
if (in == null) {
|
||||
try {
|
||||
in = context.getResources().getAssets().open("engines/list.txt");
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Error reading list.txt");
|
||||
}
|
||||
}
|
||||
|
||||
final List<SearchEngine> list = new ArrayList<SearchEngine>();
|
||||
InputStreamReader isr = null;
|
||||
|
||||
|
@ -185,11 +176,6 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
in = getEngineFromProfile(identifier);
|
||||
}
|
||||
|
||||
// Fallback for standalone search activity.
|
||||
if (in == null) {
|
||||
in = getEngineFromAssets(identifier);
|
||||
}
|
||||
|
||||
if (in == null) {
|
||||
throw new IllegalArgumentException("Couldn't find search engine for identifier: " + identifier);
|
||||
}
|
||||
|
@ -209,22 +195,6 @@ public class SearchEngineManager implements SharedPreferences.OnSharedPreference
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback for standalone search activity. These assets are not included
|
||||
* in mozilla-central.
|
||||
*
|
||||
* @param identifier search engine identifier (e.g. "google")
|
||||
* @return InputStream for open search plugin XML
|
||||
*/
|
||||
private InputStream getEngineFromAssets(String identifier) {
|
||||
try {
|
||||
return context.getResources().getAssets().open("engines/" + identifier + ".xml");
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "Exception getting search engine from assets", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file from the searchplugins directory in the Gecko jar. This will only work
|
||||
* if the search activity is built as part of mozilla-central.
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<!-- 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/. -->
|
||||
|
||||
<SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
|
||||
<ShortName>DuckDuckGo</ShortName>
|
||||
<InputEncoding>UTF-8</InputEncoding>
|
||||
<Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYxIDY0LjE0MDk0OSwgMjAxMC8xMi8wNy0xMDo1NzowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDowMTgwMTE3NDA3MjA2ODExQTUzMUNFODI2QjhFRURFRCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4REU3ODU4OUE4OTMxMUUzODAxMUE0MzZGQUQ1RTAwNyIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4REU3ODU4OEE4OTMxMUUzODAxMUE0MzZGQUQ1RTAwNyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1LjEgTWFjaW50b3NoIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MDg4MDExNzQwNzIwNjgxMUE1MzFDRTgyNkI4RUVERUQiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MDE4MDExNzQwNzIwNjgxMUE1MzFDRTgyNkI4RUVERUQiLz4gPC9yZGY6RGVzY3Jp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</Image>
|
||||
<Url type="application/x-suggestions+json" method="GET" template="https://ac.duckduckgo.com/ac/">
|
||||
<Param name="q" value="{searchTerms}"/>
|
||||
<Param name="type" value="list"/>
|
||||
</Url>
|
||||
<!-- this is effectively x-moz-phonesearch, but search service expects a text/html entry -->
|
||||
<Url type="text/html" method="GET" template="https://duckduckgo.com/">
|
||||
<Param name="q" value="{searchTerms}" />
|
||||
<Param name="t" value="fpas" />
|
||||
</Url>
|
||||
<Url type="application/x-moz-tabletsearch" method="GET" template="https://duckduckgo.com/">
|
||||
<Param name="q" value="{searchTerms}" />
|
||||
<Param name="t" value="ftas" />
|
||||
</Url>
|
||||
<SearchForm>https://duckduckgo.com</SearchForm>
|
||||
</SearchPlugin>
|
|
@ -4,3 +4,4 @@ twitter
|
|||
wikipedia
|
||||
yahoo
|
||||
bing
|
||||
duckduckgo
|
||||
|
|
|
@ -258,8 +258,17 @@ nsAsyncRedirectVerifyHelper::IsOldChannelCanceled()
|
|||
do_QueryInterface(mOldChan);
|
||||
if (oldChannelInternal) {
|
||||
oldChannelInternal->GetCanceled(&canceled);
|
||||
if (canceled)
|
||||
if (canceled) {
|
||||
return true;
|
||||
}
|
||||
} else if (mOldChan) {
|
||||
// For non-HTTP channels check on the status, failure
|
||||
// indicates the channel has probably been canceled.
|
||||
nsresult status = NS_ERROR_FAILURE;
|
||||
mOldChan->GetStatus(&status);
|
||||
if (NS_FAILED(status)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -216,10 +216,10 @@ Http2Session::LogIO(Http2Session *self, Http2Stream *stream,
|
|||
const char *label,
|
||||
const char *data, uint32_t datalen)
|
||||
{
|
||||
if (!LOG4_ENABLED())
|
||||
if (!LOG5_ENABLED())
|
||||
return;
|
||||
|
||||
LOG4(("Http2Session::LogIO %p stream=%p id=0x%X [%s]",
|
||||
LOG5(("Http2Session::LogIO %p stream=%p id=0x%X [%s]",
|
||||
self, stream, stream ? stream->StreamID() : 0, label));
|
||||
|
||||
// Max line is (16 * 3) + 10(prefix) + newline + null
|
||||
|
@ -233,7 +233,7 @@ Http2Session::LogIO(Http2Session *self, Http2Stream *stream,
|
|||
if (!(index % 16)) {
|
||||
if (index) {
|
||||
*line = 0;
|
||||
LOG4(("%s", linebuf));
|
||||
LOG5(("%s", linebuf));
|
||||
}
|
||||
line = linebuf;
|
||||
PR_snprintf(line, 128, "%08X: ", index);
|
||||
|
@ -245,7 +245,7 @@ Http2Session::LogIO(Http2Session *self, Http2Stream *stream,
|
|||
}
|
||||
if (index) {
|
||||
*line = 0;
|
||||
LOG4(("%s", linebuf));
|
||||
LOG5(("%s", linebuf));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,10 +155,10 @@ void
|
|||
SpdySession3::LogIO(SpdySession3 *self, SpdyStream3 *stream, const char *label,
|
||||
const char *data, uint32_t datalen)
|
||||
{
|
||||
if (!LOG4_ENABLED())
|
||||
if (!LOG5_ENABLED())
|
||||
return;
|
||||
|
||||
LOG4(("SpdySession3::LogIO %p stream=%p id=0x%X [%s]",
|
||||
LOG5(("SpdySession3::LogIO %p stream=%p id=0x%X [%s]",
|
||||
self, stream, stream ? stream->StreamID() : 0, label));
|
||||
|
||||
// Max line is (16 * 3) + 10(prefix) + newline + null
|
||||
|
@ -172,7 +172,7 @@ SpdySession3::LogIO(SpdySession3 *self, SpdyStream3 *stream, const char *label,
|
|||
if (!(index % 16)) {
|
||||
if (index) {
|
||||
*line = 0;
|
||||
LOG4(("%s", linebuf));
|
||||
LOG5(("%s", linebuf));
|
||||
}
|
||||
line = linebuf;
|
||||
PR_snprintf(line, 128, "%08X: ", index);
|
||||
|
@ -184,7 +184,7 @@ SpdySession3::LogIO(SpdySession3 *self, SpdyStream3 *stream, const char *label,
|
|||
}
|
||||
if (index) {
|
||||
*line = 0;
|
||||
LOG4(("%s", linebuf));
|
||||
LOG5(("%s", linebuf));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -158,10 +158,10 @@ void
|
|||
SpdySession31::LogIO(SpdySession31 *self, SpdyStream31 *stream, const char *label,
|
||||
const char *data, uint32_t datalen)
|
||||
{
|
||||
if (!LOG4_ENABLED())
|
||||
if (!LOG5_ENABLED())
|
||||
return;
|
||||
|
||||
LOG4(("SpdySession31::LogIO %p stream=%p id=0x%X [%s]",
|
||||
LOG5(("SpdySession31::LogIO %p stream=%p id=0x%X [%s]",
|
||||
self, stream, stream ? stream->StreamID() : 0, label));
|
||||
|
||||
// Max line is (16 * 3) + 10(prefix) + newline + null
|
||||
|
@ -175,7 +175,7 @@ SpdySession31::LogIO(SpdySession31 *self, SpdyStream31 *stream, const char *labe
|
|||
if (!(index % 16)) {
|
||||
if (index) {
|
||||
*line = 0;
|
||||
LOG4(("%s", linebuf));
|
||||
LOG5(("%s", linebuf));
|
||||
}
|
||||
line = linebuf;
|
||||
PR_snprintf(line, 128, "%08X: ", index);
|
||||
|
@ -187,7 +187,7 @@ SpdySession31::LogIO(SpdySession31 *self, SpdyStream31 *stream, const char *labe
|
|||
}
|
||||
if (index) {
|
||||
*line = 0;
|
||||
LOG4(("%s", linebuf));
|
||||
LOG5(("%s", linebuf));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче