Merge m-c to b2g-inbound. a=merge

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-08-07 17:49:02 -04:00
commit f286fad7b5
201 changed files with 4455 additions and 1706 deletions

View File

@ -144,6 +144,7 @@
@BINPATH@/components/content_html.xpt
@BINPATH@/components/content_xslt.xpt
@BINPATH@/components/cookie.xpt
@BINPATH@/components/devtools_security.xpt
@BINPATH@/components/directory.xpt
@BINPATH@/components/diskspacewatcher.xpt
@BINPATH@/components/docshell.xpt

View File

@ -60,14 +60,6 @@ ul {
}
}
/* common.css overrides */
button {
font-size: 1em;
min-width: 150px;
}
/* Pressing the retry button will cause the cursor to flicker from a pointer to
* not-allowed. Override the disabled cursor behaviour since we will never show
* the button disabled as the initial state. */

View File

@ -3,16 +3,30 @@
"use strict";
let notificationObserver;
registerCleanupFunction(function() {
Services.prefs.clearUserPref("browser.fixup.domainwhitelist.localhost");
if (notificationObserver) {
notificationObserver.disconnect();
}
});
function promiseNotificationForTab(value, expected, tab=gBrowser.selectedTab) {
let deferred = Promise.defer();
let notificationBox = gBrowser.getNotificationBox(tab.linkedBrowser);
if (expected) {
waitForCondition(() => notificationBox.getNotificationWithValue(value) !== null,
deferred.resolve, "Were expecting to get a notification");
let checkForNotification = function() {
if (notificationBox.getNotificationWithValue(value)) {
notificationObserver.disconnect();
notificationObserver = null;
deferred.resolve();
}
}
if (notificationObserver) {
notificationObserver.disconnect();
}
notificationObserver = new MutationObserver(checkForNotification);
notificationObserver.observe(notificationBox, {childList: true});
} else {
setTimeout(() => {
is(notificationBox.getNotificationWithValue(value), null, "We are expecting to not get a notification");

View File

@ -1819,11 +1819,11 @@
this._setupLink(linkLabel, action.detailsLink);
this._primaryButton.label = gNavigatorBundle.getString(button1.label);
this._primaryButton.accesskey = gNavigatorBundle.getString(button1.accesskey);
this._primaryButton.accessKey = gNavigatorBundle.getString(button1.accesskey);
this._primaryButton.setAttribute("action", button1.action);
this._secondaryButton.label = gNavigatorBundle.getString(button2.label);
this._secondaryButton.accesskey = gNavigatorBundle.getString(button2.accesskey);
this._secondaryButton.accessKey = gNavigatorBundle.getString(button2.accesskey);
this._secondaryButton.setAttribute("action", button2.action);
if (button1.default) {
this._primaryButton.setAttribute("default", "true");

View File

@ -11,8 +11,10 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource:///modules/loop/MozLoopService.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "hookWindowCloseForPanelClose",
"resource://gre/modules/MozSocialAPI.jsm");
"resource://gre/modules/MozSocialAPI.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
"@mozilla.org/widget/clipboardhelper;1",
"nsIClipboardHelper");
this.EXPORTED_SYMBOLS = ["injectLoopAPI"];
/**
@ -225,6 +227,19 @@ function injectLoopAPI(targetWindow) {
});
}
},
/**
* Copies passed string onto the system clipboard.
*
* @param {String} str The string to copy
*/
copyString: {
enumerable: true,
writable: true,
value: function(str) {
clipboardHelper.copyString(str);
}
}
};
let contentObj = Cu.createObjectIn(targetWindow);

View File

@ -152,11 +152,17 @@ loop.panel = (function(_, mozL10n) {
});
var CallUrlResult = React.createClass({displayName: 'CallUrlResult',
propTypes: {
callUrl: React.PropTypes.string,
notifier: React.PropTypes.object.isRequired,
client: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
pending: false,
callUrl: ''
copied: false,
callUrl: this.props.callUrl || ""
};
},
@ -184,7 +190,7 @@ loop.panel = (function(_, mozL10n) {
if (err) {
this.props.notifier.errorL10n("unable_retrieve_url");
this.setState({pending: false});
this.setState(this.getInitialState());
} else {
try {
var callUrl = new window.URL(callUrlData.callUrl);
@ -194,43 +200,57 @@ loop.panel = (function(_, mozL10n) {
callUrl.pathname.split('/').pop();
navigator.mozLoop.setLoopCharPref('loopToken', token);
this.setState({pending: false, callUrl: callUrl.href});
this.setState({pending: false, copied: false, callUrl: callUrl.href});
} catch(e) {
console.log(e);
this.props.notifier.errorL10n("unable_retrieve_url");
this.setState({pending: false});
this.setState(this.getInitialState());
}
}
},
_generateMailto: function() {
_generateMailTo: function() {
return encodeURI([
"mailto:?subject=" + __("share_email_subject") + "&",
"body=" + __("share_email_body", {callUrl: this.state.callUrl})
].join(""));
},
handleEmailButtonClick: function(event) {
// Note: side effect
document.location = event.target.dataset.mailto;
},
handleCopyButtonClick: function(event) {
// XXX the mozLoop object should be passed as a prop, to ease testing and
// using a fake implementation in UI components showcase.
navigator.mozLoop.copyString(this.state.callUrl);
this.setState({copied: true});
},
render: function() {
// XXX setting elem value from a state (in the callUrl input)
// makes it immutable ie read only but that is fine in our case.
// readOnly attr will suppress a warning regarding this issue
// from the react lib.
var cx = React.addons.classSet;
var inputCSSClass = {
"pending": this.state.pending,
"callUrl": !this.state.pending
};
return (
PanelLayout({summary: __("share_link_header_text")},
React.DOM.div({className: "invite"},
React.DOM.input({type: "url", value: this.state.callUrl, readOnly: "true",
className: cx(inputCSSClass)}),
React.DOM.a({className: cx({btn: true, hide: !this.state.callUrl}),
href: this._generateMailto()},
React.DOM.span(null,
__("share_button")
)
)
className: cx({pending: this.state.pending})}),
React.DOM.p({className: "button-group url-actions"},
React.DOM.button({className: "btn btn-email", disabled: !this.state.callUrl,
onClick: this.handleEmailButtonClick,
'data-mailto': this._generateMailTo()},
__("share_button")
),
React.DOM.button({className: "btn btn-copy", disabled: !this.state.callUrl,
onClick: this.handleCopyButtonClick},
this.state.copied ? __("copied_url_button") :
__("copy_url_button")
)
)
)
)
);
@ -243,14 +263,17 @@ loop.panel = (function(_, mozL10n) {
var PanelView = React.createClass({displayName: 'PanelView',
propTypes: {
notifier: React.PropTypes.object.isRequired,
client: React.PropTypes.object.isRequired
client: React.PropTypes.object.isRequired,
// Mostly used for UI components showcase and unit tests
callUrl: React.PropTypes.string
},
render: function() {
return (
React.DOM.div(null,
CallUrlResult({client: this.props.client,
notifier: this.props.notifier}),
notifier: this.props.notifier,
callUrl: this.props.callUrl}),
ToSView(null),
AvailabilityDropdown(null)
)

View File

@ -152,11 +152,17 @@ loop.panel = (function(_, mozL10n) {
});
var CallUrlResult = React.createClass({
propTypes: {
callUrl: React.PropTypes.string,
notifier: React.PropTypes.object.isRequired,
client: React.PropTypes.object.isRequired
},
getInitialState: function() {
return {
pending: false,
callUrl: ''
copied: false,
callUrl: this.props.callUrl || ""
};
},
@ -184,7 +190,7 @@ loop.panel = (function(_, mozL10n) {
if (err) {
this.props.notifier.errorL10n("unable_retrieve_url");
this.setState({pending: false});
this.setState(this.getInitialState());
} else {
try {
var callUrl = new window.URL(callUrlData.callUrl);
@ -194,43 +200,57 @@ loop.panel = (function(_, mozL10n) {
callUrl.pathname.split('/').pop();
navigator.mozLoop.setLoopCharPref('loopToken', token);
this.setState({pending: false, callUrl: callUrl.href});
this.setState({pending: false, copied: false, callUrl: callUrl.href});
} catch(e) {
console.log(e);
this.props.notifier.errorL10n("unable_retrieve_url");
this.setState({pending: false});
this.setState(this.getInitialState());
}
}
},
_generateMailto: function() {
_generateMailTo: function() {
return encodeURI([
"mailto:?subject=" + __("share_email_subject") + "&",
"body=" + __("share_email_body", {callUrl: this.state.callUrl})
].join(""));
},
handleEmailButtonClick: function(event) {
// Note: side effect
document.location = event.target.dataset.mailto;
},
handleCopyButtonClick: function(event) {
// XXX the mozLoop object should be passed as a prop, to ease testing and
// using a fake implementation in UI components showcase.
navigator.mozLoop.copyString(this.state.callUrl);
this.setState({copied: true});
},
render: function() {
// XXX setting elem value from a state (in the callUrl input)
// makes it immutable ie read only but that is fine in our case.
// readOnly attr will suppress a warning regarding this issue
// from the react lib.
var cx = React.addons.classSet;
var inputCSSClass = {
"pending": this.state.pending,
"callUrl": !this.state.pending
};
return (
<PanelLayout summary={__("share_link_header_text")}>
<div className="invite">
<input type="url" value={this.state.callUrl} readOnly="true"
className={cx(inputCSSClass)} />
<a className={cx({btn: true, hide: !this.state.callUrl})}
href={this._generateMailto()}>
<span>
{__("share_button")}
</span>
</a>
className={cx({pending: this.state.pending})} />
<p className="button-group url-actions">
<button className="btn btn-email" disabled={!this.state.callUrl}
onClick={this.handleEmailButtonClick}
data-mailto={this._generateMailTo()}>
{__("share_button")}
</button>
<button className="btn btn-copy" disabled={!this.state.callUrl}
onClick={this.handleCopyButtonClick}>
{this.state.copied ? __("copied_url_button") :
__("copy_url_button")}
</button>
</p>
</div>
</PanelLayout>
);
@ -243,14 +263,17 @@ loop.panel = (function(_, mozL10n) {
var PanelView = React.createClass({
propTypes: {
notifier: React.PropTypes.object.isRequired,
client: React.PropTypes.object.isRequired
client: React.PropTypes.object.isRequired,
// Mostly used for UI components showcase and unit tests
callUrl: React.PropTypes.string
},
render: function() {
return (
<div>
<CallUrlResult client={this.props.client}
notifier={this.props.notifier} />
notifier={this.props.notifier}
callUrl={this.props.callUrl} />
<ToSView />
<AvailabilityDropdown />
</div>

View File

@ -320,6 +320,7 @@
.feedback label {
display: block;
line-height: 1.5em;
}
.feedback form input[type="radio"] {

View File

@ -86,15 +86,17 @@
margin-top: 10px;
}
.share .action .btn:hover {
.share > .action .btn:hover {
background-color: #008ACB;
border: 1px solid #008ACB;
}
.share .action .btn span {
margin-top: 2px;
font-size: 12px;
display: inline-block;
.share > .action > .invite > .url-actions {
margin: 0 0 5px;
}
.share > .action > .invite > .url-actions > .btn:first-child {
-moz-margin-end: 1em;
}
/* Specific cases */

View File

@ -12,7 +12,6 @@ loop.shared.views = (function(_, OT, l10n) {
"use strict";
var sharedModels = loop.shared.models;
var __ = l10n.get;
var WINDOW_AUTOCLOSE_TIMEOUT_IN_SECONDS = 5;
/**
@ -134,7 +133,7 @@ loop.shared.views = (function(_, OT, l10n) {
var prefix = this.props.enabled ? "mute" : "unmute";
var suffix = "button_title";
var msgId = [prefix, this.props.scope, this.props.type, suffix].join("_");
return __(msgId);
return l10n.get(msgId);
},
render: function() {
@ -184,7 +183,7 @@ loop.shared.views = (function(_, OT, l10n) {
React.DOM.ul({className: "conversation-toolbar"},
React.DOM.li(null, React.DOM.button({className: "btn btn-hangup",
onClick: this.handleClickHangup,
title: __("hangup_button_title")})),
title: l10n.get("hangup_button_title")})),
React.DOM.li(null, MediaControlButton({action: this.handleToggleVideo,
enabled: this.props.video.enabled,
scope: "local", type: "video"})),
@ -371,7 +370,7 @@ loop.shared.views = (function(_, OT, l10n) {
if (this.props.reset) {
backButton = (
React.DOM.button({className: "back", type: "button", onClick: this.props.reset},
"« ", __("feedback_back_button")
"« ", l10n.get("feedback_back_button")
)
);
}
@ -405,11 +404,11 @@ loop.shared.views = (function(_, OT, l10n) {
_getCategories: function() {
return {
audio_quality: __("feedback_category_audio_quality"),
video_quality: __("feedback_category_video_quality"),
disconnected : __("feedback_category_was_disconnected"),
confusing: __("feedback_category_confusing"),
other: __("feedback_category_other")
audio_quality: l10n.get("feedback_category_audio_quality"),
video_quality: l10n.get("feedback_category_video_quality"),
disconnected : l10n.get("feedback_category_was_disconnected"),
confusing: l10n.get("feedback_category_confusing"),
other: l10n.get("feedback_category_other")
};
},
@ -420,7 +419,8 @@ loop.shared.views = (function(_, OT, l10n) {
React.DOM.label({key: key},
React.DOM.input({type: "radio", ref: "category", name: "category",
value: category,
onChange: this.handleCategoryChange}),
onChange: this.handleCategoryChange,
checked: this.state.category === category}),
categories[category]
)
);
@ -429,28 +429,43 @@ loop.shared.views = (function(_, OT, l10n) {
/**
* Checks if the form is ready for submission:
* - a category (reason) must be chosen
* - no feedback submission should be pending
*
* - no feedback submission should be pending.
* - a category (reason) must be chosen;
* - if the "other" category is chosen, a custom description must have been
* entered by the end user;
*
* @return {Boolean}
*/
_isFormReady: function() {
return this.state.category !== "" && !this.props.pending;
if (this.props.pending || !this.state.category) {
return false;
}
if (this.state.category === "other" && !this.state.description) {
return false;
}
return true;
},
handleCategoryChange: function(event) {
var category = event.target.value;
if (category !== "other") {
// resets description text field
this.setState({description: ""});
this.setState({
category: category,
description: category == "other" ? "" : this._getCategories()[category]
});
if (category == "other") {
this.refs.description.getDOMNode().focus();
}
this.setState({category: category});
},
handleCustomTextChange: function(event) {
handleDescriptionFieldChange: function(event) {
this.setState({description: event.target.value});
},
handleDescriptionFieldFocus: function(event) {
this.setState({category: "other", description: ""});
},
handleFormSubmit: function(event) {
event.preventDefault();
this.props.sendFeedback({
@ -461,18 +476,24 @@ loop.shared.views = (function(_, OT, l10n) {
},
render: function() {
var descriptionDisplayValue = this.state.category === "other" ?
this.state.description : "";
return (
FeedbackLayout({title: __("feedback_what_makes_you_sad"),
FeedbackLayout({title: l10n.get("feedback_what_makes_you_sad"),
reset: this.props.reset},
React.DOM.form({onSubmit: this.handleFormSubmit},
this._getCategoryFields(),
React.DOM.p(null, React.DOM.input({type: "text", ref: "description", name: "description",
disabled: this.state.category !== "other",
onChange: this.handleCustomTextChange,
value: this.state.description})),
React.DOM.p(null,
React.DOM.input({type: "text", ref: "description", name: "description",
onChange: this.handleDescriptionFieldChange,
onFocus: this.handleDescriptionFieldFocus,
value: descriptionDisplayValue,
placeholder:
l10n.get("feedback_custom_category_text_placeholder")})
),
React.DOM.button({type: "submit", className: "btn btn-success",
disabled: !this._isFormReady()},
__("feedback_submit_button")
l10n.get("feedback_submit_button")
)
)
)
@ -506,10 +527,11 @@ loop.shared.views = (function(_, OT, l10n) {
window.close();
}
return (
FeedbackLayout({title: __("feedback_thank_you_heading")},
React.DOM.p({className: "info thank-you"}, __("feedback_window_will_close_in", {
countdown: this.state.countdown
}))
FeedbackLayout({title: l10n.get("feedback_thank_you_heading")},
React.DOM.p({className: "info thank-you"},
l10n.get("feedback_window_will_close_in", {
countdown: this.state.countdown
}))
)
);
}
@ -573,7 +595,8 @@ loop.shared.views = (function(_, OT, l10n) {
pending: this.state.pending});
default:
return (
FeedbackLayout({title: __("feedback_call_experience_heading")},
FeedbackLayout({title:
l10n.get("feedback_call_experience_heading")},
React.DOM.div({className: "faces"},
React.DOM.button({className: "face face-happy",
onClick: this.handleHappyClick}),

View File

@ -12,7 +12,6 @@ loop.shared.views = (function(_, OT, l10n) {
"use strict";
var sharedModels = loop.shared.models;
var __ = l10n.get;
var WINDOW_AUTOCLOSE_TIMEOUT_IN_SECONDS = 5;
/**
@ -134,7 +133,7 @@ loop.shared.views = (function(_, OT, l10n) {
var prefix = this.props.enabled ? "mute" : "unmute";
var suffix = "button_title";
var msgId = [prefix, this.props.scope, this.props.type, suffix].join("_");
return __(msgId);
return l10n.get(msgId);
},
render: function() {
@ -184,7 +183,7 @@ loop.shared.views = (function(_, OT, l10n) {
<ul className="conversation-toolbar">
<li><button className="btn btn-hangup"
onClick={this.handleClickHangup}
title={__("hangup_button_title")}></button></li>
title={l10n.get("hangup_button_title")}></button></li>
<li><MediaControlButton action={this.handleToggleVideo}
enabled={this.props.video.enabled}
scope="local" type="video" /></li>
@ -371,7 +370,7 @@ loop.shared.views = (function(_, OT, l10n) {
if (this.props.reset) {
backButton = (
<button className="back" type="button" onClick={this.props.reset}>
&laquo;&nbsp;{__("feedback_back_button")}
&laquo;&nbsp;{l10n.get("feedback_back_button")}
</button>
);
}
@ -405,11 +404,11 @@ loop.shared.views = (function(_, OT, l10n) {
_getCategories: function() {
return {
audio_quality: __("feedback_category_audio_quality"),
video_quality: __("feedback_category_video_quality"),
disconnected : __("feedback_category_was_disconnected"),
confusing: __("feedback_category_confusing"),
other: __("feedback_category_other")
audio_quality: l10n.get("feedback_category_audio_quality"),
video_quality: l10n.get("feedback_category_video_quality"),
disconnected : l10n.get("feedback_category_was_disconnected"),
confusing: l10n.get("feedback_category_confusing"),
other: l10n.get("feedback_category_other")
};
},
@ -420,7 +419,8 @@ loop.shared.views = (function(_, OT, l10n) {
<label key={key}>
<input type="radio" ref="category" name="category"
value={category}
onChange={this.handleCategoryChange} />
onChange={this.handleCategoryChange}
checked={this.state.category === category} />
{categories[category]}
</label>
);
@ -429,28 +429,43 @@ loop.shared.views = (function(_, OT, l10n) {
/**
* Checks if the form is ready for submission:
* - a category (reason) must be chosen
* - no feedback submission should be pending
*
* - no feedback submission should be pending.
* - a category (reason) must be chosen;
* - if the "other" category is chosen, a custom description must have been
* entered by the end user;
*
* @return {Boolean}
*/
_isFormReady: function() {
return this.state.category !== "" && !this.props.pending;
if (this.props.pending || !this.state.category) {
return false;
}
if (this.state.category === "other" && !this.state.description) {
return false;
}
return true;
},
handleCategoryChange: function(event) {
var category = event.target.value;
if (category !== "other") {
// resets description text field
this.setState({description: ""});
this.setState({
category: category,
description: category == "other" ? "" : this._getCategories()[category]
});
if (category == "other") {
this.refs.description.getDOMNode().focus();
}
this.setState({category: category});
},
handleCustomTextChange: function(event) {
handleDescriptionFieldChange: function(event) {
this.setState({description: event.target.value});
},
handleDescriptionFieldFocus: function(event) {
this.setState({category: "other", description: ""});
},
handleFormSubmit: function(event) {
event.preventDefault();
this.props.sendFeedback({
@ -461,18 +476,24 @@ loop.shared.views = (function(_, OT, l10n) {
},
render: function() {
var descriptionDisplayValue = this.state.category === "other" ?
this.state.description : "";
return (
<FeedbackLayout title={__("feedback_what_makes_you_sad")}
<FeedbackLayout title={l10n.get("feedback_what_makes_you_sad")}
reset={this.props.reset}>
<form onSubmit={this.handleFormSubmit}>
{this._getCategoryFields()}
<p><input type="text" ref="description" name="description"
disabled={this.state.category !== "other"}
onChange={this.handleCustomTextChange}
value={this.state.description} /></p>
<p>
<input type="text" ref="description" name="description"
onChange={this.handleDescriptionFieldChange}
onFocus={this.handleDescriptionFieldFocus}
value={descriptionDisplayValue}
placeholder={
l10n.get("feedback_custom_category_text_placeholder")} />
</p>
<button type="submit" className="btn btn-success"
disabled={!this._isFormReady()}>
{__("feedback_submit_button")}
{l10n.get("feedback_submit_button")}
</button>
</form>
</FeedbackLayout>
@ -506,10 +527,11 @@ loop.shared.views = (function(_, OT, l10n) {
window.close();
}
return (
<FeedbackLayout title={__("feedback_thank_you_heading")}>
<p className="info thank-you">{__("feedback_window_will_close_in", {
countdown: this.state.countdown
})}</p>
<FeedbackLayout title={l10n.get("feedback_thank_you_heading")}>
<p className="info thank-you">{
l10n.get("feedback_window_will_close_in", {
countdown: this.state.countdown
})}</p>
</FeedbackLayout>
);
}
@ -573,7 +595,8 @@ loop.shared.views = (function(_, OT, l10n) {
pending={this.state.pending} />;
default:
return (
<FeedbackLayout title={__("feedback_call_experience_heading")}>
<FeedbackLayout title={
l10n.get("feedback_call_experience_heading")}>
<div className="faces">
<button className="face face-happy"
onClick={this.handleHappyClick}></button>

View File

@ -48,7 +48,8 @@ describe("loop.panel", function() {
return "en-US";
},
setLoopCharPref: sandbox.stub(),
getLoopCharPref: sandbox.stub().returns("unseen")
getLoopCharPref: sandbox.stub().returns("unseen"),
copyString: sandbox.stub()
};
document.mozL10n.initialize(navigator.mozLoop);
@ -314,9 +315,28 @@ describe("loop.panel", function() {
}));
view.setState({pending: false, callUrl: "http://example.com"});
TestUtils.findRenderedDOMComponentWithTag(view, "a");
var shareButton = view.getDOMNode().querySelector("a.btn");
expect(shareButton.href).to.equal(encodeURI(mailto));
TestUtils.findRenderedDOMComponentWithClass(view, "btn-email");
expect(view.getDOMNode().querySelector(".btn-email").dataset.mailto)
.to.equal(encodeURI(mailto));
});
it("should feature a copy button capable of copying the call url when clicked", function() {
fakeClient.requestCallUrl = sandbox.stub();
var view = TestUtils.renderIntoDocument(loop.panel.CallUrlResult({
notifier: notifier,
client: fakeClient
}));
view.setState({
pending: false,
copied: false,
callUrl: "http://example.com"
});
TestUtils.Simulate.click(view.getDOMNode().querySelector(".btn-copy"));
sinon.assert.calledOnce(navigator.mozLoop.copyString);
sinon.assert.calledWithExactly(navigator.mozLoop.copyString,
view.state.callUrl);
});
it("should notify the user when the operation failed", function() {

View File

@ -405,6 +405,9 @@ describe("loop.shared.views", function() {
var comp, fakeFeedbackApiClient;
beforeEach(function() {
sandbox.stub(l10n, "get", function(x) {
return x;
});
fakeFeedbackApiClient = {send: sandbox.stub()};
comp = TestUtils.renderIntoDocument(sharedViews.FeedbackView({
feedbackApiClient: fakeFeedbackApiClient
@ -476,7 +479,39 @@ describe("loop.shared.views", function() {
.querySelector("form button").disabled).eql(true);
});
it("should enable the form submit button once a choice is made",
it("should disable the form submit button when the 'other' category is " +
"chosen but no description has been entered yet",
function() {
clickSadFace(comp);
fillSadFeedbackForm(comp, "other");
expect(comp.getDOMNode()
.querySelector("form button").disabled).eql(true);
});
it("should enable the form submit button when the 'other' category is " +
"chosen and a description is entered",
function() {
clickSadFace(comp);
fillSadFeedbackForm(comp, "other", "fake");
expect(comp.getDOMNode()
.querySelector("form button").disabled).eql(false);
});
it("should empty the description field when a predefined category is " +
"chosen",
function() {
clickSadFace(comp);
fillSadFeedbackForm(comp, "confusing");
expect(comp.getDOMNode()
.querySelector("form input[type='text']").value).eql("");
});
it("should enable the form submit button once a predefined category is " +
"chosen",
function() {
clickSadFace(comp);

View File

@ -4,11 +4,12 @@
/**
* /!\ FIXME: THIS IS A HORRID HACK which fakes both the mozL10n and webL10n
* objects and makes them returning "fake string" for any requested string id.
* objects and makes them returning the string id and serialized vars if any,
* for any requested string id.
* @type {Object}
*/
document.webL10n = document.mozL10n = {
get: function() {
return "fake text";
get: function(sringId, vars) {
return "" + sringId + (vars ? ";" + JSON.stringify(vars) : "");
}
};

View File

@ -93,8 +93,14 @@
return (
ShowCase(null,
Section({name: "PanelView"},
Example({summary: "332px wide", dashed: "true", style: {width: "332px"}},
React.DOM.p({className: "note"},
React.DOM.strong(null, "Note:"), " 332px wide."
),
Example({summary: "Pending call url retrieval", dashed: "true", style: {width: "332px"}},
PanelView(null)
),
Example({summary: "Call URL retrieved", dashed: "true", style: {width: "332px"}},
PanelView({callUrl: "http://invalid.example.url/"})
)
),

View File

@ -93,9 +93,15 @@
return (
<ShowCase>
<Section name="PanelView">
<Example summary="332px wide" dashed="true" style={{width: "332px"}}>
<p className="note">
<strong>Note:</strong> 332px wide.
</p>
<Example summary="Pending call url retrieval" dashed="true" style={{width: "332px"}}>
<PanelView />
</Example>
<Example summary="Call URL retrieved" dashed="true" style={{width: "332px"}}>
<PanelView callUrl="http://invalid.example.url/" />
</Example>
</Section>
<Section name="IncomingCallView">

View File

@ -8,30 +8,31 @@
<?xml-stylesheet href="chrome://mozapps/content/preferences/preferences.css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/preferences.css"?>
<?xml-stylesheet
<?xml-stylesheet href="chrome://browser/skin/in-content/common.css"?>
<?xml-stylesheet
href="chrome://browser/skin/preferences/in-content/preferences.css"?>
<?xml-stylesheet
<?xml-stylesheet
href="chrome://browser/content/preferences/handlers.css"?>
<?xml-stylesheet href="chrome://browser/skin/preferences/applications.css"?>
<!DOCTYPE page [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % globalPreferencesDTD SYSTEM "chrome://global/locale/preferences.dtd">
<!ENTITY % preferencesDTD SYSTEM
<!ENTITY % preferencesDTD SYSTEM
"chrome://browser/locale/preferences/preferences.dtd">
<!ENTITY % privacyDTD SYSTEM "chrome://browser/locale/preferences/privacy.dtd">
<!ENTITY % tabsDTD SYSTEM "chrome://browser/locale/preferences/tabs.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
<!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd">
<!ENTITY % securityDTD SYSTEM
<!ENTITY % securityDTD SYSTEM
"chrome://browser/locale/preferences/security.dtd">
<!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
<!ENTITY % mainDTD SYSTEM "chrome://browser/locale/preferences/main.dtd">
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
<!ENTITY % contentDTD SYSTEM "chrome://browser/locale/preferences/content.dtd">
<!ENTITY % applicationsDTD SYSTEM
<!ENTITY % applicationsDTD SYSTEM
"chrome://browser/locale/preferences/applications.dtd">
<!ENTITY % advancedDTD SYSTEM
<!ENTITY % advancedDTD SYSTEM
"chrome://browser/locale/preferences/advanced.dtd">
%brandDTD;
%globalPreferencesDTD;
@ -70,7 +71,7 @@
src="chrome://browser/content/preferences/in-content/preferences.js"/>
<script src="chrome://browser/content/preferences/in-content/subdialogs.js"/>
<stringbundle id="bundleBrand"
<stringbundle id="bundleBrand"
src="chrome://branding/locale/brand.properties"/>
<stringbundle id="bundlePreferences"
src="chrome://browser/locale/preferences/preferences.properties"/>

View File

@ -11,6 +11,7 @@ let gSubDialog = {
_box: null,
_injectedStyleSheets: ["chrome://mozapps/content/preferences/preferences.css",
"chrome://browser/skin/preferences/preferences.css",
"chrome://browser/skin/in-content/common.css",
"chrome://browser/skin/preferences/in-content/preferences.css"],
init: function() {

View File

@ -9,7 +9,6 @@ support-files =
[browser_devtools_api.js]
[browser_dynamic_tool_enabling.js]
[browser_keybindings.js]
skip-if = e10s # Bug 1030318
[browser_new_activation_workflow.js]
[browser_target_events.js]
[browser_target_remote.js]
@ -19,6 +18,7 @@ skip-if = e10s # Bug 1030318
[browser_toolbox_options.js]
[browser_toolbox_options_disable_buttons.js]
[browser_toolbox_options_disable_cache.js]
skip-if = e10s # Bug 1030318
[browser_toolbox_options_disable_js.js]
# [browser_toolbox_raise.js] # Bug 962258
# skip-if = os == "win"

View File

@ -18,7 +18,7 @@ function test()
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
doc = content.document;
node = doc.querySelector("h1");
waitForFocus(setupKeyBindingsTest, content);
waitForFocus(setupKeyBindingsTest);
}, true);
content.location = "data:text/html,<html><head><title>Test for the " +

View File

@ -32,7 +32,8 @@ function onHidden() {
function onVisible() {
ok(true, "Visible event received");
target.once("will-navigate", onWillNavigate);
gBrowser.contentWindow.location = "data:text/html,test navigation";
let mm = getFrameScript();
mm.sendAsyncMessage("devtools:test:navigate", { location: "data:text/html,<meta charset='utf8'/>test navigation" });
}
function onWillNavigate(event, request) {

View File

@ -131,7 +131,8 @@ function reloadTab(tabX) {
}, true);
info("Reloading tab " + tabX.title);
content.document.location.reload(false);
let mm = getFrameScript();
mm.sendAsyncMessage("devtools:test:reload");
return def.promise;
}
@ -139,15 +140,17 @@ function reloadTab(tabX) {
function* destroyTab(tabX) {
let toolbox = gDevTools.getToolbox(tabX.target);
let onceDestroyed = promise.resolve();
if (toolbox) {
onceDestroyed = gDevTools.once("toolbox-destroyed");
}
info("Removing tab " + tabX.title);
gBrowser.removeTab(tabX.tab);
info("Removed tab " + tabX.title);
if (toolbox) {
info("Waiting for toolbox-destroyed");
yield gDevTools.once("toolbox-destroyed");
info("toolbox-destroyed event received for " + tabX.title);
}
info("Waiting for toolbox-destroyed");
yield onceDestroyed;
}
function* finishUp() {

View File

@ -32,13 +32,11 @@ function testJSEnabled(event, tool, secondPass) {
ok(true, "Toolbox selected via selectTool method");
info("Testing that JS is enabled");
let logJSEnabled = doc.getElementById("logJSEnabled");
let output = doc.getElementById("output");
// We use executeSoon here because switching docSehll.allowJavascript to true
// takes a while to become live.
executeSoon(function() {
EventUtils.synthesizeMouseAtCenter(logJSEnabled, {}, doc.defaultView);
let output = doc.getElementById("output");
doc.querySelector("#logJSEnabled").click();
is(output.textContent, "JavaScript Enabled", 'Output is "JavaScript Enabled"');
testJSEnabledIframe(secondPass);
});
@ -49,12 +47,10 @@ function testJSEnabledIframe(secondPass) {
let iframe = doc.querySelector("iframe");
let iframeDoc = iframe.contentDocument;
let logJSEnabled = iframeDoc.getElementById("logJSEnabled");
let output = iframeDoc.getElementById("output");
EventUtils.synthesizeMouseAtCenter(logJSEnabled, {}, iframe.contentWindow);
iframeDoc.querySelector("#logJSEnabled").click();
is(output.textContent, "JavaScript Enabled",
'Output is "JavaScript Enabled" in iframe');
'Output is "JavaScript Enabled" in iframe');
if (secondPass) {
finishUp();
} else {
@ -75,18 +71,13 @@ function toggleJS() {
info("Checking checkbox to disable JS");
}
// After uising scrollIntoView() we need to use executeSoon() to wait for the
// browser to scroll.
executeSoon(function() {
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
doc = content.document;
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
doc = content.document;
deferred.resolve();
}, true);
deferred.resolve();
}, true);
EventUtils.synthesizeMouseAtCenter(cbx, {}, panel.panelWin);
});
cbx.click();
return deferred.promise;
}
@ -94,13 +85,11 @@ function toggleJS() {
function testJSDisabled() {
info("Testing that JS is disabled");
let logJSDisabled = doc.getElementById("logJSDisabled");
let output = doc.getElementById("output");
doc.querySelector("#logJSDisabled").click();
EventUtils.synthesizeMouseAtCenter(logJSDisabled, {}, doc.defaultView);
ok(output.textContent !== "JavaScript Disabled",
'output is not "JavaScript Disabled"');
testJSDisabledIframe();
}
@ -109,10 +98,8 @@ function testJSDisabledIframe() {
let iframe = doc.querySelector("iframe");
let iframeDoc = iframe.contentDocument;
let logJSDisabled = iframeDoc.getElementById("logJSDisabled");
let output = iframeDoc.getElementById("output");
EventUtils.synthesizeMouseAtCenter(logJSDisabled, {}, iframe.contentWindow);
iframeDoc.querySelector("#logJSDisabled").click();
ok(output.textContent !== "JavaScript Disabled",
'output is not "JavaScript Disabled" in iframe');
toggleJS().then(function() {

View File

@ -16,6 +16,16 @@ waitForExplicitFinish();
// Uncomment this pref to dump all devtools emitted events to the console.
// Services.prefs.setBoolPref("devtools.dump.emit", true);
function getFrameScript() {
let mm = gBrowser.selectedBrowser.messageManager;
let frameURL = "chrome://browser/content/devtools/frame-script-utils.js";
mm.loadFrameScript(frameURL, false);
SimpleTest.registerCleanupFunction(() => {
mm = null;
});
return mm;
}
gDevTools.testing = true;
SimpleTest.registerCleanupFunction(() => {
gDevTools.testing = false;

View File

@ -1356,16 +1356,12 @@ Toolbox.prototype = {
}
// Destroying the walker and inspector fronts
outstanding.push(this.destroyInspector());
// Removing buttons
outstanding.push(() => {
outstanding.push(this.destroyInspector().then(() => {
// Removing buttons
this._pickerButton.removeEventListener("command", this._togglePicker, false);
this._pickerButton = null;
let container = this.doc.getElementById("toolbox-buttons");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
});
}));
// Remove the host UI
outstanding.push(this.destroyHost());

View File

@ -7,3 +7,12 @@
addMessageListener("devtools:test:history", function ({ data }) {
content.history[data.direction]();
});
addMessageListener("devtools:test:navigate", function ({ data }) {
content.location = data.location;
});
addMessageListener("devtools:test:reload", function ({ data }) {
data = data || {};
content.location.reload(data.forceget);
});

View File

@ -1483,6 +1483,10 @@ CssRuleView.prototype = {
// Remove context menu
if (this._contextmenu) {
// Destroy the Add Rule menuitem.
this.menuitemAddRule.removeEventListener("command", this._onAddRule);
this.menuitemAddRule = null;
// Destroy the Select All menuitem.
this.menuitemSelectAll.removeEventListener("command", this._onSelectAll);
this.menuitemSelectAll = null;

View File

@ -6,6 +6,7 @@ const Cu = Components.utils;
Cu.import('resource:///modules/devtools/gDevTools.jsm');
const {require} = Cu.import('resource://gre/modules/devtools/Loader.jsm', {}).devtools;
const {Services} = Cu.import('resource://gre/modules/Services.jsm');
const {Devices} = Cu.import("resource://gre/modules/devtools/Devices.jsm");
const {AppManager} = require('devtools/webide/app-manager');
const {AppActorFront} = require('devtools/app-actor-front');
const {Connection} = require('devtools/client/connection-manager');
@ -45,7 +46,8 @@ let Monitor = {
front: null,
socket: null,
wstimeout: null,
loaded: false,
b2ginfo: false,
b2gtimeout: null,
/**
* Add new data to the graphs, create a new graph if necessary.
@ -56,6 +58,12 @@ let Monitor = {
return;
}
if (Monitor.b2ginfo && data.graph === 'USS') {
// If we're polling b2g-info, ignore USS updates from the device's
// USSAgents (see Monitor.pollB2GInfo()).
return;
}
if (fallback) {
for (let key in fallback) {
if (!data[key]) {
@ -84,7 +92,6 @@ let Monitor = {
AppManager.on('app-manager-update', Monitor.onAppManagerUpdate);
Monitor.connectToRuntime();
Monitor.connectToWebSocket();
Monitor.loaded = true;
},
/**
@ -125,6 +132,7 @@ let Monitor = {
* Use an AppActorFront on a runtime to watch track its apps.
*/
connectToRuntime: function() {
Monitor.pollB2GInfo();
let client = AppManager.connection && AppManager.connection.client;
let resp = AppManager._listTabsResponse;
if (client && resp && !Monitor.front) {
@ -137,6 +145,7 @@ let Monitor = {
* Destroy our AppActorFront.
*/
disconnectFromRuntime: function() {
Monitor.unpollB2GInfo();
if (Monitor.front) {
Monitor.front.unwatchApps(Monitor.onRuntimeAppEvent);
Monitor.front = null;
@ -206,6 +215,66 @@ let Monitor = {
fallback.curve = app.manifest.name
}
Monitor.update(packet.data, fallback);
},
/**
* Bug 1047355: If possible, parsing the output of `b2g-info` has several
* benefits over bug 1037465's multi-process USSAgent approach, notably:
* - Works for older Firefox OS devices (pre-2.1),
* - Doesn't need certified-apps debugging,
* - Polling time is synchronized for all processes.
* TODO: After bug 1043324 lands, consider removing this hack.
*/
pollB2GInfo: function() {
if (AppManager.selectedRuntime) {
let id = AppManager.selectedRuntime.id;
let device = Devices.getByName(id);
if (device && device.shell) {
device.shell('b2g-info').then(s => {
let lines = s.split('\n');
let line = '';
// Find the header row to locate NAME and USS, looks like:
// ' NAME PID NICE USS PSS RSS VSIZE OOM_ADJ USER '.
while (line.indexOf('NAME') < 0) {
if (lines.length < 1) {
// Something is wrong with this output, don't trust b2g-info.
Monitor.unpollB2GInfo();
return;
}
line = lines.shift();
}
let namelength = line.indexOf('NAME') + 'NAME'.length;
let ussindex = line.slice(namelength).split(/\s+/).indexOf('USS');
// Get the NAME and USS in each following line, looks like:
// 'Homescreen 375 18 12.6 16.3 27.1 67.8 4 app_375'.
while (lines.length > 0 && lines[0].length > namelength) {
line = lines.shift();
let name = line.slice(0, namelength);
let uss = line.slice(namelength).split(/\s+/)[ussindex];
Monitor.update({
curve: name.trim(),
value: 1024 * 1024 * parseFloat(uss) // Convert MB to bytes.
}, {
// Note: We use the fallback object to set the graph name to 'USS'
// so that Monitor.update() can ignore USSAgent updates.
graph: 'USS'
});
}
});
}
}
Monitor.b2ginfo = true;
Monitor.b2gtimeout = setTimeout(Monitor.pollB2GInfo, 350);
},
/**
* Polling b2g-info doesn't work or is no longer needed.
*/
unpollB2GInfo: function() {
clearTimeout(Monitor.b2gtimeout);
Monitor.b2ginfo = false;
}
};

View File

@ -208,10 +208,8 @@ let UI = {
setupBusyTimeout: function() {
this.cancelBusyTimeout();
this._busyTimeout = setTimeout(() => {
let busyPromise = this._busyPromise;
this.unbusy();
UI.reportError("error_operationTimeout", this._busyOperationDescription);
busyPromise.reject("promise timeout: " + this._busyOperationDescription);
}, 30000);
},

View File

@ -173,6 +173,7 @@
#endif
@BINPATH@/components/content_xslt.xpt
@BINPATH@/components/cookie.xpt
@BINPATH@/components/devtools_security.xpt
@BINPATH@/components/directory.xpt
@BINPATH@/components/docshell.xpt
@BINPATH@/components/dom.xpt

View File

@ -50,6 +50,7 @@ feedback_category_video_quality=Video quality
feedback_category_was_disconnected=Was disconnected
feedback_category_confusing=Confusing
feedback_category_other=Other:
feedback_custom_category_text_placeholder=What went wrong?
feedback_submit_button=Submit
feedback_back_button=Back
## LOCALIZATION NOTE (feedback_window_will_close_in): In this item, don't
@ -61,4 +62,5 @@ feedback_window_will_close_in=This window will close in {{countdown}} seconds
share_email_subject=Loop invitation to chat
share_email_body=Please click that link to call me back:\r\n\r\n{{callUrl}}
share_button=Email
copy_url_button=Copy
copied_url_button=Copied!

View File

@ -0,0 +1,62 @@
/* - This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this file,
- You can obtain one at http://mozilla.org/MPL/2.0/. */
%include ../../shared/in-content/common.inc.css
xul|tab[selected] {
/* Override styles for tab[selected] from
toolkit/themes/linux/global/tabbox.css */
margin-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
xul|button,
xul|colorpicker[type="button"],
xul|menulist {
margin: 2px 4px;
}
xul|button > xul|*.button-box,
xul|menulist > xul|*.menulist-label-box {
-moz-appearance: none;
}
xul|button[type="menu"] > xul|*.button-box > xul|*.button-menu-dropmarker {
-moz-appearance: none !important;
}
xul|*.help-button > xul|*.button-box > xul|*.button-icon {
-moz-margin-end: 0;
}
xul|menulist {
font-size: inherit;
}
xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker {
display: -moz-box;
margin-top: 6px;
margin-bottom: 6px;
}
xul|checkbox {
-moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox");
-moz-box-align: center;
}
xul|radio {
-moz-binding: url("chrome://global/content/bindings/radio.xml#radio");
-moz-box-align: center;
-moz-margin-start: 0;
}
xul|*.radio-label-box {
-moz-appearance: none;
}
xul|*.numberbox-input-box {
-moz-appearance: none;
border-width: 0;
}

View File

@ -35,7 +35,17 @@ browser.jar:
skin/classic/browser/identity-icons-https-mixed-active.png
skin/classic/browser/identity-icons-https-mixed-display.png
skin/classic/browser/Info.png
skin/classic/browser/in-content/common.css (../shared/in-content/common.css)
* skin/classic/browser/in-content/common.css (in-content/common.css)
skin/classic/browser/in-content/check.png (../shared/in-content/check.png)
skin/classic/browser/in-content/check@2x.png (../shared/in-content/check@2x.png)
skin/classic/browser/in-content/dropdown.png (../shared/in-content/dropdown.png)
skin/classic/browser/in-content/dropdown@2x.png (../shared/in-content/dropdown@2x.png)
skin/classic/browser/in-content/dropdown-disabled.png (../shared/in-content/dropdown-disabled.png)
skin/classic/browser/in-content/dropdown-disabled@2x.png (../shared/in-content/dropdown-disabled@2x.png)
skin/classic/browser/in-content/help-glyph.png (../shared/in-content/help-glyph.png)
skin/classic/browser/in-content/help-glyph@2x.png (../shared/in-content/help-glyph@2x.png)
skin/classic/browser/in-content/sorter.png (../shared/in-content/sorter.png)
skin/classic/browser/in-content/sorter@2x.png (../shared/in-content/sorter@2x.png)
skin/classic/browser/menuPanel.png
skin/classic/browser/menuPanel-customize.png
skin/classic/browser/menuPanel-exit.png
@ -150,18 +160,8 @@ browser.jar:
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
* skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
skin/classic/browser/preferences/in-content/check.png (../shared/incontentprefs/check.png)
skin/classic/browser/preferences/in-content/check@2x.png (../shared/incontentprefs/check@2x.png)
skin/classic/browser/preferences/in-content/icons.png (../shared/incontentprefs/icons.png)
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
skin/classic/browser/preferences/in-content/help-glyph.png (../shared/incontentprefs/help-glyph.png)
skin/classic/browser/preferences/in-content/help-glyph@2x.png (../shared/incontentprefs/help-glyph@2x.png)
skin/classic/browser/preferences/in-content/dropdown.png (../shared/incontentprefs/dropdown.png)
skin/classic/browser/preferences/in-content/dropdown@2x.png (../shared/incontentprefs/dropdown@2x.png)
skin/classic/browser/preferences/in-content/sorter.png (../shared/incontentprefs/sorter.png)
skin/classic/browser/preferences/in-content/sorter@2x.png (../shared/incontentprefs/sorter@2x.png)
skin/classic/browser/preferences/in-content/dropdown-disabled.png (../shared/incontentprefs/dropdown-disabled.png)
skin/classic/browser/preferences/in-content/dropdown-disabled@2x.png (../shared/incontentprefs/dropdown-disabled@2x.png)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
skin/classic/browser/social/services-16.png (social/services-16.png)

View File

@ -4,63 +4,6 @@
%include ../../../shared/incontentprefs/preferences.css
tab[selected] {
/* Override styles for tab[selected] from
toolkit/themes/linux/global/tabbox.css */
margin-bottom: 0;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
button,
colorpicker[type="button"],
menulist {
margin: 2px 4px;
}
button > .button-box,
menulist > .menulist-label-box {
-moz-appearance: none;
}
button[type="menu"] > .button-box > .button-menu-dropmarker {
-moz-appearance: none !important;
}
.help-button > .button-box > .button-icon {
-moz-margin-end: 0;
}
menulist {
font-size: inherit;
}
menulist:not([editable="true"]) > .menulist-dropmarker {
display: -moz-box;
margin-top: 6px;
margin-bottom: 6px;
}
checkbox {
-moz-binding: url("chrome://global/content/bindings/checkbox.xml#checkbox");
-moz-box-align: center;
}
radio {
-moz-binding: url("chrome://global/content/bindings/radio.xml#radio");
-moz-box-align: center;
-moz-margin-start: 0;
}
.radio-label-box {
-moz-appearance: none;
}
.numberbox-input-box {
-moz-appearance: none;
border-width: 0;
}
spinbuttons {
-moz-appearance: none;
}

View File

@ -0,0 +1,60 @@
/* - This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this file,
- You can obtain one at http://mozilla.org/MPL/2.0/. */
%include ../../shared/in-content/common.inc.css
xul|tabs {
padding-right: 0;
padding-left: 0;
}
xul|tab[selected] {
text-shadow: none;
}
xul|button,
xul|colorpicker[type="button"],
xul|menulist {
margin-top: 3px;
}
xul|menulist:not([editable="true"]) > xul|menupopup > xul|menuitem[checked="true"]::before,
xul|menulist:not([editable="true"]) > xul|menupopup > xul|menuitem[selected="true"]::before {
display: none;
}
xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker {
display: -moz-box;
margin-top: 1px;
margin-bottom: 1px;
}
xul|menulist > xul|menupopup xul|menu,
xul|menulist > xul|menupopup xul|menuitem,
xul|button[type="menu"] > xul|menupopup xul|menu,
xul|button[type="menu"] > xul|menupopup xul|menuitem {
-moz-padding-end: 34px;
}
xul|*.help-button > xul|*.button-box > xul|*.button-icon {
-moz-margin-start: 0;
}
xul|*.checkbox-icon {
margin-right: 0;
}
xul|*.radio-icon {
-moz-margin-end: 0;
}
xul|*.numberbox-input-box {
-moz-appearance: none;
border-width: 0;
}
xul|description {
font-size: 1.25rem;
line-height: 22px;
}

View File

@ -43,7 +43,17 @@ browser.jar:
skin/classic/browser/identity-icons-https-mixed-display.png
skin/classic/browser/identity-icons-https-mixed-display@2x.png
skin/classic/browser/Info.png
skin/classic/browser/in-content/common.css (../shared/in-content/common.css)
* skin/classic/browser/in-content/common.css (in-content/common.css)
skin/classic/browser/in-content/check.png (../shared/in-content/check.png)
skin/classic/browser/in-content/check@2x.png (../shared/in-content/check@2x.png)
skin/classic/browser/in-content/dropdown.png (../shared/in-content/dropdown.png)
skin/classic/browser/in-content/dropdown@2x.png (../shared/in-content/dropdown@2x.png)
skin/classic/browser/in-content/dropdown-disabled.png (../shared/in-content/dropdown-disabled.png)
skin/classic/browser/in-content/dropdown-disabled@2x.png (../shared/in-content/dropdown-disabled@2x.png)
skin/classic/browser/in-content/help-glyph.png (../shared/in-content/help-glyph.png)
skin/classic/browser/in-content/help-glyph@2x.png (../shared/in-content/help-glyph@2x.png)
skin/classic/browser/in-content/sorter.png (../shared/in-content/sorter.png)
skin/classic/browser/in-content/sorter@2x.png (../shared/in-content/sorter@2x.png)
skin/classic/browser/keyhole-circle.png
skin/classic/browser/keyhole-circle@2x.png
skin/classic/browser/KUI-background.png
@ -248,18 +258,8 @@ browser.jar:
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
* skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
skin/classic/browser/preferences/in-content/check.png (../shared/incontentprefs/check.png)
skin/classic/browser/preferences/in-content/check@2x.png (../shared/incontentprefs/check@2x.png)
skin/classic/browser/preferences/in-content/icons.png (../shared/incontentprefs/icons.png)
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
skin/classic/browser/preferences/in-content/help-glyph.png (../shared/incontentprefs/help-glyph.png)
skin/classic/browser/preferences/in-content/help-glyph@2x.png (../shared/incontentprefs/help-glyph@2x.png)
skin/classic/browser/preferences/in-content/sorter.png (../shared/incontentprefs/sorter.png)
skin/classic/browser/preferences/in-content/sorter@2x.png (../shared/incontentprefs/sorter@2x.png)
skin/classic/browser/preferences/in-content/dropdown.png (../shared/incontentprefs/dropdown.png)
skin/classic/browser/preferences/in-content/dropdown@2x.png (../shared/incontentprefs/dropdown@2x.png)
skin/classic/browser/preferences/in-content/dropdown-disabled.png (../shared/incontentprefs/dropdown-disabled.png)
skin/classic/browser/preferences/in-content/dropdown-disabled@2x.png (../shared/incontentprefs/dropdown-disabled@2x.png)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
skin/classic/browser/social/services-16.png (social/services-16.png)

View File

@ -9,56 +9,6 @@ prefpane .groupbox-title {
margin-bottom: 0;
}
tabs {
padding-right: 0;
padding-left: 0;
}
tab[selected] {
text-shadow: none;
}
button,
colorpicker[type="button"],
menulist {
margin-top: 3px;
}
menulist:not([editable="true"]) > menupopup > menuitem[checked="true"]::before,
menulist:not([editable="true"]) > menupopup > menuitem[selected="true"]::before {
display: none;
}
menulist:not([editable="true"]) > .menulist-dropmarker {
display: -moz-box;
margin-top: 1px;
margin-bottom: 1px;
}
menulist > menupopup menu,
menulist > menupopup menuitem,
button[type="menu"] > menupopup menu,
button[type="menu"] > menupopup menuitem {
-moz-padding-end: 34px;
}
.help-button > .button-box > .button-icon {
-moz-margin-start: 0;
}
.checkbox-icon {
margin-right: 0;
}
.radio-icon {
-moz-margin-end: 0;
}
.numberbox-input-box {
-moz-appearance: none;
border-width: 0;
}
spinbuttons {
-moz-appearance: none;
}
@ -88,11 +38,6 @@ spinbuttons {
-moz-margin-end: 8px !important;
}
description {
font-size: 1.25rem;
line-height: 22px;
}
#downloadFolder > .fileFieldContentBox {
-moz-padding-start: 3px;
}

View File

Before

Width:  |  Height:  |  Size: 288 B

After

Width:  |  Height:  |  Size: 288 B

View File

Before

Width:  |  Height:  |  Size: 471 B

After

Width:  |  Height:  |  Size: 471 B

View File

@ -1,55 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
body {
font: message-box;
font-size: 15px;
font-weight: normal;
margin: 0;
color: #424e5a;
background-color: #f1f1f1;
}
h1 {
font-size: 2.5em;
font-weight: lighter;
line-height: 1.2;
margin: 0;
margin-bottom: .5em;
}
button {
line-height: 20px;
height: 30px;
max-height: 30px;
padding: 3px;
color: #333333;
border: 1px solid rgba(23,50,77,.4);
border-radius: 5px;
background-color: #f1f1f1;
background-image: linear-gradient(#fff, rgba(255,255,255,.1));
box-shadow: 0 1px 1px 0 #fff, inset 0 2px 2px 0 #fff;
text-shadow: 0 1px 1px #fefffe;
-moz-appearance: none;
-moz-border-top-colors: none !important;
-moz-border-right-colors: none !important;
-moz-border-bottom-colors: none !important;
-moz-border-left-colors: none !important;
}
button:enabled:hover {
background-image: linear-gradient(#fff, rgba(255,255,255,.6));
}
button:enabled:hover:active {
background-image: linear-gradient(rgba(255,255,255,.1), rgba(255,255,255,.6));
}
button:disabled {
cursor: not-allowed;
color: rgba(115,121,128,.5);
border-color: rgba(23,50,77,.25);
background-image: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.1));
text-shadow: 0 1px 1px #fff;
}

View File

@ -0,0 +1,593 @@
%if 0
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%endif
@namespace html "http://www.w3.org/1999/xhtml";
@namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
html|body,
xul|page {
font: message-box;
-moz-appearance: none;
background-color: #f1f1f1;
color: #424e5a;
}
*|* {
-moz-user-select: text;
}
xul|treecol {
/* override the * rule to let the treecol be sortable */
-moz-user-select: none;
}
html|body {
font-size: 15px;
font-weight: normal;
margin: 0;
}
html|h1 {
font-size: 2.5em;
font-weight: lighter;
line-height: 1.2;
margin: 0;
margin-bottom: .5em;
}
xul|caption {
-moz-appearance: none;
margin: 0;
}
xul|caption > xul|label {
font-size: 1.3rem;
font-weight: bold;
line-height: 22px;
margin: 0 !important;
}
*|*.main-content {
padding: 40px 48px 48px;
overflow: auto;
}
xul|prefpane > xul|*.content-box {
overflow: visible;
}
/* groupboxes */
xul|groupbox {
-moz-appearance: none;
border: none;
margin-top: 15px;
margin-bottom: 15px;
-moz-margin-end: 0;
-moz-padding-start: 0;
-moz-padding-end: 0;
font-size: 1.25rem;
}
xul|groupbox xul|label {
/* !important needed to override toolkit !important rule */
-moz-margin-start: 0 !important;
-moz-margin-end: 0 !important;
}
/* tabpanels and tabs */
xul|tabpanels {
-moz-appearance: none;
font-size: 1.25rem;
line-height: 22px;
border: none;
padding: 0;
background-color: transparent;
}
xul|tabs {
margin-bottom: 15px;
border-top: 1px solid #c1c1c1;
border-bottom: 1px solid #c1c1c1;
background-color: #fbfbfb;
}
xul|*.tabs-left,
xul|*.tabs-right {
border-bottom: none;
}
xul|tab {
-moz-appearance: none;
margin-top: 0;
padding: 0 20px;
min-height: 44px;
color: #424f5a;
background-color: #fbfbfb;
border-width: 0;
transition: background-color 50ms ease 0s;
}
xul|tab:hover {
background-color: #ebebeb;
}
xul|tab[selected] {
background-color: #ebebeb;
box-shadow: inset 0 -4px 0 0 #ff9500;
}
xul|*.tab-text {
font-size: 1.3rem;
line-height: 22px;
}
/* html buttons */
html|button {
padding: 3px;
/* override forms.css */
font: inherit;
}
/* xul buttons and menulists */
*|button,
xul|colorpicker[type="button"],
xul|menulist {
-moz-appearance: none;
height: 30px;
color: #333;
line-height: 20px;
text-shadow: 0 1px 1px #fefffe;
border: 1px solid #c1c1c1;
-moz-border-top-colors: none !important;
-moz-border-right-colors: none !important;
-moz-border-bottom-colors: none !important;
-moz-border-left-colors: none !important;
border-radius: 2px;
background-color: #fbfbfb;
}
html|button:enabled:hover,
xul|button:not([disabled="true"]):hover,
xul|colorpicker[type="button"]:not([disabled="true"]):hover,
xul|menulist:not([disabled="true"]):hover {
background-color: #ebebeb;
}
html|button:enabled:hover:active,
xul|button:not([disabled="true"]):hover:active,
xul|colorpicker[type="button"]:not([disabled="true"]):hover:active,
xul|menulist[open="true"]:not([disabled="true"]) {
background-color: #dadada;
}
html|button:disabled,
xul|button[disabled="true"],
xul|colorpicker[type="button"][disabled="true"],
xul|menulist[disabled="true"] {
cursor: not-allowed;
opacity: 0.5;
}
xul|colorpicker[type="button"] {
padding: 6px;
width: 50px;
}
xul|button > xul|*.button-box,
xul|menulist > xul|*.menulist-label-box {
padding-right: 10px !important;
padding-left: 10px !important;
}
xul|button[type="menu"] > xul|*.button-box > xul|*.button-menu-dropmarker {
-moz-appearance: none;
margin: 1px 0;
-moz-margin-start: 10px;
padding: 0;
width: 10px;
height: 16px;
border: none;
background-color: transparent;
list-style-image: url("chrome://browser/skin/in-content/dropdown.png");
}
xul|*.help-button {
min-width: 30px;
border-radius: 2px;
border: 1px solid #c1c1c1;
background-color: #ffcb00;
background-image: none;
box-shadow: none;
}
xul|*.help-button:not([disabled="true"]):hover {
background-color: #f4c200;
background-image: none;
}
xul|*.help-button:not([disabled="true"]):hover:active {
background-color: #eaba00;
background-image: none;
}
xul|*.close-icon > xul|*.button-box,
xul|*.help-button > xul|*.button-box {
padding-top: 0;
padding-bottom: 0;
padding-right: 0 !important;
padding-left: 0 !important;
}
xul|*.help-button > xul|*.button-box > xul|*.button-icon {
width: 26px;
height: 26px;
background-image: url("chrome://browser/skin/in-content/help-glyph.png");
background-position: center;
}
@media (min-resolution: 2dppx) {
xul|*.help-button > xul|*.button-box > xul|*.button-icon {
background-size: 26px 26px;
background-image: url("chrome://browser/skin/in-content/help-glyph@2x.png");
}
}
xul|*.help-button > xul|*.button-box > xul|*.button-text {
display: none;
}
xul|*.spinbuttons-button {
-moz-margin-start: 10px !important;
-moz-margin-end: 2px !important;
}
xul|*.spinbuttons-up {
margin-top: 2px !important;
border-radius: 1px 1px 0 0;
}
xul|*.spinbuttons-down {
margin-bottom: 2px !important;
border-radius: 0 0 1px 1px;
}
xul|*.spinbuttons-button > xul|*.button-box {
padding: 1px 5px 2px !important;
}
xul|*.spinbuttons-up > xul|*.button-box > xul|*.button-icon {
list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
}
xul|*.spinbuttons-up[disabled="true"] > xul|*.button-box > xul|*.button-icon {
list-style-image: url("chrome://global/skin/arrow/arrow-up-dis.gif");
}
xul|*.spinbuttons-down > xul|*.button-box > xul|*.button-icon {
list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
}
xul|*.spinbuttons-down[disabled="true"] > xul|*.button-box > xul|*.button-icon {
list-style-image: url("chrome://global/skin/arrow/arrow-dn-dis.gif");
}
xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker {
-moz-appearance: none;
-moz-margin-end: 10px;
padding: 0;
border: none;
background-color: transparent;
list-style-image: url("chrome://browser/skin/in-content/dropdown.png");
}
xul|menulist[disabled="true"]:not([editable="true"]) > xul|*.menulist-dropmarker {
list-style-image: url("chrome://browser/skin/in-content/dropdown-disabled.png")
}
@media (min-resolution: 2dppx) {
xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker,
xul|button[type="menu"] > xul|*.button-box > xul|*.button-menu-dropmarker {
list-style-image: url("chrome://browser/skin/in-content/dropdown@2x.png");
}
xul|menulist[disabled="true"]:not([editable="true"]) > xul|*.menulist-dropmarker {
list-style-image: url("chrome://browser/skin/in-content/dropdown-disabled@2x.png")
}
xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker > xul|*.dropmarker-icon,
xul|button[type="menu"] > xul|*.button-box > xul|*.button-menu-dropmarker > xul|*.dropmarker-icon {
width: 10px;
height: 16px;
}
}
xul|menulist > xul|menupopup,
xul|button[type="menu"] > xul|menupopup {
-moz-appearance: none;
border: 1px solid rgba(23,50,77,0.4);
border-radius: 2px;
background-color: #fff;
}
xul|menulist > xul|menupopup xul|menu,
xul|menulist > xul|menupopup xul|menuitem,
xul|button[type="menu"] > xul|menupopup xul|menu,
xul|button[type="menu"] > xul|menupopup xul|menuitem {
-moz-appearance: none;
font-size: 1.25rem;
line-height: 22px;
height: 40px;
color: #333;
-moz-padding-start: 10px;
-moz-padding-end: 30px;
}
xul|menulist > xul|menupopup > xul|menu[_moz-menuactive="true"],
xul|menulist > xul|menupopup > xul|menuitem[_moz-menuactive="true"],
xul|button[type="menu"] > xul|menupopup > xul|menu[_moz-menuactive="true"],
xul|button[type="menu"] > xul|menupopup > xul|menuitem[_moz-menuactive="true"] {
color: #333;
background-color: transparent;
background-image: linear-gradient(rgba(76,177,255,0.25), rgba(23,146,229,0.25));
}
xul|menulist > xul|menupopup > xul|menu[selected="true"],
xul|menulist > xul|menupopup > xul|menuitem[selected="true"],
xul|button[type="menu"] > xul|menupopup > xul|menu[selected="true"],
xul|button[type="menu"] > xul|menupopup > xul|menuitem[selected="true"] {
color: #fff;
background-image: linear-gradient(#4cb1ff, #1792e5);
}
xul|menulist > xul|menupopup xul|menuseparator,
xul|button[type="menu"] > xul|menupopup xul|menuseparator {
-moz-appearance: none;
margin-top: 2px;
margin-bottom: 2px;
padding: 0;
border-top: 1px solid rgba(23,50,77,0.4);
border-bottom: none;
}
/* textboxes */
*|textbox {
-moz-appearance: none;
height: 30px;
color: #333;
line-height: 20px;
text-shadow: 0 1px 1px #fefffe;
padding-right: 10px;
padding-left: 10px;
border: 1px solid #c1c1c1;
-moz-border-top-colors: none !important;
-moz-border-right-colors: none !important;
-moz-border-bottom-colors: none !important;
-moz-border-left-colors: none !important;
border-radius: 2px;
background-color: #fff;
}
html|textbox:focus,
xul|textbox[focused] {
border-color: #0095dd;
}
html|textbox:disabled,
xul|textbox[disabled="true"] {
opacity: 0.5;
}
/* Links */
xul|*.text-link,
xul|*.inline-link,
html|a.inline-link {
font-size: 1.25rem;
line-height: 22px;
color: #0095dd;
}
xul|*.text-link:hover,
xul|*.inline-link:hover {
color: #4cb1ff;
text-decoration: none;
}
xul|*.text-link:hover:active,
xul|*.inline-link:hover:active {
color: #ff9500;
text-decoration: none;
}
/* Checkboxes and radio buttons */
xul|checkbox {
-moz-margin-start: 0;
}
xul|*.checkbox-check {
-moz-appearance: none;
width: 23px;
height: 23px;
border-radius: 2px;
border: 1px solid #c1c1c1;
-moz-margin-end: 10px;
background-color: #f1f1f1;
background-image: linear-gradient(#fff, rgba(255,255,255,0.8));
background-position: center center;
background-repeat: no-repeat;
box-shadow: 0 1px 1px 0 #fff, inset 0 2px 0 0 rgba(0,0,0,0.03);
}
xul|checkbox:not([disabled="true"]):hover > xul|*.checkbox-check {
border-color: #0095dd;
}
xul|*.checkbox-check[checked] {
background-image: url("chrome://browser/skin/in-content/check.png"),
/* !important needed to override toolkit !important rule */
linear-gradient(#fff, rgba(255,255,255,0.8)) !important;
}
xul|checkbox[disabled="true"] > xul|*.checkbox-check {
opacity: 0.5;
}
xul|*.checkbox-label-box {
-moz-margin-start: -1px; /* negative margin for the transparent border */
-moz-padding-start: 0;
}
@media (min-resolution: 2dppx) {
xul|*.checkbox-check[checked] {
background-size: 12px 12px, auto;
background-image: url("chrome://browser/skin/in-content/check@2x.png"),
linear-gradient(#fff, rgba(255,255,255,0.8)) !important;
}
}
xul|*.radio-check {
-moz-appearance: none;
width: 23px;
height: 23px;
border: 1px solid #c1c1c1;
border-radius: 50%;
-moz-margin-end: 10px;
background-color: #f1f1f1;
background-image: linear-gradient(#fff, rgba(255,255,255,0.80));
box-shadow: 0 1px 1px 0 #fff, inset 0 2px 0 0 rgba(0,0,0,0.03);
}
xul|radio:not([disabled="true"]):hover > xul|*.radio-check {
border-color: #0095dd;
}
xul|*.radio-check[selected] {
background-image: radial-gradient(circle, rgb(23,146,229),
rgb(76,177,255) 5.5px, rgba(76,177,255,0.2) 6px,
transparent 6px),
linear-gradient(rgb(255,255,255), rgba(255,255,255,0.8));
}
xul|radio[disabled="true"] > xul|*.radio-check {
opacity: 0.5;
}
xul|*.radio-label-box {
-moz-margin-start: -1px; /* negative margin for the transparent border */
-moz-margin-end: 10px;
-moz-padding-start: 0;
}
/* Category List */
xul|*#categories {
-moz-appearance: none;
background-color: #424f5a;
padding-top: 39px;
margin: 0;
}
xul|*.category {
-moz-appearance: none;
color: #c1c1c1;
-moz-border-end-width: 0;
-moz-padding-start: 15px;
-moz-padding-end: 21px;
min-height: 40px;
transition: background-color 150ms;
}
xul|*.category:hover {
background-color: #5e6972;
}
xul|*.category[selected] {
background-color: #343f48;
color: #f2f2f2;
box-shadow: inset 4px 0 0 0 #ff9500;
}
xul|*#categories[keyboard-navigation="true"]:-moz-focusring > xul|*.category[current] {
border-top: 1px #ffffff dotted;
border-bottom: 1px #ffffff dotted;
}
*|*.category-name {
line-height: 22px;
font-size: 1.25rem;
padding-bottom: 2px;
-moz-padding-start: 9px;
margin: 0;
}
*|*.category-icon {
width: 24px;
height: 24px;
}
/* header */
*|*.header {
border-bottom: 1px solid #c8c8c8;
margin-bottom: 15px;
padding-bottom: 15px;
}
*|*.header-name {
font-size: 2.5rem;
font-weight: normal;
line-height: 40px;
margin: 0;
}
/* File fields */
xul|filefield {
-moz-appearance: none;
background-color: transparent;
border: none;
padding: 0;
}
xul|*.fileFieldContentBox {
background-color: transparent;
}
xul|*.fileFieldIcon {
-moz-margin-start: 10px;
-moz-margin-end: 0;
}
xul|*.fileFieldLabel {
-moz-margin-start: -26px;
-moz-padding-start: 36px;
}
xul|textbox:-moz-locale-dir(rtl),
xul|*.fileFieldLabel:-moz-locale-dir(rtl),
xul|textbox + xul|button:-moz-locale-dir(ltr),
xul|filefield + xul|button:-moz-locale-dir(ltr) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
xul|textbox:-moz-locale-dir(ltr),
xul|*.fileFieldLabel:-moz-locale-dir(ltr),
xul|textbox + xul|button:-moz-locale-dir(rtl),
xul|filefield + xul|button:-moz-locale-dir(rtl) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
xul|textbox + xul|button,
xul|filefield + xul|button {
-moz-border-start: none;
}

View File

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 412 B

View File

Before

Width:  |  Height:  |  Size: 865 B

After

Width:  |  Height:  |  Size: 865 B

View File

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 421 B

View File

Before

Width:  |  Height:  |  Size: 885 B

After

Width:  |  Height:  |  Size: 885 B

View File

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 280 B

View File

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 500 B

View File

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

View File

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 523 B

View File

@ -9,39 +9,12 @@
dialog,
window,
prefwindow,
.windowDialog,
page {
.windowDialog {
-moz-appearance: none;
background-color: #f1f1f1;
color: #424E5A;
}
* {
-moz-user-select: text;
}
treecol {
/* override the * rule to let the treecol be sortable */
-moz-user-select: none;
}
caption {
-moz-appearance: none;
margin: 0;
}
caption > label {
font-size: 1.3rem;
font-weight: bold;
line-height: 22px;
margin: 0 !important;
}
.main-content {
padding: 40px 48px 48px;
overflow: auto;
}
prefpane {
max-width: 800px;
padding: 0;
@ -50,469 +23,9 @@ prefpane {
line-height: 22px;
}
prefpane > .content-box {
overflow: visible;
}
/* groupboxes */
groupbox {
-moz-appearance: none;
border: none;
margin-top: 15px;
margin-bottom: 15px;
-moz-margin-end: 0;
-moz-padding-start: 0;
-moz-padding-end: 0;
font-size: 1.25rem;
}
groupbox label {
/* !important needed to override toolkit !important rule */
-moz-margin-start: 0 !important;
-moz-margin-end: 0 !important;
}
/* tabpanels and tabs */
tabpanels {
-moz-appearance: none;
font-size: 1.25rem;
line-height: 22px;
border: none;
padding: 0;
background-color: transparent;
}
tabs {
margin-bottom: 15px;
border-top: 1px solid #c1c1c1;
border-bottom: 1px solid #c1c1c1;
background-color: #fbfbfb;
}
.tabs-left,
.tabs-right {
border-bottom: none;
}
tab {
-moz-appearance: none;
margin-top: 0;
padding: 0 20px;
min-height: 44px;
color: #424f5a;
background-color: #fbfbfb;
border-width: 0;
transition: background-color 50ms ease 0s;
}
tab:hover {
background-color: #ebebeb;
}
tab[selected] {
background-color: #ebebeb;
box-shadow: inset 0 -4px 0 0 #ff9500;
}
.tab-text {
font-size: 1.3rem;
line-height: 22px;
}
/* buttons and menulists */
button,
colorpicker[type="button"],
menulist {
-moz-appearance: none;
height: 30px;
color: #333333;
line-height: 20px;
text-shadow: 0 1px 1px #FEFFFE;
border: 1px solid #C1C1C1;
-moz-border-top-colors: none !important;
-moz-border-right-colors: none !important;
-moz-border-bottom-colors: none !important;
-moz-border-left-colors: none !important;
border-radius: 2px;
background-color: #FBFBFB;
}
button:not([disabled="true"]):hover,
colorpicker[type="button"]:not([disabled="true"]):hover,
menulist:not([disabled="true"]):hover {
background-color: #EBEBEB;
}
button:not([disabled="true"]):hover:active,
colorpicker[type="button"]:not([disabled="true"]):hover:active,
menulist[open="true"]:not([disabled="true"]) {
background-color: #DADADA;
}
button[disabled="true"],
colorpicker[type="button"][disabled="true"],
menulist[disabled="true"] {
opacity: 0.5;
}
colorpicker[type="button"] {
padding: 6px;
width: 50px;
}
button > .button-box,
menulist > .menulist-label-box {
padding-right: 10px !important;
padding-left: 10px !important;
}
button[type="menu"] > .button-box > .button-menu-dropmarker {
-moz-appearance: none;
margin: 1px 0;
-moz-margin-start: 10px;
padding: 0;
width: 10px;
height: 16px;
border: none;
background-color: transparent;
list-style-image: url("chrome://browser/skin/preferences/in-content/dropdown.png");
}
.help-button {
min-width: 30px;
border-radius: 2px;
border: 1px solid #C1C1C1;
background-color: #FFCB00;
background-image: none;
box-shadow: none;
}
.help-button:not([disabled="true"]):hover {
background-color: #F4C200;
background-image: none;
}
.help-button:not([disabled="true"]):hover:active {
background-color: #EABA00;
background-image: none;
}
.close-icon > .button-box,
.help-button > .button-box {
padding-top: 0;
padding-bottom: 0;
padding-right: 0 !important;
padding-left: 0 !important;
}
.help-button > .button-box > .button-icon {
width: 26px;
height: 26px;
background-image: url("chrome://browser/skin/preferences/in-content/help-glyph.png");
background-position: center;
}
@media (min-resolution: 2dppx) {
.help-button > .button-box > .button-icon {
background-size: 26px 26px;
background-image: url("chrome://browser/skin/preferences/in-content/help-glyph@2x.png");
}
}
.help-button > .button-box > .button-text {
display: none;
}
.spinbuttons-button {
-moz-margin-start: 10px !important;
-moz-margin-end: 2px !important;
}
.spinbuttons-up {
margin-top: 2px !important;
border-radius: 1px 1px 0 0;
}
.spinbuttons-down {
margin-bottom: 2px !important;
border-radius: 0 0 1px 1px;
}
.spinbuttons-button > .button-box {
padding: 1px 5px 2px !important;
}
.spinbuttons-up > .button-box > .button-icon {
list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
}
.spinbuttons-up[disabled="true"] > .button-box > .button-icon {
list-style-image: url("chrome://global/skin/arrow/arrow-up-dis.gif");
}
.spinbuttons-down > .button-box > .button-icon {
list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
}
.spinbuttons-down[disabled="true"] > .button-box > .button-icon {
list-style-image: url("chrome://global/skin/arrow/arrow-dn-dis.gif");
}
menulist:not([editable="true"]) > .menulist-dropmarker {
-moz-appearance: none;
-moz-margin-end: 10px;
padding: 0;
border: none;
background-color: transparent;
list-style-image: url("chrome://browser/skin/preferences/in-content/dropdown.png")
}
menulist[disabled="true"]:not([editable="true"]) > .menulist-dropmarker {
list-style-image: url("chrome://browser/skin/preferences/in-content/dropdown-disabled.png")
}
@media (min-resolution: 2dppx) {
menulist:not([editable="true"]) > .menulist-dropmarker,
button[type="menu"] > .button-box > .button-menu-dropmarker {
list-style-image: url("chrome://browser/skin/preferences/in-content/dropdown@2x.png");
}
menulist[disabled="true"]:not([editable="true"]) > .menulist-dropmarker {
list-style-image: url("chrome://browser/skin/preferences/in-content/dropdown-disabled@2x.png")
}
menulist:not([editable="true"]) > .menulist-dropmarker > .dropmarker-icon,
button[type="menu"] > .button-box > .button-menu-dropmarker > .dropmarker-icon {
width: 10px;
height: 16px;
}
}
menulist > menupopup,
button[type="menu"] > menupopup {
-moz-appearance: none;
border: 1px solid rgba(23,50,77,0.4);
border-radius: 2px;
background-color: #FFFFFF;
}
menulist > menupopup menu,
menulist > menupopup menuitem,
button[type="menu"] > menupopup menu,
button[type="menu"] > menupopup menuitem {
-moz-appearance: none;
font-size: 1.25rem;
line-height: 22px;
height: 40px;
color: #333333;
-moz-padding-start: 10px;
-moz-padding-end: 30px;
}
menulist > menupopup > menu[_moz-menuactive="true"],
menulist > menupopup > menuitem[_moz-menuactive="true"],
button[type="menu"] > menupopup > menu[_moz-menuactive="true"],
button[type="menu"] > menupopup > menuitem[_moz-menuactive="true"] {
color: #333333;
background-color: transparent;
background-image: linear-gradient(rgba(76,177,255,0.25), rgba(23,146,229,0.25));
}
menulist > menupopup > menu[selected="true"],
menulist > menupopup > menuitem[selected="true"],
button[type="menu"] > menupopup > menu[selected="true"],
button[type="menu"] > menupopup > menuitem[selected="true"] {
color: #fff;
background-image: linear-gradient(#4CB1FF, #1792E5);
}
menulist > menupopup menuseparator,
button[type="menu"] > menupopup menuseparator {
-moz-appearance: none;
margin-top: 2px;
margin-bottom: 2px;
padding: 0;
border-top: 1px solid rgba(23,50,77,0.4);
border-bottom: none;
}
/* textboxes */
textbox {
-moz-appearance: none;
height: 30px;
color: #333333;
line-height: 20px;
text-shadow: 0 1px 1px #FEFFFE;
padding-right: 10px;
padding-left: 10px;
border: 1px solid #C1C1C1;
-moz-border-top-colors: none !important;
-moz-border-right-colors: none !important;
-moz-border-bottom-colors: none !important;
-moz-border-left-colors: none !important;
border-radius: 2px;
background-color: #FFF;
}
textbox[focused] {
border-color: #0095DD;
}
textbox[disabled="true"] {
opacity: 0.5;
}
/* Links */
.text-link,
.inline-link,
html|a.inline-link {
font-size: 1.25rem;
line-height: 22px;
color: #0095DD;
}
.text-link:hover,
.inline-link:hover {
color: #4CB1FF;
text-decoration: none;
}
.text-link:hover:active,
.inline-link:hover:active {
color: #FF9500;
text-decoration: none;
}
/* Checkboxes and radio buttons */
checkbox {
-moz-margin-start: 0;
}
.checkbox-check {
-moz-appearance: none;
width: 23px;
height: 23px;
border-radius: 2px;
border: 1px solid #C1C1C1;
-moz-margin-end: 10px;
background-color: #f1f1f1;
background-image: linear-gradient(#ffffff, rgba(255,255,255,0.8));
background-position: center center;
background-repeat: no-repeat;
box-shadow: 0 1px 1px 0 #ffffff, inset 0 2px 0 0 rgba(0,0,0,0.03);
}
checkbox:not([disabled="true"]):hover > .checkbox-check {
border-color: #0095DD;
}
.checkbox-check[checked] {
background-image: url("chrome://browser/skin/preferences/in-content/check.png"),
/* !important needed to override toolkit !important rule */
linear-gradient(#ffffff, rgba(255,255,255,0.8)) !important;
}
checkbox[disabled="true"] > .checkbox-check {
opacity: 0.5;
}
.checkbox-label-box {
-moz-margin-start: -1px; /* negative margin for the transparent border */
-moz-padding-start: 0;
}
@media (min-resolution: 2dppx) {
.checkbox-check[checked] {
background-size: 12px 12px, auto;
background-image: url("chrome://browser/skin/preferences/in-content/check@2x.png"),
linear-gradient(#ffffff, rgba(255,255,255,0.8)) !important;
}
}
.radio-check {
-moz-appearance: none;
width: 23px;
height: 23px;
border: 1px solid #C1C1C1;
border-radius: 50%;
-moz-margin-end: 10px;
background-color: #f1f1f1;
background-image: linear-gradient(#ffffff, rgba(255,255,255,0.80));
box-shadow: 0 1px 1px 0 #ffffff, inset 0 2px 0 0 rgba(0,0,0,0.03);
}
radio:not([disabled="true"]):hover > .radio-check {
border-color: #0095DD;
}
.radio-check[selected] {
background-image: radial-gradient(circle, rgb(23,146,229),
rgb(76,177,255) 5.5px, rgba(76,177,255,0.2) 6px,
transparent 6px),
linear-gradient(rgb(255,255,255), rgba(255,255,255,0.8));
}
radio[disabled="true"] > .radio-check {
opacity: 0.5;
}
.radio-label-box {
-moz-margin-start: -1px; /* negative margin for the transparent border */
-moz-margin-end: 10px;
-moz-padding-start: 0;
}
/* Category List */
#categories {
-moz-appearance: none;
background-color: #424f5a;
padding-top: 39px;
margin: 0;
}
.category {
-moz-appearance: none;
color: #c1c1c1;
-moz-border-end-width: 0;
-moz-padding-start: 15px;
-moz-padding-end: 21px;
min-height: 40px;
transition: background-color 150ms;
}
.category:hover {
background-color: #5e6972;
}
.category[selected] {
background-color: #343f48;
color: #f2f2f2;
box-shadow: inset 4px 0 0 0 #FF9500;
}
#categories[keyboard-navigation="true"]:-moz-focusring > .category[current] {
border-top: 1px #ffffff dotted;
border-bottom: 1px #ffffff dotted;
}
.category-name {
line-height: 22px;
font-size: 1.25rem;
padding-bottom: 2px;
-moz-padding-start: 9px;
margin: 0;
}
.category-icon {
width: 24px;
height: 24px;
list-style-image: url("chrome://browser/skin/preferences/in-content/icons.png");
}
@ -580,68 +93,13 @@ radio[disabled="true"] > .radio-check {
/* header */
.header {
border-bottom: 1px solid #c8c8c8;
margin-bottom: 15px;
padding-bottom: 15px;
}
#header-advanced {
border-bottom: none;
padding-bottom: 0;
}
.header-name {
font-size: 2.5rem;
font-weight: normal;
line-height: 40px;
margin: 0;
}
/* General Pane */
filefield {
-moz-appearance: none;
background-color: transparent;
border: none;
padding: 0;
}
.fileFieldContentBox {
background-color: transparent;
}
.fileFieldIcon {
-moz-margin-start: 10px;
-moz-margin-end: 0;
}
.fileFieldLabel {
-moz-margin-start: -26px;
-moz-padding-start: 36px;
}
textbox:-moz-locale-dir(rtl),
.fileFieldLabel:-moz-locale-dir(rtl),
textbox + button:-moz-locale-dir(ltr),
filefield + button:-moz-locale-dir(ltr) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
textbox:-moz-locale-dir(ltr),
.fileFieldLabel:-moz-locale-dir(ltr),
textbox + button:-moz-locale-dir(rtl),
filefield + button:-moz-locale-dir(rtl) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
textbox + button,
filefield + button {
-moz-border-start: none;
}
#downloadFolder {
-moz-margin-start: 0;
}

View File

@ -0,0 +1,35 @@
/* - This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this file,
- You can obtain one at http://mozilla.org/MPL/2.0/. */
%include ../../shared/in-content/common.inc.css
xul|caption {
background-color: transparent;
}
xul|button,
xul|colorpicker[type="button"],
xul|menulist {
margin: 2px 4px;
}
xul|menulist:not([editable="true"]) > xul|*.menulist-dropmarker {
margin-top: 1px;
margin-bottom: 1px;
}
xul|checkbox {
-moz-padding-start: 0;
}
xul|radio {
-moz-binding: url("chrome://global/content/bindings/radio.xml#radio");
-moz-margin-start: 0;
-moz-padding-start: 0;
}
xul|*.radio-icon,
xul|*.checkbox-icon {
-moz-margin-end: 0;
}

View File

@ -37,7 +37,17 @@ browser.jar:
skin/classic/browser/identity-icons-https-ev.png
skin/classic/browser/identity-icons-https-mixed-active.png
skin/classic/browser/identity-icons-https-mixed-display.png
skin/classic/browser/in-content/common.css (../shared/in-content/common.css)
* skin/classic/browser/in-content/common.css (in-content/common.css)
skin/classic/browser/in-content/check.png (../shared/in-content/check.png)
skin/classic/browser/in-content/check@2x.png (../shared/in-content/check@2x.png)
skin/classic/browser/in-content/dropdown.png (../shared/in-content/dropdown.png)
skin/classic/browser/in-content/dropdown@2x.png (../shared/in-content/dropdown@2x.png)
skin/classic/browser/in-content/dropdown-disabled.png (../shared/in-content/dropdown-disabled.png)
skin/classic/browser/in-content/dropdown-disabled@2x.png (../shared/in-content/dropdown-disabled@2x.png)
skin/classic/browser/in-content/help-glyph.png (../shared/in-content/help-glyph.png)
skin/classic/browser/in-content/help-glyph@2x.png (../shared/in-content/help-glyph@2x.png)
skin/classic/browser/in-content/sorter.png (../shared/in-content/sorter.png)
skin/classic/browser/in-content/sorter@2x.png (../shared/in-content/sorter@2x.png)
skin/classic/browser/keyhole-forward-mask.svg
skin/classic/browser/KUI-background.png
skin/classic/browser/livemark-folder.png
@ -177,18 +187,8 @@ browser.jar:
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
* skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
skin/classic/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
skin/classic/browser/preferences/in-content/check.png (../shared/incontentprefs/check.png)
skin/classic/browser/preferences/in-content/check@2x.png (../shared/incontentprefs/check@2x.png)
skin/classic/browser/preferences/in-content/icons.png (../shared/incontentprefs/icons.png)
skin/classic/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
skin/classic/browser/preferences/in-content/help-glyph.png (../shared/incontentprefs/help-glyph.png)
skin/classic/browser/preferences/in-content/help-glyph@2x.png (../shared/incontentprefs/help-glyph@2x.png)
skin/classic/browser/preferences/in-content/sorter.png (../shared/incontentprefs/sorter.png)
skin/classic/browser/preferences/in-content/sorter@2x.png (../shared/incontentprefs/sorter@2x.png)
skin/classic/browser/preferences/in-content/dropdown.png (../shared/incontentprefs/dropdown.png)
skin/classic/browser/preferences/in-content/dropdown@2x.png (../shared/incontentprefs/dropdown@2x.png)
skin/classic/browser/preferences/in-content/dropdown-disabled.png (../shared/incontentprefs/dropdown-disabled.png)
skin/classic/browser/preferences/in-content/dropdown-disabled@2x.png (../shared/incontentprefs/dropdown-disabled@2x.png)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
skin/classic/browser/social/services-16.png (social/services-16.png)
@ -456,7 +456,17 @@ browser.jar:
skin/classic/aero/browser/identity-icons-https-ev.png
skin/classic/aero/browser/identity-icons-https-mixed-active.png
skin/classic/aero/browser/identity-icons-https-mixed-display.png
skin/classic/aero/browser/in-content/common.css (../shared/in-content/common.css)
* skin/classic/aero/browser/in-content/common.css (in-content/common.css)
skin/classic/aero/browser/in-content/check.png (../shared/in-content/check.png)
skin/classic/aero/browser/in-content/check@2x.png (../shared/in-content/check@2x.png)
skin/classic/aero/browser/in-content/dropdown.png (../shared/in-content/dropdown.png)
skin/classic/aero/browser/in-content/dropdown@2x.png (../shared/in-content/dropdown@2x.png)
skin/classic/aero/browser/in-content/dropdown-disabled.png (../shared/in-content/dropdown-disabled.png)
skin/classic/aero/browser/in-content/dropdown-disabled@2x.png (../shared/in-content/dropdown-disabled@2x.png)
skin/classic/aero/browser/in-content/help-glyph.png (../shared/in-content/help-glyph.png)
skin/classic/aero/browser/in-content/help-glyph@2x.png (../shared/in-content/help-glyph@2x.png)
skin/classic/aero/browser/in-content/sorter.png (../shared/in-content/sorter.png)
skin/classic/aero/browser/in-content/sorter@2x.png (../shared/in-content/sorter@2x.png)
skin/classic/aero/browser/keyhole-forward-mask.svg
skin/classic/aero/browser/KUI-background.png
skin/classic/aero/browser/livemark-folder.png (livemark-folder-aero.png)
@ -602,18 +612,8 @@ browser.jar:
* skin/classic/aero/browser/preferences/preferences.css (preferences/preferences.css)
* skin/classic/aero/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css)
skin/classic/aero/browser/preferences/in-content/favicon.ico (../shared/incontentprefs/favicon.ico)
skin/classic/aero/browser/preferences/in-content/check.png (../shared/incontentprefs/check.png)
skin/classic/aero/browser/preferences/in-content/check@2x.png (../shared/incontentprefs/check@2x.png)
skin/classic/aero/browser/preferences/in-content/icons.png (../shared/incontentprefs/icons.png)
skin/classic/aero/browser/preferences/in-content/icons@2x.png (../shared/incontentprefs/icons@2x.png)
skin/classic/aero/browser/preferences/in-content/help-glyph.png (../shared/incontentprefs/help-glyph.png)
skin/classic/aero/browser/preferences/in-content/help-glyph@2x.png (../shared/incontentprefs/help-glyph@2x.png)
skin/classic/aero/browser/preferences/in-content/sorter.png (../shared/incontentprefs/sorter.png)
skin/classic/aero/browser/preferences/in-content/sorter@2x.png (../shared/incontentprefs/sorter@2x.png)
skin/classic/aero/browser/preferences/in-content/dropdown.png (../shared/incontentprefs/dropdown.png)
skin/classic/aero/browser/preferences/in-content/dropdown@2x.png (../shared/incontentprefs/dropdown@2x.png)
skin/classic/aero/browser/preferences/in-content/dropdown-disabled.png (../shared/incontentprefs/dropdown-disabled.png)
skin/classic/aero/browser/preferences/in-content/dropdown-disabled@2x.png (../shared/incontentprefs/dropdown-disabled@2x.png)
skin/classic/aero/browser/preferences/applications.css (preferences/applications.css)
skin/classic/aero/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
skin/classic/aero/browser/social/services-16.png (social/services-16.png)

View File

@ -4,36 +4,6 @@
%include ../../../shared/incontentprefs/preferences.css
caption {
background-color: transparent;
}
button,
colorpicker[type="button"],
menulist {
margin: 2px 4px;
}
menulist:not([editable="true"]) > .menulist-dropmarker {
margin-top: 1px;
margin-bottom: 1px;
}
checkbox {
-moz-padding-start: 0;
}
radio {
-moz-binding: url("chrome://global/content/bindings/radio.xml#radio");
-moz-margin-start: 0;
-moz-padding-start: 0;
}
.radio-icon,
.checkbox-icon {
-moz-margin-end: 0;
}
.actionsMenu > .menulist-label-box > .menulist-icon {
-moz-margin-end: 9px;
}

View File

@ -172,11 +172,6 @@ class nsContentUtils
public:
static nsresult Init();
/**
* Get a JSContext from the document's scope object.
*/
static JSContext* GetContextFromDocument(nsIDocument *aDocument);
static bool IsCallerChrome();
static bool ThreadsafeIsCallerChrome();
static bool IsCallerContentXBL();

View File

@ -1939,24 +1939,6 @@ nsContentUtils::InProlog(nsINode *aNode)
return !root || doc->IndexOf(aNode) < doc->IndexOf(root);
}
JSContext *
nsContentUtils::GetContextFromDocument(nsIDocument *aDocument)
{
nsCOMPtr<nsIScriptGlobalObject> sgo = do_QueryInterface(aDocument->GetScopeObject());
if (!sgo) {
// No script global, no context.
return nullptr;
}
nsIScriptContext *scx = sgo->GetContext();
if (!scx) {
// No context left in the scope...
return nullptr;
}
return scx->GetNativeContext();
}
//static
void
nsContentUtils::TraceSafeJSContext(JSTracer* aTrc)

View File

@ -277,7 +277,6 @@ struct MOZ_STACK_CLASS nsHandlerData
uint16_t mOperation;
nsCOMPtr<nsIDOMNode> mSource;
nsCOMPtr<nsIDOMNode> mDest;
nsCxPusher mPusher;
};
static void
@ -291,9 +290,6 @@ CallHandler(void *aObject, nsIAtom *aKey, void *aHandler, void *aData)
static_cast<nsIVariant*>(node->GetProperty(DOM_USER_DATA, aKey));
NS_ASSERTION(data, "Handler without data?");
if (!handlerData->mPusher.RePush(node)) {
return;
}
nsAutoString key;
aKey->ToString(key);
handler->Handle(handlerData->mOperation, key, data, handlerData->mSource,

View File

@ -44,15 +44,19 @@ var checkTestResults = function() {
SimpleTest.finish();
}
function loadElements() {
// save this for last so that our listeners are registered.
// ... this loads the testbed of good and bad requests.
document.getElementById('cspframe').src = 'file_CSP_evalscript_main_getCRMFRequest.html';
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed_getCRMFRequest.html';
document.getElementById('cspframe3').src = 'file_CSP_evalscript_no_CSP_at_all.html';
}
//////////////////////////////////////////////////////////////////////
// set up and go
SimpleTest.waitForExplicitFinish();
// save this for last so that our listeners are registered.
// ... this loads the testbed of good and bad requests.
document.getElementById('cspframe').src = 'file_CSP_evalscript_main_getCRMFRequest.html';
document.getElementById('cspframe2').src = 'file_CSP_evalscript_main_allowed_getCRMFRequest.html';
document.getElementById('cspframe3').src = 'file_CSP_evalscript_no_CSP_at_all.html';
SpecialPowers.pushPrefEnv({"set": [["dom.unsafe_legacy_crypto.enabled", true]]},
loadElements);
</script>
</pre>
</body>

View File

@ -7,6 +7,7 @@
#ifndef AudioEventTimeline_h_
#define AudioEventTimeline_h_
#include <algorithm>
#include "mozilla/Assertions.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/TypedEnum.h"
@ -421,8 +422,7 @@ public:
// After the duration, return the last curve value
return aCurve[aCurveLength - 1];
}
double ratio = (t - startTime) / duration;
MOZ_ASSERT(ratio >= 0.0, "Ratio can never be negative here");
double ratio = std::max((t - startTime) / duration, 0.0);
if (ratio >= 1.0) {
return aCurve[aCurveLength - 1];
}

View File

@ -87,6 +87,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/NodeInfoInlines.h"
#include "mozilla/dom/ProcessingInstruction.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/XULDocumentBinding.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/LoadInfo.h"
@ -3682,39 +3683,6 @@ XULDocument::OnScriptCompileComplete(JSScript* aScript, nsresult aStatus)
return rv;
}
nsresult
XULDocument::ExecuteScript(nsIScriptContext * aContext,
JS::Handle<JSScript*> aScriptObject)
{
NS_PRECONDITION(aScriptObject != nullptr && aContext != nullptr, "null ptr");
if (! aScriptObject || ! aContext)
return NS_ERROR_NULL_POINTER;
NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED);
// Execute the precompiled script with the given version
nsAutoMicroTask mt;
JSContext *cx = aContext->GetNativeContext();
AutoCxPusher pusher(cx);
JS::Rooted<JSObject*> baseGlobal(cx, mScriptGlobalObject->GetGlobalJSObject());
NS_ENSURE_TRUE(baseGlobal, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(baseGlobal), NS_OK);
JSAddonId *addonId = MapURIToAddonID(mCurrentPrototype->GetURI());
JS::Rooted<JSObject*> global(cx, xpc::GetAddonScope(cx, baseGlobal, addonId));
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
JS::ExposeObjectToActiveJS(global);
xpc_UnmarkGrayScript(aScriptObject);
JSAutoCompartment ac(cx, global);
// The script is in the compilation scope. Clone it into the target scope
// and execute it.
if (!JS::CloneAndExecuteScript(cx, global, aScriptObject))
nsJSUtils::ReportPendingException(cx);
return NS_OK;
}
nsresult
XULDocument::ExecuteScript(nsXULPrototypeScript *aScript)
{
@ -3726,16 +3694,34 @@ XULDocument::ExecuteScript(nsXULPrototypeScript *aScript)
rv = mScriptGlobalObject->EnsureScriptEnvironment();
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIScriptContext> context =
mScriptGlobalObject->GetScriptContext();
// failure getting a script context is fatal.
NS_ENSURE_TRUE(context != nullptr, NS_ERROR_UNEXPECTED);
JS::HandleScript scriptObject = aScript->GetScriptObject();
NS_ENSURE_TRUE(scriptObject, NS_ERROR_UNEXPECTED);
if (aScript->GetScriptObject())
rv = ExecuteScript(context, aScript->GetScriptObject());
else
rv = NS_ERROR_UNEXPECTED;
return rv;
// Execute the precompiled script with the given version
nsAutoMicroTask mt;
// We're about to run script via JS::CloneAndExecuteScript, so we need an
// AutoEntryScript. This is Gecko specific and not in any spec.
AutoEntryScript aes(mScriptGlobalObject);
JSContext* cx = aes.cx();
JS::Rooted<JSObject*> baseGlobal(cx, JS::CurrentGlobalOrNull(cx));
NS_ENSURE_TRUE(nsContentUtils::GetSecurityManager()->ScriptAllowed(baseGlobal), NS_OK);
JSAddonId* addonId = MapURIToAddonID(mCurrentPrototype->GetURI());
JS::Rooted<JSObject*> global(cx, xpc::GetAddonScope(cx, baseGlobal, addonId));
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
JS::ExposeObjectToActiveJS(global);
xpc_UnmarkGrayScript(scriptObject);
JSAutoCompartment ac(cx, global);
// The script is in the compilation scope. Clone it into the target scope
// and execute it.
if (!JS::CloneAndExecuteScript(cx, global, scriptObject)) {
nsJSUtils::ReportPendingException(cx);
}
return NS_OK;
}

View File

@ -412,14 +412,7 @@ protected:
/**
* Execute the precompiled script object scoped by this XUL document's
* containing window object, and using its associated script context.
*/
nsresult ExecuteScript(nsIScriptContext *aContext,
JS::Handle<JSScript*> aScriptObject);
/**
* Helper method for the above that uses aScript to find the appropriate
* script context and object.
* containing window object.
*/
nsresult ExecuteScript(nsXULPrototypeScript *aScript);

View File

@ -26,8 +26,6 @@
<script>
<![CDATA[
SimpleTest.expectAssertions(1, 2);
SimpleTest.waitForExplicitFinish();
copyToProfile('animals.sqlite');

View File

@ -166,7 +166,6 @@
#endif
#include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsIChannelPolicy.h"
#include "nsIContentSecurityPolicy.h"
#include "nsILoadInfo.h"
@ -192,6 +191,7 @@
#include "nsIWebBrowserFind.h"
#include "nsIWidget.h"
#include "mozilla/dom/EncodingUtils.h"
#include "mozilla/dom/ScriptSettings.h"
static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
@ -10772,19 +10772,7 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
nsCOMPtr<nsIPrincipal> origPrincipal = origDocument->NodePrincipal();
scContainer = new nsStructuredCloneContainer();
JSContext *cx = aCx;
nsCxPusher pusher;
if (!cx) {
cx = nsContentUtils::GetContextFromDocument(document);
pusher.Push(cx);
}
rv = scContainer->InitFromJSVal(aData, cx);
// If we're running in the document's context and the structured clone
// failed, clear the context's pending exception. See bug 637116.
if (NS_FAILED(rv) && !aCx) {
JS_ClearPendingException(aCx);
}
rv = scContainer->InitFromJSVal(aData);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocument> newDocument = GetDocument();
@ -12602,8 +12590,8 @@ public:
NS_IMETHOD Run() {
nsAutoPopupStatePusher popupStatePusher(mPopupState);
nsCxPusher pusher;
if (mIsTrusted || pusher.Push(mContent)) {
AutoJSAPI jsapi;
if (mIsTrusted || jsapi.Init(mContent->OwnerDoc()->GetScopeObject())) {
mHandler->OnLinkClickSync(mContent, mURI,
mTargetSpec.get(), mFileName,
mPostDataStream, mHeadersDataStream,

View File

@ -1741,6 +1741,7 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
JS::Handle<JSObject*> obj, const JS::CallArgs &args)
{
MOZ_ASSERT(obj);
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
nsresult rv;
nsCOMPtr<nsISupports> native;
@ -1793,9 +1794,6 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
return NS_ERROR_UNEXPECTED;
}
nsCxPusher pusher;
pusher.Push(cx);
JSAutoCompartment ac(cx, thisObject);
JS::Rooted<JS::Value> funval(cx);

View File

@ -8,15 +8,18 @@
#include "nsStructuredCloneContainer.h"
#include "nsCOMPtr.h"
#include "nsIScriptContext.h"
#include "nsIGlobalObject.h"
#include "nsIVariant.h"
#include "nsIXPConnect.h"
#include "nsServiceManagerUtils.h"
#include "nsContentUtils.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "js/StructuredClone.h"
#include "xpcpublic.h"
#include "mozilla/Base64.h"
#include "mozilla/dom/ScriptSettings.h"
using namespace mozilla;
@ -39,22 +42,31 @@ nsStructuredCloneContainer::~nsStructuredCloneContainer()
}
nsresult
nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
JSContext* aCx)
nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData)
{
NS_ENSURE_STATE(!mData);
NS_ENSURE_ARG_POINTER(aCx);
// Make sure that we serialize in the right context.
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
JS::Rooted<JS::Value> jsData(aCx, aData);
bool success = JS_WrapValue(aCx, &jsData);
NS_ENSURE_STATE(success);
uint64_t* jsBytes = nullptr;
success = JS_WriteStructuredClone(aCx, jsData, &jsBytes, &mSize,
nullptr, nullptr,
JS::UndefinedHandleValue);
bool success = false;
if (aData.isPrimitive()) {
// |aData| is a primitive, so the structured clone algorithm won't run
// script and we can just use AutoJSAPI.
dom::AutoJSAPI jsapi;
jsapi.Init();
success = JS_WriteStructuredClone(jsapi.cx(), aData, &jsBytes, &mSize,
nullptr, nullptr,
JS::UndefinedHandleValue);
} else {
// |aData| is an object and the structured clone algorithm can run script as
// part of the "own" "deep clone" sub-steps, so we need an AutoEntryScript.
// http://www.whatwg.org/specs/web-apps/current-work/#internal-structured-cloning-algorithm
nsIGlobalObject* nativeGlobal =
xpc::GetNativeForGlobal(js::GetGlobalForObjectCrossCompartment(&aData.toObject()));
dom::AutoEntryScript aes(nativeGlobal);
success = JS_WriteStructuredClone(aes.cx(), aData, &jsBytes, &mSize,
nullptr, nullptr,
JS::UndefinedHandleValue);
}
NS_ENSURE_STATE(success);
NS_ENSURE_STATE(jsBytes);

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1017086</title>
<meta name="author" content="Maksim Lebedev" />
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
/** Test for Bug 1017086 **/
var testelem = undefined;
var pointer_events = ["onpointerover", "onpointerenter",
"onpointermove",
"onpointerdown", "onpointerup",
"onpointerout", "onpointerleave",
"onpointercancel"];
function check(expected_value, event_name, container, container_name) {
var text = event_name + " in " + container_name + " should be " + expected_value;
parent.is(event_name in container, expected_value, text);
}
function runTest() {
testelem = document.getElementById("test");
is(!!testelem, true, "Document should have element with id 'test'");
parent.turnOnOffPointerEvents( function() {
parent.part_of_checks(pointer_events, check, window, document, testelem);
});
}
</script>
</head>
<body onload="runTest();">
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1017086">Mozilla Bug 1017086</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -126,11 +126,17 @@ skip-if = toolkit == 'android'
[test_bug864040.html]
skip-if = buildapp == 'b2g' # b2g(failing when the test gets moved around, and on debug) b2g-debug(failing when the test gets moved around, and on debug) b2g-desktop(failing when the test gets moved around, and on debug)
[test_bug930374-content.html]
[test_bug944011.html]
[test_bug944847.html]
[test_bug946632.html]
[test_bug967796.html]
skip-if = toolkit == "gonk" || e10s
[test_bug944011.html]
[test_bug946632.html]
[test_bug985988.html]
[test_bug998809.html]
[test_bug1017086_disable.html]
support-files = bug1017086_inner.html
[test_bug1017086_enable.html]
support-files = bug1017086_inner.html
[test_clickevent_on_input.html]
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_continuous_wheel_events.html]
@ -140,6 +146,7 @@ skip-if = buildapp == 'b2g' || e10s # b2g(5535 passed, 108 failed - more tests r
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_dom_mouse_event.html]
skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
[test_dom_storage_event.html]
[test_dom_wheel_event.html]
skip-if = buildapp == 'b2g' || e10s # b2g(456 failed out of 19873, mousewheel test) b2g-debug(456 failed out of 19873, mousewheel test) b2g-desktop(456 failed out of 19873, mousewheel test)
[test_draggableprop.html]
@ -159,6 +166,3 @@ skip-if = buildapp == 'mulet'
[test_onerror_handler_args.html]
[test_wheel_default_action.html]
skip-if = buildapp == 'mulet' || buildapp == 'b2g' || e10s
[test_bug985988.html]
[test_dom_storage_event.html]
[test_bug998809.html]

View File

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1017086</title>
<meta name="author" content="Maksim Lebedev" />
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript">
/** Test for Bug 1017086 **/
var pointer_events_enabled = false;
function prepareTest() {
SimpleTest.waitForExplicitFinish();
turnOnOffPointerEvents(startTest);
}
function turnOnOffPointerEvents(callback) {
SpecialPowers.pushPrefEnv({
"set": [
["dom.w3c_pointer_events.enabled", pointer_events_enabled]
]
}, callback);
}
function startTest() {
var iframe = document.getElementById("testFrame");
iframe.src = "bug1017086_inner.html";
}
function part_of_checks(pointer_events, check, window, document, testelem) {
for(item in pointer_events) { check(false, pointer_events[item], window, "window"); }
for(item in pointer_events) { check(false, pointer_events[item], document, "document"); }
for(item in pointer_events) { check(false, pointer_events[item], testelem, "element"); }
SimpleTest.finish();
}
</script>
</head>
<body onload="prepareTest()">
<iframe id="testFrame" height="700" width="700"></iframe>
</body>
</html>

View File

@ -0,0 +1,43 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1017086
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1017086</title>
<meta name="author" content="Maksim Lebedev" />
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="text/javascript">
/** Test for Bug 1017086 **/
var pointer_events_enabled = true;
function prepareTest() {
SimpleTest.waitForExplicitFinish();
turnOnOffPointerEvents(startTest);
}
function turnOnOffPointerEvents(callback) {
SpecialPowers.pushPrefEnv({
"set": [
["dom.w3c_pointer_events.enabled", pointer_events_enabled]
]
}, callback);
}
function startTest() {
var iframe = document.getElementById("testFrame");
iframe.src = "bug1017086_inner.html";
}
function part_of_checks(pointer_events, check, window, document, testelem) {
for(item in pointer_events) { check(true, pointer_events[item], window, "window"); }
/** TODO
for(item in pointer_events) { check(false, pointer_events[item], document, "document"); }
**/
for(item in pointer_events) { check(true, pointer_events[item], testelem, "element"); }
SimpleTest.finish();
}
</script>
</head>
<body onload="prepareTest()">
<iframe id="testFrame" height="700" width="700"></iframe>
</body>
</html>

View File

@ -27,14 +27,14 @@ interface nsIDocument;
* string containing a copy of the container's serialized data, using
* getDataAsBase64.
*/
[scriptable, uuid(c8852f01-4c05-47c3-acca-253a958f39f6)]
[scriptable, uuid(8144021a-7f8a-483a-a0f1-ca02b761403f)]
interface nsIStructuredCloneContainer : nsISupports
{
/**
* Initialize this structured clone container so it contains a clone of the
* given jsval.
*/
[noscript, implicit_jscontext]
[noscript]
void initFromJSVal(in jsval aData);
/**

View File

@ -1650,8 +1650,8 @@ ContentChild::RecvActivateA11y()
#ifdef ACCESSIBILITY
// Start accessibility in content process if it's running in chrome
// process.
nsCOMPtr<nsIAccessibilityService> accService =
do_GetService("@mozilla.org/accessibilityService;1");
nsCOMPtr<nsIAccessibilityService> accService =
services::GetAccessibilityService();
#endif
return true;
}

View File

@ -23,7 +23,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=983504
* Run a test to verify that we can complete a start and stop media playback
* cycle for an screenshare LocalMediaStream on a video HTMLMediaElement.
*/
SimpleTest.expectAssertions(0, 1); // Bug 1047842
SimpleTest.expectAssertions(0, 3); // Bug 1047842
runTest(function () {
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;

View File

@ -23,7 +23,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=983504
* Run a test to verify that we can complete a start and stop media playback
* cycle for an screenshare LocalMediaStream on a video HTMLMediaElement.
*/
SimpleTest.expectAssertions(0, 1); // Bug 1047842
SimpleTest.expectAssertions(0, 3); // Bug 1047842
runTest(function () {
const isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;

View File

@ -1,2 +0,0 @@
[test_no_legacy.html]
skip-if = e10s

View File

@ -2,3 +2,4 @@
skip-if = e10s
[test_getRandomValues.html]
[test_no_legacy.html]

View File

@ -2,50 +2,59 @@
<html>
<head>
<title>Test presence of legacy window.crypto features when
MOZ_DISABLE_CRYPTOLEGACY is NOT set.</title>
MOZ_DISABLE_CRYPTOLEGACY is NOT set and dom.unsafe_legacy_crypto.enabled is true</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<script class="testbody" type="text/javascript">
ok("crypto" in window, "crypto in window");
ok("version" in window.crypto, "version in window.crypto");
ok("enableSmartCardEvents" in window.crypto,
"enableSmartCardEvents in window.crypto");
ok("generateCRMFRequest" in window.crypto,
"generateCRMFRequest in window.crypto");
ok("importUserCertificates" in window.crypto,
"importUserCertificates in window.crypto");
ok("signText" in window.crypto, "signText in window.crypto");
function test_unsafe_legacy_crypto_enabled() {
ok("crypto" in window, "crypto in window");
ok("version" in window.crypto, "version in window.crypto");
ok("enableSmartCardEvents" in window.crypto,
"enableSmartCardEvents in window.crypto");
ok("generateCRMFRequest" in window.crypto,
"generateCRMFRequest in window.crypto");
ok("importUserCertificates" in window.crypto,
"importUserCertificates in window.crypto");
ok("signText" in window.crypto, "signText in window.crypto");
function jsCallback () {
function jsCallback () {
}
try {
window.crypto.generateCRMFRequest(null, null, null, null, jsCallback.toString());
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
} catch (e) {
ok(e.toString().search(/Failure/) > -1,
"Expected error: ReqDN cannot be null");
}
try {
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
null);
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
} catch (e) {
ok(e.toString().search(/Failure/) > -1,
"Expected error: jsCallback cannot be null");
}
try {
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
jsCallback.toString(), 1024);
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
} catch (e) {
ok(e.toString().search(/TypeError/) > -1,
"Expected error: Not enough arguments");
}
SimpleTest.finish();
}
try {
window.crypto.generateCRMFRequest(null, null, null, null, jsCallback.toString());
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
} catch (e) {
ok(e.toString().search(/Failure/) > -1,
"Expected error: ReqDN cannot be null");
}
SpecialPowers.pushPrefEnv({"set": [["dom.unsafe_legacy_crypto.enabled", true]]},
test_unsafe_legacy_crypto_enabled);
SimpleTest.waitForExplicitFinish();
try {
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
null);
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
} catch (e) {
ok(e.toString().search(/Failure/) > -1,
"Expected error: jsCallback cannot be null");
}
try {
window.crypto.generateCRMFRequest(document.documentElement, null, null, null,
jsCallback.toString(), 1024);
ok(false, "window.crypto.generateCRMFRequest failed, should throw error");
} catch (e) {
ok(e.toString().search(/TypeError/) > -1,
"Expected error: Not enough arguments");
}
</script>
</body></html>

View File

@ -2,7 +2,7 @@
<html>
<head>
<title>Test lack of legacy window.crypto features when
MOZ_DISABLE_CRYPTOLEGACY is set</title>
MOZ_DISABLE_CRYPTOLEGACY is set or dom.unsafe_legacy_crypto.enabled is false</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>

View File

@ -48,11 +48,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gtk2':
'mochitest/pointerlock/mochitest.ini',
]
if CONFIG['MOZ_DISABLE_CRYPTOLEGACY']:
MOCHITEST_MANIFESTS += [
'mochitest/crypto/mochitest-no-legacy.ini',
]
else:
if not CONFIG['MOZ_DISABLE_CRYPTOLEGACY']:
MOCHITEST_MANIFESTS += [
'mochitest/crypto/mochitest-legacy.ini',
]

View File

@ -23,12 +23,13 @@ interface Crypto {
#ifndef MOZ_DISABLE_CRYPTOLEGACY
[NoInterfaceObject]
interface CryptoLegacy {
[Pref="dom.unsafe_legacy_crypto.enabled"]
readonly attribute DOMString version;
[SetterThrows]
[SetterThrows,Pref="dom.unsafe_legacy_crypto.enabled"]
attribute boolean enableSmartCardEvents;
[Throws,NewObject]
[Throws,NewObject,Pref="dom.unsafe_legacy_crypto.enabled"]
CRMFObject? generateCRMFRequest(ByteString? reqDN,
ByteString? regToken,
ByteString? authenticator,
@ -36,16 +37,17 @@ interface CryptoLegacy {
ByteString? jsCallback,
any... args);
[Throws]
[Throws,Pref="dom.unsafe_legacy_crypto.enabled"]
DOMString importUserCertificates(DOMString nickname,
DOMString cmmfResponse,
boolean doForcedBackup);
[Pref="dom.unsafe_legacy_crypto.enabled"]
DOMString signText(DOMString stringToSign,
DOMString caOption,
ByteString... args);
[Throws]
[Throws,Pref="dom.unsafe_legacy_crypto.enabled"]
void logout();
};

View File

@ -10,8 +10,6 @@
#include "nsIDocument.h"
#include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsIScriptGlobalObject.h"
#include "nsIScriptContext.h"
#include "nsIXPConnect.h"
#include "nsIServiceManager.h"
#include "nsIDOMNode.h"
@ -19,6 +17,7 @@
#include "nsXBLProtoImplProperty.h"
#include "nsIURI.h"
#include "mozilla/AddonPathService.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/XULElementBinding.h"
#include "xpcpublic.h"
#include "js/CharacterEncoding.h"
@ -42,13 +41,20 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
// nsXBLProtoImplAnonymousMethod::Execute
nsIDocument* document = aBinding->GetBoundElement()->OwnerDoc();
nsCOMPtr<nsIScriptGlobalObject> global = do_QueryInterface(document->GetScopeObject());
if (!global) return NS_OK;
// This sometimes gets called when we have no outer window and if we don't
// catch this, we get leaks during crashtests and reftests.
if (NS_WARN_IF(!document->GetWindow())) {
return NS_OK;
}
nsCOMPtr<nsIScriptContext> context = global->GetContext();
if (!context) return NS_OK;
JSContext* cx = context->GetNativeContext();
AutoCxPusher pusher(cx);
// |propertyHolder| (below) can be an existing object, so in theory we might
// hit something that could end up running script. We never want that to
// happen here, so we use an AutoJSAPI instead of an AutoEntryScript.
dom::AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(document->GetScopeObject()))) {
return NS_OK;
}
JSContext* cx = jsapi.cx();
// InitTarget objects gives us back the JS object that represents the bound element and the
// class object in the bound document that represents the concrete version of this implementation.

View File

@ -653,7 +653,9 @@ DrawGradient(CGColorSpaceRef aColorSpace,
if (aPattern.GetType() == PatternType::LINEAR_GRADIENT) {
const LinearGradientPattern& pat = static_cast<const LinearGradientPattern&>(aPattern);
GradientStopsCG *stops = static_cast<GradientStopsCG*>(pat.mStops.get());
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(pat.mMatrix));
CGAffineTransform patternMatrix = GfxMatrixToCGAffineTransform(pat.mMatrix);
CGContextConcatCTM(cg, patternMatrix);
CGRect extents = CGRectApplyAffineTransform(aExtents, CGAffineTransformInvert(patternMatrix));
if (stops->mExtend == ExtendMode::CLAMP) {
// XXX: we should take the m out of the properties of LinearGradientPatterns
@ -667,11 +669,13 @@ DrawGradient(CGColorSpaceRef aColorSpace,
CGContextDrawLinearGradient(cg, stops->mGradient, startPoint, endPoint,
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
} else if (stops->mExtend == ExtendMode::REPEAT || stops->mExtend == ExtendMode::REFLECT) {
DrawLinearRepeatingGradient(aColorSpace, cg, pat, aExtents, stops->mExtend == ExtendMode::REFLECT);
DrawLinearRepeatingGradient(aColorSpace, cg, pat, extents, stops->mExtend == ExtendMode::REFLECT);
}
} else if (aPattern.GetType() == PatternType::RADIAL_GRADIENT) {
const RadialGradientPattern& pat = static_cast<const RadialGradientPattern&>(aPattern);
CGContextConcatCTM(cg, GfxMatrixToCGAffineTransform(pat.mMatrix));
CGAffineTransform patternMatrix = GfxMatrixToCGAffineTransform(pat.mMatrix);
CGContextConcatCTM(cg, patternMatrix);
CGRect extents = CGRectApplyAffineTransform(aExtents, CGAffineTransformInvert(patternMatrix));
GradientStopsCG *stops = static_cast<GradientStopsCG*>(pat.mStops.get());
if (stops->mExtend == ExtendMode::CLAMP) {
@ -685,7 +689,7 @@ DrawGradient(CGColorSpaceRef aColorSpace,
CGContextDrawRadialGradient(cg, stops->mGradient, startCenter, startRadius, endCenter, endRadius,
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
} else if (stops->mExtend == ExtendMode::REPEAT || stops->mExtend == ExtendMode::REFLECT) {
DrawRadialRepeatingGradient(aColorSpace, cg, pat, aExtents, stops->mExtend == ExtendMode::REFLECT);
DrawRadialRepeatingGradient(aColorSpace, cg, pat, extents, stops->mExtend == ExtendMode::REFLECT);
}
} else {
assert(0);

View File

@ -530,6 +530,10 @@ ContainerRender(ContainerT* aContainer,
LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(aContainer->GetMaskLayer(),
effectChain,
!aContainer->GetTransform().CanDraw2D());
if (autoMaskEffect.Failed()) {
NS_WARNING("Failed to apply a mask effect.");
return;
}
aContainer->AddBlendModeEffect(effectChain);
effectChain.mPrimaryEffect = new EffectRenderTarget(surface);

View File

@ -828,7 +828,7 @@ LayerManagerComposite::CreateRefLayerComposite()
LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
EffectChain& aEffects,
bool aIs3D)
: mCompositable(nullptr)
: mCompositable(nullptr), mFailed(false)
{
if (!aMaskLayer) {
return;
@ -837,11 +837,13 @@ LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
mCompositable = ToLayerComposite(aMaskLayer)->GetCompositableHost();
if (!mCompositable) {
NS_WARNING("Mask layer with no compositable host");
mFailed = true;
return;
}
if (!mCompositable->AddMaskEffect(aEffects, aMaskLayer->GetEffectiveTransform(), aIs3D)) {
mCompositable = nullptr;
mFailed = true;
}
}

View File

@ -184,8 +184,10 @@ public:
bool aIs3D = false);
~AutoAddMaskEffect();
bool Failed() const { return mFailed; }
private:
CompositableHost* mCompositable;
bool mFailed;
};
/**

View File

@ -8,6 +8,7 @@
#define js_RootingAPI_h
#include "mozilla/Attributes.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/GuardObjects.h"
#include "mozilla/LinkedList.h"
#include "mozilla/NullPtr.h"
@ -166,6 +167,23 @@ struct JS_PUBLIC_API(NullPtr)
static void * const constNullValue;
};
#ifdef JSGC_GENERATIONAL
JS_FRIEND_API(void) HeapCellPostBarrier(js::gc::Cell **cellp);
JS_FRIEND_API(void) HeapCellRelocate(js::gc::Cell **cellp);
#endif
#ifdef JS_DEBUG
/*
* For generational GC, assert that an object is in the tenured generation as
* opposed to being in the nursery.
*/
extern JS_FRIEND_API(void)
AssertGCThingMustBeTenured(JSObject* obj);
#else
inline void
AssertGCThingMustBeTenured(JSObject *obj) {}
#endif
/*
* The Heap<T> class is a heap-stored reference to a JS GC thing. All members of
* heap classes that refer to GC things should use Heap<T> (or possibly
@ -285,18 +303,6 @@ class Heap : public js::HeapBase<T>
T ptr;
};
#ifdef JS_DEBUG
/*
* For generational GC, assert that an object is in the tenured generation as
* opposed to being in the nursery.
*/
extern JS_FRIEND_API(void)
AssertGCThingMustBeTenured(JSObject* obj);
#else
inline void
AssertGCThingMustBeTenured(JSObject *obj) {}
#endif
/*
* The TenuredHeap<T> class is similar to the Heap<T> class above in that it
* encapsulates the GC concerns of an on-heap reference to a JS object. However,
@ -560,11 +566,6 @@ class MOZ_STACK_CLASS MutableHandle : public js::MutableHandleBase<T>
void operator=(MutableHandle other) MOZ_DELETE;
};
#ifdef JSGC_GENERATIONAL
JS_FRIEND_API(void) HeapCellPostBarrier(js::gc::Cell **cellp);
JS_FRIEND_API(void) HeapCellRelocate(js::gc::Cell **cellp);
#endif
} /* namespace JS */
namespace js {
@ -666,6 +667,12 @@ struct GCMethods<JSObject *>
{
static JSObject *initial() { return nullptr; }
static bool poisoned(JSObject *v) { return JS::IsPoisonedPtr(v); }
static gc::Cell *asGCThingOrNull(JSObject *v) {
if (!v)
return nullptr;
JS_ASSERT(uintptr_t(v) > 32);
return reinterpret_cast<gc::Cell *>(v);
}
static bool needsPostBarrier(JSObject *v) {
return v != nullptr && gc::IsInsideNursery(reinterpret_cast<gc::Cell *>(v));
}
@ -1246,6 +1253,24 @@ class CompilerRootNode
js::gc::Cell *ptr_;
};
} /* namespace js */
namespace gc {
template <typename T, typename TraceCallbacks>
void
CallTraceCallbackOnNonHeap(T *v, const TraceCallbacks &aCallbacks, const char *aName, void *aClosure)
{
static_assert(sizeof(T) == sizeof(JS::Heap<T>), "T and Heap<T> must be compatible.");
MOZ_ASSERT(v);
mozilla::DebugOnly<Cell *> cell = GCMethods<T>::asGCThingOrNull(*v);
MOZ_ASSERT(cell);
MOZ_ASSERT(!IsInsideNursery(cell));
JS::Heap<T> *asHeapT = reinterpret_cast<JS::Heap<T>*>(v);
aCallbacks.Trace(asHeapT, aName, aClosure);
MOZ_ASSERT(GCMethods<T>::asGCThingOrNull(*v) == cell);
}
} /* namespace gc */
} /* namespace js */
#endif /* js_RootingAPI_h */

View File

@ -1637,6 +1637,9 @@ template <> struct GCMethods<JS::Value>
static bool poisoned(const JS::Value &v) {
return v.isMarkable() && JS::IsPoisonedPtr(v.toGCThing());
}
static gc::Cell *asGCThingOrNull(const JS::Value &v) {
return v.isMarkable() ? v.toGCThing() : nullptr;
}
static bool needsPostBarrier(const JS::Value &v) {
return v.isObject() && gc::IsInsideNursery(reinterpret_cast<gc::Cell*>(&v.toObject()));
}

View File

@ -285,10 +285,13 @@ private:
typedef enum {
OP2_UD2 = 0x0B,
OP2_MOVSD_VsdWsd = 0x10,
OP2_MOVPS_VpsWps = 0x10,
OP2_MOVSD_WsdVsd = 0x11,
OP2_MOVPS_WpsVps = 0x11,
OP2_UNPCKLPS_VsdWsd = 0x14,
OP2_MOVAPD_VsdWsd = 0x28,
OP2_MOVAPS_VsdWsd = 0x28,
OP2_MOVAPS_WsdVsd = 0x29,
OP2_CVTSI2SD_VsdEd = 0x2A,
OP2_CVTTSD2SI_GdWsd = 0x2C,
OP2_UCOMISD_VsdWsd = 0x2E,
@ -307,11 +310,12 @@ private:
OP2_ORPD_VpdWpd = 0x56,
OP2_XORPD_VpdWpd = 0x57,
OP2_MOVD_VdEd = 0x6E,
OP2_MOVDQA_VsdWsd = 0x6F,
OP2_MOVDQ_VsdWsd = 0x6F,
OP2_MOVDQ_VdqWdq = 0x6F,
OP2_PSRLDQ_Vd = 0x73,
OP2_PCMPEQW = 0x75,
OP2_MOVD_EdVd = 0x7E,
OP2_MOVDQA_WsdVsd = 0x7F,
OP2_MOVDQ_WdqVdq = 0x7F,
OP2_JCC_rel32 = 0x80,
OP_SETCC = 0x90,
OP2_IMUL_GvEv = 0xAF,
@ -2834,25 +2838,117 @@ public:
}
#endif
void movaps_rr(XMMRegisterID src, XMMRegisterID dst) {
void movaps_rr(XMMRegisterID src, XMMRegisterID dst)
{
spew("movaps %s, %s",
nameFPReg(src), nameFPReg(dst));
m_formatter.twoByteOp(OP2_MOVAPS_VsdWsd, (RegisterID)dst, (RegisterID)src);
}
void movaps_rm(XMMRegisterID src, int offset, RegisterID base)
{
spew("movaps %s, %s0x%x(%s)",
nameFPReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
m_formatter.twoByteOp(OP2_MOVAPS_WsdVsd, (RegisterID)src, base, offset);
}
void movaps_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
{
spew("movaps %s, %d(%s,%s,%d)",
nameFPReg(src), offset, nameIReg(base), nameIReg(index), 1<<scale);
m_formatter.twoByteOp(OP2_MOVAPS_WsdVsd, (RegisterID)src, base, index, scale, offset);
}
void movaps_mr(int offset, RegisterID base, XMMRegisterID dst)
{
spew("movaps %s0x%x(%s), %s",
PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
m_formatter.twoByteOp(OP2_MOVAPS_VsdWsd, (RegisterID)dst, base, offset);
}
void movaps_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
{
spew("movaps %d(%s,%s,%d), %s",
offset, nameIReg(base), nameIReg(index), 1<<scale, nameFPReg(dst));
m_formatter.twoByteOp(OP2_MOVAPS_VsdWsd, (RegisterID)dst, base, index, scale, offset);
}
void movapd_rr(XMMRegisterID src, XMMRegisterID dst) {
void movups_rm(XMMRegisterID src, int offset, RegisterID base)
{
spew("movups %s, %s0x%x(%s)",
nameFPReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
m_formatter.twoByteOp(OP2_MOVPS_WpsVps, (RegisterID)src, base, offset);
}
void movups_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
{
spew("movups %s, %d(%s,%s,%d)",
nameFPReg(src), offset, nameIReg(base), nameIReg(index), 1<<scale);
m_formatter.twoByteOp(OP2_MOVPS_WpsVps, (RegisterID)src, base, index, scale, offset);
}
void movups_mr(int offset, RegisterID base, XMMRegisterID dst)
{
spew("movups %s0x%x(%s), %s",
PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
m_formatter.twoByteOp(OP2_MOVPS_VpsWps, (RegisterID)dst, base, offset);
}
void movups_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
{
spew("movups %d(%s,%s,%d), %s",
offset, nameIReg(base), nameIReg(index), 1<<scale, nameFPReg(dst));
m_formatter.twoByteOp(OP2_MOVPS_VpsWps, (RegisterID)dst, base, index, scale, offset);
}
void movapd_rr(XMMRegisterID src, XMMRegisterID dst)
{
spew("movapd %s, %s",
nameFPReg(src), nameFPReg(dst));
m_formatter.prefix(PRE_SSE_66);
m_formatter.twoByteOp(OP2_MOVAPD_VsdWsd, (RegisterID)dst, (RegisterID)src);
}
void movdqu_rm(XMMRegisterID src, int offset, RegisterID base)
{
spew("movdqu %s, %s0x%x(%s)",
nameFPReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
m_formatter.prefix(PRE_SSE_F3);
m_formatter.twoByteOp(OP2_MOVDQ_WdqVdq, (RegisterID)src, base, offset);
}
void movdqu_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
{
spew("movdqu %s, %d(%s,%s,%d)",
nameFPReg(src), offset, nameIReg(base), nameIReg(index), 1<<scale);
m_formatter.prefix(PRE_SSE_F3);
m_formatter.twoByteOp(OP2_MOVDQ_WdqVdq, (RegisterID)src, base, index, scale, offset);
}
void movdqu_mr(int offset, RegisterID base, XMMRegisterID dst)
{
spew("movdqu %s0x%x(%s), %s",
PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
m_formatter.prefix(PRE_SSE_F3);
m_formatter.twoByteOp(OP2_MOVDQ_VdqWdq, (RegisterID)dst, base, offset);
}
void movdqu_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
{
spew("movdqu %d(%s,%s,%d), %s",
offset, nameIReg(base), nameIReg(index), 1<<scale, nameFPReg(dst));
m_formatter.prefix(PRE_SSE_F3);
m_formatter.twoByteOp(OP2_MOVDQ_VdqWdq, (RegisterID)dst, base, index, scale, offset);
}
void movdqa_rr(XMMRegisterID src, XMMRegisterID dst)
{
spew("movdqa %s, %s",
nameFPReg(src), nameFPReg(dst));
m_formatter.prefix(PRE_SSE_66);
m_formatter.twoByteOp(OP2_MOVDQ_VdqWdq, (RegisterID)dst, (RegisterID)src);
}
void movdqa_rm(XMMRegisterID src, int offset, RegisterID base)
{
spew("movdqa %s, %s0x%x(%s)",
nameFPReg(src), PRETTY_PRINT_OFFSET(offset), nameIReg(base));
m_formatter.prefix(PRE_SSE_66);
m_formatter.twoByteOp(OP2_MOVDQA_WsdVsd, (RegisterID)src, base, offset);
m_formatter.twoByteOp(OP2_MOVDQ_WdqVdq, (RegisterID)src, base, offset);
}
void movdqa_rm(XMMRegisterID src, int offset, RegisterID base, RegisterID index, int scale)
@ -2860,7 +2956,7 @@ public:
spew("movdqa %s, %d(%s,%s,%d)",
nameFPReg(src), offset, nameIReg(base), nameIReg(index), 1<<scale);
m_formatter.prefix(PRE_SSE_66);
m_formatter.twoByteOp(OP2_MOVDQA_WsdVsd, (RegisterID)src, base, index, scale, offset);
m_formatter.twoByteOp(OP2_MOVDQ_WdqVdq, (RegisterID)src, base, index, scale, offset);
}
void movdqa_mr(int offset, RegisterID base, XMMRegisterID dst)
@ -2868,7 +2964,7 @@ public:
spew("movdqa %s0x%x(%s), %s",
PRETTY_PRINT_OFFSET(offset), nameIReg(base), nameFPReg(dst));
m_formatter.prefix(PRE_SSE_66);
m_formatter.twoByteOp(OP2_MOVDQA_VsdWsd, (RegisterID)dst, base, offset);
m_formatter.twoByteOp(OP2_MOVDQ_VdqWdq, (RegisterID)dst, base, offset);
}
void movdqa_mr(int offset, RegisterID base, RegisterID index, int scale, XMMRegisterID dst)
@ -2876,7 +2972,7 @@ public:
spew("movdqa %d(%s,%s,%d), %s",
offset, nameIReg(base), nameIReg(index), 1<<scale, nameFPReg(dst));
m_formatter.prefix(PRE_SSE_66);
m_formatter.twoByteOp(OP2_MOVDQA_VsdWsd, (RegisterID)dst, base, index, scale, offset);
m_formatter.twoByteOp(OP2_MOVDQ_VdqWdq, (RegisterID)dst, base, index, scale, offset);
}
void mulsd_rr(XMMRegisterID src, XMMRegisterID dst)

View File

@ -560,7 +560,7 @@ js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string,
return RegExpRunStatus_Error;
/* Inlined steps 6, 7, 9a with doubles to detect failure case. */
if ((re->global() || re->sticky()) && (d < 0 || d > length)) {
if (reobj->needUpdateLastIndex() && (d < 0 || d > length)) {
reobj->zeroLastIndex();
return RegExpRunStatus_Success_NotFound;
}
@ -587,7 +587,7 @@ js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string,
/* Steps 9a and 11 (with sticky extension). */
if (status == RegExpRunStatus_Success_NotFound)
reobj->zeroLastIndex();
else if (re->global() || re->sticky())
else if (reobj->needUpdateLastIndex())
reobj->setLastIndex(lastIndexInt);
return status;

View File

@ -21,3 +21,20 @@ keeping them separate from other `Debugger` facilities.
You can retrieve the allocation site for a given object with the
[`Debugger.Object.prototype.allocationSite`][allocation-site] accessor
property.
`maxAllocationsLogLength`
: The maximum number of allocation sites to accumulate in the allocations log
at a time. Its default value is `5000`.
## Function Properties of the `Debugger.Memory.prototype` Object
`drainAllocationsLog()`
: When `trackingAllocationSites` is `true`, this method returns an array of
allocation sites (as [captured stacks][saved-frame]) for recent `Object`
allocations within the set of debuggees. *Recent* is defined as the
`maxAllocationsLogLength` most recent `Object` allocations since the last
call to `drainAllocationsLog`. Therefore, calling this method effectively
clears the log.
When `trackingAllocationSites` is `false`, `drainAllocationsLog()` throws an
`Error`.

View File

@ -0,0 +1,31 @@
// Test basic usage of drainAllocationsLog()
const root = newGlobal();
const dbg = new Debugger();
const wrappedRoot = dbg.addDebuggee(root)
dbg.memory.trackingAllocationSites = true;
root.eval("(" + function immediate() {
this.tests = [
({}),
[],
/(two|2)\s*problems/,
new function Ctor(){},
new Object(),
new Array(),
new Date(),
];
} + "());");
const allocs = dbg.memory.drainAllocationsLog();
print(allocs.join("\n--------------------------------------------------------------------------\n"));
print("Total number of allocations logged: " + allocs.length);
let idx = -1;
for (let object of root.tests) {
let wrappedObject = wrappedRoot.makeDebuggeeValue(object);
let allocSite = wrappedObject.allocationSite;
let newIdx = allocs.indexOf(allocSite);
assertEq(newIdx > idx, true);
idx = newIdx;
}

View File

@ -0,0 +1,14 @@
// Test that drainAllocationsLog fails when we aren't trackingAllocationSites.
load(libdir + 'asserts.js');
const root = newGlobal();
const dbg = new Debugger();
dbg.memory.trackingAllocationSites = true;
root.eval("this.alloc1 = {}");
dbg.memory.trackingAllocationSites = false;
root.eval("this.alloc2 = {};");
assertThrowsInstanceOf(() => dbg.memory.drainAllocationsLog(),
Error);

View File

@ -0,0 +1,24 @@
// Test when there are more allocations than the maximum log length.
const root = newGlobal();
const dbg = new Debugger();
dbg.addDebuggee(root)
dbg.memory.maxAllocationsLogLength = 3;
dbg.memory.trackingAllocationSites = true;
root.eval([
"this.alloc1 = {};", // line 1
"this.alloc2 = {};", // line 2
"this.alloc3 = {};", // line 3
"this.alloc4 = {};", // line 4
].join("\n"));
const allocs = dbg.memory.drainAllocationsLog();
// Should have stayed at the maximum length.
assertEq(allocs.length, 3);
// Should have kept the most recent allocation.
assertEq(allocs[2].line, 4);
// Should have thrown away the oldest allocation.
assertEq(allocs.map(x => x.line).indexOf(1), -1);

View File

@ -0,0 +1,21 @@
// Test that when we shorten the maximum log length, we won't get a longer log
// than that new maximum afterwards.
const root = newGlobal();
const dbg = new Debugger();
dbg.addDebuggee(root)
dbg.memory.trackingAllocationSites = true;
root.eval([
"this.alloc1 = {};", // line 1
"this.alloc2 = {};", // line 2
"this.alloc3 = {};", // line 3
"this.alloc4 = {};", // line 4
].join("\n"));
dbg.memory.maxAllocationsLogLength = 1;
const allocs = dbg.memory.drainAllocationsLog();
// Should have trimmed down to the new maximum length.
assertEq(allocs.length, 1);

View File

@ -0,0 +1,9 @@
// Test an empty allocation log.
const root = newGlobal();
const dbg = new Debugger();
dbg.addDebuggee(root)
dbg.memory.trackingAllocationSites = true;
const allocs = dbg.memory.drainAllocationsLog();
assertEq(allocs.length, 0);

View File

@ -0,0 +1,23 @@
// Test doing a GC while we have a non-empty log.
const root = newGlobal();
const dbg = new Debugger();
dbg.addDebuggee(root)
dbg.memory.trackingAllocationSites = true;
root.eval("(" + function immediate() {
this.tests = [
({}),
[],
/(two|2)\s*problems/,
new function Ctor(){},
new Object(),
new Array(),
new Date(),
];
} + "());");
gc();
const allocs = dbg.memory.drainAllocationsLog();
assertEq(allocs.length >= root.tests.length, true);

View File

@ -0,0 +1,10 @@
// Test retrieving the log when allocation tracking hasn't ever been enabled.
load(libdir + 'asserts.js');
const root = newGlobal();
const dbg = new Debugger();
dbg.addDebuggee(root)
assertThrowsInstanceOf(() => dbg.memory.drainAllocationsLog(),
Error);

View File

@ -0,0 +1,30 @@
// Test retrieving the log multiple times.
const root = newGlobal();
const dbg = new Debugger();
dbg.addDebuggee(root)
root.eval([
"this.allocs = [];",
"this.doFirstAlloc = " + function () {
this.allocs.push({}); this.firstAllocLine = Error().lineNumber;
},
"this.doSecondAlloc = " + function () {
this.allocs.push(new Object()); this.secondAllocLine = Error().lineNumber;
}
].join("\n"));
dbg.memory.trackingAllocationSites = true;
root.doFirstAlloc();
let allocs1 = dbg.memory.drainAllocationsLog();
root.doSecondAlloc();
let allocs2 = dbg.memory.drainAllocationsLog();
let allocs1Lines = allocs1.map(x => x.line);
assertEq(allocs1Lines.indexOf(root.firstAllocLine) != -1, true);
assertEq(allocs1Lines.indexOf(root.secondAllocLine) == -1, true);
let allocs2Lines = allocs2.map(x => x.line);
assertEq(allocs2Lines.indexOf(root.secondAllocLine) != -1, true);
assertEq(allocs2Lines.indexOf(root.firstAllocLine) == -1, true);

View File

@ -0,0 +1,20 @@
// Test logs that contain allocations from many debuggee compartments.
const dbg = new Debugger();
const root1 = newGlobal();
const root2 = newGlobal();
const root3 = newGlobal();
dbg.addDebuggee(root1);
dbg.addDebuggee(root2);
dbg.addDebuggee(root3);
dbg.memory.trackingAllocationSites = true;
root1.eval("this.alloc = {}");
root2.eval("this.alloc = {}");
root3.eval("this.alloc = {}");
const allocs = dbg.memory.drainAllocationsLog();
assertEq(allocs.length >= 3, true);

View File

@ -0,0 +1,21 @@
// Test logs that contain allocations from debuggee compartments added as we are
// logging.
const dbg = new Debugger();
dbg.memory.trackingAllocationSites = true;
const root1 = newGlobal();
dbg.addDebuggee(root1);
root1.eval("this.alloc = {}");
const root2 = newGlobal();
dbg.addDebuggee(root2);
root2.eval("this.alloc = {}");
const root3 = newGlobal();
dbg.addDebuggee(root3);
root3.eval("this.alloc = {}");
const allocs = dbg.memory.drainAllocationsLog();
assertEq(allocs.length >= 3, true);

View File

@ -0,0 +1,25 @@
// Test logs that shouldn't contain allocations from debuggee compartments
// removed as we are logging.
const dbg = new Debugger();
const root1 = newGlobal();
dbg.addDebuggee(root1);
const root2 = newGlobal();
dbg.addDebuggee(root2);
const root3 = newGlobal();
dbg.addDebuggee(root3);
dbg.memory.trackingAllocationSites = true;
dbg.removeDebuggee(root1);
root1.eval("this.alloc = {}");
dbg.removeDebuggee(root2);
root2.eval("this.alloc = {}");
dbg.removeDebuggee(root3);
root3.eval("this.alloc = {}");
const allocs = dbg.memory.drainAllocationsLog();
assertEq(allocs.length, 0);

View File

@ -0,0 +1,17 @@
// Test that disabling the debugger disables allocation tracking.
load(libdir + "asserts.js");
const dbg = new Debugger();
const root = newGlobal();
dbg.addDebuggee(root);
dbg.memory.trackingAllocationSites = true;
dbg.enabled = false;
root.eval("this.alloc = {}");
// We shouldn't accumulate allocations in our log while the debugger is
// disabled.
let allocs = dbg.memory.drainAllocationsLog();
assertEq(allocs.length, 0);

Some files were not shown because too many files have changed in this diff Show More