зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to b2g-inbound a=merge
This commit is contained in:
Коммит
0ba238ad0c
4
CLOBBER
4
CLOBBER
|
@ -22,4 +22,8 @@
|
|||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
<<<<<<< local
|
||||
Bug 1092813 needs a CLOBBER
|
||||
=======
|
||||
Bug 1056337 - Change the default compiler on B2G ICS to gcc 4.8.
|
||||
>>>>>>> other
|
||||
|
|
|
@ -50,4 +50,4 @@ if CONFIG['MOZ_ENABLE_GTK']:
|
|||
if CONFIG['MOZ_ENABLE_DBUS']:
|
||||
CXXFLAGS += CONFIG['MOZ_DBUS_CFLAGS']
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
|
|
@ -5,6 +5,5 @@
|
|||
/gtest/***
|
||||
/pk12util
|
||||
/ssltunnel
|
||||
/webapprt-stub
|
||||
/xpcshell
|
||||
/XUL
|
||||
|
|
|
@ -106,6 +106,11 @@ const checkForParticipantsUpdate = function(room, updatedRoom) {
|
|||
let LoopRoomsInternal = {
|
||||
rooms: new Map(),
|
||||
|
||||
get sessionType() {
|
||||
return MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA :
|
||||
LOOP_SESSION_TYPE.GUEST;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch a list of rooms that the currently registered user is a member of.
|
||||
*
|
||||
|
@ -131,10 +136,8 @@ let LoopRoomsInternal = {
|
|||
}
|
||||
|
||||
// Fetch the rooms from the server.
|
||||
let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA :
|
||||
LOOP_SESSION_TYPE.GUEST;
|
||||
let url = "/rooms" + (version ? "?version=" + encodeURIComponent(version) : "");
|
||||
let response = yield MozLoopService.hawkRequest(sessionType, url, "GET");
|
||||
let response = yield MozLoopService.hawkRequest(this.sessionType, url, "GET");
|
||||
let roomsList = JSON.parse(response.body);
|
||||
if (!Array.isArray(roomsList)) {
|
||||
throw new Error("Missing array of rooms in response.");
|
||||
|
@ -188,9 +191,7 @@ let LoopRoomsInternal = {
|
|||
return;
|
||||
}
|
||||
|
||||
let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA :
|
||||
LOOP_SESSION_TYPE.GUEST;
|
||||
MozLoopService.hawkRequest(sessionType, "/rooms/" + encodeURIComponent(roomToken), "GET")
|
||||
MozLoopService.hawkRequest(this.sessionType, "/rooms/" + encodeURIComponent(roomToken), "GET")
|
||||
.then(response => {
|
||||
let data = JSON.parse(response.body);
|
||||
|
||||
|
@ -227,10 +228,7 @@ let LoopRoomsInternal = {
|
|||
return;
|
||||
}
|
||||
|
||||
let sessionType = MozLoopService.userProfile ? LOOP_SESSION_TYPE.FXA :
|
||||
LOOP_SESSION_TYPE.GUEST;
|
||||
|
||||
MozLoopService.hawkRequest(sessionType, "/rooms", "POST", room)
|
||||
MozLoopService.hawkRequest(this.sessionType, "/rooms", "POST", room)
|
||||
.then(response => {
|
||||
let data = JSON.parse(response.body);
|
||||
extend(room, data);
|
||||
|
@ -252,6 +250,28 @@ let LoopRoomsInternal = {
|
|||
MozLoopService.openChatWindow(windowData);
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes a room.
|
||||
*
|
||||
* @param {String} roomToken The room token.
|
||||
* @param {Function} callback Function that will be invoked once the operation
|
||||
* finished. The first argument passed will be an
|
||||
* `Error` object or `null`.
|
||||
*/
|
||||
delete: function(roomToken, callback) {
|
||||
// XXX bug 1092954: Before deleting a room, the client should check room
|
||||
// membership and forceDisconnect() all current participants.
|
||||
let room = this.rooms.get(roomToken);
|
||||
let url = "/rooms/" + encodeURIComponent(roomToken);
|
||||
MozLoopService.hawkRequest(this.sessionType, url, "DELETE")
|
||||
.then(response => {
|
||||
this.rooms.delete(roomToken);
|
||||
eventEmitter.emit("delete", room);
|
||||
callback(null, room);
|
||||
}, error => callback(error)).catch(error => callback(error));
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Callback used to indicate changes to rooms data on the LoopServer.
|
||||
*
|
||||
|
@ -273,7 +293,7 @@ Object.freeze(LoopRoomsInternal);
|
|||
* At this point the following events may be subscribed to:
|
||||
* - 'add[:{room-id}]': A new room object was successfully added to the data
|
||||
* store.
|
||||
* - 'remove[:{room-id}]': A room was successfully removed from the data store.
|
||||
* - 'delete[:{room-id}]': A room was successfully removed from the data store.
|
||||
* - 'update[:{room-id}]': A room object was successfully updated with changed
|
||||
* properties in the data store.
|
||||
* - 'joined[:{room-id}]': A participant joined a room.
|
||||
|
@ -298,6 +318,10 @@ this.LoopRooms = {
|
|||
return LoopRoomsInternal.open(roomToken);
|
||||
},
|
||||
|
||||
delete: function(roomToken, callback) {
|
||||
return LoopRoomsInternal.delete(roomToken, callback);
|
||||
},
|
||||
|
||||
promise: function(method, ...params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this[method](...params, (error, result) => {
|
||||
|
|
|
@ -467,8 +467,8 @@ loop.panel = (function(_, mozL10n) {
|
|||
*/
|
||||
var RoomEntry = React.createClass({displayName: 'RoomEntry',
|
||||
propTypes: {
|
||||
openRoom: React.PropTypes.func.isRequired,
|
||||
room: React.PropTypes.instanceOf(loop.store.Room).isRequired
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
room: React.PropTypes.instanceOf(loop.store.Room).isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -480,9 +480,11 @@ loop.panel = (function(_, mozL10n) {
|
|||
(nextState.urlCopied !== this.state.urlCopied);
|
||||
},
|
||||
|
||||
handleClickRoom: function(event) {
|
||||
handleClickRoomUrl: function(event) {
|
||||
event.preventDefault();
|
||||
this.props.openRoom(this.props.room);
|
||||
this.props.dispatcher.dispatch(new sharedActions.OpenRoom({
|
||||
roomToken: this.props.room.roomToken
|
||||
}));
|
||||
},
|
||||
|
||||
handleCopyButtonClick: function(event) {
|
||||
|
@ -491,6 +493,14 @@ loop.panel = (function(_, mozL10n) {
|
|||
this.setState({urlCopied: true});
|
||||
},
|
||||
|
||||
handleDeleteButtonClick: function(event) {
|
||||
event.preventDefault();
|
||||
// XXX We should prompt end user for confirmation; see bug 1092953.
|
||||
this.props.dispatcher.dispatch(new sharedActions.DeleteRoom({
|
||||
roomToken: this.props.room.roomToken
|
||||
}));
|
||||
},
|
||||
|
||||
handleMouseLeave: function(event) {
|
||||
this.setState({urlCopied: false});
|
||||
},
|
||||
|
@ -507,20 +517,22 @@ loop.panel = (function(_, mozL10n) {
|
|||
"room-active": this._isActive()
|
||||
});
|
||||
var copyButtonClasses = React.addons.classSet({
|
||||
'copy-link': true,
|
||||
'checked': this.state.urlCopied
|
||||
"copy-link": true,
|
||||
"checked": this.state.urlCopied
|
||||
});
|
||||
|
||||
return (
|
||||
React.DOM.div({className: roomClasses, onMouseLeave: this.handleMouseLeave},
|
||||
React.DOM.h2(null,
|
||||
React.DOM.span({className: "room-notification"}),
|
||||
room.roomName,
|
||||
room.roomName,
|
||||
React.DOM.button({className: copyButtonClasses,
|
||||
onClick: this.handleCopyButtonClick})
|
||||
onClick: this.handleCopyButtonClick}),
|
||||
React.DOM.button({className: "delete-link",
|
||||
onClick: this.handleDeleteButtonClick})
|
||||
),
|
||||
React.DOM.p(null,
|
||||
React.DOM.a({ref: "room", href: "#", onClick: this.handleClickRoom},
|
||||
React.DOM.a({href: "#", onClick: this.handleClickRoomUrl},
|
||||
room.roomUrl
|
||||
)
|
||||
)
|
||||
|
@ -581,12 +593,6 @@ loop.panel = (function(_, mozL10n) {
|
|||
}));
|
||||
},
|
||||
|
||||
openRoom: function(room) {
|
||||
this.props.dispatcher.dispatch(new sharedActions.OpenRoom({
|
||||
roomToken: room.roomToken
|
||||
}));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.error) {
|
||||
// XXX Better end user reporting of errors.
|
||||
|
@ -598,7 +604,11 @@ loop.panel = (function(_, mozL10n) {
|
|||
React.DOM.h1(null, this._getListHeading()),
|
||||
React.DOM.div({className: "room-list"},
|
||||
this.state.rooms.map(function(room, i) {
|
||||
return RoomEntry({key: i, room: room, openRoom: this.openRoom});
|
||||
return RoomEntry({
|
||||
key: room.roomToken,
|
||||
dispatcher: this.props.dispatcher,
|
||||
room: room}
|
||||
);
|
||||
}, this)
|
||||
),
|
||||
React.DOM.p(null,
|
||||
|
|
|
@ -467,8 +467,8 @@ loop.panel = (function(_, mozL10n) {
|
|||
*/
|
||||
var RoomEntry = React.createClass({
|
||||
propTypes: {
|
||||
openRoom: React.PropTypes.func.isRequired,
|
||||
room: React.PropTypes.instanceOf(loop.store.Room).isRequired
|
||||
dispatcher: React.PropTypes.instanceOf(loop.Dispatcher).isRequired,
|
||||
room: React.PropTypes.instanceOf(loop.store.Room).isRequired
|
||||
},
|
||||
|
||||
getInitialState: function() {
|
||||
|
@ -480,9 +480,11 @@ loop.panel = (function(_, mozL10n) {
|
|||
(nextState.urlCopied !== this.state.urlCopied);
|
||||
},
|
||||
|
||||
handleClickRoom: function(event) {
|
||||
handleClickRoomUrl: function(event) {
|
||||
event.preventDefault();
|
||||
this.props.openRoom(this.props.room);
|
||||
this.props.dispatcher.dispatch(new sharedActions.OpenRoom({
|
||||
roomToken: this.props.room.roomToken
|
||||
}));
|
||||
},
|
||||
|
||||
handleCopyButtonClick: function(event) {
|
||||
|
@ -491,6 +493,14 @@ loop.panel = (function(_, mozL10n) {
|
|||
this.setState({urlCopied: true});
|
||||
},
|
||||
|
||||
handleDeleteButtonClick: function(event) {
|
||||
event.preventDefault();
|
||||
// XXX We should prompt end user for confirmation; see bug 1092953.
|
||||
this.props.dispatcher.dispatch(new sharedActions.DeleteRoom({
|
||||
roomToken: this.props.room.roomToken
|
||||
}));
|
||||
},
|
||||
|
||||
handleMouseLeave: function(event) {
|
||||
this.setState({urlCopied: false});
|
||||
},
|
||||
|
@ -507,20 +517,22 @@ loop.panel = (function(_, mozL10n) {
|
|||
"room-active": this._isActive()
|
||||
});
|
||||
var copyButtonClasses = React.addons.classSet({
|
||||
'copy-link': true,
|
||||
'checked': this.state.urlCopied
|
||||
"copy-link": true,
|
||||
"checked": this.state.urlCopied
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={roomClasses} onMouseLeave={this.handleMouseLeave}>
|
||||
<h2>
|
||||
<span className="room-notification" />
|
||||
{room.roomName}
|
||||
{room.roomName}
|
||||
<button className={copyButtonClasses}
|
||||
onClick={this.handleCopyButtonClick}/>
|
||||
onClick={this.handleCopyButtonClick} />
|
||||
<button className="delete-link"
|
||||
onClick={this.handleDeleteButtonClick} />
|
||||
</h2>
|
||||
<p>
|
||||
<a ref="room" href="#" onClick={this.handleClickRoom}>
|
||||
<a href="#" onClick={this.handleClickRoomUrl}>
|
||||
{room.roomUrl}
|
||||
</a>
|
||||
</p>
|
||||
|
@ -581,12 +593,6 @@ loop.panel = (function(_, mozL10n) {
|
|||
}));
|
||||
},
|
||||
|
||||
openRoom: function(room) {
|
||||
this.props.dispatcher.dispatch(new sharedActions.OpenRoom({
|
||||
roomToken: room.roomToken
|
||||
}));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.state.error) {
|
||||
// XXX Better end user reporting of errors.
|
||||
|
@ -598,7 +604,11 @@ loop.panel = (function(_, mozL10n) {
|
|||
<h1>{this._getListHeading()}</h1>
|
||||
<div className="room-list">{
|
||||
this.state.rooms.map(function(room, i) {
|
||||
return <RoomEntry key={i} room={room} openRoom={this.openRoom} />;
|
||||
return <RoomEntry
|
||||
key={room.roomToken}
|
||||
dispatcher={this.props.dispatcher}
|
||||
room={room}
|
||||
/>;
|
||||
}, this)
|
||||
}</div>
|
||||
<p>
|
||||
|
|
|
@ -222,37 +222,48 @@ body {
|
|||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.room-list > .room-entry > h2 > .copy-link {
|
||||
@keyframes drop-and-fade-in {
|
||||
0% {opacity: 0; top: -15px;}
|
||||
25% {opacity: 0; top: -15px;}
|
||||
100% {opacity: 1; top: 0px;}
|
||||
}
|
||||
|
||||
.room-list > .room-entry > h2 > button {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border: none;
|
||||
margin: .1em .5em; /* relative to _this_ line's font, not the document's */
|
||||
margin: .1em .1em .1em .5em; /* relative to _this_ line's font, not the document's */
|
||||
background-color: transparent; /* override browser default for button tags */
|
||||
top: -15px;
|
||||
}
|
||||
|
||||
@keyframes drop-and-fade-in {
|
||||
from { opacity: 0; transform: translateY(-10px); }
|
||||
to { opacity: 100; transform: translateY(0); }
|
||||
.room-list > .room-entry:hover > h2 > button {
|
||||
animation: drop-and-fade-in 0.250s;
|
||||
animation-fill-mode: forwards;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.room-list > .room-entry:hover > h2 > .copy-link {
|
||||
background: transparent url(../img/svg/copy-16x16.svg);
|
||||
cursor: pointer;
|
||||
animation: drop-and-fade-in 0.4s;
|
||||
animation-fill-mode: forwards;
|
||||
background-image: url(../img/icons-16x16.svg#copy);
|
||||
}
|
||||
|
||||
.room-list > .room-entry:hover > h2 > .delete-link {
|
||||
background-image: url(../img/icons-16x16.svg#trash);
|
||||
}
|
||||
|
||||
/* scale this up to 1.1x and then back to the original size */
|
||||
@keyframes pulse {
|
||||
0%, 100% { transform: scale(1.0); }
|
||||
50% { transform: scale(1.1); }
|
||||
50% { transform: scale(1.1); }
|
||||
}
|
||||
|
||||
.room-list > .room-entry > h2 > .copy-link.checked {
|
||||
background: transparent url(../img/svg/checkmark-16x16.svg);
|
||||
animation: pulse .250s;
|
||||
background: transparent url(../img/icons-16x16.svg#checkmark);
|
||||
animation: pulse .150s;
|
||||
animation-timing-function: ease-in-out;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.room-list > .room-entry > h2 {
|
||||
|
|
|
@ -87,6 +87,37 @@ use[id$="-red"] {
|
|||
<path id="video-shape" fill-rule="evenodd" clip-rule="evenodd" d="M14.9,3.129l-3.476,3.073V3.873c0-0.877-0.663-1.587-1.482-1.587
|
||||
H1.482C0.663,2.286,0,2.996,0,3.873v8.254c0,0.877,0.663,1.587,1.482,1.587h8.461c0.818,0,1.482-0.711,1.482-1.587V9.762
|
||||
l3.476,3.073c0.3,0.321,0.714,0.416,1.1,0.331V2.798C15.614,2.713,15.2,2.808,14.9,3.129z"/>
|
||||
<g id="copy-shape">
|
||||
<circle fill-rule="evenodd" clip-rule="evenodd" fill="#0096DD" cx="8" cy="8" r="8"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="none"
|
||||
stroke="#FFFFFF" stroke-width="0.75" stroke-miterlimit="10"
|
||||
d="M10.815,6.286H7.556c-0.164,0-0.296,0.128-0.296,0.286v5.143C7.259,11.872,7.392,12,7.556,12h4.148
|
||||
C11.867,12,12,11.872,12,11.714V7.429L10.815,6.286z
|
||||
M8.741,6.275V5.143L7.556,4H7.528C6.509,4,4.593,4,4.593,4H4.296
|
||||
C4.133,4,4,4.128,4,4.286v5.143c0,0.158,0.133,0.286,0.296,0.286H7.25V6.561c0-0.158,0.133-0.286,0.296-0.286H8.741z"/>
|
||||
<polygon fill-rule="evenodd" clip-rule="evenodd"
|
||||
fill="#FFFFFF" points="10.222,8 10.222,6.857 11.407,8"/>
|
||||
<polygon fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
|
||||
points="6.963,5.714 6.963,4.571 8.148,5.714"/>
|
||||
</g>
|
||||
<g id="checkmark-shape">
|
||||
<circle fill-rule="evenodd" clip-rule="evenodd" fill="#0096DD" cx="8"
|
||||
cy="8" r="8"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
|
||||
d="M7.236,12L12,5.007L10.956,4L7.224,9.465l-2.14-2.326L4,8.146L7.236,12z"/>
|
||||
</g>
|
||||
<g id="trash-shape">
|
||||
<circle fill-rule="evenodd" clip-rule="evenodd" fill="#D74345" cx="8" cy="8" r="8"/>
|
||||
<path fill="#FFFFFF" d="M12,5.79c0-0.742-0.537-1.344-1.2-1.344h-0.583V4.121c0-0.713-0.516-1.29-1.152-1.29h-2.13
|
||||
c-0.636,0-1.152,0.578-1.152,1.29v0.324H5.2C4.537,4.446,4,5.048,4,5.79v0.898h0.687l0.508,5.438
|
||||
c0.054,0.585,0.543,1.044,1.114,1.044h3.38c0.57,0,1.06-0.458,1.114-1.043l0.509-5.439H12V5.79z M6.407,4.264V4.165
|
||||
c0-0.375,0.271-0.678,0.606-0.678h1.974c0.334,0,0.606,0.304,0.606,0.678v0.099c0,0.063-0.01,0.123-0.025,0.181H6.432
|
||||
C6.417,4.387,6.407,4.328,6.407,4.264z M10.057,12.056c-0.019,0.197-0.188,0.363-0.368,0.363h-3.38
|
||||
c-0.182,0-0.35-0.166-0.368-0.363L5.44,6.687h5.12L10.057,12.056z"/>
|
||||
<rect x="7.75" y="7.542" fill="#FFFFFF" width="0.5" height="4"/>
|
||||
<polyline fill="#FFFFFF" points="9.25,7.542 8.75,7.542 8.75,11.542 9.25,11.542 "/>
|
||||
<rect x="6.75" y="7.542" fill="#FFFFFF" width="0.5" height="4"/>
|
||||
</g>
|
||||
</defs>
|
||||
<use id="audio" xlink:href="#audio-shape"/>
|
||||
<use id="audio-hover" xlink:href="#audio-shape"/>
|
||||
|
@ -98,6 +129,8 @@ use[id$="-red"] {
|
|||
<use id="contacts" xlink:href="#contacts-shape"/>
|
||||
<use id="contacts-hover" xlink:href="#contacts-shape"/>
|
||||
<use id="contacts-active" xlink:href="#contacts-shape"/>
|
||||
<use id="copy" xlink:href="#copy-shape"/>
|
||||
<use id="checkmark" xlink:href="#checkmark-shape"/>
|
||||
<use id="google" xlink:href="#google-shape"/>
|
||||
<use id="google-hover" xlink:href="#google-shape"/>
|
||||
<use id="google-active" xlink:href="#google-shape"/>
|
||||
|
@ -113,6 +146,7 @@ use[id$="-red"] {
|
|||
<use id="tag" xlink:href="#tag-shape"/>
|
||||
<use id="tag-hover" xlink:href="#tag-shape"/>
|
||||
<use id="tag-active" xlink:href="#tag-shape"/>
|
||||
<use id="trash" xlink:href="#trash-shape"/>
|
||||
<use id="unblock" xlink:href="#unblock-shape"/>
|
||||
<use id="unblock-hover" xlink:href="#unblock-shape"/>
|
||||
<use id="unblock-active" xlink:href="#unblock-shape"/>
|
||||
|
|
До Ширина: | Высота: | Размер: 8.2 KiB После Ширина: | Высота: | Размер: 10 KiB |
|
@ -1,10 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<circle fill-rule="evenodd" clip-rule="evenodd" fill="#0096DD" cx="8"
|
||||
cy="8" r="8"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
|
||||
d="M7.236,12L12,5.007L10.956,4L7.224,9.465l-2.14-2.326L4,8.146L7.236,12z"/>
|
||||
</svg>
|
До Ширина: | Высота: | Размер: 597 B |
|
@ -1,28 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">
|
||||
<circle fill-rule="evenodd" clip-rule="evenodd" fill="#0096DD" cx="8" cy="8"
|
||||
r="8"/>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="none"
|
||||
stroke="#FFFFFF" stroke-width="0.75" stroke-miterlimit="10"
|
||||
d="M10.815,6.286H7.556c-0.164,0-0.296,0.128-0.296,0.286v5.143C7.259,11.872,7.392,12,7.556,12h4.148
|
||||
C11.867,12,12,11.872,12,11.714V7.429L10.815,6.286z
|
||||
M8.741,6.275V5.143L7.556,4H7.528C6.509,4,4.593,4,4.593,4H4.296
|
||||
C4.133,4,4,4.128,4,4.286v5.143c0,0.158,0.133,0.286,0.296,0.286H7.25V6.561c0-0.158,0.133-0.286,0.296-0.286H8.741z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<polygon fill-rule="evenodd" clip-rule="evenodd"
|
||||
fill="#FFFFFF" points="10.222,8 10.222,6.857 11.407,8"/>
|
||||
</g>
|
||||
<g>
|
||||
<polygon fill-rule="evenodd" clip-rule="evenodd" fill="#FFFFFF"
|
||||
points="6.963,5.714 6.963,4.571 8.148,5.714"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
До Ширина: | Высота: | Размер: 1.3 KiB |
|
@ -158,6 +158,22 @@ loop.shared.actions = (function() {
|
|||
error: Error
|
||||
}),
|
||||
|
||||
/**
|
||||
* Deletes a room.
|
||||
* XXX: should move to some roomActions module - refs bug 1079284
|
||||
*/
|
||||
DeleteRoom: Action.define("deleteRoom", {
|
||||
roomToken: String
|
||||
}),
|
||||
|
||||
/**
|
||||
* Room deletion error.
|
||||
* XXX: should move to some roomActions module - refs bug 1079284
|
||||
*/
|
||||
DeleteRoomError: Action.define("deleteRoomError", {
|
||||
error: Error
|
||||
}),
|
||||
|
||||
/**
|
||||
* Retrieves room list.
|
||||
* XXX: should move to some roomActions module - refs bug 1079284
|
||||
|
|
|
@ -71,6 +71,8 @@ loop.store = loop.store || {};
|
|||
this._dispatcher.register(this, [
|
||||
"createRoom",
|
||||
"createRoomError",
|
||||
"deleteRoom",
|
||||
"deleteRoomError",
|
||||
"getAllRooms",
|
||||
"getAllRoomsError",
|
||||
"openRoom",
|
||||
|
@ -139,7 +141,7 @@ loop.store = loop.store || {};
|
|||
// Rooms event registration
|
||||
this._mozLoop.rooms.on("add", this._onRoomAdded.bind(this));
|
||||
this._mozLoop.rooms.on("update", this._onRoomUpdated.bind(this));
|
||||
this._mozLoop.rooms.on("remove", this._onRoomRemoved.bind(this));
|
||||
this._mozLoop.rooms.on("delete", this._onRoomRemoved.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -181,7 +183,7 @@ loop.store = loop.store || {};
|
|||
},
|
||||
|
||||
/**
|
||||
* Executed when a room is removed.
|
||||
* Executed when a room is deleted.
|
||||
*
|
||||
* @param {String} eventName The event name (unused).
|
||||
* @param {Object} removedRoomData The removed room data.
|
||||
|
@ -194,7 +196,6 @@ loop.store = loop.store || {};
|
|||
}));
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Maps and sorts the raw room list received from the mozLoop API.
|
||||
*
|
||||
|
@ -267,7 +268,7 @@ loop.store = loop.store || {};
|
|||
this._mozLoop.rooms.create(roomCreationData, function(err) {
|
||||
this.setStoreState({pendingCreation: false});
|
||||
if (err) {
|
||||
this._dispatchAction(new sharedActions.CreateRoomError({error: err}));
|
||||
this._dispatchAction(new sharedActions.CreateRoomError({error: err}));
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
@ -284,6 +285,28 @@ loop.store = loop.store || {};
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new room.
|
||||
*
|
||||
* @param {sharedActions.DeleteRoom} actionData The action data.
|
||||
*/
|
||||
deleteRoom: function(actionData) {
|
||||
this._mozLoop.rooms.delete(actionData.roomToken, function(err) {
|
||||
if (err) {
|
||||
this._dispatchAction(new sharedActions.DeleteRoomError({error: err}));
|
||||
}
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Executed when a room deletion error occurs.
|
||||
*
|
||||
* @param {sharedActions.DeleteRoomError} actionData The action data.
|
||||
*/
|
||||
deleteRoomError: function(actionData) {
|
||||
this.setStoreState({error: actionData.error});
|
||||
},
|
||||
|
||||
/**
|
||||
* Gather the list of all available rooms from the MozLoop API.
|
||||
*/
|
||||
|
|
|
@ -49,8 +49,6 @@ browser.jar:
|
|||
content/browser/loop/shared/img/svg/glyph-account-16x16.svg (content/shared/img/svg/glyph-account-16x16.svg)
|
||||
content/browser/loop/shared/img/svg/glyph-signin-16x16.svg (content/shared/img/svg/glyph-signin-16x16.svg)
|
||||
content/browser/loop/shared/img/svg/glyph-signout-16x16.svg (content/shared/img/svg/glyph-signout-16x16.svg)
|
||||
content/browser/loop/shared/img/svg/copy-16x16.svg (content/shared/img/svg/copy-16x16.svg)
|
||||
content/browser/loop/shared/img/svg/checkmark-16x16.svg (content/shared/img/svg/checkmark-16x16.svg)
|
||||
content/browser/loop/shared/img/audio-call-avatar.svg (content/shared/img/audio-call-avatar.svg)
|
||||
content/browser/loop/shared/img/beta-ribbon.svg (content/shared/img/beta-ribbon.svg)
|
||||
content/browser/loop/shared/img/icons-10x10.svg (content/shared/img/icons-10x10.svg)
|
||||
|
|
|
@ -639,7 +639,7 @@ describe("loop.panel", function() {
|
|||
});
|
||||
|
||||
describe("loop.panel.RoomEntry", function() {
|
||||
var buttonNode, roomData, roomEntry, roomStore, dispatcher;
|
||||
var dispatcher, roomData;
|
||||
|
||||
beforeEach(function() {
|
||||
dispatcher = new loop.Dispatcher();
|
||||
|
@ -656,52 +656,104 @@ describe("loop.panel", function() {
|
|||
],
|
||||
ctime: 1405517418
|
||||
};
|
||||
roomStore = new loop.store.Room(roomData);
|
||||
roomEntry = mountRoomEntry();
|
||||
buttonNode = roomEntry.getDOMNode().querySelector("button.copy-link");
|
||||
});
|
||||
|
||||
function mountRoomEntry() {
|
||||
return TestUtils.renderIntoDocument(loop.panel.RoomEntry({
|
||||
openRoom: sandbox.stub(),
|
||||
room: roomStore
|
||||
}));
|
||||
function mountRoomEntry(props) {
|
||||
return TestUtils.renderIntoDocument(loop.panel.RoomEntry(props));
|
||||
}
|
||||
|
||||
it("should not display copy-link button by default", function() {
|
||||
expect(buttonNode).to.not.equal(null);
|
||||
});
|
||||
describe("Copy button", function() {
|
||||
var roomEntry, copyButton;
|
||||
|
||||
it("should copy the URL when the click event fires", function() {
|
||||
TestUtils.Simulate.click(buttonNode);
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.copyString);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.copyString,
|
||||
roomData.roomUrl);
|
||||
});
|
||||
|
||||
it("should set state.urlCopied when the click event fires", function() {
|
||||
TestUtils.Simulate.click(buttonNode);
|
||||
|
||||
expect(roomEntry.state.urlCopied).to.equal(true);
|
||||
});
|
||||
|
||||
it("should switch to displaying a check icon when the URL has been copied",
|
||||
function() {
|
||||
TestUtils.Simulate.click(buttonNode);
|
||||
|
||||
expect(buttonNode.classList.contains("checked")).eql(true);
|
||||
beforeEach(function() {
|
||||
roomEntry = mountRoomEntry({
|
||||
dispatcher: dispatcher,
|
||||
deleteRoom: sandbox.stub(),
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
copyButton = roomEntry.getDOMNode().querySelector("button.copy-link");
|
||||
});
|
||||
|
||||
it("should not display a check icon after mouse leaves the entry",
|
||||
function() {
|
||||
var roomNode = roomEntry.getDOMNode();
|
||||
TestUtils.Simulate.click(buttonNode);
|
||||
|
||||
TestUtils.SimulateNative.mouseOut(roomNode);
|
||||
|
||||
expect(buttonNode.classList.contains("checked")).eql(false);
|
||||
it("should not display a copy button by default", function() {
|
||||
expect(copyButton).to.not.equal(null);
|
||||
});
|
||||
|
||||
it("should copy the URL when the click event fires", function() {
|
||||
TestUtils.Simulate.click(copyButton);
|
||||
|
||||
sinon.assert.calledOnce(navigator.mozLoop.copyString);
|
||||
sinon.assert.calledWithExactly(navigator.mozLoop.copyString,
|
||||
roomData.roomUrl);
|
||||
});
|
||||
|
||||
it("should set state.urlCopied when the click event fires", function() {
|
||||
TestUtils.Simulate.click(copyButton);
|
||||
|
||||
expect(roomEntry.state.urlCopied).to.equal(true);
|
||||
});
|
||||
|
||||
it("should switch to displaying a check icon when the URL has been copied",
|
||||
function() {
|
||||
TestUtils.Simulate.click(copyButton);
|
||||
|
||||
expect(copyButton.classList.contains("checked")).eql(true);
|
||||
});
|
||||
|
||||
it("should not display a check icon after mouse leaves the entry",
|
||||
function() {
|
||||
var roomNode = roomEntry.getDOMNode();
|
||||
TestUtils.Simulate.click(copyButton);
|
||||
|
||||
TestUtils.SimulateNative.mouseOut(roomNode);
|
||||
|
||||
expect(copyButton.classList.contains("checked")).eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Delete button click", function() {
|
||||
var roomEntry, deleteButton;
|
||||
|
||||
beforeEach(function() {
|
||||
roomEntry = mountRoomEntry({
|
||||
dispatcher: dispatcher,
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
deleteButton = roomEntry.getDOMNode().querySelector("button.delete-link");
|
||||
});
|
||||
|
||||
it("should not display a delete button by default", function() {
|
||||
expect(deleteButton).to.not.equal(null);
|
||||
});
|
||||
|
||||
it("should call the delete function when clicked", function() {
|
||||
sandbox.stub(dispatcher, "dispatch");
|
||||
|
||||
TestUtils.Simulate.click(deleteButton);
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
new sharedActions.DeleteRoom({roomToken: roomData.roomToken}));
|
||||
});
|
||||
});
|
||||
|
||||
describe("Room URL click", function() {
|
||||
var roomEntry;
|
||||
|
||||
it("should dispatch an OpenRoom action", function() {
|
||||
sandbox.stub(dispatcher, "dispatch");
|
||||
roomEntry = mountRoomEntry({
|
||||
dispatcher: dispatcher,
|
||||
room: new loop.store.Room(roomData)
|
||||
});
|
||||
var urlLink = roomEntry.getDOMNode().querySelector("p > a");
|
||||
|
||||
TestUtils.Simulate.click(urlLink);
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWithExactly(dispatcher.dispatch,
|
||||
new sharedActions.OpenRoom({roomToken: roomData.roomToken}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("loop.panel.RoomList", function() {
|
||||
|
@ -775,20 +827,6 @@ describe("loop.panel", function() {
|
|||
var buttonNode = view.getDOMNode().querySelector("button[disabled]");
|
||||
expect(buttonNode).to.not.equal(null);
|
||||
});
|
||||
|
||||
describe("#openRoom", function() {
|
||||
it("should dispatch an OpenRoom action", function() {
|
||||
var view = createTestComponent();
|
||||
var dispatch = sandbox.stub(dispatcher, "dispatch");
|
||||
|
||||
view.openRoom({roomToken: "42cba"});
|
||||
|
||||
sinon.assert.calledOnce(dispatch);
|
||||
sinon.assert.calledWithExactly(dispatch, new sharedActions.OpenRoom({
|
||||
roomToken: "42cba"
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('loop.panel.ToSView', function() {
|
||||
|
|
|
@ -135,9 +135,9 @@ describe("loop.store.RoomListStore", function () {
|
|||
});
|
||||
});
|
||||
|
||||
describe("remove", function() {
|
||||
it("should remove a room from the list", function() {
|
||||
fakeMozLoop.rooms.trigger("remove", "remove", {
|
||||
describe("delete", function() {
|
||||
it("should delete a room from the list", function() {
|
||||
fakeMozLoop.rooms.trigger("delete", "delete", {
|
||||
roomToken: "_nxD4V4FflQ"
|
||||
});
|
||||
|
||||
|
|
|
@ -262,6 +262,15 @@ add_task(function* test_createRoom() {
|
|||
compareRooms(room, kCreateRoomProps);
|
||||
});
|
||||
|
||||
// Test if deleting a room works as expected.
|
||||
add_task(function* test_deleteRoom() {
|
||||
let roomToken = "QzBbvGmIZWU";
|
||||
let deletedRoom = yield LoopRooms.promise("delete", roomToken);
|
||||
Assert.equal(deletedRoom.roomToken, roomToken);
|
||||
let rooms = yield LoopRooms.promise("getAll");
|
||||
Assert.ok(!rooms.some((room) => room.roomToken == roomToken));
|
||||
});
|
||||
|
||||
// Test if opening a new room window works correctly.
|
||||
add_task(function* test_openRoom() {
|
||||
let openedUrl;
|
||||
|
|
|
@ -162,3 +162,24 @@
|
|||
/* Removes the fake video image for ended conversations */
|
||||
background: none;
|
||||
}
|
||||
|
||||
/* SVG icons showcase */
|
||||
|
||||
.svg-icon-entry {
|
||||
width: 180px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.svg-icon-entry > p {
|
||||
float: left;
|
||||
margin-right: .5rem;
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 16px 16px;
|
||||
background-position: center;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,41 @@
|
|||
detailsButtonLabel: "Retry",
|
||||
});
|
||||
|
||||
var SVGIcon = React.createClass({displayName: 'SVGIcon',
|
||||
render: function() {
|
||||
return (
|
||||
React.DOM.span({className: "svg-icon", style: {
|
||||
"background-image": "url(/content/shared/img/icons-16x16.svg#" + this.props.shapeId + ")"
|
||||
}})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var SVGIcons = React.createClass({displayName: 'SVGIcons',
|
||||
shapes: [
|
||||
"audio", "audio-hover", "audio-active", "block",
|
||||
"block-red", "block-hover", "block-active", "contacts", "contacts-hover",
|
||||
"contacts-active", "copy", "checkmark", "google", "google-hover",
|
||||
"google-active", "history", "history-hover", "history-active",
|
||||
"precall", "precall-hover", "precall-active", "settings", "settings-hover",
|
||||
"settings-active", "tag", "tag-hover", "tag-active", "trash", "unblock",
|
||||
"unblock-hover", "unblock-active", "video", "video-hover", "video-active"
|
||||
],
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
React.DOM.div({className: "svg-icon-list"},
|
||||
this.shapes.map(function(shapeId, i) {
|
||||
return React.DOM.div({className: "svg-icon-entry"},
|
||||
React.DOM.p(null, SVGIcon({key: i, shapeId: shapeId})),
|
||||
React.DOM.p(null, shapeId)
|
||||
);
|
||||
}, this)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Example = React.createClass({displayName: 'Example',
|
||||
makeId: function(prefix) {
|
||||
return (prefix || "") + this.props.summary.toLowerCase().replace(/\s/g, "-");
|
||||
|
@ -490,6 +525,12 @@
|
|||
UnsupportedDeviceView(null)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
Section({name: "SVG icons preview"},
|
||||
Example({summary: "16x16"},
|
||||
SVGIcons(null)
|
||||
)
|
||||
)
|
||||
|
||||
)
|
||||
|
|
|
@ -101,6 +101,41 @@
|
|||
detailsButtonLabel: "Retry",
|
||||
});
|
||||
|
||||
var SVGIcon = React.createClass({
|
||||
render: function() {
|
||||
return (
|
||||
<span className="svg-icon" style={{
|
||||
"background-image": "url(/content/shared/img/icons-16x16.svg#" + this.props.shapeId + ")"
|
||||
}} />
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var SVGIcons = React.createClass({
|
||||
shapes: [
|
||||
"audio", "audio-hover", "audio-active", "block",
|
||||
"block-red", "block-hover", "block-active", "contacts", "contacts-hover",
|
||||
"contacts-active", "copy", "checkmark", "google", "google-hover",
|
||||
"google-active", "history", "history-hover", "history-active",
|
||||
"precall", "precall-hover", "precall-active", "settings", "settings-hover",
|
||||
"settings-active", "tag", "tag-hover", "tag-active", "trash", "unblock",
|
||||
"unblock-hover", "unblock-active", "video", "video-hover", "video-active"
|
||||
],
|
||||
|
||||
render: function() {
|
||||
return (
|
||||
<div className="svg-icon-list">{
|
||||
this.shapes.map(function(shapeId, i) {
|
||||
return <div className="svg-icon-entry">
|
||||
<p><SVGIcon key={i} shapeId={shapeId} /></p>
|
||||
<p>{shapeId}</p>
|
||||
</div>;
|
||||
}, this)
|
||||
}</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Example = React.createClass({
|
||||
makeId: function(prefix) {
|
||||
return (prefix || "") + this.props.summary.toLowerCase().replace(/\s/g, "-");
|
||||
|
@ -492,6 +527,12 @@
|
|||
</Example>
|
||||
</Section>
|
||||
|
||||
<Section name="SVG icons preview">
|
||||
<Example summary="16x16">
|
||||
<SVGIcons />
|
||||
</Example>
|
||||
</Section>
|
||||
|
||||
</ShowCase>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -856,11 +856,7 @@ bin/libfreebl_32int64_3.so
|
|||
#ifdef XP_WIN
|
||||
@BINPATH@/webapp-uninstaller@BIN_SUFFIX@
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
@APPNAME@/Contents/MacOS/webapprt-stub@BIN_SUFFIX@
|
||||
#else
|
||||
@BINPATH@/webapprt-stub@BIN_SUFFIX@
|
||||
#endif
|
||||
@BINPATH@/webapprt/webapprt.ini
|
||||
@BINPATH@/webapprt/chrome.manifest
|
||||
@BINPATH@/webapprt/chrome/webapprt@JAREXT@
|
||||
|
|
|
@ -4,18 +4,18 @@ export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC120.CRT
|
|||
## moz tools location for 64-bit builders ##
|
||||
export MOZ_TOOLS=C:/mozilla-build/moztools
|
||||
|
||||
## includes: win8 sdk includes, winrt headers for metro, msvc std library, directx sdk for d3d9 ##
|
||||
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
|
||||
## includes: win8.1 sdk includes, winrt headers for metro, msvc std library, directx sdk for d3d9 ##
|
||||
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
|
||||
|
||||
## libs: win8 sdk x86 (32-bit) libs, msvc (32-bit) std library, msvc atl libs, directx sdk (32-bit) for d3d9 ##
|
||||
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
|
||||
export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
|
||||
## libs: win8.1 sdk x86 (32-bit) libs, msvc (32-bit) std library, msvc atl libs, directx sdk (32-bit) for d3d9 ##
|
||||
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
|
||||
export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
|
||||
|
||||
## paths: win8 sdk x86 (32-bit) tools, msvc (64-bit compiling 32-bit) build toolchain, moz tools ##
|
||||
export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64_x86:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}"
|
||||
## paths: win8.1 sdk x86 (32-bit) tools, msvc (64-bit compiling 32-bit) build toolchain, moz tools ##
|
||||
export PATH="/c/Program Files (x86)/Windows Kits/8.1/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64_x86:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}"
|
||||
|
||||
## WindowsSDKDir ##
|
||||
export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/"
|
||||
export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.1/"
|
||||
|
||||
. $topsrcdir/build/mozconfig.vs-common
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
_VSPATH="/c/tools/vs2013"
|
||||
export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x64/Microsoft.VC120.CRT
|
||||
|
||||
## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ##
|
||||
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
|
||||
## includes: win8.1 sdk includes, winrt headers for metro, msvc std library, directx sdk for d3d9 ##
|
||||
export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
|
||||
|
||||
## libs: win8 sdk x64 (64-bit) libs, msvc 10 (64-bit) std library, msvc 10 atl libs, directx sdk (64-bit) for d3d9 ##
|
||||
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
|
||||
export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
|
||||
## libs: win8.1 sdk x64 (64-bit) libs, msvc (64-bit) std library, msvc atl libs, directx sdk (64-bit) for d3d9 ##
|
||||
export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
|
||||
export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.1/Lib/winv6.3/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
|
||||
|
||||
## paths: win8 sdk x64 (64-bit) tools, msvc 10 (64-bit) build toolchain, moz tools ##
|
||||
export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x64:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/VC/BIN/x86_amd64:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:${PATH}"
|
||||
## paths: win8.1 sdk x64 (64-bit) tools, msvc (64-bit) build toolchain, moz tools ##
|
||||
export PATH="/c/Program Files (x86)/Windows Kits/8.1/bin/x64:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/VC/BIN/x86_amd64:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:${PATH}"
|
||||
|
||||
## WindowsSDKDir ##
|
||||
export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/"
|
||||
export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.1/"
|
||||
|
||||
. $topsrcdir/build/mozconfig.vs-common
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
|
|||
[test_popup-navigates-children.html]
|
||||
skip-if = buildapp == 'b2g' # b2g(Needs multiple window.open support, also uses docshelltreenode) b2g-debug(Needs multiple window.open support, also uses docshelltreenode) b2g-desktop(Needs multiple window.open support, also uses docshelltreenode)
|
||||
[test_reserved.html]
|
||||
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug))
|
||||
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || android_version == '10' #too slow on Android 2.3 aws only; bug 1030403
|
||||
[test_sessionhistory.html]
|
||||
skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'android' #RANDOM # b2g-debug(Perma-orange on debug emulator builds) b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
|
||||
[test_sibling-matching-parent.html]
|
||||
|
|
|
@ -11,6 +11,7 @@ support-files =
|
|||
[webgl-mochitest/test_fb_param_crash.html]
|
||||
[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
|
||||
[webgl-mochitest/test_noprog_draw.html]
|
||||
[webgl-mochitest/test_privileged_exts.html]
|
||||
[webgl-mochitest/test_texsubimage_float.html]
|
||||
|
|
|
@ -395,7 +395,7 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop spec
|
|||
[test_bug658746.html]
|
||||
[test_bug659596.html]
|
||||
[test_bug659743.xml]
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
|
||||
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') || android_version == '10' #Bug 931116, b2g desktop specific, initial triage #Android 2.3 aws only; bug 1031103
|
||||
[test_bug660663.html]
|
||||
[test_bug660959-1.html]
|
||||
[test_bug660959-2.html]
|
||||
|
|
|
@ -1907,6 +1907,17 @@ ContentChild::RecvGeolocationUpdate(const GeoPosition& somewhere)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvGeolocationError(const uint16_t& errorCode)
|
||||
{
|
||||
nsCOMPtr<nsIGeolocationUpdate> gs = do_GetService("@mozilla.org/geolocation/service;1");
|
||||
if (!gs) {
|
||||
return true;
|
||||
}
|
||||
gs->NotifyError(errorCode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvUpdateDictionaryList(const InfallibleTArray<nsString>& aDictionaries)
|
||||
{
|
||||
|
|
|
@ -305,6 +305,8 @@ public:
|
|||
|
||||
virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvGeolocationError(const uint16_t& errorCode) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvUpdateDictionaryList(const InfallibleTArray<nsString>& aDictionaries) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvAddPermission(const IPC::Permission& permission) MOZ_OVERRIDE;
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
#include "nsICycleCollectorListener.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMGeoGeolocation.h"
|
||||
#include "nsIDOMGeoPositionError.h"
|
||||
#include "mozilla/dom/WakeLock.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIExternalProtocolService.h"
|
||||
|
@ -2590,6 +2591,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ContentParent)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIContentParent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionErrorCallback)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -3689,7 +3691,7 @@ ContentParent::RecvFilePathUpdateNotify(const nsString& aType,
|
|||
}
|
||||
|
||||
static int32_t
|
||||
AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, bool highAccuracy)
|
||||
AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, nsIDOMGeoPositionErrorCallback* errorCallBack, bool highAccuracy)
|
||||
{
|
||||
nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
|
||||
if (!geo) {
|
||||
|
@ -3701,7 +3703,7 @@ AddGeolocationListener(nsIDOMGeoPositionCallback* watcher, bool highAccuracy)
|
|||
options->mMaximumAge = 0;
|
||||
options->mEnableHighAccuracy = highAccuracy;
|
||||
int32_t retval = 1;
|
||||
geo->WatchPosition(watcher, nullptr, options, &retval);
|
||||
geo->WatchPosition(watcher, errorCallBack, options, &retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -3722,7 +3724,7 @@ ContentParent::RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
|
|||
// To ensure no geolocation updates are skipped, we always force the
|
||||
// creation of a new listener.
|
||||
RecvRemoveGeolocationListener();
|
||||
mGeolocationWatchID = AddGeolocationListener(this, aHighAccuracy);
|
||||
mGeolocationWatchID = AddGeolocationListener(this, this, aHighAccuracy);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3747,7 +3749,7 @@ ContentParent::RecvSetGeolocationHigherAccuracy(const bool& aEnable)
|
|||
// so this check allows us to forgo securing privileges.
|
||||
if (mGeolocationWatchID != -1) {
|
||||
RecvRemoveGeolocationListener();
|
||||
mGeolocationWatchID = AddGeolocationListener(this, aEnable);
|
||||
mGeolocationWatchID = AddGeolocationListener(this, this, aEnable);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -3759,6 +3761,17 @@ ContentParent::HandleEvent(nsIDOMGeoPosition* postion)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentParent::HandleEvent(nsIDOMGeoPositionError* postionError)
|
||||
{
|
||||
int16_t errorCode;
|
||||
nsresult rv;
|
||||
rv = postionError->GetCode(&errorCode);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
unused << SendGeolocationError(errorCode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsConsoleService *
|
||||
ContentParent::GetConsoleService()
|
||||
{
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "nsIObserver.h"
|
||||
#include "nsIThreadInternal.h"
|
||||
#include "nsIDOMGeoPositionCallback.h"
|
||||
#include "nsIDOMGeoPositionErrorCallback.h"
|
||||
#include "PermissionMessageUtils.h"
|
||||
|
||||
#define CHILD_PROCESS_SHUTDOWN_MESSAGE NS_LITERAL_STRING("child-process-shutdown")
|
||||
|
@ -68,6 +69,7 @@ class ContentParent MOZ_FINAL : public PContentParent
|
|||
, public nsIContentParent
|
||||
, public nsIObserver
|
||||
, public nsIDOMGeoPositionCallback
|
||||
, public nsIDOMGeoPositionErrorCallback
|
||||
, public mozilla::LinkedListElement<ContentParent>
|
||||
{
|
||||
typedef mozilla::ipc::GeckoChildProcessHost GeckoChildProcessHost;
|
||||
|
@ -160,6 +162,7 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIDOMGEOPOSITIONCALLBACK
|
||||
NS_DECL_NSIDOMGEOPOSITIONERRORCALLBACK
|
||||
|
||||
/**
|
||||
* MessageManagerCallback methods that we override.
|
||||
|
|
|
@ -449,6 +449,8 @@ child:
|
|||
|
||||
GeolocationUpdate(GeoPosition somewhere);
|
||||
|
||||
GeolocationError(uint16_t errorCode);
|
||||
|
||||
UpdateDictionaryList(nsString[] dictionaries);
|
||||
|
||||
// nsIPermissionManager messages
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[DEFAULT]
|
||||
skip-if = (os == 'win' && contentSandbox != 'off') # contentSandbox(Bug 1042735)
|
||||
skip-if = (os == 'win' && contentSandbox != 'off') || android_version == '10' # contentSandbox(Bug 1042735) #Android 2.3 only; bug 981881
|
||||
support-files =
|
||||
head.js
|
||||
constraints.js
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
[test_bluetooth.html]
|
||||
skip-if = (toolkit == 'gonk' && debug) # bug 1093079
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
|
||||
function successCallback() {
|
||||
do_check_true(false);
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
function errorCallback(err) {
|
||||
do_check_eq(Ci.nsIDOMGeoPositionError.POSITION_UNAVAILABLE, err.code);
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
do_test_pending();
|
||||
|
||||
if (Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||||
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
|
||||
// XPCShell does not get a profile by default. The geolocation service
|
||||
// depends on the settings service which uses IndexedDB and IndexedDB
|
||||
// needs a place where it can store databases.
|
||||
do_get_profile();
|
||||
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
prefs.setBoolPref("geo.wifi.scan", false);
|
||||
prefs.setCharPref("geo.wifi.uri", "UrlNotUsedHere:");
|
||||
prefs.setBoolPref("dom.testing.ignore_ipc_principal", true);
|
||||
}
|
||||
|
||||
geolocation = Cc["@mozilla.org/geolocation;1"].getService(Ci.nsISupports);
|
||||
geolocation.getCurrentPosition(successCallback, errorCallback);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
|
||||
function run_test() {
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
prefs.setBoolPref("geo.wifi.scan", false);
|
||||
|
||||
prefs.setCharPref("geo.wifi.uri", "UrlNotUsedHere");
|
||||
prefs.setBoolPref("dom.testing.ignore_ipc_principal", true);
|
||||
run_test_in_child("./test_geolocation_position_unavailable.js");
|
||||
}
|
|
@ -18,4 +18,8 @@ skip-if = os == "mac" || os == "android"
|
|||
skip-if = os == "android"
|
||||
[test_geolocation_reset_accuracy_wrap.js]
|
||||
skip-if = os == "mac" || os == "android"
|
||||
[test_geolocation_position_unavailable.js]
|
||||
skip-if = os == "android"
|
||||
[test_geolocation_position_unavailable_wrap.js]
|
||||
skip-if = os == "mac" || os == "android"
|
||||
[test_PromiseDebugging.js]
|
||||
|
|
|
@ -747,7 +747,7 @@ MessageChannel::SendAndWait(Message* aMsg, Message* aReply)
|
|||
MOZ_ASSERT(mRecvd->type() == replyType, "wrong reply type");
|
||||
MOZ_ASSERT(mRecvd->seqno() == replySeqno);
|
||||
|
||||
*aReply = *mRecvd;
|
||||
*aReply = Move(*mRecvd);
|
||||
mRecvd = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
@ -838,10 +838,10 @@ MessageChannel::Call(Message* aMsg, Message* aReply)
|
|||
if ((it = mOutOfTurnReplies.find(mInterruptStack.top().seqno()))
|
||||
!= mOutOfTurnReplies.end())
|
||||
{
|
||||
recvd = it->second;
|
||||
recvd = Move(it->second);
|
||||
mOutOfTurnReplies.erase(it);
|
||||
} else if (!mPending.empty()) {
|
||||
recvd = mPending.front();
|
||||
recvd = Move(mPending.front());
|
||||
mPending.pop_front();
|
||||
} else {
|
||||
// because of subtleties with nested event loops, it's possible
|
||||
|
@ -882,7 +882,7 @@ MessageChannel::Call(Message* aMsg, Message* aReply)
|
|||
if ((mSide == ChildSide && recvd.seqno() > outcall.seqno()) ||
|
||||
(mSide != ChildSide && recvd.seqno() < outcall.seqno()))
|
||||
{
|
||||
mOutOfTurnReplies[recvd.seqno()] = recvd;
|
||||
mOutOfTurnReplies[recvd.seqno()] = Move(recvd);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -896,8 +896,9 @@ MessageChannel::Call(Message* aMsg, Message* aReply)
|
|||
// this frame and return the reply.
|
||||
mInterruptStack.pop();
|
||||
|
||||
if (!recvd.is_reply_error()) {
|
||||
*aReply = recvd;
|
||||
bool is_reply_error = recvd.is_reply_error();
|
||||
if (!is_reply_error) {
|
||||
*aReply = Move(recvd);
|
||||
}
|
||||
|
||||
// If we have no more pending out calls waiting on replies, then
|
||||
|
@ -906,7 +907,7 @@ MessageChannel::Call(Message* aMsg, Message* aReply)
|
|||
"still have pending replies with no pending out-calls",
|
||||
true);
|
||||
|
||||
return !recvd.is_reply_error();
|
||||
return !is_reply_error;
|
||||
}
|
||||
|
||||
// Dispatch an Interrupt in-call. Snapshot the current stack depth while we
|
||||
|
@ -1017,7 +1018,7 @@ MessageChannel::OnMaybeDequeueOne()
|
|||
if (IsOnCxxStack() && recvd.is_interrupt() && recvd.is_reply()) {
|
||||
// We probably just received a reply in a nested loop for an
|
||||
// Interrupt call sent before entering that loop.
|
||||
mOutOfTurnReplies[recvd.seqno()] = recvd;
|
||||
mOutOfTurnReplies[recvd.seqno()] = Move(recvd);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ skip-if = toolkit == 'android'
|
|||
[test_initial_storage.html]
|
||||
[test_keyframes_rules.html]
|
||||
[test_media_queries.html]
|
||||
skip-if = (toolkit == 'gonk' && debug) #debug-only failure; timed out
|
||||
skip-if = (toolkit == 'gonk' && debug) || android_version == '10' #debug-only failure; timed out #Android 2.3 aws only; bug 1030419
|
||||
[test_media_queries_dynamic.html]
|
||||
[test_media_queries_dynamic_xbl.html]
|
||||
[test_media_query_list.html]
|
||||
|
@ -170,7 +170,6 @@ skip-if = (toolkit == 'gonk' && debug) #debug-only failure; timed out
|
|||
[test_parse_url.html]
|
||||
[test_parser_diagnostics_unprintables.html]
|
||||
[test_pixel_lengths.html]
|
||||
skip-if = true # bug 891840 - intermittent crashes
|
||||
[test_pointer-events.html]
|
||||
[test_position_sticky.html]
|
||||
support-files = file_position_sticky.html
|
||||
|
@ -201,6 +200,7 @@ skip-if = (toolkit == 'gonk' && debug) || toolkit == 'android' #bug 775227 #debu
|
|||
[test_transitions_and_restyles.html]
|
||||
[test_transitions_and_zoom.html]
|
||||
[test_transitions_cancel_near_end.html]
|
||||
skip-if = android_version == '10' #Android 2.3 aws only; bug 1030432
|
||||
[test_transitions_computed_values.html]
|
||||
[test_transitions_computed_value_combinations.html]
|
||||
[test_transitions_events.html]
|
||||
|
|
|
@ -222,6 +222,10 @@ BackCert::RememberExtension(Reader& extnID, const Input& extnValue,
|
|||
static const uint8_t id_pe_authorityInfoAccess[] = {
|
||||
0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01
|
||||
};
|
||||
// python DottedOIDToCode.py id-pkix-ocsp-nocheck 1.3.6.1.5.5.7.48.1.5
|
||||
static const uint8_t id_pkix_ocsp_nocheck[] = {
|
||||
0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05
|
||||
};
|
||||
// python DottedOIDToCode.py Netscape-certificate-type 2.16.840.1.113730.1.1
|
||||
static const uint8_t Netscape_certificate_type[] = {
|
||||
0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01
|
||||
|
@ -237,6 +241,17 @@ BackCert::RememberExtension(Reader& extnID, const Input& extnValue,
|
|||
// ignore the extension.
|
||||
Input dummyPolicyConstraints;
|
||||
|
||||
// We don't need to save the contents of this extension if it is present. We
|
||||
// just need to handle its presence (it is essentially ignored right now).
|
||||
Input dummyOCSPNocheck;
|
||||
|
||||
// For compatibility reasons, for some extensions we have to allow empty
|
||||
// extension values. This would normally interfere with our duplicate
|
||||
// extension checking code. However, as long as the extensions we allow to
|
||||
// have empty values are also the ones we implicitly allow duplicates of,
|
||||
// this will work fine.
|
||||
bool emptyValueAllowed = false;
|
||||
|
||||
// RFC says "Conforming CAs MUST mark this extension as non-critical" for
|
||||
// both authorityKeyIdentifier and subjectKeyIdentifier, and we do not use
|
||||
// them for anything, so we totally ignore them here.
|
||||
|
@ -259,6 +274,17 @@ BackCert::RememberExtension(Reader& extnID, const Input& extnValue,
|
|||
out = &inhibitAnyPolicy;
|
||||
} else if (extnID.MatchRest(id_pe_authorityInfoAccess)) {
|
||||
out = &authorityInfoAccess;
|
||||
} else if (extnID.MatchRest(id_pkix_ocsp_nocheck) && critical) {
|
||||
// We need to make sure we don't reject delegated OCSP response signing
|
||||
// certificates that contain the id-pkix-ocsp-nocheck extension marked as
|
||||
// critical when validating OCSP responses. Without this, an application
|
||||
// that implements soft-fail OCSP might ignore a valid Revoked or Unknown
|
||||
// response, and an application that implements hard-fail OCSP might fail
|
||||
// to connect to a server given a valid Good response.
|
||||
out = &dummyOCSPNocheck;
|
||||
// We allow this extension to have an empty value.
|
||||
// See http://comments.gmane.org/gmane.ietf.x509/30947
|
||||
emptyValueAllowed = true;
|
||||
} else if (extnID.MatchRest(Netscape_certificate_type) && critical) {
|
||||
out = &criticalNetscapeCertificateType;
|
||||
}
|
||||
|
@ -266,7 +292,7 @@ BackCert::RememberExtension(Reader& extnID, const Input& extnValue,
|
|||
if (out) {
|
||||
// Don't allow an empty value for any extension we understand. This way, we
|
||||
// can test out->GetLength() != 0 or out->Init() to check for duplicates.
|
||||
if (extnValue.GetLength() == 0) {
|
||||
if (extnValue.GetLength() == 0 && !emptyValueAllowed) {
|
||||
return Result::ERROR_EXTENSION_VALUE_INVALID;
|
||||
}
|
||||
if (out->Init(extnValue) != Success) {
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include "pkix/pkix.h"
|
||||
#include "pkixder.h"
|
||||
#include "pkixgtest.h"
|
||||
#include "pkixtestutil.h"
|
||||
|
||||
|
@ -107,7 +108,144 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
class pkixcert_extension : public ::testing::Test
|
||||
// python DottedOIDToCode.py --tlv unknownExtensionOID 1.3.6.1.4.1.13769.666.666.666.1.500.9.3
|
||||
static const uint8_t tlv_unknownExtensionOID[] = {
|
||||
0x06, 0x12, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, 0x1a, 0x85, 0x1a,
|
||||
0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x03
|
||||
};
|
||||
|
||||
// python DottedOIDToCode.py --tlv id-pe-authorityInformationAccess 1.3.6.1.5.5.7.1.1
|
||||
static const uint8_t tlv_id_pe_authorityInformationAccess[] = {
|
||||
0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01
|
||||
};
|
||||
|
||||
// python DottedOIDToCode.py --tlv wrongExtensionOID 1.3.6.6.1.5.5.7.1.1
|
||||
// (there is an extra "6" that shouldn't be in this OID)
|
||||
static const uint8_t tlv_wrongExtensionOID[] = {
|
||||
0x06, 0x09, 0x2b, 0x06, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01
|
||||
};
|
||||
|
||||
// python DottedOIDToCode.py --tlv id-ce-unknown 2.5.29.55
|
||||
// (this is a made-up OID for testing "id-ce"-prefixed OIDs that mozilla::pkix
|
||||
// doesn't handle)
|
||||
static const uint8_t tlv_id_ce_unknown[] = {
|
||||
0x06, 0x03, 0x55, 0x1d, 0x37
|
||||
};
|
||||
|
||||
// python DottedOIDToCode.py --tlv id-ce-inhibitAnyPolicy 2.5.29.54
|
||||
static const uint8_t tlv_id_ce_inhibitAnyPolicy[] = {
|
||||
0x06, 0x03, 0x55, 0x1d, 0x36
|
||||
};
|
||||
|
||||
// python DottedOIDToCode.py --tlv id-pkix-ocsp-nocheck 1.3.6.1.5.5.7.48.1.5
|
||||
static const uint8_t tlv_id_pkix_ocsp_nocheck[] = {
|
||||
0x06, 0x09, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05
|
||||
};
|
||||
|
||||
template <size_t L>
|
||||
inline ByteString
|
||||
BytesToByteString(const uint8_t (&bytes)[L])
|
||||
{
|
||||
return ByteString(bytes, L);
|
||||
}
|
||||
|
||||
struct ExtensionTestcase
|
||||
{
|
||||
ByteString extension;
|
||||
Result expectedResult;
|
||||
};
|
||||
|
||||
static const ExtensionTestcase EXTENSION_TESTCASES[] =
|
||||
{
|
||||
// Tests that a non-critical extension not in the id-ce or id-pe arcs (which
|
||||
// is thus unknown to us) verifies successfully even if empty (extensions we
|
||||
// know about aren't normally allowed to be empty).
|
||||
{ TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_unknownExtensionOID) +
|
||||
TLV(der::OCTET_STRING, ByteString())),
|
||||
Success
|
||||
},
|
||||
|
||||
// Tests that a critical extension not in the id-ce or id-pe arcs (which is
|
||||
// thus unknown to us) is detected and that verification fails with the
|
||||
// appropriate error.
|
||||
{ TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_unknownExtensionOID) +
|
||||
Boolean(true) +
|
||||
TLV(der::OCTET_STRING, ByteString())),
|
||||
Result::ERROR_UNKNOWN_CRITICAL_EXTENSION
|
||||
},
|
||||
|
||||
// Tests that a id-pe-authorityInformationAccess critical extension
|
||||
// is detected and that verification succeeds.
|
||||
// XXX: According to RFC 5280 an AIA that consists of an empty sequence is
|
||||
// not legal, but we accept it and that is not what we're testing here.
|
||||
{ TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_id_pe_authorityInformationAccess) +
|
||||
Boolean(true) +
|
||||
TLV(der::OCTET_STRING, TLV(der::SEQUENCE, ByteString()))),
|
||||
Success
|
||||
},
|
||||
|
||||
// Tests that an incorrect OID for id-pe-authorityInformationAccess
|
||||
// (when marked critical) is detected and that verification fails.
|
||||
// (Until bug 1020993 was fixed, this wrong value was used for
|
||||
// id-pe-authorityInformationAccess.)
|
||||
{ TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_wrongExtensionOID) +
|
||||
Boolean(true) +
|
||||
TLV(der::OCTET_STRING, ByteString())),
|
||||
Result::ERROR_UNKNOWN_CRITICAL_EXTENSION
|
||||
},
|
||||
|
||||
// We know about some id-ce extensions (OID arc 2.5.29), but not all of them.
|
||||
// Tests that an unknown id-ce extension is detected and that verification
|
||||
// fails.
|
||||
{ TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_id_ce_unknown) +
|
||||
Boolean(true) +
|
||||
TLV(der::OCTET_STRING, ByteString())),
|
||||
Result::ERROR_UNKNOWN_CRITICAL_EXTENSION
|
||||
},
|
||||
|
||||
// Tests that a certificate with a known critical id-ce extension (in this
|
||||
// case, OID 2.5.29.54, which is id-ce-inhibitAnyPolicy), verifies
|
||||
// successfully.
|
||||
{ TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_id_ce_inhibitAnyPolicy) +
|
||||
Boolean(true) +
|
||||
TLV(der::OCTET_STRING, Integer(0))),
|
||||
Success
|
||||
},
|
||||
|
||||
// Tests that a certificate with the id-pkix-ocsp-nocheck extension (marked
|
||||
// critical) verifies successfully.
|
||||
// RFC 6960:
|
||||
// ext-ocsp-nocheck EXTENSION ::= { SYNTAX NULL IDENTIFIED
|
||||
// BY id-pkix-ocsp-nocheck }
|
||||
{ TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_id_pkix_ocsp_nocheck) +
|
||||
Boolean(true) +
|
||||
TLV(der::OCTET_STRING, TLV(der::NULLTag, ByteString()))),
|
||||
Success
|
||||
},
|
||||
|
||||
// Tests that a certificate with another representation of the
|
||||
// id-pkix-ocsp-nocheck extension (marked critical) verifies successfully.
|
||||
// According to http://comments.gmane.org/gmane.ietf.x509/30947,
|
||||
// some code creates certificates where value of the extension is
|
||||
// an empty OCTET STRING.
|
||||
{ TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_id_pkix_ocsp_nocheck) +
|
||||
Boolean(true) +
|
||||
TLV(der::OCTET_STRING, ByteString())),
|
||||
Success
|
||||
},
|
||||
};
|
||||
|
||||
class pkixcert_extension
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<ExtensionTestcase>
|
||||
{
|
||||
protected:
|
||||
static TrustEverythingTrustDomain trustDomain;
|
||||
|
@ -115,29 +253,15 @@ protected:
|
|||
|
||||
/*static*/ TrustEverythingTrustDomain pkixcert_extension::trustDomain;
|
||||
|
||||
// Tests that a critical extension not in the id-ce or id-pe arcs (which is
|
||||
// thus unknown to us) is detected and that verification fails with the
|
||||
// appropriate error.
|
||||
TEST_F(pkixcert_extension, UnknownCriticalExtension)
|
||||
TEST_P(pkixcert_extension, ExtensionHandledProperly)
|
||||
{
|
||||
static const uint8_t unknownCriticalExtensionBytes[] = {
|
||||
0x30, 0x19, // SEQUENCE (length = 25)
|
||||
0x06, 0x12, // OID (length = 18)
|
||||
// 1.3.6.1.4.1.13769.666.666.666.1.500.9.3
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, 0x1a,
|
||||
0x85, 0x1a, 0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x03,
|
||||
0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE
|
||||
0x04, 0x00 // OCTET STRING (length = 0)
|
||||
};
|
||||
static const ByteString
|
||||
unknownCriticalExtension(unknownCriticalExtensionBytes,
|
||||
sizeof(unknownCriticalExtensionBytes));
|
||||
const char* certCN = "Cert With Unknown Critical Extension";
|
||||
ByteString cert(CreateCertWithOneExtension(certCN, unknownCriticalExtension));
|
||||
const ExtensionTestcase& testcase(GetParam());
|
||||
const char* cn = "Cert Extension Test";
|
||||
ByteString cert(CreateCertWithOneExtension(cn, testcase.extension));
|
||||
ASSERT_FALSE(ENCODING_FAILED(cert));
|
||||
Input certInput;
|
||||
ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
|
||||
ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION,
|
||||
ASSERT_EQ(testcase.expectedResult,
|
||||
BuildCertChain(trustDomain, certInput, Now(),
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::noParticularKeyUsageRequired,
|
||||
|
@ -146,172 +270,24 @@ TEST_F(pkixcert_extension, UnknownCriticalExtension)
|
|||
nullptr/*stapledOCSPResponse*/));
|
||||
}
|
||||
|
||||
// Tests that a non-critical extension not in the id-ce or id-pe arcs (which is
|
||||
// thus unknown to us) verifies successfully.
|
||||
TEST_F(pkixcert_extension, UnknownNonCriticalExtension)
|
||||
{
|
||||
static const uint8_t unknownNonCriticalExtensionBytes[] = {
|
||||
0x30, 0x16, // SEQUENCE (length = 22)
|
||||
0x06, 0x12, // OID (length = 18)
|
||||
// 1.3.6.1.4.1.13769.666.666.666.1.500.9.3
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, 0x1a,
|
||||
0x85, 0x1a, 0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x03,
|
||||
0x04, 0x00 // OCTET STRING (length = 0)
|
||||
};
|
||||
static const ByteString
|
||||
unknownNonCriticalExtension(unknownNonCriticalExtensionBytes,
|
||||
sizeof(unknownNonCriticalExtensionBytes));
|
||||
const char* certCN = "Cert With Unknown NonCritical Extension";
|
||||
ByteString cert(CreateCertWithOneExtension(certCN,
|
||||
unknownNonCriticalExtension));
|
||||
ASSERT_FALSE(ENCODING_FAILED(cert));
|
||||
Input certInput;
|
||||
ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
|
||||
ASSERT_EQ(Success,
|
||||
BuildCertChain(trustDomain, certInput, Now(),
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::noParticularKeyUsageRequired,
|
||||
KeyPurposeId::anyExtendedKeyUsage,
|
||||
CertPolicyId::anyPolicy,
|
||||
nullptr/*stapledOCSPResponse*/));
|
||||
}
|
||||
|
||||
// Tests that an incorrect OID for id-pe-authorityInformationAccess
|
||||
// (when marked critical) is detected and that verification fails.
|
||||
// (Until bug 1020993 was fixed, the code checked for this OID.)
|
||||
TEST_F(pkixcert_extension, WrongOIDCriticalExtension)
|
||||
{
|
||||
static const uint8_t wrongOIDCriticalExtensionBytes[] = {
|
||||
0x30, 0x10, // SEQUENCE (length = 16)
|
||||
0x06, 0x09, // OID (length = 9)
|
||||
// 1.3.6.6.1.5.5.7.1.1 (there is an extra "6" that shouldn't be there)
|
||||
0x2b, 0x06, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
|
||||
0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE
|
||||
0x04, 0x00 // OCTET STRING (length = 0)
|
||||
};
|
||||
static const ByteString
|
||||
wrongOIDCriticalExtension(wrongOIDCriticalExtensionBytes,
|
||||
sizeof(wrongOIDCriticalExtensionBytes));
|
||||
const char* certCN = "Cert With Critical Wrong OID Extension";
|
||||
ByteString cert(CreateCertWithOneExtension(certCN,
|
||||
wrongOIDCriticalExtension));
|
||||
ASSERT_FALSE(ENCODING_FAILED(cert));
|
||||
Input certInput;
|
||||
ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
|
||||
ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION,
|
||||
BuildCertChain(trustDomain, certInput, Now(),
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::noParticularKeyUsageRequired,
|
||||
KeyPurposeId::anyExtendedKeyUsage,
|
||||
CertPolicyId::anyPolicy,
|
||||
nullptr/*stapledOCSPResponse*/));
|
||||
}
|
||||
|
||||
// Tests that a id-pe-authorityInformationAccess critical extension
|
||||
// is detected and that verification succeeds.
|
||||
TEST_F(pkixcert_extension, CriticalAIAExtension)
|
||||
{
|
||||
// XXX: According to RFC 5280 an AIA that consists of an empty sequence is
|
||||
// not legal, but we accept it and that is not what we're testing here.
|
||||
static const uint8_t criticalAIAExtensionBytes[] = {
|
||||
0x30, 0x11, // SEQUENCE (length = 17)
|
||||
0x06, 0x08, // OID (length = 8)
|
||||
// 1.3.6.1.5.5.7.1.1
|
||||
0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01,
|
||||
0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE
|
||||
0x04, 0x02, // OCTET STRING (length = 2)
|
||||
0x30, 0x00, // SEQUENCE (length = 0)
|
||||
};
|
||||
static const ByteString
|
||||
criticalAIAExtension(criticalAIAExtensionBytes,
|
||||
sizeof(criticalAIAExtensionBytes));
|
||||
const char* certCN = "Cert With Critical AIA Extension";
|
||||
ByteString cert(CreateCertWithOneExtension(certCN, criticalAIAExtension));
|
||||
ASSERT_FALSE(ENCODING_FAILED(cert));
|
||||
Input certInput;
|
||||
ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
|
||||
ASSERT_EQ(Success,
|
||||
BuildCertChain(trustDomain, certInput, Now(),
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::noParticularKeyUsageRequired,
|
||||
KeyPurposeId::anyExtendedKeyUsage,
|
||||
CertPolicyId::anyPolicy,
|
||||
nullptr/*stapledOCSPResponse*/));
|
||||
}
|
||||
|
||||
// We know about some id-ce extensions (OID arc 2.5.29), but not all of them.
|
||||
// Tests that an unknown id-ce extension is detected and that verification
|
||||
// fails.
|
||||
TEST_F(pkixcert_extension, UnknownCriticalCEExtension)
|
||||
{
|
||||
static const uint8_t unknownCriticalCEExtensionBytes[] = {
|
||||
0x30, 0x0a, // SEQUENCE (length = 10)
|
||||
0x06, 0x03, // OID (length = 3)
|
||||
0x55, 0x1d, 0x37, // 2.5.29.55
|
||||
0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE
|
||||
0x04, 0x00 // OCTET STRING (length = 0)
|
||||
};
|
||||
static const ByteString
|
||||
unknownCriticalCEExtension(unknownCriticalCEExtensionBytes,
|
||||
sizeof(unknownCriticalCEExtensionBytes));
|
||||
const char* certCN = "Cert With Unknown Critical id-ce Extension";
|
||||
ByteString cert(CreateCertWithOneExtension(certCN,
|
||||
unknownCriticalCEExtension));
|
||||
ASSERT_FALSE(ENCODING_FAILED(cert));
|
||||
Input certInput;
|
||||
ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
|
||||
ASSERT_EQ(Result::ERROR_UNKNOWN_CRITICAL_EXTENSION,
|
||||
BuildCertChain(trustDomain, certInput, Now(),
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::noParticularKeyUsageRequired,
|
||||
KeyPurposeId::anyExtendedKeyUsage,
|
||||
CertPolicyId::anyPolicy,
|
||||
nullptr/*stapledOCSPResponse*/));
|
||||
}
|
||||
|
||||
// Tests that a certificate with a known critical id-ce extension (in this case,
|
||||
// OID 2.5.29.54, which is id-ce-inhibitAnyPolicy), verifies successfully.
|
||||
TEST_F(pkixcert_extension, KnownCriticalCEExtension)
|
||||
{
|
||||
static const uint8_t criticalCEExtensionBytes[] = {
|
||||
0x30, 0x0d, // SEQUENCE (length = 13)
|
||||
0x06, 0x03, // OID (length = 3)
|
||||
0x55, 0x1d, 0x36, // 2.5.29.54 (id-ce-inhibitAnyPolicy)
|
||||
0x01, 0x01, 0xff, // BOOLEAN (length = 1) TRUE
|
||||
0x04, 0x03, // OCTET STRING (length = 3)
|
||||
0x02, 0x01, 0x00, // INTEGER (length = 1, value = 0)
|
||||
};
|
||||
static const ByteString
|
||||
criticalCEExtension(criticalCEExtensionBytes,
|
||||
sizeof(criticalCEExtensionBytes));
|
||||
const char* certCN = "Cert With Known Critical id-ce Extension";
|
||||
ByteString cert(CreateCertWithOneExtension(certCN, criticalCEExtension));
|
||||
ASSERT_FALSE(ENCODING_FAILED(cert));
|
||||
Input certInput;
|
||||
ASSERT_EQ(Success, certInput.Init(cert.data(), cert.length()));
|
||||
ASSERT_EQ(Success,
|
||||
BuildCertChain(trustDomain, certInput, Now(),
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::noParticularKeyUsageRequired,
|
||||
KeyPurposeId::anyExtendedKeyUsage,
|
||||
CertPolicyId::anyPolicy,
|
||||
nullptr/*stapledOCSPResponse*/));
|
||||
}
|
||||
INSTANTIATE_TEST_CASE_P(pkixcert_extension,
|
||||
pkixcert_extension,
|
||||
testing::ValuesIn(EXTENSION_TESTCASES));
|
||||
|
||||
// Two subjectAltNames must result in an error.
|
||||
TEST_F(pkixcert_extension, DuplicateSubjectAltName)
|
||||
{
|
||||
static const uint8_t DER_BYTES[] = {
|
||||
0x30, 22, // SEQUENCE (length = 22)
|
||||
0x06, 3, // OID (length = 3)
|
||||
0x55, 0x1d, 0x11, // 2.5.29.17
|
||||
0x04, 15, // OCTET STRING (length = 15)
|
||||
0x30, 13, // GeneralNames (SEQUENCE) (length = 13)
|
||||
0x82, 11, // [2] (dNSName) (length = 11)
|
||||
'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'
|
||||
// python DottedOIDToCode.py --tlv id-ce-subjectAltName 2.5.29.17
|
||||
static const uint8_t tlv_id_ce_subjectAltName[] = {
|
||||
0x06, 0x03, 0x55, 0x1d, 0x11
|
||||
};
|
||||
static const ByteString DER(DER_BYTES, sizeof(DER_BYTES));
|
||||
static const ByteString extensions[] = { DER, DER, ByteString() };
|
||||
|
||||
ByteString subjectAltName(
|
||||
TLV(der::SEQUENCE,
|
||||
BytesToByteString(tlv_id_ce_subjectAltName) +
|
||||
TLV(der::OCTET_STRING, TLV(der::SEQUENCE, DNSName("example.com")))));
|
||||
static const ByteString extensions[] = { subjectAltName, subjectAltName,
|
||||
ByteString() };
|
||||
static const char* certCN = "Cert With Duplicate subjectAltName";
|
||||
ByteString cert(CreateCertWithExtensions(certCN, extensions));
|
||||
ASSERT_FALSE(ENCODING_FAILED(cert));
|
||||
|
|
|
@ -183,7 +183,7 @@ BitString(const ByteString& rawBytes, bool corrupt)
|
|||
return TLV(der::BIT_STRING, prefixed);
|
||||
}
|
||||
|
||||
static ByteString
|
||||
ByteString
|
||||
Boolean(bool value)
|
||||
{
|
||||
ByteString encodedValue;
|
||||
|
@ -191,7 +191,7 @@ Boolean(bool value)
|
|||
return TLV(der::BOOLEAN, encodedValue);
|
||||
}
|
||||
|
||||
static ByteString
|
||||
ByteString
|
||||
Integer(long value)
|
||||
{
|
||||
if (value < 0 || value > 127) {
|
||||
|
|
|
@ -111,6 +111,8 @@ mozilla::pkix::Time YMDHMS(int16_t year, int16_t month, int16_t day,
|
|||
int16_t hour, int16_t minutes, int16_t seconds);
|
||||
|
||||
ByteString TLV(uint8_t tag, const ByteString& value);
|
||||
ByteString Boolean(bool value);
|
||||
ByteString Integer(long value);
|
||||
|
||||
ByteString CN(const ByteString&, uint8_t encodingTag = 0x0c /*UTF8String*/);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ config = {
|
|||
"--apk=%(installer_path)s", "--no-logfiles",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--manifest=tests/xpcshell.ini",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
},
|
||||
}, # end suite_definitions
|
||||
|
|
|
@ -61,7 +61,8 @@ config = {
|
|||
"--local-lib-dir=../fennec",
|
||||
"--apk=../%(apk_name)s",
|
||||
"--no-logfiles",
|
||||
"--symbols-path=%(symbols_path)s"
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
"jittest_options": [
|
||||
"bin/js",
|
||||
|
|
|
@ -33,6 +33,7 @@ config = {
|
|||
"--apk=%(installer_path)s", "--no-logfiles",
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--manifest=tests/xpcshell.ini",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
},
|
||||
}, # end suite_definitions
|
||||
|
|
|
@ -47,6 +47,7 @@ config = {
|
|||
"--logdir=%(logcat_dir)s", "--manifest=tests/xpcshell.ini", "--use-device-libs",
|
||||
"--testing-modules-dir=%(modules_dir)s", "--symbols-path=%(symbols_path)s",
|
||||
"--busybox=%(busybox)s", "--total-chunks=%(total_chunks)s", "--this-chunk=%(this_chunk)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
|
||||
"cppunittest_options": [
|
||||
|
|
|
@ -24,7 +24,8 @@ config = {
|
|||
],
|
||||
"xpcshell_options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--test-plugin-path=%(test_plugin_path)s"
|
||||
"--test-plugin-path=%(test_plugin_path)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
"cppunittest_options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
|
|
|
@ -23,7 +23,8 @@ config = {
|
|||
],
|
||||
"xpcshell_options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--test-plugin-path=%(test_plugin_path)s"
|
||||
"--test-plugin-path=%(test_plugin_path)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
"cppunittest_options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
|
|
|
@ -23,7 +23,8 @@ config = {
|
|||
],
|
||||
"xpcshell_options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
"--test-plugin-path=%(test_plugin_path)s"
|
||||
"--test-plugin-path=%(test_plugin_path)s",
|
||||
"--log-raw=%(raw_log_file)s",
|
||||
],
|
||||
"cppunittest_options": [
|
||||
"--symbols-path=%(symbols_path)s",
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
{
|
||||
"runtests": {},
|
||||
"excludetests": {
|
||||
"dom/html/test/test_bug659743.xml": "Android 2.3 aws only; bug 1031103",
|
||||
"docshell/test/navigation/test_reserved.html": "too slow on Android 2.3 aws only; bug 1030403",
|
||||
"dom/canvas/test/webgl-conformance": "bug 865443 - separate suite -- mochitest-gl",
|
||||
"dom/canvas/test/webgl-mochitest/test_no_arr_points.html": "Android 2.3 aws only; bug 1030942",
|
||||
"dom/media/tests/mochitest": "Android 2.3 only; bug 981881",
|
||||
"layout/style/test/test_media_queries.html": "Android 2.3 aws only; bug 1030419",
|
||||
"layout/style/test/test_transitions_cancel_near_end.html": "Android 2.3 aws only; bug 1030432"
|
||||
"dom/canvas/test/webgl-conformance": "bug 865443 - separate suite -- mochitest-gl"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ class MochitestRunner(MozbuildObject):
|
|||
appname = 'webapprt-stub' + mozinfo.info.get('bin_suffix', '')
|
||||
if sys.platform.startswith('darwin'):
|
||||
appname = os.path.join(self.distdir, self.substs['MOZ_MACBUNDLE_NAME'],
|
||||
'Contents', 'MacOS', appname)
|
||||
'Contents', 'Resources', appname)
|
||||
else:
|
||||
appname = os.path.join(self.distdir, 'bin', appname)
|
||||
return appname
|
||||
|
|
|
@ -114,7 +114,7 @@ class ADBCommand(object):
|
|||
from mozdevice import ADBCommand
|
||||
|
||||
try:
|
||||
adbcommand = ADBCommand(...)
|
||||
adbcommand = ADBCommand()
|
||||
except NotImplementedError:
|
||||
print "ADBCommand can not be instantiated."
|
||||
|
||||
|
@ -280,7 +280,7 @@ class ADBHost(ADBCommand):
|
|||
|
||||
from mozdevice import ADBHost
|
||||
|
||||
adbhost = ADBHost(...)
|
||||
adbhost = ADBHost()
|
||||
adbhost.start_server()
|
||||
|
||||
"""
|
||||
|
@ -442,7 +442,7 @@ class ADBDevice(ADBCommand):
|
|||
|
||||
from mozdevice import ADBDevice
|
||||
|
||||
adbdevice = ADBDevice(...)
|
||||
adbdevice = ADBDevice()
|
||||
print adbdevice.list_files("/mnt/sdcard")
|
||||
if adbdevice.process_exist("org.mozilla.fennec"):
|
||||
print "Fennec is running"
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
mozharness.json is a manifest file that is currently only used on try.
|
||||
It allows you to lock mozharness to a repository and a revision.
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"repo": "http://hg.mozilla.org/build/mozharness",
|
||||
"revision": "production"
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# Script name: repository_manifest.py
|
||||
# Purpose: Reads from a json file a repository and revision to use.
|
||||
# If none is found we fall back to the default values.
|
||||
# Author(s): Zambrano Gasparnian, Armen <armenzg@mozilla.com>
|
||||
# Target: Python 2.7.x
|
||||
#
|
||||
from optparse import OptionParser
|
||||
import json
|
||||
import re
|
||||
import urllib2
|
||||
import urlparse
|
||||
import sys
|
||||
import os
|
||||
|
||||
def main():
|
||||
'''
|
||||
Determine which repository and revision mozharness.json indicates.
|
||||
If none is found we fall back to the default repository
|
||||
'''
|
||||
parser = OptionParser()
|
||||
parser.add_option("--repository-manifest-url", dest="repository_manifest_url", type="string",
|
||||
help="It indicates from where to download the talos.json file.")
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
# 1) check that the url was passed
|
||||
if options.repository_manifest_url == None:
|
||||
print "You need to specify --repository-manifest-url."
|
||||
sys.exit(1)
|
||||
|
||||
# 2) try to download the talos.json file
|
||||
try:
|
||||
jsonFilename = download_file(options.talos_json_url)
|
||||
except Exception, e:
|
||||
print "ERROR: We tried to download the talos.json file but something failed."
|
||||
print "ERROR: %s" % str(e)
|
||||
sys.exit(1)
|
||||
|
||||
# 3) download the necessary files
|
||||
print "INFO: talos.json URL: %s" % options.talos_json_url
|
||||
try:
|
||||
key = 'talos.zip'
|
||||
entity = get_value(jsonFilename, key)
|
||||
if passesRestrictions(options.talos_json_url, entity["url"]):
|
||||
# the key is at the same time the filename e.g. talos.zip
|
||||
print "INFO: Downloading %s as %s" % (entity["url"], os.path.join(entity["path"], key))
|
||||
download_file(entity["url"], entity["path"], key)
|
||||
else:
|
||||
print "ERROR: You have tried to download a file " + \
|
||||
"from: %s " % entity["url"] + \
|
||||
"which is a location different than http://talos-bundles.pvt.build.mozilla.org/"
|
||||
print "ERROR: This is only allowed for the certain branches."
|
||||
sys.exit(1)
|
||||
except Exception, e:
|
||||
print "ERROR: %s" % str(e)
|
||||
sys.exit(1)
|
||||
|
||||
def passesRestrictions(talosJsonUrl, fileUrl):
|
||||
'''
|
||||
Only certain branches are exempted from having to host their downloadable files
|
||||
in talos-bundles.pvt.build.mozilla.org
|
||||
'''
|
||||
if talosJsonUrl.startswith("http://hg.mozilla.org/try/") or \
|
||||
talosJsonUrl.startswith("https://hg.mozilla.org/try/") or \
|
||||
talosJsonUrl.startswith("http://hg.mozilla.org/projects/pine/") or \
|
||||
talosJsonUrl.startswith("https://hg.mozilla.org/projects/pine/") or \
|
||||
talosJsonUrl.startswith("http://hg.mozilla.org/projects/ash/") or \
|
||||
talosJsonUrl.startswith("https://hg.mozilla.org/projects/ash/"):
|
||||
return True
|
||||
else:
|
||||
p = re.compile('^http://talos-bundles.pvt.build.mozilla.org/')
|
||||
m = p.match(fileUrl)
|
||||
if m == None:
|
||||
return False
|
||||
return True
|
||||
|
||||
def get_filename_from_url(url):
|
||||
'''
|
||||
This returns the filename of the file we're trying to download
|
||||
'''
|
||||
parsed = urlparse.urlsplit(url.rstrip('/'))
|
||||
if parsed.path != '':
|
||||
return parsed.path.rsplit('/', 1)[-1]
|
||||
else:
|
||||
print "ERROR: We were trying to download a file from %s " + \
|
||||
"but the URL seems to be incorrect."
|
||||
sys.exit(1)
|
||||
|
||||
def download_file(url, path="", saveAs=None):
|
||||
'''
|
||||
It downloads a file from URL to the indicated path
|
||||
'''
|
||||
req = urllib2.Request(url)
|
||||
f = urllib2.urlopen(req)
|
||||
if path != "" and not os.path.isdir(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
print "INFO: directory %s created" % path
|
||||
except Exception, e:
|
||||
print "ERROR: %s" % str(e)
|
||||
sys.exit(1)
|
||||
filename = saveAs if saveAs else get_filename_from_url(url)
|
||||
local_file = open(os.path.join(path, filename), 'wb')
|
||||
local_file.write(f.read())
|
||||
local_file.close()
|
||||
return filename
|
||||
|
||||
def get_value(json_filename, key):
|
||||
'''
|
||||
It loads up a JSON file and returns the value for the given string
|
||||
'''
|
||||
f = open(json_filename, 'r')
|
||||
return json.load(f)[key]
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -169,7 +169,7 @@ endif
|
|||
$(CHECK_TEST_ERROR)
|
||||
|
||||
ifeq ($(OS_ARCH),Darwin)
|
||||
webapprt_stub_path = $(TARGET_DIST)/$(MOZ_MACBUNDLE_NAME)/Contents/MacOS/webapprt-stub$(BIN_SUFFIX)
|
||||
webapprt_stub_path = $(TARGET_DIST)/$(MOZ_MACBUNDLE_NAME)/Contents/Resources/webapprt-stub$(BIN_SUFFIX)
|
||||
endif
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
webapprt_stub_path = $(TARGET_DIST)/bin/webapprt-stub$(BIN_SUFFIX)
|
||||
|
|
|
@ -222,7 +222,8 @@ NativeApp.prototype = {
|
|||
|
||||
_copyPrebuiltFiles: function(aDir) {
|
||||
let destDir = getFile(aDir, this.macOSDir);
|
||||
let stub = getFile(this.runtimeFolder, "webapprt-stub");
|
||||
let stub = getFile(OS.Path.join(OS.Path.dirname(this.runtimeFolder),
|
||||
"Resources"), "webapprt-stub");
|
||||
stub.copyTo(destDir, "webapprt");
|
||||
},
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ let runTest = Task.async(function*() {
|
|||
|
||||
let fakeInstallDir;
|
||||
if (MAC) {
|
||||
fakeInstallDir = getFile(testAppInfo.installPath, "Contents", "MacOS");
|
||||
fakeInstallDir = getFile(testAppInfo.installPath, "Contents", "Resources");
|
||||
} else {
|
||||
fakeInstallDir = getFile(OS.Constants.Path.profileDir, "fakeInstallDir");
|
||||
fakeInstallDir.createUnique(Ci.nsIFile.DIRECTORY_TYPE, 0o755);
|
||||
|
|
|
@ -166,7 +166,7 @@ main(int argc, char **argv)
|
|||
|
||||
//we know the firefox path, so copy the new webapprt here
|
||||
NSString *newWebRTPath =
|
||||
[NSString stringWithFormat: @"%@%s%s", firefoxPath, APP_MACOS_PATH,
|
||||
[NSString stringWithFormat: @"%@%s%s", firefoxPath, APP_RESOURCES_PATH,
|
||||
WEBAPPRT_EXECUTABLE];
|
||||
NSLog(@"### Firefox webapprt path: %@", newWebRTPath);
|
||||
if (![fileClerk fileExistsAtPath:newWebRTPath]) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче