зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound, a=merge
MozReview-Commit-ID: LWHPArc07kI
This commit is contained in:
Коммит
5157f17709
10
.cron.yml
10
.cron.yml
|
@ -9,11 +9,10 @@ jobs:
|
|||
treeherder-symbol: Nd
|
||||
triggered-by: nightly
|
||||
target-tasks-method: nightly_linux
|
||||
projects:
|
||||
run-on-projects:
|
||||
- mozilla-central
|
||||
- date
|
||||
when:
|
||||
- {hour: 16, minute: 0}
|
||||
when: [] # never (temporary)
|
||||
|
||||
- name: nightly-android
|
||||
job:
|
||||
|
@ -21,9 +20,8 @@ jobs:
|
|||
treeherder-symbol: Na
|
||||
triggered-by: nightly
|
||||
target-tasks-method: nightly_fennec
|
||||
projects:
|
||||
run-on-projects:
|
||||
- mozilla-central
|
||||
- date
|
||||
when:
|
||||
- {hour: 16, minute: 0}
|
||||
when: [] # never (temporary)
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ static const nsRoleMapEntry sWAIRoleMaps[] =
|
|||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
eList,
|
||||
kNoReqStates
|
||||
states::READONLY
|
||||
},
|
||||
{ // document
|
||||
&nsGkAtoms::document,
|
||||
|
|
|
@ -179,6 +179,9 @@
|
|||
testStates("aria_treegrid_readonly_cell_inherited", STATE_READONLY, 0,
|
||||
0, EXT_STATE_EDITABLE);
|
||||
|
||||
// aria-readonly on directory
|
||||
testStates("aria_directory", STATE_READONLY);
|
||||
|
||||
// aria-selectable
|
||||
testStates("aria_selectable_listitem", STATE_SELECTABLE | STATE_SELECTED);
|
||||
|
||||
|
@ -625,5 +628,8 @@
|
|||
<div role="row"><div role="gridcell">h</div></div>
|
||||
</div>
|
||||
|
||||
<!-- Test that directory is readonly -->
|
||||
<div id="aria_directory" role="directory"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -6,6 +6,7 @@ var gFxAccounts = {
|
|||
|
||||
_initialized: false,
|
||||
_inCustomizationMode: false,
|
||||
_profileFetched: false,
|
||||
|
||||
get weave() {
|
||||
delete this.weave;
|
||||
|
@ -140,9 +141,9 @@ var gFxAccounts = {
|
|||
|
||||
observe(subject, topic, data) {
|
||||
switch (topic) {
|
||||
case this.FxAccountsCommon.ONPROFILE_IMAGE_CHANGE_NOTIFICATION:
|
||||
this.updateUI();
|
||||
break;
|
||||
case this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION:
|
||||
this._profileFetched = false;
|
||||
// Fallthrough intended
|
||||
default:
|
||||
this.updateUI();
|
||||
break;
|
||||
|
@ -254,7 +255,7 @@ var gFxAccounts = {
|
|||
updateWithUserData(userData);
|
||||
// unverified users cause us to spew log errors fetching an OAuth token
|
||||
// to fetch the profile, so don't even try in that case.
|
||||
if (!userData || !userData.verified || !profileInfoEnabled) {
|
||||
if (!userData || !userData.verified || !profileInfoEnabled || this._profileFetched) {
|
||||
return null; // don't even try to grab the profile.
|
||||
}
|
||||
return fxAccounts.getSignedInUserProfile().catch(err => {
|
||||
|
@ -266,6 +267,7 @@ var gFxAccounts = {
|
|||
return;
|
||||
}
|
||||
updateWithProfile(profile);
|
||||
this._profileFetched = true; // Try to avoid fetching the profile on every UI update
|
||||
}).catch(error => {
|
||||
// This is most likely in tests, were we quickly log users in and out.
|
||||
// The most likely scenario is a user logged out, so reflect that.
|
||||
|
|
|
@ -874,6 +874,12 @@ function serializeInputStream(aStream) {
|
|||
// A shared function used by both remote and non-remote browser XBL bindings to
|
||||
// load a URI or redirect it to the correct process.
|
||||
function _loadURIWithFlags(browser, uri, params) {
|
||||
let tab = gBrowser.getTabForBrowser(browser);
|
||||
// Preloaded browsers don't have tabs, so we ignore those.
|
||||
if (tab) {
|
||||
maybeRecordAbandonmentTelemetry(tab, "newURI");
|
||||
}
|
||||
|
||||
if (!uri) {
|
||||
uri = "about:blank";
|
||||
}
|
||||
|
@ -1789,6 +1795,16 @@ function HandleAppCommandEvent(evt) {
|
|||
evt.preventDefault();
|
||||
}
|
||||
|
||||
function maybeRecordAbandonmentTelemetry(tab, type) {
|
||||
if (!tab.hasAttribute("busy")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let histogram = Services.telemetry
|
||||
.getHistogramById("BUSY_TAB_ABANDONED");
|
||||
histogram.add(type);
|
||||
}
|
||||
|
||||
function gotoHistoryIndex(aEvent) {
|
||||
let index = aEvent.target.getAttribute("index");
|
||||
if (!index)
|
||||
|
@ -1800,6 +1816,8 @@ function gotoHistoryIndex(aEvent) {
|
|||
// Normal click. Go there in the current tab and update session history.
|
||||
|
||||
try {
|
||||
maybeRecordAbandonmentTelemetry(gBrowser.selectedTab,
|
||||
"historyNavigation");
|
||||
gBrowser.gotoIndex(index);
|
||||
} catch (ex) {
|
||||
return false;
|
||||
|
@ -1818,6 +1836,7 @@ function BrowserForward(aEvent) {
|
|||
|
||||
if (where == "current") {
|
||||
try {
|
||||
maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "forward");
|
||||
gBrowser.goForward();
|
||||
} catch (ex) {
|
||||
}
|
||||
|
@ -1831,6 +1850,7 @@ function BrowserBack(aEvent) {
|
|||
|
||||
if (where == "current") {
|
||||
try {
|
||||
maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "back");
|
||||
gBrowser.goBack();
|
||||
} catch (ex) {
|
||||
}
|
||||
|
@ -1863,6 +1883,7 @@ function BrowserHandleShiftBackspace() {
|
|||
|
||||
function BrowserStop() {
|
||||
const stopFlags = nsIWebNavigation.STOP_ALL;
|
||||
maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "stop");
|
||||
gBrowser.webNavigation.stop(stopFlags);
|
||||
}
|
||||
|
||||
|
@ -3255,6 +3276,12 @@ function BrowserReloadWithFlags(reloadFlags) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Do this after the above case where we might flip remoteness.
|
||||
// Unfortunately, we'll count the remoteness flip case as a
|
||||
// "newURL" load, since we're using loadURIWithFlags, but hopefully
|
||||
// that's rare enough to not matter.
|
||||
maybeRecordAbandonmentTelemetry(gBrowser.selectedTab, "reload");
|
||||
|
||||
// Reset temporary permissions on the current tab. This is done here
|
||||
// because we only want to reset permissions on user reload.
|
||||
SitePermissions.clearTemporaryPermissions(gBrowser.selectedBrowser);
|
||||
|
|
|
@ -166,7 +166,8 @@
|
|||
orient="vertical"
|
||||
noautofocus="true"
|
||||
consumeoutsideclicks="false"
|
||||
level="parent">
|
||||
level="parent"
|
||||
tabspecific="true">
|
||||
<iframe id="dateTimePopupFrame"/>
|
||||
</panel>
|
||||
|
||||
|
|
|
@ -2498,6 +2498,8 @@
|
|||
var skipPermitUnload = aParams.skipPermitUnload;
|
||||
}
|
||||
|
||||
window.maybeRecordAbandonmentTelemetry(aTab, "tabClosed");
|
||||
|
||||
// Handle requests for synchronously removing an already
|
||||
// asynchronously closing tab.
|
||||
if (!animate &&
|
||||
|
|
|
@ -32,31 +32,7 @@ support-files =
|
|||
feed_tab.html
|
||||
file_generic_favicon.ico
|
||||
file_with_favicon.html
|
||||
file_bug822367_1.html
|
||||
file_bug822367_1.js
|
||||
file_bug822367_2.html
|
||||
file_bug822367_3.html
|
||||
file_bug822367_4.html
|
||||
file_bug822367_4.js
|
||||
file_bug822367_4B.html
|
||||
file_bug822367_5.html
|
||||
file_bug822367_6.html
|
||||
file_bug902156.js
|
||||
file_bug902156_1.html
|
||||
file_bug902156_2.html
|
||||
file_bug902156_3.html
|
||||
file_bug906190_1.html
|
||||
file_bug906190_2.html
|
||||
file_bug906190_3_4.html
|
||||
file_bug906190_redirected.html
|
||||
file_bug906190.js
|
||||
file_bug906190.sjs
|
||||
file_mediaPlayback.html
|
||||
file_mixedContentFromOnunload.html
|
||||
file_mixedContentFromOnunload_test1.html
|
||||
file_mixedContentFromOnunload_test2.html
|
||||
file_mixedContentFramesOnHttp.html
|
||||
file_mixedPassiveContent.html
|
||||
file_bug970276_popup1.html
|
||||
file_bug970276_popup2.html
|
||||
file_bug970276_favicon1.ico
|
||||
|
@ -85,8 +61,6 @@ support-files =
|
|||
subtst_contextmenu.html
|
||||
subtst_contextmenu_input.html
|
||||
subtst_contextmenu_xul.xul
|
||||
test-mixedcontent-securityerrors.html
|
||||
test_bug435035.html
|
||||
test_bug462673.html
|
||||
test_bug628179.html
|
||||
test_bug839103.html
|
||||
|
@ -100,21 +74,6 @@ support-files =
|
|||
web_video1.ogv
|
||||
web_video1.ogv^headers^
|
||||
zoom_test.html
|
||||
test_no_mcb_on_http_site_img.html
|
||||
test_no_mcb_on_http_site_img.css
|
||||
test_no_mcb_on_http_site_font.html
|
||||
test_no_mcb_on_http_site_font.css
|
||||
test_no_mcb_on_http_site_font2.html
|
||||
test_no_mcb_on_http_site_font2.css
|
||||
test_mcb_redirect.html
|
||||
test_mcb_redirect_image.html
|
||||
test_mcb_double_redirect_image.html
|
||||
test_mcb_redirect.js
|
||||
test_mcb_redirect.sjs
|
||||
file_bug1045809_1.html
|
||||
file_bug1045809_2.html
|
||||
file_csp_block_all_mixedcontent.html
|
||||
file_csp_block_all_mixedcontent.js
|
||||
file_install_extensions.html
|
||||
browser_webext_permissions.xpi
|
||||
browser_webext_nopermissions.xpi
|
||||
|
@ -122,9 +81,6 @@ support-files =
|
|||
browser_webext_update2.xpi
|
||||
browser_webext_update.json
|
||||
!/image/test/mochitest/blue.png
|
||||
!/toolkit/components/passwordmgr/test/browser/form_basic.html
|
||||
!/toolkit/components/passwordmgr/test/browser/insecure_test.html
|
||||
!/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html
|
||||
!/toolkit/content/tests/browser/common/mockTransfer.js
|
||||
!/toolkit/modules/tests/browser/metadata_*.html
|
||||
!/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi
|
||||
|
@ -184,7 +140,6 @@ skip-if = true # bug 428712
|
|||
[browser_bug427559.js]
|
||||
[browser_bug431826.js]
|
||||
[browser_bug432599.js]
|
||||
[browser_bug435035.js]
|
||||
[browser_bug435325.js]
|
||||
[browser_bug441778.js]
|
||||
[browser_bug455852.js]
|
||||
|
@ -264,19 +219,9 @@ skip-if = os == "win" && debug && e10s # Bug 1315042
|
|||
[browser_bug763468_perwindowpb.js]
|
||||
[browser_bug767836_perwindowpb.js]
|
||||
[browser_bug817947.js]
|
||||
[browser_bug822367.js]
|
||||
tags = mcb
|
||||
[browser_bug832435.js]
|
||||
[browser_bug839103.js]
|
||||
[browser_bug882977.js]
|
||||
[browser_bug902156.js]
|
||||
tags = mcb
|
||||
[browser_bug906190.js]
|
||||
tags = mcb
|
||||
[browser_mixedContentFromOnunload.js]
|
||||
tags = mcb
|
||||
[browser_mixedContentFramesOnHttp.js]
|
||||
tags = mcb
|
||||
[browser_bug970746.js]
|
||||
[browser_bug1015721.js]
|
||||
skip-if = os == 'win'
|
||||
|
@ -324,9 +269,6 @@ skip-if = e10s # Bug 863514 - no gesture support.
|
|||
[browser_getshortcutoruri.js]
|
||||
[browser_hide_removing.js]
|
||||
[browser_homeDrop.js]
|
||||
[browser_identity_UI.js]
|
||||
[browser_insecureLoginForms.js]
|
||||
support-files = insecure_opener.html
|
||||
[browser_invalid_uri_back_forward_manipulation.js]
|
||||
[browser_keywordBookmarklets.js]
|
||||
[browser_keywordSearch.js]
|
||||
|
@ -339,9 +281,6 @@ skip-if = os != "win" # The Fitts Law menu button is only supported on Windows (
|
|||
subsuite = clipboard
|
||||
[browser_minimize.js]
|
||||
[browser_misused_characters_in_strings.js]
|
||||
[browser_mixed_content_cert_override.js]
|
||||
[browser_mixedcontent_securityflags.js]
|
||||
tags = mcb
|
||||
[browser_modifiedclick_inherit_principal.js]
|
||||
[browser_offlineQuotaNotification.js]
|
||||
[browser_feed_discovery.js]
|
||||
|
@ -484,11 +423,7 @@ skip-if = (os == "win" && !debug)
|
|||
[browser_zbug569342.js]
|
||||
skip-if = e10s || debug # Bug 1094240 - has findbar-related failures
|
||||
[browser_registerProtocolHandler_notification.js]
|
||||
[browser_no_mcb_on_http_site.js]
|
||||
tags = mcb
|
||||
[browser_addCertException.js]
|
||||
[browser_bug1045809.js]
|
||||
tags = mcb
|
||||
[browser_e10s_about_page_triggeringprincipal.js]
|
||||
[browser_e10s_switchbrowser.js]
|
||||
[browser_e10s_about_process.js]
|
||||
|
@ -496,8 +431,6 @@ tags = mcb
|
|||
[browser_e10s_javascript.js]
|
||||
[browser_blockHPKP.js]
|
||||
tags = psm
|
||||
[browser_mcb_redirect.js]
|
||||
tags = mcb
|
||||
[browser_windowactivation.js]
|
||||
[browser_contextmenu_childprocess.js]
|
||||
[browser_bug963945.js]
|
||||
|
@ -506,8 +439,6 @@ tags = fullscreen
|
|||
[browser_menuButtonBadgeManager.js]
|
||||
[browser_newTabDrop.js]
|
||||
[browser_newWindowDrop.js]
|
||||
[browser_csp_block_all_mixedcontent.js]
|
||||
tags = mcb
|
||||
[browser_newwindow_focus.js]
|
||||
skip-if = (os == "linux" && !e10s) # Bug 1263254 - Perma fails on Linux without e10s for some reason.
|
||||
[browser_bug1299667.js]
|
||||
|
|
|
@ -116,6 +116,7 @@ add_task(function* test_verifiedUserEmptyProfile() {
|
|||
// we first fetch the profile. We want them both to fire or we aren't testing
|
||||
// the state we think we are testing.
|
||||
let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateUI", 2);
|
||||
gFxAccounts._profileFetched = false;
|
||||
configureProfileURL({}); // successful but empty profile.
|
||||
yield setSignedInUser(true); // this will fire the observer that does the update.
|
||||
yield promiseUpdateDone;
|
||||
|
@ -135,6 +136,7 @@ add_task(function* test_verifiedUserEmptyProfile() {
|
|||
|
||||
add_task(function* test_verifiedUserDisplayName() {
|
||||
let promiseUpdateDone = promiseObserver("test:browser_fxaccounts:updateUI", 2);
|
||||
gFxAccounts._profileFetched = false;
|
||||
configureProfileURL({ displayName: "Test User Display Name" });
|
||||
yield setSignedInUser(true); // this will fire the observer that does the update.
|
||||
yield promiseUpdateDone;
|
||||
|
|
|
@ -108,10 +108,6 @@ let gWhitelist = [{
|
|||
file: "pocket.properties",
|
||||
key: "tos",
|
||||
type: "double-quote"
|
||||
}, {
|
||||
file: "pocket.properties",
|
||||
key: "tos",
|
||||
type: "apostrophe"
|
||||
}, {
|
||||
file: "aboutNetworking.dtd",
|
||||
key: "aboutNetworking.logTutorial",
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Tests for Bug 947079 - Fix bug in nsSecureBrowserUIImpl that sets the wrong
|
||||
* security state on a page because of a subresource load that is not on the
|
||||
* same page.
|
||||
*/
|
||||
|
||||
// We use different domains for each test and for navigation within each test
|
||||
const gHttpTestRoot1 = "http://example.com/browser/browser/base/content/test/general/";
|
||||
const gHttpsTestRoot1 = "https://test1.example.com/browser/browser/base/content/test/general/";
|
||||
const gHttpTestRoot2 = "http://example.net/browser/browser/base/content/test/general/";
|
||||
const gHttpsTestRoot2 = "https://test2.example.com/browser/browser/base/content/test/general/";
|
||||
|
||||
var gTestBrowser = null;
|
||||
add_task(function *() {
|
||||
let url = gHttpTestRoot1 + "file_mixedContentFromOnunload.html";
|
||||
yield BrowserTestUtils.withNewTab({gBrowser, url}, function*() {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["security.mixed_content.block_active_content", true],
|
||||
["security.mixed_content.block_display_content", false]
|
||||
]
|
||||
});
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
// Navigation from an http page to a https page with no mixed content
|
||||
// The http page loads an http image on unload
|
||||
url = gHttpsTestRoot1 + "file_mixedContentFromOnunload_test1.html";
|
||||
yield BrowserTestUtils.loadURI(gTestBrowser, url);
|
||||
yield BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
// check security state. Since current url is https and doesn't have any
|
||||
// mixed content resources, we expect it to be secure.
|
||||
isSecurityState("secure");
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: false});
|
||||
// Navigation from an http page to a https page that has mixed display content
|
||||
// The https page loads an http image on unload
|
||||
url = gHttpTestRoot2 + "file_mixedContentFromOnunload.html";
|
||||
yield BrowserTestUtils.loadURI(gTestBrowser, url);
|
||||
yield BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
url = gHttpsTestRoot2 + "file_mixedContentFromOnunload_test2.html";
|
||||
yield BrowserTestUtils.loadURI(gTestBrowser, url);
|
||||
yield BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
isSecurityState("broken");
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
|
||||
});
|
||||
});
|
|
@ -1,9 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html><head><meta charset="utf-8">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
</head>
|
||||
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
|
||||
<body>
|
||||
<script src="http://example.com/browser/browser/base/content/test/general/file_csp_block_all_mixedcontent.js"/>
|
||||
</body>
|
||||
</html>
|
|
@ -645,170 +645,6 @@ function waitForNewTabEvent(aTabBrowser) {
|
|||
return promiseWaitForEvent(aTabBrowser.tabContainer, "TabOpen");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the state of the identity box and control center to make
|
||||
* sure they are correctly showing the expected mixed content states.
|
||||
*
|
||||
* @note The checks are done synchronously, but new code should wait on the
|
||||
* returned Promise object to ensure the identity panel has closed.
|
||||
* Bug 1221114 is filed to fix the existing code.
|
||||
*
|
||||
* @param tabbrowser
|
||||
* @param Object states
|
||||
* MUST include the following properties:
|
||||
* {
|
||||
* activeLoaded: true|false,
|
||||
* activeBlocked: true|false,
|
||||
* passiveLoaded: true|false,
|
||||
* }
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When the operation has finished and the identity panel has closed.
|
||||
*/
|
||||
function assertMixedContentBlockingState(tabbrowser, states = {}) {
|
||||
if (!tabbrowser || !("activeLoaded" in states) ||
|
||||
!("activeBlocked" in states) || !("passiveLoaded" in states)) {
|
||||
throw new Error("assertMixedContentBlockingState requires a browser and a states object");
|
||||
}
|
||||
|
||||
let {passiveLoaded, activeLoaded, activeBlocked} = states;
|
||||
let {gIdentityHandler} = tabbrowser.ownerGlobal;
|
||||
let doc = tabbrowser.ownerDocument;
|
||||
let identityBox = gIdentityHandler._identityBox;
|
||||
let classList = identityBox.classList;
|
||||
let connectionIcon = doc.getElementById("connection-icon");
|
||||
let connectionIconImage = tabbrowser.ownerGlobal.getComputedStyle(connectionIcon).
|
||||
getPropertyValue("list-style-image");
|
||||
|
||||
let stateSecure = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_SECURE;
|
||||
let stateBroken = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN;
|
||||
let stateInsecure = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_INSECURE;
|
||||
let stateActiveBlocked = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
|
||||
let stateActiveLoaded = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT;
|
||||
let statePassiveLoaded = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT;
|
||||
|
||||
is(activeBlocked, !!stateActiveBlocked, "Expected state for activeBlocked matches UI state");
|
||||
is(activeLoaded, !!stateActiveLoaded, "Expected state for activeLoaded matches UI state");
|
||||
is(passiveLoaded, !!statePassiveLoaded, "Expected state for passiveLoaded matches UI state");
|
||||
|
||||
if (stateInsecure) {
|
||||
// HTTP request, there should be no MCB classes for the identity box and the non secure icon
|
||||
// should always be visible regardless of MCB state.
|
||||
ok(classList.contains("unknownIdentity"), "unknownIdentity on HTTP page");
|
||||
is_element_hidden(connectionIcon);
|
||||
|
||||
ok(!classList.contains("mixedActiveContent"), "No MCB icon on HTTP page");
|
||||
ok(!classList.contains("mixedActiveBlocked"), "No MCB icon on HTTP page");
|
||||
ok(!classList.contains("mixedDisplayContent"), "No MCB icon on HTTP page");
|
||||
ok(!classList.contains("mixedDisplayContentLoadedActiveBlocked"), "No MCB icon on HTTP page");
|
||||
} else {
|
||||
// Make sure the identity box UI has the correct mixedcontent states and icons
|
||||
is(classList.contains("mixedActiveContent"), activeLoaded,
|
||||
"identityBox has expected class for activeLoaded");
|
||||
is(classList.contains("mixedActiveBlocked"), activeBlocked && !passiveLoaded,
|
||||
"identityBox has expected class for activeBlocked && !passiveLoaded");
|
||||
is(classList.contains("mixedDisplayContent"), passiveLoaded && !(activeLoaded || activeBlocked),
|
||||
"identityBox has expected class for passiveLoaded && !(activeLoaded || activeBlocked)");
|
||||
is(classList.contains("mixedDisplayContentLoadedActiveBlocked"), passiveLoaded && activeBlocked,
|
||||
"identityBox has expected class for passiveLoaded && activeBlocked");
|
||||
|
||||
is_element_visible(connectionIcon);
|
||||
if (activeLoaded) {
|
||||
is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-active-loaded.svg#icon\")",
|
||||
"Using active loaded icon");
|
||||
}
|
||||
if (activeBlocked && !passiveLoaded) {
|
||||
is(connectionIconImage, "url(\"chrome://browser/skin/connection-secure.svg\")",
|
||||
"Using active blocked icon");
|
||||
}
|
||||
if (passiveLoaded && !(activeLoaded || activeBlocked)) {
|
||||
is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
|
||||
"Using passive loaded icon");
|
||||
}
|
||||
if (passiveLoaded && activeBlocked) {
|
||||
is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
|
||||
"Using active blocked and passive loaded icon");
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the identity popup has the correct mixedcontent states
|
||||
gIdentityHandler._identityBox.click();
|
||||
let popupAttr = doc.getElementById("identity-popup").getAttribute("mixedcontent");
|
||||
let bodyAttr = doc.getElementById("identity-popup-securityView-body").getAttribute("mixedcontent");
|
||||
|
||||
is(popupAttr.includes("active-loaded"), activeLoaded,
|
||||
"identity-popup has expected attr for activeLoaded");
|
||||
is(bodyAttr.includes("active-loaded"), activeLoaded,
|
||||
"securityView-body has expected attr for activeLoaded");
|
||||
|
||||
is(popupAttr.includes("active-blocked"), activeBlocked,
|
||||
"identity-popup has expected attr for activeBlocked");
|
||||
is(bodyAttr.includes("active-blocked"), activeBlocked,
|
||||
"securityView-body has expected attr for activeBlocked");
|
||||
|
||||
is(popupAttr.includes("passive-loaded"), passiveLoaded,
|
||||
"identity-popup has expected attr for passiveLoaded");
|
||||
is(bodyAttr.includes("passive-loaded"), passiveLoaded,
|
||||
"securityView-body has expected attr for passiveLoaded");
|
||||
|
||||
// Make sure the correct icon is visible in the Control Center.
|
||||
// This logic is controlled with CSS, so this helps prevent regressions there.
|
||||
let securityView = doc.getElementById("identity-popup-securityView");
|
||||
let securityViewBG = tabbrowser.ownerGlobal.getComputedStyle(securityView).
|
||||
getPropertyValue("background-image");
|
||||
let securityContentBG = tabbrowser.ownerGlobal.getComputedStyle(securityView).
|
||||
getPropertyValue("background-image");
|
||||
|
||||
if (stateInsecure) {
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/conn-not-secure.svg\")",
|
||||
"CC using 'not secure' icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/conn-not-secure.svg\")",
|
||||
"CC using 'not secure' icon");
|
||||
}
|
||||
|
||||
if (stateSecure) {
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
|
||||
"CC using secure icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
|
||||
"CC using secure icon");
|
||||
}
|
||||
|
||||
if (stateBroken) {
|
||||
if (activeLoaded) {
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
|
||||
"CC using active loaded icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
|
||||
"CC using active loaded icon");
|
||||
} else if (activeBlocked || passiveLoaded) {
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
|
||||
"CC using degraded icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
|
||||
"CC using degraded icon");
|
||||
} else {
|
||||
// There is a case here with weak ciphers, but no bc tests are handling this yet.
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
|
||||
"CC using degraded icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
|
||||
"CC using degraded icon");
|
||||
}
|
||||
}
|
||||
|
||||
if (activeLoaded || activeBlocked || passiveLoaded) {
|
||||
doc.getElementById("identity-popup-security-expander").click();
|
||||
is(Array.filter(doc.querySelectorAll("[observes=identity-popup-mcb-learn-more]"),
|
||||
element => !is_hidden(element)).length, 1,
|
||||
"The 'Learn more' link should be visible once.");
|
||||
}
|
||||
|
||||
gIdentityHandler._identityPopup.hidden = true;
|
||||
|
||||
// Wait for the panel to be closed before continuing. The promisePopupHidden
|
||||
// function cannot be used because it's unreliable unless promisePopupShown is
|
||||
// also called before closing the panel. This cannot be done until all callers
|
||||
// are made asynchronous (bug 1221114).
|
||||
return new Promise(resolve => executeSoon(resolve));
|
||||
}
|
||||
|
||||
function is_hidden(element) {
|
||||
var style = element.ownerGlobal.getComputedStyle(element);
|
||||
if (style.display == "none")
|
||||
|
@ -923,35 +759,6 @@ function promiseNewSearchEngine(basename) {
|
|||
});
|
||||
}
|
||||
|
||||
// Compares the security state of the page with what is expected
|
||||
function isSecurityState(expectedState) {
|
||||
let ui = gTestBrowser.securityUI;
|
||||
if (!ui) {
|
||||
ok(false, "No security UI to get the security state");
|
||||
return;
|
||||
}
|
||||
|
||||
const wpl = Components.interfaces.nsIWebProgressListener;
|
||||
|
||||
// determine the security state
|
||||
let isSecure = ui.state & wpl.STATE_IS_SECURE;
|
||||
let isBroken = ui.state & wpl.STATE_IS_BROKEN;
|
||||
let isInsecure = ui.state & wpl.STATE_IS_INSECURE;
|
||||
|
||||
let actualState;
|
||||
if (isSecure && !(isBroken || isInsecure)) {
|
||||
actualState = "secure";
|
||||
} else if (isBroken && !(isSecure || isInsecure)) {
|
||||
actualState = "broken";
|
||||
} else if (isInsecure && !(isSecure || isBroken)) {
|
||||
actualState = "insecure";
|
||||
} else {
|
||||
actualState = "unknown";
|
||||
}
|
||||
|
||||
is(expectedState, actualState, "Expected state " + expectedState + " and the actual state is " + actualState + ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves when a bookmark with the given uri is added.
|
||||
*/
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<img src="http://example.com/browser/browser/base/content/test/general/moz.png">
|
|
@ -1,6 +1,91 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
head.js
|
||||
!/image/test/mochitest/blue.png
|
||||
|
||||
[browser_bug435035.js]
|
||||
support-files =
|
||||
test_bug435035.html
|
||||
[browser_bug822367.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
file_bug822367_1.html
|
||||
file_bug822367_1.js
|
||||
file_bug822367_2.html
|
||||
file_bug822367_3.html
|
||||
file_bug822367_4.html
|
||||
file_bug822367_4.js
|
||||
file_bug822367_4B.html
|
||||
file_bug822367_5.html
|
||||
file_bug822367_6.html
|
||||
[browser_bug902156.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
file_bug902156.js
|
||||
file_bug902156_1.html
|
||||
file_bug902156_2.html
|
||||
file_bug902156_3.html
|
||||
[browser_bug906190.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
file_bug906190_1.html
|
||||
file_bug906190_2.html
|
||||
file_bug906190_3_4.html
|
||||
file_bug906190_redirected.html
|
||||
file_bug906190.js
|
||||
file_bug906190.sjs
|
||||
[browser_bug1045809.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
file_bug1045809_1.html
|
||||
file_bug1045809_2.html
|
||||
[browser_csp_block_all_mixedcontent.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
file_csp_block_all_mixedcontent.html
|
||||
file_csp_block_all_mixedcontent.js
|
||||
[browser_identity_UI.js]
|
||||
[browser_identityBlock_focus.js]
|
||||
support-files = ../general/permissions.html
|
||||
[browser_insecureLoginForms.js]
|
||||
support-files =
|
||||
insecure_opener.html
|
||||
!/toolkit/components/passwordmgr/test/browser/form_basic.html
|
||||
!/toolkit/components/passwordmgr/test/browser/insecure_test.html
|
||||
!/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html
|
||||
[browser_mcb_redirect.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
test_mcb_redirect.html
|
||||
test_mcb_redirect_image.html
|
||||
test_mcb_double_redirect_image.html
|
||||
test_mcb_redirect.js
|
||||
test_mcb_redirect.sjs
|
||||
[browser_mixed_content_cert_override.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
test-mixedcontent-securityerrors.html
|
||||
[browser_mixedcontent_securityflags.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
test-mixedcontent-securityerrors.html
|
||||
[browser_mixedContentFramesOnHttp.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
file_mixedContentFramesOnHttp.html
|
||||
file_mixedPassiveContent.html
|
||||
[browser_mixedContentFromOnunload.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
file_mixedContentFromOnunload.html
|
||||
file_mixedContentFromOnunload_test1.html
|
||||
file_mixedContentFromOnunload_test2.html
|
||||
[browser_no_mcb_on_http_site.js]
|
||||
tags = mcb
|
||||
support-files =
|
||||
test_no_mcb_on_http_site_img.html
|
||||
test_no_mcb_on_http_site_img.css
|
||||
test_no_mcb_on_http_site_font.html
|
||||
test_no_mcb_on_http_site_font.css
|
||||
test_no_mcb_on_http_site_font2.html
|
||||
test_no_mcb_on_http_site_font2.css
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Test that the Mixed Content Doorhanger Action to re-enable protection works
|
||||
|
||||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
const TEST_URL = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "file_bug1045809_1.html";
|
||||
|
||||
var origBlockActive;
|
||||
|
||||
|
@ -16,13 +17,10 @@ add_task(function* () {
|
|||
// Make sure mixed content blocking is on
|
||||
Services.prefs.setBoolPref(PREF_ACTIVE, true);
|
||||
|
||||
var url =
|
||||
"https://test1.example.com/browser/browser/base/content/test/general/" +
|
||||
"file_bug1045809_1.html";
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
|
||||
// Test 1: mixed content must be blocked
|
||||
yield promiseTabLoadEvent(tab, url);
|
||||
yield promiseTabLoadEvent(tab, TEST_URL);
|
||||
yield* test1(gBrowser.getBrowserForTab(tab));
|
||||
|
||||
yield promiseTabLoadEvent(tab);
|
|
@ -1,3 +1,5 @@
|
|||
const TEST_URL = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "test_bug435035.html";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
|
@ -11,7 +13,5 @@ function test() {
|
|||
finish();
|
||||
});
|
||||
|
||||
gBrowser.loadURI(
|
||||
"https://example.com/browser/browser/base/content/test/general/test_bug435035.html"
|
||||
);
|
||||
gBrowser.loadURI(TEST_URL);
|
||||
}
|
|
@ -7,8 +7,8 @@ const PREF_DISPLAY = "security.mixed_content.block_display_content";
|
|||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
|
||||
// We alternate for even and odd test cases to simulate different hosts
|
||||
const gHttpTestRoot = "https://example.com/browser/browser/base/content/test/general/";
|
||||
const gHttpTestRoot2 = "https://test1.example.com/browser/browser/base/content/test/general/";
|
||||
const HTTPS_TEST_ROOT = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
|
||||
const HTTPS_TEST_ROOT_2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://test1.example.com");
|
||||
|
||||
var gTestBrowser = null;
|
||||
|
||||
|
@ -37,7 +37,7 @@ function test() {
|
|||
|
||||
// Mixed Script Test
|
||||
gTestBrowser.addEventListener("load", MixedTest1A, true);
|
||||
var url = gHttpTestRoot + "file_bug822367_1.html";
|
||||
var url = HTTPS_TEST_ROOT + "file_bug822367_1.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ function MixedTest1A() {
|
|||
gIdentityHandler.disableMixedContentProtection();
|
||||
}
|
||||
function MixedTest1B() {
|
||||
waitForCondition(() => content.document.getElementById("p1").innerHTML == "hello", MixedTest1C, "Waited too long for mixed script to run in Test 1");
|
||||
BrowserTestUtils.waitForCondition(() => content.document.getElementById("p1").innerHTML == "hello", "Waited too long for mixed script to run in Test 1").then(MixedTest1C);
|
||||
}
|
||||
function MixedTest1C() {
|
||||
ok(content.document.getElementById("p1").innerHTML == "hello", "Mixed script didn't load in Test 1");
|
||||
|
@ -63,7 +63,7 @@ function MixedTest1C() {
|
|||
// Mixed Display Test - Doorhanger should not appear
|
||||
function MixedTest2() {
|
||||
gTestBrowser.addEventListener("load", MixedTest2A, true);
|
||||
var url = gHttpTestRoot2 + "file_bug822367_2.html";
|
||||
var url = HTTPS_TEST_ROOT_2 + "file_bug822367_2.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ function MixedTest2A() {
|
|||
function MixedTest3() {
|
||||
gTestBrowser.removeEventListener("load", MixedTest2A, true);
|
||||
gTestBrowser.addEventListener("load", MixedTest3A, true);
|
||||
var url = gHttpTestRoot + "file_bug822367_3.html";
|
||||
var url = HTTPS_TEST_ROOT + "file_bug822367_3.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
function MixedTest3A() {
|
||||
|
@ -89,10 +89,10 @@ function MixedTest3A() {
|
|||
gIdentityHandler.disableMixedContentProtection();
|
||||
}
|
||||
function MixedTest3B() {
|
||||
waitForCondition(() => content.document.getElementById("p1").innerHTML == "hello", MixedTest3C, "Waited too long for mixed script to run in Test 3");
|
||||
BrowserTestUtils.waitForCondition(() => content.document.getElementById("p1").innerHTML == "hello", "Waited too long for mixed script to run in Test 3").then(MixedTest3C);
|
||||
}
|
||||
function MixedTest3C() {
|
||||
waitForCondition(() => content.document.getElementById("p2").innerHTML == "bye", MixedTest3D, "Waited too long for mixed image to load in Test 3");
|
||||
BrowserTestUtils.waitForCondition(() => content.document.getElementById("p2").innerHTML == "bye", "Waited too long for mixed image to load in Test 3").then(MixedTest3D);
|
||||
}
|
||||
function MixedTest3D() {
|
||||
ok(content.document.getElementById("p1").innerHTML == "hello", "Mixed script didn't load in Test 3");
|
||||
|
@ -105,7 +105,7 @@ function MixedTest3D() {
|
|||
function MixedTest4() {
|
||||
gTestBrowser.removeEventListener("load", MixedTest3B, true);
|
||||
gTestBrowser.addEventListener("load", MixedTest4A, true);
|
||||
var url = gHttpTestRoot2 + "file_bug822367_4.html";
|
||||
var url = HTTPS_TEST_ROOT_2 + "file_bug822367_4.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
function MixedTest4A() {
|
||||
|
@ -118,14 +118,14 @@ function MixedTest4A() {
|
|||
gIdentityHandler.disableMixedContentProtection();
|
||||
}
|
||||
function MixedTest4B() {
|
||||
waitForCondition(() => content.document.location == gHttpTestRoot + "file_bug822367_4B.html", MixedTest4C, "Waited too long for mixed script to run in Test 4");
|
||||
BrowserTestUtils.waitForCondition(() => content.document.location == HTTPS_TEST_ROOT + "file_bug822367_4B.html", "Waited too long for mixed script to run in Test 4").then(MixedTest4C);
|
||||
}
|
||||
function MixedTest4C() {
|
||||
ok(content.document.location == gHttpTestRoot + "file_bug822367_4B.html", "Location didn't change in test 4");
|
||||
ok(content.document.location == HTTPS_TEST_ROOT + "file_bug822367_4B.html", "Location didn't change in test 4");
|
||||
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: true, passiveLoaded: false});
|
||||
|
||||
waitForCondition(() => content.document.getElementById("p1").innerHTML == "", MixedTest4D, "Mixed script loaded in test 4 after location change!");
|
||||
BrowserTestUtils.waitForCondition(() => content.document.getElementById("p1").innerHTML == "", "Mixed script loaded in test 4 after location change!").then(MixedTest4D);
|
||||
}
|
||||
function MixedTest4D() {
|
||||
ok(content.document.getElementById("p1").innerHTML == "", "p1.innerHTML changed; mixed script loaded after location change in Test 4");
|
||||
|
@ -136,7 +136,7 @@ function MixedTest4D() {
|
|||
function MixedTest5() {
|
||||
gTestBrowser.removeEventListener("load", MixedTest4B, true);
|
||||
gTestBrowser.addEventListener("load", MixedTest5A, true);
|
||||
var url = gHttpTestRoot + "file_bug822367_5.html";
|
||||
var url = HTTPS_TEST_ROOT + "file_bug822367_5.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
function MixedTest5A() {
|
||||
|
@ -149,7 +149,7 @@ function MixedTest5A() {
|
|||
gIdentityHandler.disableMixedContentProtection();
|
||||
}
|
||||
function MixedTest5B() {
|
||||
waitForCondition(() => content.document.getElementById("p1").innerHTML == "hello", MixedTest5C, "Waited too long for mixed script to run in Test 5");
|
||||
BrowserTestUtils.waitForCondition(() => content.document.getElementById("p1").innerHTML == "hello", "Waited too long for mixed script to run in Test 5").then(MixedTest5C);
|
||||
}
|
||||
function MixedTest5C() {
|
||||
ok(content.document.getElementById("p1").innerHTML == "hello", "Mixed script didn't load in Test 5");
|
||||
|
@ -160,13 +160,13 @@ function MixedTest5C() {
|
|||
function MixedTest6() {
|
||||
gTestBrowser.removeEventListener("load", MixedTest5B, true);
|
||||
gTestBrowser.addEventListener("load", MixedTest6A, true);
|
||||
var url = gHttpTestRoot2 + "file_bug822367_6.html";
|
||||
var url = HTTPS_TEST_ROOT_2 + "file_bug822367_6.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
function MixedTest6A() {
|
||||
gTestBrowser.removeEventListener("load", MixedTest6A, true);
|
||||
let {gIdentityHandler} = gTestBrowser.ownerGlobal;
|
||||
waitForCondition(() => gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"), MixedTest6B, "Waited too long for control center to get mixed active blocked state");
|
||||
BrowserTestUtils.waitForCondition(() => gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"), "Waited too long for control center to get mixed active blocked state").then(MixedTest6B);
|
||||
}
|
||||
|
||||
function MixedTest6B() {
|
||||
|
@ -180,13 +180,13 @@ function MixedTest6B() {
|
|||
|
||||
function MixedTest6C() {
|
||||
gTestBrowser.removeEventListener("load", MixedTest6C, true);
|
||||
waitForCondition(function() {
|
||||
BrowserTestUtils.waitForCondition(function() {
|
||||
try {
|
||||
return content.document.getElementById("f1").contentDocument.getElementById("p1").innerHTML == "hello";
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}, MixedTest6D, "Waited too long for mixed script to run in Test 6");
|
||||
}, "Waited too long for mixed script to run in Test 6").then(MixedTest6D);
|
||||
}
|
||||
function MixedTest6D() {
|
||||
ok(content.document.getElementById("f1").contentDocument.getElementById("p1").innerHTML == "hello", "Mixed script didn't load in Test 6");
|
|
@ -25,8 +25,8 @@
|
|||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
|
||||
// We alternate for even and odd test cases to simulate different hosts
|
||||
const gHttpTestRoot1 = "https://test1.example.com/browser/browser/base/content/test/general/";
|
||||
const gHttpTestRoot2 = "https://test2.example.com/browser/browser/base/content/test/general/";
|
||||
const HTTPS_TEST_ROOT_1 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://test1.example.com");
|
||||
const HTTPS_TEST_ROOT_2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://test2.example.com");
|
||||
|
||||
var origBlockActive;
|
||||
var gTestBrowser = null;
|
||||
|
@ -56,9 +56,9 @@ function test1A() {
|
|||
|
||||
function test1B() {
|
||||
var expected = "Mixed Content Blocker disabled";
|
||||
waitForCondition(
|
||||
BrowserTestUtils.waitForCondition(
|
||||
() => content.document.getElementById("mctestdiv").innerHTML == expected,
|
||||
test1C, "Error: Waited too long for mixed script to run in Test 1B");
|
||||
"Error: Waited too long for mixed script to run in Test 1B").then(test1C);
|
||||
}
|
||||
|
||||
function test1C() {
|
||||
|
@ -69,7 +69,7 @@ function test1C() {
|
|||
// page and see if our decision is persistent
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test1D);
|
||||
|
||||
var url = gHttpTestRoot1 + "file_bug902156_2.html";
|
||||
var url = HTTPS_TEST_ROOT_1 + "file_bug902156_2.html";
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ function test1D() {
|
|||
|
||||
function test2() {
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test2A);
|
||||
var url = gHttpTestRoot2 + "file_bug902156_2.html";
|
||||
var url = HTTPS_TEST_ROOT_2 + "file_bug902156_2.html";
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
||||
|
||||
|
@ -105,9 +105,9 @@ function test2A() {
|
|||
|
||||
function test2B() {
|
||||
var expected = "Mixed Content Blocker disabled";
|
||||
waitForCondition(
|
||||
BrowserTestUtils.waitForCondition(
|
||||
() => content.document.getElementById("mctestdiv").innerHTML == expected,
|
||||
test2C, "Error: Waited too long for mixed script to run in Test 2B");
|
||||
"Error: Waited too long for mixed script to run in Test 2B").then(test2C);
|
||||
}
|
||||
|
||||
function test2C() {
|
||||
|
@ -139,7 +139,7 @@ function test2D() {
|
|||
|
||||
function test3() {
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test3A);
|
||||
var url = gHttpTestRoot1 + "file_bug902156_3.html";
|
||||
var url = HTTPS_TEST_ROOT_1 + "file_bug902156_3.html";
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
||||
|
||||
|
@ -169,6 +169,6 @@ function test() {
|
|||
|
||||
// Starting Test Number 1:
|
||||
BrowserTestUtils.browserLoaded(gTestBrowser).then(test1A);
|
||||
var url = gHttpTestRoot1 + "file_bug902156_1.html";
|
||||
var url = HTTPS_TEST_ROOT_1 + "file_bug902156_1.html";
|
||||
gTestBrowser.loadURI(url);
|
||||
}
|
|
@ -10,8 +10,8 @@ requestLongerTimeout(2);
|
|||
|
||||
// We use the different urls for testing same origin checks before allowing
|
||||
// mixed content on child tabs.
|
||||
const gHttpTestRoot1 = "https://test1.example.com/browser/browser/base/content/test/general/";
|
||||
const gHttpTestRoot2 = "https://test2.example.com/browser/browser/base/content/test/general/";
|
||||
const HTTPS_TEST_ROOT_1 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://test1.example.com");
|
||||
const HTTPS_TEST_ROOT_2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://test2.example.com");
|
||||
|
||||
/**
|
||||
* For all tests, we load the pages over HTTPS and test both:
|
||||
|
@ -35,7 +35,7 @@ function* doTest(parentTabSpec, childTabSpec, testTaskFn, waitForMetaRefresh) {
|
|||
|
||||
// Wait for the script in the page to update the contents of the test div.
|
||||
let testDiv = content.document.getElementById("mctestdiv");
|
||||
yield promiseWaitForCondition(
|
||||
yield BrowserTestUtils.waitForCondition(
|
||||
() => testDiv.innerHTML == "Mixed Content Blocker disabled");
|
||||
|
||||
// Add the link for the child tab to the page.
|
||||
|
@ -111,8 +111,8 @@ add_task(function* test_initialize() {
|
|||
* - Doorhanger should >> NOT << appear anymore!
|
||||
*/
|
||||
add_task(function* test_same_origin() {
|
||||
yield doTest(gHttpTestRoot1 + "file_bug906190_1.html",
|
||||
gHttpTestRoot1 + "file_bug906190_2.html", function* () {
|
||||
yield doTest(HTTPS_TEST_ROOT_1 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190_2.html", function* () {
|
||||
// The doorhanger should appear but activeBlocked should be >> NOT << true,
|
||||
// because our decision of disabling the mixed content blocker is persistent
|
||||
// across tabs.
|
||||
|
@ -132,8 +132,8 @@ add_task(function* test_same_origin() {
|
|||
* - Doorhanger >> SHOULD << appear again!
|
||||
*/
|
||||
add_task(function* test_different_origin() {
|
||||
yield doTest(gHttpTestRoot1 + "file_bug906190_2.html",
|
||||
gHttpTestRoot2 + "file_bug906190_2.html", function* () {
|
||||
yield doTest(HTTPS_TEST_ROOT_1 + "file_bug906190_2.html",
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190_2.html", function* () {
|
||||
// The doorhanger should appear and activeBlocked should be >> TRUE <<,
|
||||
// because our decision of disabling the mixed content blocker should only
|
||||
// persist if pages are from the same domain.
|
||||
|
@ -155,8 +155,8 @@ add_task(function* test_different_origin() {
|
|||
*/
|
||||
add_task(function* test_same_origin_metarefresh_same_origin() {
|
||||
// file_bug906190_3_4.html redirects to page test1.example.com/* using meta-refresh
|
||||
yield doTest(gHttpTestRoot1 + "file_bug906190_1.html",
|
||||
gHttpTestRoot1 + "file_bug906190_3_4.html", function* () {
|
||||
yield doTest(HTTPS_TEST_ROOT_1 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190_3_4.html", function* () {
|
||||
// The doorhanger should appear but activeBlocked should be >> NOT << true!
|
||||
yield assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: true, activeBlocked: false, passiveLoaded: false,
|
||||
|
@ -175,8 +175,8 @@ add_task(function* test_same_origin_metarefresh_same_origin() {
|
|||
* - Doorhanger >> SHOULD << appear again!
|
||||
*/
|
||||
add_task(function* test_same_origin_metarefresh_different_origin() {
|
||||
yield doTest(gHttpTestRoot2 + "file_bug906190_1.html",
|
||||
gHttpTestRoot2 + "file_bug906190_3_4.html", function* () {
|
||||
yield doTest(HTTPS_TEST_ROOT_2 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190_3_4.html", function* () {
|
||||
// The doorhanger should appear and activeBlocked should be >> TRUE <<.
|
||||
yield assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: false, activeBlocked: true, passiveLoaded: false,
|
||||
|
@ -195,8 +195,8 @@ add_task(function* test_same_origin_metarefresh_different_origin() {
|
|||
*/
|
||||
add_task(function* test_same_origin_302redirect_same_origin() {
|
||||
// the sjs files returns a 302 redirect- note, same origins
|
||||
yield doTest(gHttpTestRoot1 + "file_bug906190_1.html",
|
||||
gHttpTestRoot1 + "file_bug906190.sjs", function* () {
|
||||
yield doTest(HTTPS_TEST_ROOT_1 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_1 + "file_bug906190.sjs", function* () {
|
||||
// The doorhanger should appear but activeBlocked should be >> NOT << true.
|
||||
// Currently it is >> TRUE << - see follow up bug 914860
|
||||
ok(!gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
|
||||
|
@ -215,8 +215,8 @@ add_task(function* test_same_origin_302redirect_same_origin() {
|
|||
*/
|
||||
add_task(function* test_same_origin_302redirect_different_origin() {
|
||||
// the sjs files returns a 302 redirect - note, different origins
|
||||
yield doTest(gHttpTestRoot2 + "file_bug906190_1.html",
|
||||
gHttpTestRoot2 + "file_bug906190.sjs", function* () {
|
||||
yield doTest(HTTPS_TEST_ROOT_2 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190.sjs", function* () {
|
||||
// The doorhanger should appear and activeBlocked should be >> TRUE <<.
|
||||
yield assertMixedContentBlockingState(gBrowser, {
|
||||
activeLoaded: false, activeBlocked: true, passiveLoaded: false,
|
||||
|
@ -232,8 +232,8 @@ add_task(function* test_same_origin_302redirect_different_origin() {
|
|||
*/
|
||||
add_task(function* test_bad_redirection() {
|
||||
// the sjs files returns a 302 redirect - note, different origins
|
||||
yield doTest(gHttpTestRoot2 + "file_bug906190_1.html",
|
||||
gHttpTestRoot2 + "file_bug906190.sjs?bad-redirection=1", function* () {
|
||||
yield doTest(HTTPS_TEST_ROOT_2 + "file_bug906190_1.html",
|
||||
HTTPS_TEST_ROOT_2 + "file_bug906190.sjs?bad-redirection=1", function* () {
|
||||
// Nothing to do. Just see if memory leak is reported in the end.
|
||||
ok(true, "Nothing to do");
|
||||
});
|
|
@ -6,7 +6,7 @@
|
|||
* should still appear fully encrypted with a green lock.
|
||||
*/
|
||||
|
||||
const PRE_PATH = "https://example.com/browser/browser/base/content/test/general/";
|
||||
const PRE_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
|
||||
var gTestBrowser = null;
|
||||
|
||||
// ------------------------------------------------------
|
|
@ -99,12 +99,12 @@ function nextTest() {
|
|||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, gCurrentTest.location);
|
||||
} else {
|
||||
// Open the Control Center and make sure it closes after nav (Bug 1207542).
|
||||
let popupShown = promisePopupShown(gIdentityHandler._identityPopup);
|
||||
gPopupHidden = promisePopupHidden(gIdentityHandler._identityPopup);
|
||||
let popupShown = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popupshown");
|
||||
gPopupHidden = BrowserTestUtils.waitForEvent(gIdentityHandler._identityPopup, "popuphidden");
|
||||
gIdentityHandler._identityBox.click();
|
||||
info("Waiting for the Control Center to be shown");
|
||||
popupShown.then(() => {
|
||||
is_element_visible(gIdentityHandler._identityPopup, "Control Center is visible");
|
||||
ok(!is_hidden(gIdentityHandler._identityPopup), "Control Center is visible");
|
||||
// Show the subview, which is an easy way in automation to reproduce
|
||||
// Bug 1207542, where the CC wouldn't close on navigation.
|
||||
gBrowser.ownerDocument.querySelector("#identity-popup-security-expander").click();
|
||||
|
@ -140,7 +140,7 @@ function checkResult(event) {
|
|||
info("Waiting for the Control Center to hide");
|
||||
gPopupHidden.then(() => {
|
||||
gPopupHidden = null;
|
||||
is_element_hidden(gIdentityHandler._identityPopup, "control center is hidden");
|
||||
ok(is_hidden(gIdentityHandler._identityPopup), "Control Center is hidden");
|
||||
executeSoon(nextTest);
|
||||
});
|
||||
} else {
|
|
@ -41,7 +41,7 @@ add_task(function* test_simple() {
|
|||
document.getElementById("identity-popup-security-expander").click();
|
||||
|
||||
if (expectWarning) {
|
||||
is_element_visible(document.getElementById("connection-icon"));
|
||||
ok(is_visible(document.getElementById("connection-icon")), "Connection icon should be visible");
|
||||
let connectionIconImage = gBrowser.ownerGlobal
|
||||
.getComputedStyle(document.getElementById("connection-icon"))
|
||||
.getPropertyValue("list-style-image");
|
|
@ -55,8 +55,8 @@
|
|||
|
||||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
const PREF_DISPLAY = "security.mixed_content.block_display_content";
|
||||
const gHttpsTestRoot = "https://example.com/browser/browser/base/content/test/general/";
|
||||
const gHttpTestRoot = "http://example.com/browser/browser/base/content/test/general/";
|
||||
const HTTPS_TEST_ROOT = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
|
||||
const HTTP_TEST_ROOT = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
|
||||
|
||||
var origBlockActive;
|
||||
var origBlockDisplay;
|
||||
|
@ -101,7 +101,7 @@ function waitForCondition(condition, nextTest, errorMsg, okMsg) {
|
|||
|
||||
function test1() {
|
||||
gTestBrowser.addEventListener("load", checkUIForTest1, true);
|
||||
var url = gHttpsTestRoot + "test_mcb_redirect.html"
|
||||
var url = HTTPS_TEST_ROOT + "test_mcb_redirect.html"
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -121,7 +121,7 @@ function checkUIForTest1() {
|
|||
|
||||
function test2() {
|
||||
gTestBrowser.addEventListener("load", checkUIForTest2, true);
|
||||
var url = gHttpTestRoot + "test_mcb_redirect.html"
|
||||
var url = HTTP_TEST_ROOT + "test_mcb_redirect.html"
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ function checkUIForTest2() {
|
|||
// HTTPS page loading insecure image
|
||||
function test3() {
|
||||
gTestBrowser.addEventListener("load", checkLoadEventForTest3, true);
|
||||
var url = gHttpsTestRoot + "test_mcb_redirect_image.html"
|
||||
var url = HTTPS_TEST_ROOT + "test_mcb_redirect_image.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ function checkLoadEventForTest3() {
|
|||
// HTTP page loading insecure image
|
||||
function test4() {
|
||||
gTestBrowser.addEventListener("load", checkLoadEventForTest4, true);
|
||||
var url = gHttpTestRoot + "test_mcb_redirect_image.html"
|
||||
var url = HTTP_TEST_ROOT + "test_mcb_redirect_image.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,7 @@ function test5() {
|
|||
gTestBrowser.addEventListener("load", checkLoadEventForTest5, true);
|
||||
// Go into offline mode
|
||||
Services.io.offline = true;
|
||||
var url = gHttpTestRoot + "test_mcb_redirect_image.html"
|
||||
var url = HTTP_TEST_ROOT + "test_mcb_redirect_image.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ function test6() {
|
|||
gTestBrowser.addEventListener("load", checkLoadEventForTest6, true);
|
||||
// Go into offline mode
|
||||
Services.io.offline = true;
|
||||
var url = gHttpsTestRoot + "test_mcb_redirect_image.html"
|
||||
var url = HTTPS_TEST_ROOT + "test_mcb_redirect_image.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ function checkLoadEventForTest6() {
|
|||
// HTTP page loading insecure image that went through a double redirect
|
||||
function test7() {
|
||||
gTestBrowser.addEventListener("load", checkLoadEventForTest7, true);
|
||||
var url = gHttpTestRoot + "test_mcb_double_redirect_image.html"
|
||||
var url = HTTP_TEST_ROOT + "test_mcb_double_redirect_image.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ function test8() {
|
|||
gTestBrowser.addEventListener("load", checkLoadEventForTest8, true);
|
||||
// Go into offline mode
|
||||
Services.io.offline = true;
|
||||
var url = gHttpTestRoot + "test_mcb_double_redirect_image.html"
|
||||
var url = HTTP_TEST_ROOT + "test_mcb_double_redirect_image.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ function test9() {
|
|||
gTestBrowser.addEventListener("load", checkLoadEventForTest9, true);
|
||||
// Go into offline mode
|
||||
Services.io.offline = true;
|
||||
var url = gHttpsTestRoot + "test_mcb_double_redirect_image.html"
|
||||
var url = HTTPS_TEST_ROOT + "test_mcb_double_redirect_image.html";
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
|
@ -303,7 +303,9 @@ function test() {
|
|||
Services.prefs.setBoolPref(PREF_ACTIVE, true);
|
||||
Services.prefs.setBoolPref(PREF_DISPLAY, true);
|
||||
|
||||
pushPrefs(["dom.ipc.processCount", 1]).then(() => {
|
||||
// TODO (Bug 1301015): This was forced into single process mode in
|
||||
// bug 1301340, need to find a real fix.
|
||||
SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount", 1]]}, () => {
|
||||
var newTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = newTab;
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
|
@ -10,9 +10,7 @@
|
|||
* the HTTP top level page to broken HTTPS.
|
||||
*/
|
||||
|
||||
const gHttpTestUrl = "http://example.com/browser/browser/base/content/test/general/file_mixedContentFramesOnHttp.html";
|
||||
|
||||
var gTestBrowser = null;
|
||||
const TEST_URL = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com") + "file_mixedContentFramesOnHttp.html";
|
||||
|
||||
add_task(function *() {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
|
@ -21,12 +19,9 @@ add_task(function *() {
|
|||
["security.mixed_content.block_display_content", false]
|
||||
]});
|
||||
|
||||
let url = gHttpTestUrl
|
||||
yield BrowserTestUtils.withNewTab({gBrowser, url}, function*() {
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
// check security state is insecure
|
||||
isSecurityState("insecure");
|
||||
assertMixedContentBlockingState(gTestBrowser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
|
||||
yield BrowserTestUtils.withNewTab(TEST_URL, function*(browser) {
|
||||
isSecurityState(browser, "insecure");
|
||||
assertMixedContentBlockingState(browser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Tests for Bug 947079 - Fix bug in nsSecureBrowserUIImpl that sets the wrong
|
||||
* security state on a page because of a subresource load that is not on the
|
||||
* same page.
|
||||
*/
|
||||
|
||||
// We use different domains for each test and for navigation within each test
|
||||
const HTTP_TEST_ROOT_1 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
|
||||
const HTTPS_TEST_ROOT_1 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://test1.example.com");
|
||||
const HTTP_TEST_ROOT_2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.net");
|
||||
const HTTPS_TEST_ROOT_2 = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://test2.example.com");
|
||||
|
||||
add_task(function *() {
|
||||
let url = HTTP_TEST_ROOT_1 + "file_mixedContentFromOnunload.html";
|
||||
yield BrowserTestUtils.withNewTab(url, function*(browser) {
|
||||
yield SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["security.mixed_content.block_active_content", true],
|
||||
["security.mixed_content.block_display_content", false]
|
||||
]
|
||||
});
|
||||
// Navigation from an http page to a https page with no mixed content
|
||||
// The http page loads an http image on unload
|
||||
url = HTTPS_TEST_ROOT_1 + "file_mixedContentFromOnunload_test1.html";
|
||||
yield BrowserTestUtils.loadURI(browser, url);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
// check security state. Since current url is https and doesn't have any
|
||||
// mixed content resources, we expect it to be secure.
|
||||
isSecurityState(browser, "secure");
|
||||
assertMixedContentBlockingState(browser, {activeLoaded: false, activeBlocked: false, passiveLoaded: false});
|
||||
// Navigation from an http page to a https page that has mixed display content
|
||||
// The https page loads an http image on unload
|
||||
url = HTTP_TEST_ROOT_2 + "file_mixedContentFromOnunload.html";
|
||||
yield BrowserTestUtils.loadURI(browser, url);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
url = HTTPS_TEST_ROOT_2 + "file_mixedContentFromOnunload_test2.html";
|
||||
yield BrowserTestUtils.loadURI(browser, url);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
isSecurityState(browser, "broken");
|
||||
assertMixedContentBlockingState(browser, {activeLoaded: false, activeBlocked: false, passiveLoaded: true});
|
||||
});
|
||||
});
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const MIXED_CONTENT_URL = "https://self-signed.example.com/browser/browser/base/content/test/general/test-mixedcontent-securityerrors.html";
|
||||
const MIXED_CONTENT_URL = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://self-signed.example.com") + "test-mixedcontent-securityerrors.html";
|
||||
|
||||
function getConnectionState() {
|
||||
return document.getElementById("identity-popup").getAttribute("connection");
|
|
@ -10,7 +10,7 @@
|
|||
// * We override protection so all mixed content can load and check the
|
||||
// flags again.
|
||||
|
||||
const TEST_URI = "https://example.com/browser/browser/base/content/test/general/test-mixedcontent-securityerrors.html";
|
||||
const TEST_URI = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com") + "test-mixedcontent-securityerrors.html";
|
||||
const PREF_DISPLAY = "security.mixed_content.block_display_content";
|
||||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
var gTestBrowser = null;
|
|
@ -26,7 +26,7 @@
|
|||
const PREF_ACTIVE = "security.mixed_content.block_active_content";
|
||||
const PREF_DISPLAY = "security.mixed_content.block_display_content";
|
||||
|
||||
const gHttpTestRoot = "http://example.com/browser/browser/base/content/test/general/";
|
||||
const HTTP_TEST_ROOT = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
|
||||
|
||||
var gTestBrowser = null;
|
||||
|
||||
|
@ -38,7 +38,7 @@ function cleanUpAfterTests() {
|
|||
add_task(function* init() {
|
||||
yield SpecialPowers.pushPrefEnv({ set: [[ PREF_ACTIVE, true ],
|
||||
[ PREF_DISPLAY, true ]] });
|
||||
let url = gHttpTestRoot + "test_no_mcb_on_http_site_img.html";
|
||||
let url = HTTP_TEST_ROOT + "test_no_mcb_on_http_site_img.html";
|
||||
let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, url)
|
||||
gTestBrowser = tab.linkedBrowser;
|
||||
});
|
||||
|
@ -59,7 +59,7 @@ add_task(function* test1() {
|
|||
ok(true, "test 1 passed");
|
||||
|
||||
// set up test 2
|
||||
let url = gHttpTestRoot + "test_no_mcb_on_http_site_font.html";
|
||||
let url = HTTP_TEST_ROOT + "test_no_mcb_on_http_site_font.html";
|
||||
BrowserTestUtils.loadURI(gTestBrowser, url);
|
||||
yield BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
});
|
||||
|
@ -79,7 +79,7 @@ add_task(function* test2() {
|
|||
ok(true, "test 2 passed");
|
||||
|
||||
// set up test 3
|
||||
let url = gHttpTestRoot + "test_no_mcb_on_http_site_font2.html";
|
||||
let url = HTTP_TEST_ROOT + "test_no_mcb_on_http_site_font2.html";
|
||||
BrowserTestUtils.loadURI(gTestBrowser, url);
|
||||
yield BrowserTestUtils.browserLoaded(gTestBrowser);
|
||||
});
|
|
@ -2,6 +2,6 @@
|
|||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<iframe src="http://test1.example.com/browser/browser/base/content/test/general/file_bug1045809_2.html"></iframe>
|
||||
<iframe src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug1045809_2.html"></iframe>
|
||||
</body>
|
||||
</html>
|
|
@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
|||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_1.js">
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
|||
<p id="p1"></p>
|
||||
<img src="http://example.com/tests/image/test/mochitest/blue.png" onload="foo()">
|
||||
</div>
|
||||
<script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_1.js">
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
|||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_4.js">
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_4.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1 +1 @@
|
|||
document.location = "https://example.com/browser/browser/base/content/test/general/file_bug822367_4B.html";
|
||||
document.location = "https://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_4B.html";
|
|
@ -12,7 +12,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
|||
<div id="testContent">
|
||||
<p id="p1"></p>
|
||||
</div>
|
||||
<script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_1.js">
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_1.js">
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -10,7 +10,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
|||
<script>
|
||||
function createDoc() {
|
||||
var doc = document.open("text/html", "replace");
|
||||
doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/browser/browser/base/content/test/general/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
|
||||
doc.write('<!DOCTYPE html><html><body><p id="p1">This is some content</p><script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_1.js">\<\/script\>\<\/body>\<\/html>');
|
||||
doc.close();
|
||||
}
|
||||
</script>
|
|
@ -10,7 +10,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=822367
|
|||
</head>
|
||||
<body>
|
||||
<div id="testContent">
|
||||
<iframe name="f1" id="f1" src="https://example.com/browser/browser/base/content/test/general/file_bug822367_5.html"></iframe>
|
||||
<iframe name="f1" id="f1" src="https://example.com/browser/browser/base/content/test/siteIdentity/file_bug822367_5.html"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -10,6 +10,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/general/file_bug902156.js" ></script>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug902156.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -10,8 +10,8 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<a href="https://test2.example.com/browser/browser/base/content/test/general/file_bug902156_1.html"
|
||||
<a href="https://test2.example.com/browser/browser/base/content/test/siteIdentity/file_bug902156_1.html"
|
||||
id="mctestlink" target="_top">Go to http site</a>
|
||||
<script src="http://test2.example.com/browser/browser/base/content/test/general/file_bug902156.js" ></script>
|
||||
<script src="http://test2.example.com/browser/browser/base/content/test/siteIdentity/file_bug902156.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -10,6 +10,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/general/file_bug902156.js" ></script>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug902156.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,6 +1,6 @@
|
|||
function handleRequest(request, response) {
|
||||
var page = "<!DOCTYPE html><html><body>bug 906190</body></html>";
|
||||
var path = "https://test1.example.com/browser/browser/base/content/test/general/";
|
||||
var path = "https://test1.example.com/browser/browser/base/content/test/siteIdentity/";
|
||||
var url;
|
||||
|
||||
if (request.queryString.includes('bad-redirection=1')) {
|
|
@ -10,6 +10,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/general/file_bug906190.js" ></script>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug906190.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -10,6 +10,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test2.example.com/browser/browser/base/content/test/general/file_bug906190.js" ></script>
|
||||
<script src="http://test2.example.com/browser/browser/base/content/test/siteIdentity/file_bug906190.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -6,7 +6,7 @@
|
|||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="refresh" content="0; url=https://test1.example.com/browser/browser/base/content/test/general/file_bug906190_redirected.html">
|
||||
<meta http-equiv="refresh" content="0; url=https://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug906190_redirected.html">
|
||||
<title>Test 3 and 4 for Bug 906190</title>
|
||||
</head>
|
||||
<body>
|
|
@ -10,6 +10,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">Mixed Content Blocker enabled</div>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/general/file_bug906190.js" ></script>
|
||||
<script src="http://test1.example.com/browser/browser/base/content/test/siteIdentity/file_bug906190.js" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bug 1122236 - CSP: Implement block-all-mixed-content</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
|
||||
</head>
|
||||
<body>
|
||||
<script src="http://example.com/browser/browser/base/content/test/siteIdentity/file_csp_block_all_mixedcontent.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -9,6 +9,6 @@ Test for https://bugzilla.mozilla.org/show_bug.cgi?id=1182551
|
|||
</head>
|
||||
<body>
|
||||
<p>Test for Bug 1182551. This is an HTTP top level page. We include an HTTPS iframe that loads mixed passive content.</p>
|
||||
<iframe src="https://example.org/browser/browser/base/content/test/general/file_mixedPassiveContent.html"></iframe>
|
||||
<iframe src="https://example.org/browser/browser/base/content/test/siteIdentity/file_mixedPassiveContent.html"></iframe>
|
||||
</body>
|
||||
</html>
|
|
@ -4,3 +4,337 @@ XPCOMUtils.defineLazyModuleGetter(this, "Promise",
|
|||
"resource://gre/modules/Promise.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Task",
|
||||
"resource://gre/modules/Task.jsm");
|
||||
|
||||
function is_hidden(element) {
|
||||
var style = element.ownerGlobal.getComputedStyle(element);
|
||||
if (style.display == "none")
|
||||
return true;
|
||||
if (style.visibility != "visible")
|
||||
return true;
|
||||
if (style.display == "-moz-popup")
|
||||
return ["hiding", "closed"].indexOf(element.state) != -1;
|
||||
|
||||
// Hiding a parent element will hide all its children
|
||||
if (element.parentNode != element.ownerDocument)
|
||||
return is_hidden(element.parentNode);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function is_visible(element) {
|
||||
var style = element.ownerGlobal.getComputedStyle(element);
|
||||
if (style.display == "none")
|
||||
return false;
|
||||
if (style.visibility != "visible")
|
||||
return false;
|
||||
if (style.display == "-moz-popup" && element.state != "open")
|
||||
return false;
|
||||
|
||||
// Hiding a parent element will hide all its children
|
||||
if (element.parentNode != element.ownerDocument)
|
||||
return is_visible(element.parentNode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Promise that resolves once a new tab has been opened in
|
||||
* a xul:tabbrowser.
|
||||
*
|
||||
* @param aTabBrowser
|
||||
* The xul:tabbrowser to monitor for a new tab.
|
||||
* @return {Promise}
|
||||
* Resolved when the new tab has been opened.
|
||||
* @resolves to the TabOpen event that was fired.
|
||||
* @rejects Never.
|
||||
*/
|
||||
function waitForNewTabEvent(aTabBrowser) {
|
||||
return BrowserTestUtils.waitForEvent(aTabBrowser.tabContainer, "TabOpen");
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for a load (or custom) event to finish in a given tab. If provided
|
||||
* load an uri into the tab.
|
||||
*
|
||||
* @param tab
|
||||
* The tab to load into.
|
||||
* @param [optional] url
|
||||
* The url to load, or the current url.
|
||||
* @return {Promise} resolved when the event is handled.
|
||||
* @resolves to the received event
|
||||
* @rejects if a valid load event is not received within a meaningful interval
|
||||
*/
|
||||
function promiseTabLoadEvent(tab, url) {
|
||||
info("Wait tab event: load");
|
||||
|
||||
function handle(loadedUrl) {
|
||||
if (loadedUrl === "about:blank" || (url && loadedUrl !== url)) {
|
||||
info(`Skipping spurious load event for ${loadedUrl}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
info("Tab event received: load");
|
||||
return true;
|
||||
}
|
||||
|
||||
let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, handle);
|
||||
|
||||
if (url)
|
||||
BrowserTestUtils.loadURI(tab.linkedBrowser, url);
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
// Compares the security state of the page with what is expected
|
||||
function isSecurityState(browser, expectedState) {
|
||||
let ui = browser.securityUI;
|
||||
if (!ui) {
|
||||
ok(false, "No security UI to get the security state");
|
||||
return;
|
||||
}
|
||||
|
||||
const wpl = Components.interfaces.nsIWebProgressListener;
|
||||
|
||||
// determine the security state
|
||||
let isSecure = ui.state & wpl.STATE_IS_SECURE;
|
||||
let isBroken = ui.state & wpl.STATE_IS_BROKEN;
|
||||
let isInsecure = ui.state & wpl.STATE_IS_INSECURE;
|
||||
|
||||
let actualState;
|
||||
if (isSecure && !(isBroken || isInsecure)) {
|
||||
actualState = "secure";
|
||||
} else if (isBroken && !(isSecure || isInsecure)) {
|
||||
actualState = "broken";
|
||||
} else if (isInsecure && !(isSecure || isBroken)) {
|
||||
actualState = "insecure";
|
||||
} else {
|
||||
actualState = "unknown";
|
||||
}
|
||||
|
||||
is(expectedState, actualState, "Expected state " + expectedState + " and the actual state is " + actualState + ".");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the state of the identity box and control center to make
|
||||
* sure they are correctly showing the expected mixed content states.
|
||||
*
|
||||
* @note The checks are done synchronously, but new code should wait on the
|
||||
* returned Promise object to ensure the identity panel has closed.
|
||||
* Bug 1221114 is filed to fix the existing code.
|
||||
*
|
||||
* @param tabbrowser
|
||||
* @param Object states
|
||||
* MUST include the following properties:
|
||||
* {
|
||||
* activeLoaded: true|false,
|
||||
* activeBlocked: true|false,
|
||||
* passiveLoaded: true|false,
|
||||
* }
|
||||
*
|
||||
* @return {Promise}
|
||||
* @resolves When the operation has finished and the identity panel has closed.
|
||||
*/
|
||||
function assertMixedContentBlockingState(tabbrowser, states = {}) {
|
||||
if (!tabbrowser || !("activeLoaded" in states) ||
|
||||
!("activeBlocked" in states) || !("passiveLoaded" in states)) {
|
||||
throw new Error("assertMixedContentBlockingState requires a browser and a states object");
|
||||
}
|
||||
|
||||
let {passiveLoaded, activeLoaded, activeBlocked} = states;
|
||||
let {gIdentityHandler} = tabbrowser.ownerGlobal;
|
||||
let doc = tabbrowser.ownerDocument;
|
||||
let identityBox = gIdentityHandler._identityBox;
|
||||
let classList = identityBox.classList;
|
||||
let connectionIcon = doc.getElementById("connection-icon");
|
||||
let connectionIconImage = tabbrowser.ownerGlobal.getComputedStyle(connectionIcon).
|
||||
getPropertyValue("list-style-image");
|
||||
|
||||
let stateSecure = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_SECURE;
|
||||
let stateBroken = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN;
|
||||
let stateInsecure = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_IS_INSECURE;
|
||||
let stateActiveBlocked = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT;
|
||||
let stateActiveLoaded = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT;
|
||||
let statePassiveLoaded = gIdentityHandler._state & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT;
|
||||
|
||||
is(activeBlocked, !!stateActiveBlocked, "Expected state for activeBlocked matches UI state");
|
||||
is(activeLoaded, !!stateActiveLoaded, "Expected state for activeLoaded matches UI state");
|
||||
is(passiveLoaded, !!statePassiveLoaded, "Expected state for passiveLoaded matches UI state");
|
||||
|
||||
if (stateInsecure) {
|
||||
// HTTP request, there should be no MCB classes for the identity box and the non secure icon
|
||||
// should always be visible regardless of MCB state.
|
||||
ok(classList.contains("unknownIdentity"), "unknownIdentity on HTTP page");
|
||||
ok(is_hidden(connectionIcon), "connection icon should be hidden");
|
||||
|
||||
ok(!classList.contains("mixedActiveContent"), "No MCB icon on HTTP page");
|
||||
ok(!classList.contains("mixedActiveBlocked"), "No MCB icon on HTTP page");
|
||||
ok(!classList.contains("mixedDisplayContent"), "No MCB icon on HTTP page");
|
||||
ok(!classList.contains("mixedDisplayContentLoadedActiveBlocked"), "No MCB icon on HTTP page");
|
||||
} else {
|
||||
// Make sure the identity box UI has the correct mixedcontent states and icons
|
||||
is(classList.contains("mixedActiveContent"), activeLoaded,
|
||||
"identityBox has expected class for activeLoaded");
|
||||
is(classList.contains("mixedActiveBlocked"), activeBlocked && !passiveLoaded,
|
||||
"identityBox has expected class for activeBlocked && !passiveLoaded");
|
||||
is(classList.contains("mixedDisplayContent"), passiveLoaded && !(activeLoaded || activeBlocked),
|
||||
"identityBox has expected class for passiveLoaded && !(activeLoaded || activeBlocked)");
|
||||
is(classList.contains("mixedDisplayContentLoadedActiveBlocked"), passiveLoaded && activeBlocked,
|
||||
"identityBox has expected class for passiveLoaded && activeBlocked");
|
||||
|
||||
ok(!is_hidden(connectionIcon), "connection icon should be visible");
|
||||
if (activeLoaded) {
|
||||
is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-active-loaded.svg#icon\")",
|
||||
"Using active loaded icon");
|
||||
}
|
||||
if (activeBlocked && !passiveLoaded) {
|
||||
is(connectionIconImage, "url(\"chrome://browser/skin/connection-secure.svg\")",
|
||||
"Using active blocked icon");
|
||||
}
|
||||
if (passiveLoaded && !(activeLoaded || activeBlocked)) {
|
||||
is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
|
||||
"Using passive loaded icon");
|
||||
}
|
||||
if (passiveLoaded && activeBlocked) {
|
||||
is(connectionIconImage, "url(\"chrome://browser/skin/connection-mixed-passive-loaded.svg#icon\")",
|
||||
"Using active blocked and passive loaded icon");
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the identity popup has the correct mixedcontent states
|
||||
gIdentityHandler._identityBox.click();
|
||||
let popupAttr = doc.getElementById("identity-popup").getAttribute("mixedcontent");
|
||||
let bodyAttr = doc.getElementById("identity-popup-securityView-body").getAttribute("mixedcontent");
|
||||
|
||||
is(popupAttr.includes("active-loaded"), activeLoaded,
|
||||
"identity-popup has expected attr for activeLoaded");
|
||||
is(bodyAttr.includes("active-loaded"), activeLoaded,
|
||||
"securityView-body has expected attr for activeLoaded");
|
||||
|
||||
is(popupAttr.includes("active-blocked"), activeBlocked,
|
||||
"identity-popup has expected attr for activeBlocked");
|
||||
is(bodyAttr.includes("active-blocked"), activeBlocked,
|
||||
"securityView-body has expected attr for activeBlocked");
|
||||
|
||||
is(popupAttr.includes("passive-loaded"), passiveLoaded,
|
||||
"identity-popup has expected attr for passiveLoaded");
|
||||
is(bodyAttr.includes("passive-loaded"), passiveLoaded,
|
||||
"securityView-body has expected attr for passiveLoaded");
|
||||
|
||||
// Make sure the correct icon is visible in the Control Center.
|
||||
// This logic is controlled with CSS, so this helps prevent regressions there.
|
||||
let securityView = doc.getElementById("identity-popup-securityView");
|
||||
let securityViewBG = tabbrowser.ownerGlobal.getComputedStyle(securityView).
|
||||
getPropertyValue("background-image");
|
||||
let securityContentBG = tabbrowser.ownerGlobal.getComputedStyle(securityView).
|
||||
getPropertyValue("background-image");
|
||||
|
||||
if (stateInsecure) {
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/conn-not-secure.svg\")",
|
||||
"CC using 'not secure' icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/conn-not-secure.svg\")",
|
||||
"CC using 'not secure' icon");
|
||||
}
|
||||
|
||||
if (stateSecure) {
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
|
||||
"CC using secure icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-secure\")",
|
||||
"CC using secure icon");
|
||||
}
|
||||
|
||||
if (stateBroken) {
|
||||
if (activeLoaded) {
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
|
||||
"CC using active loaded icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
|
||||
"CC using active loaded icon");
|
||||
} else if (activeBlocked || passiveLoaded) {
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
|
||||
"CC using degraded icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
|
||||
"CC using degraded icon");
|
||||
} else {
|
||||
// There is a case here with weak ciphers, but no bc tests are handling this yet.
|
||||
is(securityViewBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
|
||||
"CC using degraded icon");
|
||||
is(securityContentBG, "url(\"chrome://browser/skin/controlcenter/connection.svg#connection-degraded\")",
|
||||
"CC using degraded icon");
|
||||
}
|
||||
}
|
||||
|
||||
if (activeLoaded || activeBlocked || passiveLoaded) {
|
||||
doc.getElementById("identity-popup-security-expander").click();
|
||||
is(Array.filter(doc.querySelectorAll("[observes=identity-popup-mcb-learn-more]"),
|
||||
element => !is_hidden(element)).length, 1,
|
||||
"The 'Learn more' link should be visible once.");
|
||||
}
|
||||
|
||||
gIdentityHandler._identityPopup.hidden = true;
|
||||
|
||||
// Wait for the panel to be closed before continuing. The promisePopupHidden
|
||||
// function cannot be used because it's unreliable unless promisePopupShown is
|
||||
// also called before closing the panel. This cannot be done until all callers
|
||||
// are made asynchronous (bug 1221114).
|
||||
return new Promise(resolve => executeSoon(resolve));
|
||||
}
|
||||
|
||||
function* loadBadCertPage(url) {
|
||||
const EXCEPTION_DIALOG_URI = "chrome://pippki/content/exceptionDialog.xul";
|
||||
let exceptionDialogResolved = new Promise(function(resolve) {
|
||||
// When the certificate exception dialog has opened, click the button to add
|
||||
// an exception.
|
||||
let certExceptionDialogObserver = {
|
||||
observe(aSubject, aTopic, aData) {
|
||||
if (aTopic == "cert-exception-ui-ready") {
|
||||
Services.obs.removeObserver(this, "cert-exception-ui-ready");
|
||||
let certExceptionDialog = getCertExceptionDialog(EXCEPTION_DIALOG_URI);
|
||||
ok(certExceptionDialog, "found exception dialog");
|
||||
executeSoon(function() {
|
||||
certExceptionDialog.documentElement.getButton("extra1").click();
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Services.obs.addObserver(certExceptionDialogObserver,
|
||||
"cert-exception-ui-ready", false);
|
||||
});
|
||||
|
||||
let loaded = BrowserTestUtils.waitForErrorPage(gBrowser.selectedBrowser);
|
||||
yield BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
|
||||
yield loaded;
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
|
||||
content.document.getElementById("exceptionDialogButton").click();
|
||||
});
|
||||
yield exceptionDialogResolved;
|
||||
yield BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
|
||||
}
|
||||
|
||||
// Utility function to get a handle on the certificate exception dialog.
|
||||
// Modified from toolkit/components/passwordmgr/test/prompt_common.js
|
||||
function getCertExceptionDialog(aLocation) {
|
||||
let enumerator = Services.wm.getXULWindowEnumerator(null);
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let win = enumerator.getNext();
|
||||
let windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
|
||||
|
||||
let containedDocShells = windowDocShell.getDocShellEnumerator(
|
||||
Ci.nsIDocShellTreeItem.typeChrome,
|
||||
Ci.nsIDocShell.ENUMERATE_FORWARDS);
|
||||
while (containedDocShells.hasMoreElements()) {
|
||||
// Get the corresponding document for this docshell
|
||||
let childDocShell = containedDocShells.getNext();
|
||||
let childDoc = childDocShell.QueryInterface(Ci.nsIDocShell)
|
||||
.contentViewer
|
||||
.DOMDocument;
|
||||
|
||||
if (childDoc.location.href == aLocation) {
|
||||
return childDoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<img src="http://example.com/browser/browser/base/content/test/siteIdentity/moz.png">
|
|
@ -18,6 +18,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv"></div>
|
||||
<img src="https://example.com/browser/browser/base/content/test/general/test_mcb_redirect.sjs?image_redirect_http_sjs" onload="image_loaded()" onerror="image_blocked()" ></image>
|
||||
<img src="https://example.com/browser/browser/base/content/test/siteIdentity/test_mcb_redirect.sjs?image_redirect_http_sjs" onload="image_loaded()" onerror="image_blocked()" ></image>
|
||||
</body>
|
||||
</html>
|
|
@ -10,6 +10,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv">script blocked</div>
|
||||
<script src="https://example.com/browser/browser/base/content/test/general/test_mcb_redirect.sjs?script" ></script>
|
||||
<script src="https://example.com/browser/browser/base/content/test/siteIdentity/test_mcb_redirect.sjs?script" ></script>
|
||||
</body>
|
||||
</html>
|
|
@ -2,13 +2,13 @@ function handleRequest(request, response) {
|
|||
var page = "<!DOCTYPE html><html><body>bug 418354 and bug 1082837</body></html>";
|
||||
|
||||
if (request.queryString === "script") {
|
||||
var redirect = "http://example.com/browser/browser/base/content/test/general/test_mcb_redirect.js";
|
||||
var redirect = "http://example.com/browser/browser/base/content/test/siteIdentity/test_mcb_redirect.js";
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
} else if (request.queryString === "image_http") {
|
||||
var redirect = "http://example.com/tests/image/test/mochitest/blue.png";
|
||||
response.setHeader("Cache-Control", "max-age=3600", false);
|
||||
} else if (request.queryString === "image_redirect_http_sjs") {
|
||||
var redirect = "http://example.com/browser/browser/base/content/test/general/test_mcb_redirect.sjs?image_redirect_https";
|
||||
var redirect = "http://example.com/browser/browser/base/content/test/siteIdentity/test_mcb_redirect.sjs?image_redirect_https";
|
||||
response.setHeader("Cache-Control", "max-age=3600", false);
|
||||
} else if (request.queryString === "image_redirect_https") {
|
||||
var redirect = "https://example.com/tests/image/test/mochitest/blue.png";
|
|
@ -18,6 +18,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<div id="mctestdiv"></div>
|
||||
<img src="https://example.com/browser/browser/base/content/test/general/test_mcb_redirect.sjs?image_http" onload="image_loaded()" onerror="image_blocked()" ></image>
|
||||
<img src="https://example.com/browser/browser/base/content/test/siteIdentity/test_mcb_redirect.sjs?image_http" onload="image_loaded()" onerror="image_blocked()" ></image>
|
||||
</body>
|
||||
</html>
|
|
@ -7,7 +7,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 2 for Bug 909920</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/general/test_no_mcb_on_http_site_font.css" />
|
||||
<link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/siteIdentity/test_no_mcb_on_http_site_font.css" />
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
|
@ -1 +1 @@
|
|||
@import url(http://example.com/browser/browser/base/content/test/general/test_no_mcb_on_http_site_font.css);
|
||||
@import url(http://example.com/browser/browser/base/content/test/siteIdentity/test_no_mcb_on_http_site_font.css);
|
|
@ -7,7 +7,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 3 for Bug 909920</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/general/test_no_mcb_on_http_site_font2.css" />
|
||||
<link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/siteIdentity/test_no_mcb_on_http_site_font2.css" />
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
|
@ -7,7 +7,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test 1 for Bug 909920</title>
|
||||
<link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/general/test_no_mcb_on_http_site_img.css" />
|
||||
<link rel="stylesheet" type="text/css" href="https://example.com/browser/browser/base/content/test/siteIdentity/test_no_mcb_on_http_site_img.css" />
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
|
@ -2,6 +2,7 @@
|
|||
support-files =
|
||||
dummy_page.html
|
||||
|
||||
[browser_abandonment_telemetry.js]
|
||||
[browser_allow_process_switches_despite_related_browser.js]
|
||||
[browser_tabSpinnerProbe.js]
|
||||
skip-if = !e10s # Tab spinner is e10s only.
|
||||
|
|
|
@ -0,0 +1,305 @@
|
|||
"use strict";
|
||||
|
||||
const {TabStateFlusher} = Cu.import("resource:///modules/sessionstore/TabStateFlusher.jsm", {});
|
||||
|
||||
// Keep this in sync with the order in Histograms.json for
|
||||
// BUSY_TAB_ABANDONED
|
||||
const CATEGORIES = [
|
||||
"stop",
|
||||
"back",
|
||||
"forward",
|
||||
"historyNavigation",
|
||||
"reload",
|
||||
"tabClosed",
|
||||
"newURI",
|
||||
];
|
||||
|
||||
const PAGE_2 = "data:text/html,<html>Page 2</html>";
|
||||
|
||||
/**
|
||||
* This little framework helps to extract the unique things
|
||||
* involved in testing each category of the BUSY_TAB_ABANDONED
|
||||
* probe from all of the common things. The little framework
|
||||
* in this test will take each item in PROBE_TEST, let it
|
||||
* do some test preparation, then create a "busy" tab to be
|
||||
* manipulated by the test. The "category" of the test will then
|
||||
* be used to determine if the appropriate index in the
|
||||
* histogram was bumped.
|
||||
*
|
||||
* Here's a more verbose breakdown of what each PROBE_TEST
|
||||
* should supply:
|
||||
*
|
||||
* name (String):
|
||||
* Human readable description of the test. This is dumped
|
||||
* out via info().
|
||||
*
|
||||
* category (String):
|
||||
* The string representation of the index that will get
|
||||
* incremented in the BUSY_TAB_ABANDONED probe. This should
|
||||
* be a value inside CATEGORIES.
|
||||
*
|
||||
* prepare (function*)
|
||||
* A function that can yield Promises. This will be run once
|
||||
* we have a brand new browser to deal with, and should be used by
|
||||
* the PROBE_TEST to do any history preparation before the browser
|
||||
* is made to appear "busy" and is tested.
|
||||
*
|
||||
* @param browser (<xul:browser>)
|
||||
* The newly created browser that the test will use.
|
||||
*
|
||||
* doAction (function*)
|
||||
* A function that can yield Promises. This will be run once
|
||||
* the browser appears busy, and should cause the user action
|
||||
* that will change the BUSY_TAB_ABANDONED probe.
|
||||
*
|
||||
* @param browser (<xul:browser>)
|
||||
* The busy browser to perform the action on.
|
||||
*/
|
||||
const PROBE_TESTS = [
|
||||
|
||||
// Test stopping the tab
|
||||
{
|
||||
name: "Stopping the browser",
|
||||
|
||||
category: "stop",
|
||||
|
||||
* prepare(browser) {},
|
||||
|
||||
* doAction(browser) {
|
||||
document.getElementById("Browser:Stop").doCommand();
|
||||
},
|
||||
},
|
||||
|
||||
// Test going back to a previous page
|
||||
{
|
||||
name: "Going back to a previous page",
|
||||
|
||||
category: "back",
|
||||
|
||||
* prepare(browser) {
|
||||
browser.loadURI(PAGE_2);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
},
|
||||
|
||||
* doAction(browser) {
|
||||
let pageShow =
|
||||
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
||||
document.getElementById("Browser:Back").doCommand();
|
||||
yield pageShow;
|
||||
},
|
||||
},
|
||||
|
||||
// Test going forward to a previous page
|
||||
{
|
||||
name: "Going forward to the next page",
|
||||
|
||||
category: "forward",
|
||||
|
||||
* prepare(browser) {
|
||||
browser.loadURI(PAGE_2);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
let pageShow =
|
||||
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
||||
browser.goBack();
|
||||
yield pageShow;
|
||||
},
|
||||
|
||||
* doAction(browser) {
|
||||
let pageShow =
|
||||
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
||||
document.getElementById("Browser:Forward").doCommand();
|
||||
yield pageShow;
|
||||
},
|
||||
},
|
||||
|
||||
// Test going backwards more than one page back via gotoIndex
|
||||
{
|
||||
name: "Going backward to a previous page via gotoIndex",
|
||||
|
||||
category: "historyNavigation",
|
||||
|
||||
* prepare(browser) {
|
||||
browser.loadURI(PAGE_2);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
browser.loadURI("http://example.com");
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
yield TabStateFlusher.flush(browser);
|
||||
},
|
||||
|
||||
* doAction(browser) {
|
||||
let pageShow =
|
||||
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
||||
synthesizeHistoryNavigationToIndex(0);
|
||||
yield pageShow;
|
||||
},
|
||||
},
|
||||
|
||||
// Test going forwards more than one page back via gotoIndex
|
||||
{
|
||||
name: "Going forward to a previous page via gotoIndex",
|
||||
|
||||
category: "historyNavigation",
|
||||
|
||||
* prepare(browser) {
|
||||
browser.loadURI(PAGE_2);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
browser.loadURI("http://example.com");
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
let pageShow =
|
||||
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
||||
browser.gotoIndex(0);
|
||||
yield pageShow;
|
||||
yield TabStateFlusher.flush(browser);
|
||||
},
|
||||
|
||||
* doAction(browser) {
|
||||
let pageShow =
|
||||
BrowserTestUtils.waitForContentEvent(browser, "pageshow");
|
||||
synthesizeHistoryNavigationToIndex(2);
|
||||
yield pageShow;
|
||||
},
|
||||
},
|
||||
|
||||
// Test reloading the tab
|
||||
{
|
||||
name: "Reloading the browser",
|
||||
|
||||
category: "reload",
|
||||
|
||||
* prepare(browser) {},
|
||||
|
||||
* doAction(browser) {
|
||||
document.getElementById("Browser:Reload").doCommand();
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
},
|
||||
},
|
||||
|
||||
// Testing closing the tab is done in its own test later on
|
||||
// in this file.
|
||||
|
||||
// Test browsing to a new URL
|
||||
{
|
||||
name: "Browsing to a new URL",
|
||||
|
||||
category: "newURI",
|
||||
|
||||
* prepare(browser) {},
|
||||
|
||||
* doAction(browser) {
|
||||
openUILinkIn(PAGE_2, "current");
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
/**
|
||||
* Takes a Telemetry histogram snapshot and makes sure
|
||||
* that the index for that value (as defined by CATEGORIES)
|
||||
* has a count of 1, and that it's the only value that
|
||||
* has been incremented.
|
||||
*
|
||||
* @param snapshot (Object)
|
||||
* The Telemetry histogram snapshot to examine.
|
||||
* @param category (String)
|
||||
* The category in CATEGORIES whose index we expect to have
|
||||
* been set to 1.
|
||||
*/
|
||||
function assertOnlyOneTypeSet(snapshot, category) {
|
||||
let categoryIndex = CATEGORIES.indexOf(category);
|
||||
Assert.equal(snapshot.counts[categoryIndex], 1,
|
||||
`Should have seen the ${category} count increment.`);
|
||||
// Use Array.prototype.reduce to sum up all of the
|
||||
// snapshot.count entries
|
||||
Assert.equal(snapshot.counts.reduce((a, b) => a + b), 1,
|
||||
"Should only be 1 collected value.");
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper function for simulating clicking on the history
|
||||
* navigation popup menu that you get if you click and hold
|
||||
* on the back or forward buttons when you have some browsing
|
||||
* history.
|
||||
*
|
||||
* @param index (int)
|
||||
* The index for the menuitem we want to simulate
|
||||
* clicking on.
|
||||
*/
|
||||
function synthesizeHistoryNavigationToIndex(index) {
|
||||
let popup = document.getElementById("backForwardMenu");
|
||||
// I don't want to deal with popup listening - that's
|
||||
// notoriously flake-y in automated tests. I'll just
|
||||
// directly call the function that populates the menu.
|
||||
FillHistoryMenu(popup);
|
||||
Assert.ok(popup.childElementCount > 0,
|
||||
"Should have some items in the back/forward menu");
|
||||
let menuitem = popup.querySelector(`menuitem[index="${index}"]`);
|
||||
Assert.ok(menuitem, `Should find a menuitem with index ${index}`);
|
||||
// Now pretend we clicked on the right item.
|
||||
let cmdEvent = new CustomEvent("command", {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
menuitem.dispatchEvent(cmdEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Goes through each of the categories for the BUSY_TAB_ABANDONED
|
||||
* probe, and tests that they're properly changed.
|
||||
*/
|
||||
add_task(function* test_probes() {
|
||||
let oldCanRecord = Services.telemetry.canRecordExtended;
|
||||
Services.telemetry.canRecordExtended = true;
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.telemetry.canRecordExtended = oldCanRecord;
|
||||
});
|
||||
|
||||
let histogram = Services.telemetry
|
||||
.getHistogramById("BUSY_TAB_ABANDONED");
|
||||
|
||||
// If you want to add new tests for probes that don't involve
|
||||
// the tab or window hosting the tab closing, see the documentation
|
||||
// above PROBE_TESTS for how to hook into this little framework.
|
||||
for (let probeTest of PROBE_TESTS) {
|
||||
yield BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: "http://example.com",
|
||||
}, function*(browser) {
|
||||
let tab = gBrowser.getTabForBrowser(browser);
|
||||
info(`Test: "${probeTest.name}"`);
|
||||
|
||||
yield* probeTest.prepare(browser);
|
||||
// Instead of trying to fiddle with network state or
|
||||
// anything, we'll just set this attribute to fool our
|
||||
// telemetry probes into thinking the browser is in the
|
||||
// middle of loading some resources.
|
||||
tab.setAttribute("busy", true);
|
||||
|
||||
histogram.clear();
|
||||
yield* probeTest.doAction(browser);
|
||||
let snapshot = histogram.snapshot();
|
||||
assertOnlyOneTypeSet(snapshot, probeTest.category);
|
||||
});
|
||||
}
|
||||
|
||||
// The above tests used BrowserTestUtils.withNewTab, which is
|
||||
// fine for almost all categories for this probe, except for
|
||||
// "tabClosed", since withNewTab closes the tab automatically
|
||||
// before resolving, which doesn't work well for a tabClosed
|
||||
// test in the above framework. So the tabClosed tests are
|
||||
// done separately below.
|
||||
|
||||
histogram.clear();
|
||||
// Now test that we can close a busy tab and get the tabClosed
|
||||
// measurement bumped.
|
||||
let newTab = yield BrowserTestUtils.openNewForegroundTab(gBrowser);
|
||||
// As above, instead of trying to fiddle with network state
|
||||
// or anything, we'll just set this attribute to fool our
|
||||
// telemetry probes into thinking the browser is in the
|
||||
// middle of loading some resources.
|
||||
newTab.setAttribute("busy", true);
|
||||
|
||||
yield BrowserTestUtils.removeTab(newTab);
|
||||
let snapshot = histogram.snapshot();
|
||||
assertOnlyOneTypeSet(snapshot, "tabClosed");
|
||||
});
|
|
@ -6,7 +6,7 @@ addtags = Amestar etiquetes
|
|||
alreadyhaveacct = ¿Yá yes un usuariu de Pocket?
|
||||
continueff = Siguir con Firefox
|
||||
errorgeneric = Hebo un fallu tentando de guardar en Pocket.
|
||||
learnmore = Depriendi más
|
||||
learnmore = Deprendi más
|
||||
loginnow = Aniciar sesión
|
||||
maxtaglength = Les etiquetes lléndense a 25 caráuteres
|
||||
mustbeconnected = Has tar coneutáu a internet pa guardar en Pocket. Comprueba la to conexón y volvi tentalo, por favor.
|
||||
|
@ -24,7 +24,7 @@ signuptosave = Rexístrate en Pocket. Ye de baldre.
|
|||
suggestedtags = Etiquetes suxeríes
|
||||
tagline = Guardar artículos y vídeos dende Firefox pa ver en Pocket o en cualquier preséu, en cualquier momentu.
|
||||
taglinestory_one = Fai clic nel botón de Pocket pa guardar cualquier artículu, videu o páxina dende Firefox.
|
||||
taglinestory_two = Ver en Pocker o en cualquier preséu, en cualquier momentu.
|
||||
taglinestory_two = Ver en Pocket o en cualquier preséu, en cualquier momentu.
|
||||
tagssaved = Etiquetes amestaes
|
||||
tos = Sigiuiendo, tas acordies colos <a href="%1$S" target="_blank">Términos de Serviciu</a> y la <a href="%2$S" target="_blank">Política de privacidá</a> de Pocket
|
||||
tryitnow = Pruébalu agora
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = ট্যাগ যোগ করুন
|
||||
alreadyhaveacct = ইতিমধ্যে কি একজন Pocket ব্যবহারকারী?
|
||||
continueff = Firefox দিয়ে এগোন
|
||||
errorgeneric = Pocket-এ সংরক্ষণ করার সময় ত্রুটি হয়েছিল।
|
||||
learnmore = আরও জানুন
|
||||
loginnow = লগ ইন করুন
|
||||
maxtaglength = ট্যাগগুলি 25 টি অক্ষরে সীমাবদ্ধ
|
||||
mustbeconnected = আপনি Pocket এ সংরক্ষণ করার জন্য ইন্টারনেটের সাথে সংযুক্ত করা আবশ্যক। আপনার সংযোগ পরীক্ষা করুন এবং আবার চেষ্টা করুন।
|
||||
onlylinkssaved = শুধু লিঙ্ক সংরক্ষণ করা যাবে
|
||||
pagenotsaved = পেজ সংরক্ষিত হয়নি
|
||||
pageremoved = পেজ অপসারিত
|
||||
pagesaved = Pocket এ সংরক্ষিত
|
||||
processingremove = পেজ মুছে ফেলা হচ্ছে…
|
||||
processingtags = ট্যাগ যোগ করা হচ্ছে…
|
||||
removepage = Page অপসারণ করুন
|
||||
save = সংরক্ষণ করুন
|
||||
saving = সংরক্ষণ করা হচ্ছে…
|
||||
signupemail = ই-মেইল দিয়ে সাইন-ইন করুন
|
||||
signuptosave = Pocket এর জন্য সাইন আপ করুন। এটা বিনামূল্যে।
|
||||
suggestedtags = প্রস্তাবিত ট্যাগসমুহ
|
||||
tagline = কোনো ডিভাইসে যে কোনো সময় Firefox থেকে Pocket এর মধ্যে দেখতে নিবন্ধ এবং ভিডিও সংরক্ষণ করুন।
|
||||
taglinestory_one = Firefox থেকে একটি নিবন্ধ, ভিডিও বা পেজ সংরক্ষণ করতে পকেট বাটন ক্লিক করুন।
|
||||
taglinestory_two = কোনো ডিভাইসে, যে কোনো সময় Pocket এর মধ্যে দেখুন।
|
||||
tagssaved = ট্যাগগুলি যোগ করা হয়েছে
|
||||
tos = এগিয়ে, আপনি Pocket এর <a href="%1$S" target="_blank">পরিসেবার নিয়মাবলী</a> এবং <a href="%2$S" target="_blank">গোপনীয়তা সংক্রান্ত নীতি</a> মানলেন
|
||||
tryitnow = এটা এখনি চেষ্টা করুন
|
||||
signinfirefox = Firefox দিয়ে সাইন ইন করুন
|
||||
signupfirefox = Firefox দিয়ে সাইন আপ করুন
|
||||
viewlist = তালিকা দেখুন
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = Pocket এ সংরক্ষণ করুন
|
||||
saveToPocketCmd.label = Pocket এ পেজ সংরক্ষণ করুন
|
||||
saveToPocketCmd.accesskey = k
|
||||
saveLinkToPocketCmd.label = Pocket এ লিঙ্ক সংরক্ষণ করুন
|
||||
saveLinkToPocketCmd.accesskey = o
|
||||
pocketMenuitem.label = Pocket এর তালিকা দেখুন
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = Προσθήκη ετικετών
|
||||
alreadyhaveacct = Είστε ήδη χρήστης του Pocket;
|
||||
continueff = Συνέχεια με το Firefox
|
||||
errorgeneric = Προέκυψε σφάλμα κατά την προσπάθεια αποθήκευσης στο Pocket.
|
||||
learnmore = Μάθετε περισσότερα
|
||||
loginnow = Σύνδεση
|
||||
maxtaglength = Οι ετικέτες έχουν όριο 25 χαρακτήρες
|
||||
mustbeconnected = Πρέπει να είστε συνδεδεμένοι στο διαδίκτυο προκειμένου να αποθηκεύσετε στο Pocket. Παρακαλώ ελέγξτε τη σύνδεσή σας και δοκιμάστε ξανά.
|
||||
onlylinkssaved = Μόνο οι σύνδεσμοι μπορούν να αποθηκευτούν
|
||||
pagenotsaved = Η σελίδα δεν αποθηκεύτηκε
|
||||
pageremoved = Η σελίδα αφαιρέθηκε
|
||||
pagesaved = Αποθηκεύτηκε στο Pocket
|
||||
processingremove = Αφαίρεση σελίδας…
|
||||
processingtags = Προσθήκη ετικετών…
|
||||
removepage = Αφαίρεση σελίδας
|
||||
save = Αποθήκευση
|
||||
saving = Αποθήκευση…
|
||||
signupemail = Εγγραφή με email
|
||||
signuptosave = Εγγραφείτε στο Pocket. Δωρεάν.
|
||||
suggestedtags = Προτεινόμενες ετικέτες
|
||||
tagline = Αποθηκεύστε άρθρα και βίντεο από το Firefox για προβολή στο Pocket από οποιαδήποτε συσκευή, ανά πάσα στιγμή.
|
||||
taglinestory_one = Κάντε κλικ στο κουμπί του Pocket για να αποθηκεύσετε οποιοδήποτε άρθρο, βίντεο ή σελίδα από το Firefox.
|
||||
taglinestory_two = Προβολή στο Pocket σε οποιαδήποτε συσκευή, ανά πάσα στιγμή.
|
||||
tagssaved = Προστέθηκαν ετικέτες
|
||||
tos = Συνεχίζοντας, συμφωνείτε με τους <a href="%1$S" target="_blank">όρους υπηρεσίας</a> και την <a href="%2$S" target="_blank">πολιτική απορρήτου</a> του Pocket
|
||||
tryitnow = Δοκιμάστε το τώρα
|
||||
signinfirefox = Σύνδεση με Λογαριασμό Firefox
|
||||
signupfirefox = Εγγραφή με Λογαριασμό Firefox
|
||||
viewlist = Προβολή λίστας
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = Αποθήκευση στο Pocket
|
||||
saveToPocketCmd.label = Αποθήκευση της σελίδας στο Pocket
|
||||
saveToPocketCmd.accesskey = k
|
||||
saveLinkToPocketCmd.label = Αποθήκευση συνδέσμου στο Pocket
|
||||
saveLinkToPocketCmd.accesskey = o
|
||||
pocketMenuitem.label = Προβολή λίστας Pocket
|
|
@ -26,7 +26,7 @@ tagline = Save articles and videos from Firefox to view in Pocket on any device,
|
|||
taglinestory_one = Click the Pocket Button to save any article, video or page from Firefox.
|
||||
taglinestory_two = View in Pocket on any device, any time.
|
||||
tagssaved = Tags Added
|
||||
tos = By continuing, you agree to Pocket's <a href="%1$S" target="_blank">Terms of Service</a> and <a href="%2$S" target="_blank">Privacy Policy</a>
|
||||
tos = By continuing, you agree to Pocket’s <a href="%1$S" target="_blank">Terms of Service</a> and <a href="%2$S" target="_blank">Privacy Policy</a>
|
||||
tryitnow = Try It Now
|
||||
signinfirefox = Sign in with Firefox
|
||||
signupfirefox = Sign up with Firefox
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = Aldoni langetojn
|
||||
alreadyhaveacct = Ĉu vi jam estas uzanto de Pocket?
|
||||
continueff = Daŭrigi per Firefox
|
||||
errorgeneric = Okazis eraro dum la klopodo konservi en Pocket.
|
||||
learnmore = Pli da informo
|
||||
loginnow = Komenci seancon
|
||||
maxtaglength = Etikedoj povas enhavi ĝis 25 signojn
|
||||
mustbeconnected = Vi devas esti konektita al la interreto por povi konservi en Pocket. Bonvolu kontroli vian retaliron kaj provi denove.
|
||||
onlylinkssaved = Nur ligiloj povas esti konservitaj
|
||||
pagenotsaved = Paĝo ne konservita
|
||||
pageremoved = Paĝo forigita
|
||||
pagesaved = Konservita en Pocket
|
||||
processingremove = Paĝo forigata…
|
||||
processingtags = Etikedoj aldonataj…
|
||||
removepage = Forigi paĝon
|
||||
save = Konservi
|
||||
saving = Konservo…
|
||||
signupemail = Enskribiĝi per retpoŝto
|
||||
signuptosave = Enskribiĝi al Pocket. Estas senpage.
|
||||
suggestedtags = Sugestitaj etikedoj
|
||||
tagline = Konservi artikolojn kaj filmetojn el Firefox por povi vidi en Pocket en iu ajn aparato, iam ajn.
|
||||
taglinestory_one = Alklaku la butonon Pocket por konservi iun ajn artikolon, filmeton aŭ paĝon el Firefox.
|
||||
taglinestory_two = Vidi Pocket en iu ajn aparato, iam ajn.
|
||||
tagssaved = Etikedoj aldonitaj
|
||||
tos = Se vi daŭrigas, vi akceptas la <a href="%1$S" target="_blank">kondiĉojn de la servo</a> Pocket kaj ĝian <a href="%2$S" target="_blank">politikon pri privateco</a>
|
||||
tryitnow = Provi ĝin nun
|
||||
signinfirefox = Komenci seancon per Firefox
|
||||
signupfirefox = Enskribiĝi per Firefox
|
||||
viewlist = Vidi liston
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = Konservi en Pocket
|
||||
saveToPocketCmd.label = Konservi paĝon en Pocket
|
||||
saveToPocketCmd.accesskey = k
|
||||
saveLinkToPocketCmd.label = Konservi ligilon en Pocket
|
||||
saveLinkToPocketCmd.accesskey = o
|
||||
pocketMenuitem.label = Vidi liston de Pocket
|
|
@ -24,7 +24,7 @@ signuptosave = Regístrate en Pocket. Es gratis.
|
|||
suggestedtags = Etiquetas sugeridas
|
||||
tagline = Guardar artículos y videos desde Firefox para ver en Pocket o en cualquier dispositivo, en cualquier momento.
|
||||
taglinestory_one = Haz clic en el botón de Pocket para guardar cualquier artículo, video o página desde Firefox.
|
||||
taglinestory_two = Ver en Pocker o en cualquier dispositivo, en cualquier momento.
|
||||
taglinestory_two = Ver en Pocket o en cualquier dispositivo, en cualquier momento.
|
||||
tagssaved = Etiquetas agregadas
|
||||
tos = Al continuar, aceptas los <a href="%1$S" target="_blank">Términos del servicio</a> y la <a href="%2$S" target="_blank">Política de privacidad</a> de Pocket
|
||||
tryitnow = Pruébalo ahora
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = افزودن برچسب
|
||||
alreadyhaveacct = از قبل کاربر Pocket هستید؟
|
||||
continueff = ادامه در فایرفاکس
|
||||
errorgeneric = خطایی در هنگام تلاش برای ذخیرهسازی در Pocket رخ داده است.
|
||||
learnmore = بیشتر بدانید
|
||||
loginnow = ورود به سیستم
|
||||
maxtaglength = برچسبها شامل محدودیت ۲۵ حرفی میباشند
|
||||
mustbeconnected = جهت ذخیرهسازی در Pocket بایستی به اینترنت متصل باشید. لطفا اتصال اینترنت خود را بررسی کنید و مجددا تلاش کنید.
|
||||
onlylinkssaved = تنها لینکها می توانند ذخیره شوند
|
||||
pagenotsaved = صفحه ذخیره نشد
|
||||
pageremoved = صفحه حذف شد
|
||||
pagesaved = در Pocket ذخیره شده
|
||||
processingremove = در حال حذف صفحه…
|
||||
processingtags = در حال اضافه کردن برچسبها…
|
||||
removepage = حذف صفحه
|
||||
save = ذخیره
|
||||
saving = در حال ذخیره…
|
||||
signupemail = ثبتنام با ایمیل
|
||||
signuptosave = در Pocket ثبتنام کنید. رایگان است.
|
||||
suggestedtags = برچسبهای پیشنهادی
|
||||
tagline = مقالهها و ویدئوها را با فایرفاکس ذخیره کنید و در هر زمان و دستگاهی به وسیلهی Pocket ببینید.
|
||||
taglinestory_one = بر روی دکمه Pocket کلیک کنید تا مقاله، ویدئو یا صفحات را از طریق فایرفاکس ذخیره کنید.
|
||||
taglinestory_two = نمایش در Pocket در هر دستگاه و در هر زمانی.
|
||||
tagssaved = برچسبها اضافه شد
|
||||
tos = با ادامه دادن، شما با <a href="%1$S" target="_blank">قوانین سرویس</a> و <a href="%2$S" target="_blank">سیاست حفظ حریمخصوصی</a> Pocket موافقت میکنید.
|
||||
tryitnow = حالا امتحان کنید
|
||||
signinfirefox = ورود از طریق فایرفاکس
|
||||
signupfirefox = ثبت نام توسط فایرفاکس
|
||||
viewlist = \u0020نمایش فهرست
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = ذخیرهسازی در Pocket
|
||||
saveToPocketCmd.label = ذخیرهٔ صفحه در Pocket
|
||||
saveToPocketCmd.accesskey = k
|
||||
saveLinkToPocketCmd.label = ذخیرهٔ پیوند در Pocket
|
||||
saveLinkToPocketCmd.accesskey = o
|
||||
pocketMenuitem.label = نمایش فهرست Pocket
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = Ɓeydu Tage
|
||||
alreadyhaveacct = Aɗa huutoroo Pocket kisa?
|
||||
continueff = Jokku to Firefox
|
||||
errorgeneric = Waɗii juumre tuma etagol danndude to Pocket.
|
||||
learnmore = Ɓeydi Humpito
|
||||
loginnow = Seŋo
|
||||
maxtaglength = Tage mbaawa ɓurde alkule 25
|
||||
mustbeconnected = Alaa e sago ceŋo-ɗaa e Enternet ngam danndude to Pocket. Tiiɗno ƴeewto ceŋol maa kisa eto-ɗaa kadi.
|
||||
onlylinkssaved = Ko jokke tan mbaawi danndeede
|
||||
pagenotsaved = Hello Danndaaka
|
||||
pageremoved = Hello Momtaama
|
||||
pagesaved = Danndaama to Pocket
|
||||
processingremove = Nana Momta Hello…
|
||||
processingtags = Nana ɓeyda tage…
|
||||
removepage = Momtu Hello
|
||||
save = Danndu
|
||||
saving = Nana dannda…
|
||||
signupemail = Winnditoro iimeel
|
||||
signuptosave = Winndito e Pocket. Yoɓetaake.
|
||||
suggestedtags = Tage Basiyaaɗe
|
||||
tagline = Danndu binndanɗe e widewooji Firedox ngam yiyde e Pockete kaɓirgol kala, sahaa kala.
|
||||
taglinestory_one = Dobo e Butoŋ Pocket oo ngam danndude winndannde, widewoo wala hello iwde e Firefox.
|
||||
taglinestory_two = Yiy e Pocket e kaɓirgol kala, sahaa kala.
|
||||
tagssaved = Tage Ɓeydaama
|
||||
tos = Ɓennude ɗoo firti ko e jaɓii <a href="%1$S" target="_blank">Sarɗiiji Carwe</a> e <a href="%2$S" target="_blank">Dawirgol Suturo</a> Pocket
|
||||
tryitnow = Ƴeewndo ɗum Jooni
|
||||
signinfirefox = Seŋoro Firefox
|
||||
signupfirefox = Winnditoro Firefox
|
||||
viewlist = Yiy Doggol
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = Danndu to Pocket
|
||||
saveToPocketCmd.label = Danndu Hello to Pocket
|
||||
saveToPocketCmd.accesskey = k
|
||||
saveLinkToPocketCmd.label = Danndu Jokkol to Pocket
|
||||
saveLinkToPocketCmd.accesskey = o
|
||||
pocketMenuitem.label = Yiy Doggol Pocket
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = Cuir tagaichean ris
|
||||
alreadyhaveacct = A bheil thu a’ cleachdadh Pocket mu thràth?
|
||||
continueff = Lean ort ann am Firefox
|
||||
errorgeneric = Thachair mearachd nuair a dh’fheuch sinn ri rud a shàbhaladh ann am Pocket.
|
||||
learnmore = Barrachd fiosrachaidh
|
||||
loginnow = Clàraich a-steach
|
||||
maxtaglength = Chan fhaod taga a bhith nas fhaide na 25 caractar
|
||||
mustbeconnected = Feumaidh ceangal ris an eadar-lìon a bhith agad mus urrainn dhut rud a shàbhaladh ann am Pocket. Thoir sùil air a’ cheangal agad is feuch ris a-rithist.
|
||||
onlylinkssaved = Cha ghabh ach ceanglaichean a shàbhaladh
|
||||
pagenotsaved = Cha deach an duilleag a shàbhaladh
|
||||
pageremoved = Chaidh an duilleag a thoirt air falbh
|
||||
pagesaved = Air a shàbhaladh ann am Pocket
|
||||
processingremove = A’ toirt air falbh na duilleige…
|
||||
processingtags = A’ cur ris nan tagaichean…
|
||||
removepage = Thoir an duilleag air falbh
|
||||
save = Sàbhail
|
||||
saving = ’Ga shàbhaladh…
|
||||
signupemail = Clàraich slighe puist-d
|
||||
signuptosave = Cha chosg clàradh aig Pocket sgillinn.
|
||||
suggestedtags = Tagaichean a mholar
|
||||
tagline = Sàbhail artaigilean is videothan o Firefox ann am Pocket agus coimhead orra air uidheam sam bith, uair sam bith.
|
||||
taglinestory_one = Briog air a’ phutan Pocket gus artaigeal, video no duilleag a shàbhaladh o Firefox.
|
||||
taglinestory_two = Seall ann am Pocket air uidheam sam bith, uair sam bith.
|
||||
tagssaved = Tagaichean air an cur ris
|
||||
tos = Ma leanas tu air adhart, bidh thu ag aontachadh ri <a href="%1$S" target="_blank">teirmichean a’ chleachdaidh</a> agus <a href="%2$S" target="_blank">am poileasaidh prìobhaideachd</a> aig Pocket
|
||||
tryitnow = Feuch e an-dràsta
|
||||
signinfirefox = Clàraich a-steach le Firefox
|
||||
signupfirefox = Clàraich le Firefox
|
||||
viewlist = Seall an liosta
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = Sàbhail ann am Pocket
|
||||
saveToPocketCmd.label = Sàbhail an duilleag ann am Pocket
|
||||
saveToPocketCmd.accesskey = k
|
||||
saveLinkToPocketCmd.label = Sàbhail an ceangail ann am Pocket
|
||||
saveLinkToPocketCmd.accesskey = o
|
||||
pocketMenuitem.label = Seall liosta Pocket
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = הוספת תגיות
|
||||
alreadyhaveacct = כבר התחלת להשתמש ב־Pocket?
|
||||
continueff = להמשיך עם Firefox
|
||||
errorgeneric = אירעה שגיאה בעת ניסיון לשמור ל־Pocket.
|
||||
learnmore = מידע נוסף
|
||||
loginnow = כניסה
|
||||
maxtaglength = התגיות מוגבלות ל־25 תווים
|
||||
mustbeconnected = יש להתחבר לאינטרנט כדי לשמור ל־Pocket. נא לבדוק את החיבור שלך ולנסות שוב.
|
||||
onlylinkssaved = ניתן לשמור קישורים בלבד
|
||||
pagenotsaved = העמוד לא נשמר
|
||||
pageremoved = העמוד הוסר
|
||||
pagesaved = נשמר ל־Pocket
|
||||
processingremove = העמוד מוסר…
|
||||
processingtags = התגיות נוספות…
|
||||
removepage = הסרת עמוד
|
||||
save = שמירה
|
||||
saving = שמירה…
|
||||
signupemail = הרשמה עם דוא״ל
|
||||
signuptosave = להירשם ל־Pocket. זה חינם.
|
||||
suggestedtags = תגיות מוצעות
|
||||
tagline = לשמור מאמרים וסרטונים מ־Firefox כדי להציג ב־Pocket בכל מכשיר, בכל זמן.
|
||||
taglinestory_one = כדי לשמור כל מאמר, סרטון או דף מ־Firefox יש ללחוץ על כפתור ה־Pocket.
|
||||
taglinestory_two = להציג ב־Pocket בכל מכשיר, בכל זמן.
|
||||
tagssaved = נוספו תגיות
|
||||
tos = השימוש ברכיב זה מהווה אישור ל<a href="%1$S" target="_blank">תנאי השימוש</a> ב־Pocket ו<a href="%2$S" target="_blank">מדיניות הפרטיות</a>
|
||||
tryitnow = נסו את זה כעת
|
||||
signinfirefox = כניסה עם Firefox
|
||||
signupfirefox = רישום עם Firefox
|
||||
viewlist = הצגת הרשימה
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = שמירה אל Pocket
|
||||
saveToPocketCmd.label = שמירת דף אל Pocket
|
||||
saveToPocketCmd.accesskey = ד
|
||||
saveLinkToPocketCmd.label = שמירת קישור ב־Pocket
|
||||
saveLinkToPocketCmd.accesskey = ק
|
||||
pocketMenuitem.label = הצגת רשימת Pocket
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = टैग जोड़ें
|
||||
alreadyhaveacct = पहले से Pocket के उपयोगकर्ता हैं?
|
||||
continueff = Firefox के साथ जारी रखें
|
||||
errorgeneric = पॉकेट में सहेजने की कोशिश करते समय त्रुटि हुई थी.
|
||||
learnmore = और जानें
|
||||
loginnow = लॉग इन
|
||||
maxtaglength = टैग 25 वर्णों तक सीमीत है
|
||||
mustbeconnected = Pocket में सहेजने के लिए आप इन्टरनेट से जुडें होना आवश्यक हैं. कृपया अपना कनेक्शन जॉंचे और फिरसे कोशिश करें.
|
||||
onlylinkssaved = सिर्फ लिंक सहेजा जा सकता हैं
|
||||
pagenotsaved = पेज सहेजा नही गया
|
||||
pageremoved = पृष्ठ हटाया गया
|
||||
pagesaved = Pocket में सहेजा
|
||||
processingremove = पृष्ठ मिटा रहा है…
|
||||
processingtags = टैग्स जोड़ रहे हैं...
|
||||
removepage = पृष्ठ हटाएं
|
||||
save = सहेजें
|
||||
saving = सहेजा जा रहा है ...
|
||||
signupemail = ईमेल के साथ साइन अप करें
|
||||
signuptosave = पॉकेट के लिए साइन अप करें। यह मुफ़्त है।\u0020
|
||||
suggestedtags = सुझाये हुए टैग्स.
|
||||
tagline = किसी भी समय, Pocket में कोई भी डिवाइस पर देखने के लिए Firefox से आलेख और वीडियो सहेजें.
|
||||
taglinestory_one = Firefox से कोई भी आलेख, वीडियो या पृष्ठ को सहेजने के लिए Pocket बटन को क्लिक करे.
|
||||
taglinestory_two = किसी भी समय, पॉकेट में कोई भी डिवाइस पर देखे.
|
||||
tagssaved = टैग जोड़ा गया
|
||||
tos = जारी रखने के द्वारा, आप Pocket के <a href="%1$S" target="_blank">सेवा की शर्तों</a> और <a href="%2$S" target="_blank">गोपनीयता नीति</a> पर सहमति प्रदान करते हैं
|
||||
tryitnow = अभी आज़माएँ
|
||||
signinfirefox = Firefox के साथ साइन इन करें
|
||||
signupfirefox = Firefox के साथ साइन अप करें
|
||||
viewlist = सूची देखें
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = Pocket में सहेजा
|
||||
saveToPocketCmd.label = Pocket में पृष्ठ को सहेजे
|
||||
saveToPocketCmd.accesskey = k
|
||||
saveLinkToPocketCmd.label = Pocket में लिंक को सहेजे
|
||||
saveLinkToPocketCmd.accesskey = o
|
||||
pocketMenuitem.label = Pocket सूची देखे
|
|
@ -3,7 +3,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
addtags = タグを追加
|
||||
alreadyhaveacct = Pocket に登録済みですか?
|
||||
alreadyhaveacct = Pocket にユーザー登録済みですか?
|
||||
continueff = Firefox で続行
|
||||
errorgeneric = Pocket への保存中にエラーがありました。
|
||||
learnmore = 詳細
|
||||
|
@ -20,7 +20,7 @@ removepage = ページを削除
|
|||
save = 保存
|
||||
saving = 保存しています...
|
||||
signupemail = メールアドレスで新規登録
|
||||
signuptosave = Pocket に新規登録します。無料です。
|
||||
signuptosave = Pocket にユーザー登録しましょう。無料です。
|
||||
suggestedtags = 提案タグ
|
||||
tagline = Firefox で記事や動画を保存すると、いつでもどこでも Pocket で閲覧できます。
|
||||
taglinestory_one = Firefox で Pocket ボタンをクリックすると、様々な記事や動画やページを保存できます。
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
# These are used for the big if statement, as the preprocessor can't handle
|
||||
# dashes.
|
||||
#define bn_BD bn-BD
|
||||
#define bn_IN bn-IN
|
||||
#define en_GB en-GB
|
||||
#define en_US en-US
|
||||
#define es_AR es-AR
|
||||
|
@ -14,6 +15,7 @@
|
|||
#define es_MX es-MX
|
||||
#define fy_NL fy-NL
|
||||
#define gu_IN gu-IN
|
||||
#define hi_IN hi-IN
|
||||
#define nn_NO nn-NO
|
||||
#define pt_BR pt-BR
|
||||
#define pt_PT pt-PT
|
||||
|
@ -26,7 +28,7 @@
|
|||
# For locales we support, include the file from the locale's directory in the
|
||||
# source tree.
|
||||
# For other locales (and en-US) fallback to the en-US directory.
|
||||
#if AB_CD == ast || AB_CD == az || AB_CD == bg || AB_CD == bn_BD || AB_CD == cs || AB_CD == da || AB_CD == de || AB_CD == dsb || AB_CD == en_GB || AB_CD == en_US || AB_CD == es_AR || AB_CD == es_CL || AB_CD == es_ES || AB_CD == es_MX || AB_CD == et || AB_CD == fi || AB_CD == fr || AB_CD == fy_NL || AB_CD == gu_IN || AB_CD == hr || AB_CD == hsb || AB_CD == hu || AB_CD == it || AB_CD == ja || AB_CD == ka || AB_CD == kab || AB_CD == lt || AB_CD == lv || AB_CD == mr || AB_CD == ms || AB_CD == nl || AB_CD == nn_NO || AB_CD == or || AB_CD == pl || AB_CD == pt_BR || AB_CD == pt_PT || AB_CD == rm || AB_CD == ro || AB_CD == ru || AB_CD == sk || AB_CD == sl || AB_CD == sq || AB_CD == sr || AB_CD == sv_SE || AB_CD == te || AB_CD == th || AB_CD == tr || AB_CD == uk || AB_CD == zh_CN || AB_CD == zh_TW
|
||||
#if AB_CD == ast || AB_CD == az || AB_CD == bg || AB_CD == bn_BD || AB_CD == bn_IN || AB_CD == cs || AB_CD == da || AB_CD == de || AB_CD == dsb || AB_CD == en_GB || AB_CD == en_US || AB_CD == es_AR || AB_CD == es_CL || AB_CD == es_ES || AB_CD == es_MX || AB_CD == el || AB_CD == eo || AB_CD == et || AB_CD == fa || AB_CD == fi || AB_CD == ff || AB_CD == fr || AB_CD == fy_NL || AB_CD == gd || AB_CD == gu_IN || AB_CD == he || AB_CD == hi_IN || AB_CD == hr || AB_CD == hsb || AB_CD == hu || AB_CD == it || AB_CD == ja || AB_CD == ka || AB_CD == kab || AB_CD == ko || AB_CD == lt || AB_CD == lv || AB_CD == mr || AB_CD == ms || AB_CD == nl || AB_CD == nn_NO || AB_CD == or || AB_CD == pl || AB_CD == pt_BR || AB_CD == pt_PT || AB_CD == rm || AB_CD == ro || AB_CD == ru || AB_CD == sk || AB_CD == sl || AB_CD == sq || AB_CD == sr || AB_CD == sv_SE || AB_CD == te || AB_CD == th || AB_CD == tr || AB_CD == uk || AB_CD == zh_CN || AB_CD == zh_TW
|
||||
locale/@AB_CD@/ (@AB_CD@/*)
|
||||
#else
|
||||
locale/@AB_CD@/ (en-US/*)
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# 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/.
|
||||
|
||||
addtags = 태그 추가
|
||||
alreadyhaveacct = 이미 Pocket을 쓰고 있습니까?
|
||||
continueff = Firefox로 계속하기
|
||||
errorgeneric = Pocket에 저장하다 잘못되었습니다.
|
||||
learnmore = 더 알아보기
|
||||
loginnow = 로그인
|
||||
maxtaglength = 태그는 25자를 넘으면 안됨
|
||||
mustbeconnected = Pocket에 저장하려면 인터넷에 연결되어 있어야 합니다. 연결을 확인하고 다시 시도해 주십시오.
|
||||
onlylinkssaved = 링크만 저장할 수 있음
|
||||
pagenotsaved = 페이지를 저장하지 못했음
|
||||
pageremoved = 페이지가 삭제됨
|
||||
pagesaved = Pocket에 저장
|
||||
processingremove = 페이지를 삭제하는 중…
|
||||
processingtags = 페이지를 추가하는 중…
|
||||
removepage = 페이지 삭제
|
||||
save = 저장
|
||||
saving = 저장 중…
|
||||
signupemail = 이메일로 가입
|
||||
signuptosave = Pocket에 가입하십시오. 무료입니다.
|
||||
suggestedtags = 추천하는 태그
|
||||
tagline = Firefox에서 글과 동영상을 저장하면 모든 기기에서 아무 때나 보실 수 있습니다.
|
||||
taglinestory_one = Pocket 단추를 누르면 Firefox에서 어떠한 글, 동영상, 또는 페이지도 저장합니다.
|
||||
taglinestory_two = 모든 기기에서 아무 때나 Pocket에서 볼 수 있습니다.
|
||||
tagssaved = 태그를 추가함
|
||||
tos = 계속하시면 Pocket의 <a href="%1$S" target="_blank">약관</a> 과 <a href="%2$S" target="_blank">개인정보정책</a> 에 동의하게 됩니다
|
||||
tryitnow = 지금 사용해보기
|
||||
signinfirefox = Firefox로 로그인
|
||||
signupfirefox = Firefox로 가입하기
|
||||
viewlist = 목록 보기
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
# "Pocket" is a brand name.
|
||||
pocket-button.label = Pocket
|
||||
pocket-button.tooltiptext = Pocket에 저장
|
||||
saveToPocketCmd.label = Pocket에 페이지 저장
|
||||
saveToPocketCmd.accesskey = k
|
||||
saveLinkToPocketCmd.label = Pocket에 링크 저장
|
||||
saveLinkToPocketCmd.accesskey = o
|
||||
pocketMenuitem.label = Pocket의 목록 보기
|
|
@ -19,17 +19,17 @@ processingtags = Adicionando etiquetas…
|
|||
removepage = Remover página
|
||||
save = Salvar
|
||||
saving = Salvando…
|
||||
signupemail = Registrar com e-mail
|
||||
signupemail = Registre-se via e-mail
|
||||
signuptosave = Registre-se no Pocket. É gratuito.
|
||||
suggestedtags = Etiquetas sugeridas
|
||||
tagline = Salve os artigos e vídeos do Firefox no Pocket para vê-los mais tarde e em qualquer local.
|
||||
taglinestory_one = Clique no botão Pocket para salvar um artigo, vídeo ou página do Firefox.
|
||||
taglinestory_two = Ver no Pocket em qualquer dispositivo, a qualquer hora.
|
||||
tagssaved = Etiquetas adicionadas
|
||||
tos = Continuando, você concorda com os <a href="%1$S" target="_blank">Termos de serviço</a> e <a href="%2$S" target="_blank">Política de privacidade</a> do Pocket
|
||||
tos = Continuando, você concorda com os <a href="%1$S" target="_blank">Termos de serviço</a> e a <a href="%2$S" target="_blank">Política de privacidade</a> do Pocket
|
||||
tryitnow = Experimente-o agora
|
||||
signinfirefox = Entrar com o Firefox
|
||||
signupfirefox = Cadastre-se com o Firefox
|
||||
signinfirefox = Identifique-se via Firefox
|
||||
signupfirefox = Registre-se via Firefox
|
||||
viewlist = Ver lista
|
||||
|
||||
# LOCALIZATION NOTE(pocket-button.label, pocket-button.tooltiptext, saveToPocketCmd.label, saveLinkToPocketCmd.label, pocketMenuitem.label):
|
||||
|
|
|
@ -174,10 +174,10 @@ this.ExtensionsUI = {
|
|||
}
|
||||
name = this._sanitizeName(name);
|
||||
|
||||
let addonLabel = `<label class="addon-webext-name">${name}</label>`;
|
||||
let addonName = `<span class="addon-webext-name">${name}</span>`;
|
||||
let bundle = win.gNavigatorBundle;
|
||||
|
||||
let header = bundle.getFormattedString("webextPerms.header", [addonLabel]);
|
||||
let header = bundle.getFormattedString("webextPerms.header", [addonName]);
|
||||
let text = "";
|
||||
let listIntro = bundle.getString("webextPerms.listIntro");
|
||||
|
||||
|
@ -187,7 +187,7 @@ this.ExtensionsUI = {
|
|||
let cancelKey = bundle.getString("webextPerms.cancel.accessKey");
|
||||
|
||||
if (info.type == "sideload") {
|
||||
header = bundle.getFormattedString("webextPerms.sideloadHeader", [addonLabel]);
|
||||
header = bundle.getFormattedString("webextPerms.sideloadHeader", [addonName]);
|
||||
text = bundle.getString("webextPerms.sideloadText");
|
||||
acceptText = bundle.getString("webextPerms.sideloadEnable.label");
|
||||
acceptKey = bundle.getString("webextPerms.sideloadEnable.accessKey");
|
||||
|
@ -195,7 +195,7 @@ this.ExtensionsUI = {
|
|||
cancelKey = bundle.getString("webextPerms.sideloadDisable.accessKey");
|
||||
} else if (info.type == "update") {
|
||||
header = "";
|
||||
text = bundle.getFormattedString("webextPerms.updateText", [addonLabel]);
|
||||
text = bundle.getFormattedString("webextPerms.updateText", [addonName]);
|
||||
acceptText = bundle.getString("webextPerms.updateAccept.label");
|
||||
acceptKey = bundle.getString("webextPerms.updateAccept.accessKey");
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ this.ExtensionsUI = {
|
|||
let popups = win.PopupNotifications;
|
||||
|
||||
let name = this._sanitizeName(addon.name);
|
||||
let addonLabel = `<label class="addon-webext-name">${name}</label>`;
|
||||
let addonName = `<span class="addon-webext-name">${name}</span>`;
|
||||
let addonIcon = '<image class="addon-addon-icon"/>';
|
||||
let toolbarIcon = '<image class="addon-toolbar-icon"/>';
|
||||
|
||||
|
@ -330,7 +330,7 @@ this.ExtensionsUI = {
|
|||
|
||||
let bundle = win.gNavigatorBundle;
|
||||
let msg1 = bundle.getFormattedString("addonPostInstall.message1",
|
||||
[addonLabel, appName]);
|
||||
[addonName, appName]);
|
||||
let msg2 = bundle.getFormattedString("addonPostInstall.messageDetail",
|
||||
[addonIcon, toolbarIcon]);
|
||||
|
||||
|
|
|
@ -838,6 +838,7 @@ menuitem.bookmark-item {
|
|||
}
|
||||
|
||||
.addon-webext-name {
|
||||
display: inline;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -3096,6 +3096,7 @@ menulist.translate-infobar-element > .menulist-dropmarker {
|
|||
}
|
||||
|
||||
.addon-webext-name {
|
||||
display: inline;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -100,14 +100,6 @@
|
|||
}
|
||||
|
||||
/* GRID */
|
||||
body.compact #newtab-grid {
|
||||
/* Allow #topsites-heading to use position:absolute such that it doesn't
|
||||
affect how many cells we can fit into the grid. */
|
||||
position: relative;
|
||||
padding-top: 1em;
|
||||
margin-top: -1em;
|
||||
}
|
||||
|
||||
#topsites-heading {
|
||||
color: #7A7A7A;
|
||||
font-size: 1em;
|
||||
|
@ -115,9 +107,9 @@ body.compact #newtab-grid {
|
|||
/* Position the heading such that it doesn't affect how many cells we
|
||||
can fit into the grid. */
|
||||
position: absolute;
|
||||
top: 0;
|
||||
/* The horizontal margin aligns the heading with the cells. */
|
||||
margin: 0 10px;
|
||||
/* The top margin moves the heading away from the grid.
|
||||
The horizontal margin aligns the heading with the cells. */
|
||||
margin: -1em 10px 0;
|
||||
}
|
||||
|
||||
/* CELLS */
|
||||
|
|
|
@ -2141,6 +2141,7 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
|
|||
}
|
||||
|
||||
.addon-webext-name {
|
||||
display: inline;
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
}
|
||||
|
|
|
@ -9,15 +9,6 @@ Rust code is built using ``cargo`` in the typical way, so it is
|
|||
straightforward to take an existing Rust crate and integrate it
|
||||
into Firefox.
|
||||
|
||||
.. important::
|
||||
|
||||
Rust code is enabled by default in Firefox builds. Until we have
|
||||
a required component written in Rust, you can build without by
|
||||
setting ``ac_add_options --disable-rust`` in your mozconfig.
|
||||
This option will be around for a little longer
|
||||
(`bug 1284816 <https://bugzilla.mozilla.org/show_bug.cgi?id=1284816>`_).
|
||||
|
||||
|
||||
Linking Rust Crates into libxul
|
||||
===============================
|
||||
|
||||
|
|
|
@ -4,20 +4,10 @@
|
|||
# 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/.
|
||||
|
||||
option('--disable-rust', help='Don\'t include Rust language sources')
|
||||
|
||||
@depends('--enable-rust')
|
||||
def rust_compiler_names(value):
|
||||
if value:
|
||||
return ['rustc']
|
||||
|
||||
@depends('--enable-rust')
|
||||
def cargo_binary_names(value):
|
||||
if value:
|
||||
return ['cargo']
|
||||
|
||||
rustc = check_prog('RUSTC', rust_compiler_names, allow_missing=True)
|
||||
cargo = check_prog('CARGO', cargo_binary_names, allow_missing=True)
|
||||
# Rust is required by `rust_compiler` below. We allow_missing here
|
||||
# to propagate failures to the better error message there.
|
||||
rustc = check_prog('RUSTC', ['rustc'], allow_missing=True)
|
||||
cargo = check_prog('CARGO', ['cargo'], allow_missing=True)
|
||||
|
||||
@depends_if(rustc)
|
||||
@checking('rustc version', lambda info: info.version)
|
||||
|
@ -47,36 +37,35 @@ def cargo_supports_frozen(cargo):
|
|||
|
||||
set_config('MOZ_CARGO_SUPPORTS_FROZEN', cargo_supports_frozen)
|
||||
|
||||
@depends('--enable-rust', rustc, rustc_info)
|
||||
@depends(rustc, rustc_info)
|
||||
@imports(_from='textwrap', _import='dedent')
|
||||
def rust_compiler(value, rustc, rustc_info):
|
||||
if value:
|
||||
if not rustc:
|
||||
die(dedent('''\
|
||||
Rust compiler not found.
|
||||
To compile rust language sources, you must have 'rustc' in your path.
|
||||
See https//www.rust-lang.org/ for more information.
|
||||
def rust_compiler(rustc, rustc_info):
|
||||
if not rustc:
|
||||
die(dedent('''\
|
||||
Rust compiler not found.
|
||||
To compile rust language sources, you must have 'rustc' in your path.
|
||||
See https//www.rust-lang.org/ for more information.
|
||||
|
||||
You can install rust by running './mach bootstrap'
|
||||
or by directly running the installer from https://rustup.rs/
|
||||
'''))
|
||||
version = rustc_info.version
|
||||
min_version = Version('1.13')
|
||||
if version < min_version:
|
||||
die(dedent('''\
|
||||
Rust compiler {} is too old.
|
||||
You can install rust by running './mach bootstrap'
|
||||
or by directly running the installer from https://rustup.rs/
|
||||
'''))
|
||||
version = rustc_info.version
|
||||
min_version = Version('1.13')
|
||||
if version < min_version:
|
||||
die(dedent('''\
|
||||
Rust compiler {} is too old.
|
||||
|
||||
To compile Rust language sources please install at least
|
||||
version {} of the 'rustc' toolchain and make sure it is
|
||||
first in your path.
|
||||
To compile Rust language sources please install at least
|
||||
version {} of the 'rustc' toolchain and make sure it is
|
||||
first in your path.
|
||||
|
||||
You can verify this by typing 'rustc --version'.
|
||||
You can verify this by typing 'rustc --version'.
|
||||
|
||||
If you have the 'rustup' tool installed you can upgrade
|
||||
to the latest release by typing 'rustup update'. The
|
||||
installer is available from https://rustup.rs/
|
||||
'''.format(version, min_version)))
|
||||
return True
|
||||
If you have the 'rustup' tool installed you can upgrade
|
||||
to the latest release by typing 'rustup update'. The
|
||||
installer is available from https://rustup.rs/
|
||||
'''.format(version, min_version)))
|
||||
return True
|
||||
|
||||
set_config('MOZ_RUST', rust_compiler)
|
||||
|
||||
|
|
|
@ -182,6 +182,22 @@ https://tracking.example.com:443
|
|||
https://not-tracking.example.com:443
|
||||
https://tracking.example.org:443
|
||||
|
||||
#
|
||||
# Used while testing flash blocking (Bug 1307604)
|
||||
#
|
||||
http://flashallow.example.com:80
|
||||
http://exception.flashallow.example.com:80
|
||||
http://flashblock.example.com:80
|
||||
http://exception.flashblock.example.com:80
|
||||
http://subdocument.example.com:80
|
||||
http://exception.subdocument.example.com:80
|
||||
|
||||
#
|
||||
# Flash usage can fail unless this URL exists
|
||||
#
|
||||
http://fpdownload2.macromedia.com:80
|
||||
https://fpdownload2.macromedia.com:443
|
||||
|
||||
# Bug 1281083
|
||||
http://bug1281083.example.com:80
|
||||
|
||||
|
|
|
@ -279,6 +279,7 @@ public:
|
|||
bool IsPlaying() const
|
||||
{
|
||||
return mPlaybackRate != 0.0 &&
|
||||
mTimeline &&
|
||||
(PlayState() == AnimationPlayState::Running ||
|
||||
mPendingState == PendingState::PlayPending);
|
||||
}
|
||||
|
|
|
@ -1330,6 +1330,16 @@ BuildSegmentsFromValueEntries(nsTArray<KeyframeValueEntry>& aEntries,
|
|||
}
|
||||
}
|
||||
|
||||
// Skip this entry if the next entry has the same offset except for initial
|
||||
// and final ones. We will handle missing keyframe in the next loop
|
||||
// if the property is changed on the next entry.
|
||||
if (aEntries[i].mProperty == aEntries[i + 1].mProperty &&
|
||||
aEntries[i].mOffset == aEntries[i + 1].mOffset &&
|
||||
aEntries[i].mOffset != 1.0f && aEntries[i].mOffset != 0.0f) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// No keyframe for this property at offset 1.
|
||||
if (aEntries[i].mProperty != aEntries[i + 1].mProperty &&
|
||||
aEntries[i].mOffset != 1.0f) {
|
||||
|
@ -1340,13 +1350,18 @@ BuildSegmentsFromValueEntries(nsTArray<KeyframeValueEntry>& aEntries,
|
|||
continue;
|
||||
}
|
||||
|
||||
// Starting from i, determine the next [i, j] interval from which to
|
||||
// generate a segment.
|
||||
size_t j;
|
||||
// Starting from i + 1, determine the next [i, j] interval from which to
|
||||
// generate a segment. Basically, j is i + 1, but there are some special
|
||||
// cases for offset 0 and 1, so we need to handle them specifically.
|
||||
// Note: From this moment, we make sure [i + 1] is valid and
|
||||
// there must be an initial entry (i.e. mOffset = 0.0) and
|
||||
// a final entry (i.e. mOffset = 1.0). Besides, all the entries
|
||||
// with the same offsets except for initial/final ones are filtered
|
||||
// out already.
|
||||
size_t j = i + 1;
|
||||
if (aEntries[i].mOffset == 0.0f && aEntries[i + 1].mOffset == 0.0f) {
|
||||
// We need to generate an initial zero-length segment.
|
||||
MOZ_ASSERT(aEntries[i].mProperty == aEntries[i + 1].mProperty);
|
||||
j = i + 1;
|
||||
while (j + 1 < n &&
|
||||
aEntries[j + 1].mOffset == 0.0f &&
|
||||
aEntries[j + 1].mProperty == aEntries[j].mProperty) {
|
||||
|
@ -1356,7 +1371,6 @@ BuildSegmentsFromValueEntries(nsTArray<KeyframeValueEntry>& aEntries,
|
|||
if (aEntries[i + 1].mOffset == 1.0f &&
|
||||
aEntries[i + 1].mProperty == aEntries[i].mProperty) {
|
||||
// We need to generate a final zero-length segment.
|
||||
j = i + 1;
|
||||
while (j + 1 < n &&
|
||||
aEntries[j + 1].mOffset == 1.0f &&
|
||||
aEntries[j + 1].mProperty == aEntries[j].mProperty) {
|
||||
|
@ -1369,12 +1383,6 @@ BuildSegmentsFromValueEntries(nsTArray<KeyframeValueEntry>& aEntries,
|
|||
++i;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
while (aEntries[i].mOffset == aEntries[i + 1].mOffset &&
|
||||
aEntries[i].mProperty == aEntries[i + 1].mProperty) {
|
||||
++i;
|
||||
}
|
||||
j = i + 1;
|
||||
}
|
||||
|
||||
// If we've moved on to a new property, create a new AnimationProperty
|
||||
|
|
|
@ -709,6 +709,33 @@ var gTests = [
|
|||
values: [ value(0, undefined, 'add', 'linear'),
|
||||
value(1, '5px', 'replace') ] } ]
|
||||
},
|
||||
{ desc: 'a missing property in initial keyframe and there are some ' +
|
||||
'keyframes with the same offset',
|
||||
frames: [ { },
|
||||
{ margin: '10px', offset: 0.5 },
|
||||
{ margin: '20px', offset: 0.5 },
|
||||
{ margin: '30px'} ],
|
||||
expected: [ { property: 'margin-top',
|
||||
values: [ value(0, undefined, 'add', 'linear'),
|
||||
value(0.5, '10px', 'replace'),
|
||||
value(0.5, '20px', 'replace', 'linear'),
|
||||
value(1, '30px', 'replace') ] },
|
||||
{ property: 'margin-right',
|
||||
values: [ value(0, undefined, 'add', 'linear'),
|
||||
value(0.5, '10px', 'replace'),
|
||||
value(0.5, '20px', 'replace', 'linear'),
|
||||
value(1, '30px', 'replace') ] },
|
||||
{ property: 'margin-bottom',
|
||||
values: [ value(0, undefined, 'add', 'linear'),
|
||||
value(0.5, '10px', 'replace'),
|
||||
value(0.5, '20px', 'replace', 'linear'),
|
||||
value(1, '30px', 'replace') ] },
|
||||
{ property: 'margin-left',
|
||||
values: [ value(0, undefined, 'add', 'linear'),
|
||||
value(0.5, '10px', 'replace'),
|
||||
value(0.5, '20px', 'replace', 'linear'),
|
||||
value(1, '30px', 'replace') ] } ]
|
||||
},
|
||||
{ desc: 'a missing property in final keyframe',
|
||||
frames: [ { margin: '5px' },
|
||||
{ } ],
|
||||
|
@ -725,6 +752,33 @@ var gTests = [
|
|||
values: [ value(0, '5px', 'replace', 'linear'),
|
||||
value(1, undefined, 'add') ] } ]
|
||||
},
|
||||
{ desc: 'a missing property in final keyframe and there are some ' +
|
||||
'keyframes with the same offsets',
|
||||
frames: [ { margin: '5px' },
|
||||
{ margin: '10px', offset: 0.5 },
|
||||
{ margin: '20px', offset: 0.5 },
|
||||
{ } ],
|
||||
expected: [ { property: 'margin-top',
|
||||
values: [ value(0, '5px', 'replace', 'linear'),
|
||||
value(0.5, '10px', 'replace'),
|
||||
value(0.5, '20px', 'replace', 'linear'),
|
||||
value(1, undefined, 'add') ] },
|
||||
{ property: 'margin-right',
|
||||
values: [ value(0, '5px', 'replace', 'linear'),
|
||||
value(0.5, '10px', 'replace'),
|
||||
value(0.5, '20px', 'replace', 'linear'),
|
||||
value(1, undefined, 'add') ] },
|
||||
{ property: 'margin-bottom',
|
||||
values: [ value(0, '5px', 'replace', 'linear'),
|
||||
value(0.5, '10px', 'replace'),
|
||||
value(0.5, '20px', 'replace', 'linear'),
|
||||
value(1, undefined, 'add') ] },
|
||||
{ property: 'margin-left',
|
||||
values: [ value(0, '5px', 'replace', 'linear'),
|
||||
value(0.5, '10px', 'replace'),
|
||||
value(0.5, '20px', 'replace', 'linear'),
|
||||
value(1, undefined, 'add') ] } ]
|
||||
},
|
||||
{ desc: 'a missing property in final keyframe where it forms the last'
|
||||
+ ' segment in the series',
|
||||
frames: [ { margin: '5px' },
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче