Bug 1881094 - 4. remove and revise prettier exclusions for firefox-android r=android-reviewers,frontend-codestyle-reviewers,gl,webcompat-reviewers,twisniewski

- remove the firefox-android exclusions from .prettierignore
 - add a few specific exclusions to .prettierignore for files with existing errors
 - add a few specific entries to Generated.txt and ThirdPartyPaths.txt
 - add `initial_experiments.json` to the list of generated files: these are updated from Nimbus
 - run `mach lint --fix --linter=eslint -- mobile/android` to generate all the formatting changes

Differential Revision: https://phabricator.services.mozilla.com/D206915
This commit is contained in:
Geoff Brown 2024-05-07 20:24:38 +00:00
parent 9857880129
commit 6356370a37
89 changed files with 19328 additions and 27178 deletions

View file

@ -905,7 +905,12 @@ layout/style/test/test_mql_event_listener_leaks.html
layout/style/test/test_pointer-events.html
layout/style/test/test_reframe_image_loading.html
layout/tables/test/test_bug337124.html
mobile/android/android-components/docs/_includes/footer.html
mobile/android/android-components/docs/_includes/head.html
mobile/android/android-components/docs/_layouts/home.html
mobile/android/components/extensions/test/mochitest/file_dummy.html
mobile/android/fenix/app/src/androidTest/assets/pages/htmlControls.html
mobile/android/fenix/app/src/androidTest/assets/pages/trackingPage.html
mobile/android/geckoview/src/androidTest/assets/www/accessibility/test-headings.html
mobile/android/geckoview/src/androidTest/assets/www/autoplay.html
mobile/android/geckoview/src/androidTest/assets/www/badVideoPath.html
@ -1149,14 +1154,6 @@ mobile/android/docs/geckoview/assets/js/search-data.json
# Uses `#filter substitution`
mobile/android/app/geckoview-prefs.js
# TODO - Bug 1881094: temporarily ignored for firefox-android migration
mobile/android/android-components/
mobile/android/fenix/
mobile/android/focus-android/
mobile/android/docs/_includes/
mobile/android/docs/_layouts/
mobile/android/docs/assets/js/icon-js.js
# Not much JS to lint and non-standard at that
mobile/android/installer/
mobile/android/locales/
@ -1385,6 +1382,9 @@ media/openmax_il/
media/webrtc/signaling/gtest/MockCall.h
mfbt/double-conversion/double-conversion/
mfbt/lz4/.*
mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readability/JSDOMParser-0.4.2.js
mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readability/readability-0.4.2.js
mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readability/readability-readerable-0.4.2.js
mobile/android/exoplayer2/
modules/brotli/
modules/fdlibm/
@ -1484,8 +1484,6 @@ dom/tests/ajax/mochikit/
intl/components/src/UnicodeScriptCodes.h
intl/unicharutil/util/nsSpecialCasingData.cpp
intl/unicharutil/util/nsUnicodePropertyData.cpp
mobile/locales/l10n-changesets.json
mobile/locales/l10n-onchange-changesets.json
mobile/android/**/.build-cache
mobile/android/**/.gradle
mobile/android/**/build
@ -1493,6 +1491,12 @@ mobile/android/**/bin
mobile/android/**/generated
mobile/android/**\/local.properties
mobile/android/**\/manifest.json
mobile/android/android-components/components/feature/search/src/main/assets/search/search_telemetry_v2.json
mobile/android/android-components/samples/glean/src/main/res/raw/initial_experiments.json
mobile/android/fenix/app/src/debug/res/raw/initial_experiments.json
mobile/android/fenix/app/src/main/res/raw/initial_experiments.json
mobile/locales/l10n-changesets.json
mobile/locales/l10n-onchange-changesets.json
node_modules/
python/mozperftest/mozperftest/tests/data/
security/manager/tools/KnownRootHashes.json

View file

@ -6,50 +6,54 @@
* Handles the parsing of the ErrorPages URI and then passes them to injectValues
*/
function parseQuery(queryString) {
if (queryString[0] === '?') {
queryString = queryString.substr(1);
}
const query = Object.fromEntries(new URLSearchParams(queryString).entries());
injectValues(query)
updateShowSSL(query)
updateShowHSTS(query)
};
if (queryString[0] === "?") {
queryString = queryString.substr(1);
}
const query = Object.fromEntries(new URLSearchParams(queryString).entries());
injectValues(query);
updateShowSSL(query);
updateShowHSTS(query);
}
/**
* Updates the HTML elements based on the queryMap
*/
function injectValues(queryMap) {
const tryAgainButton = document.getElementById('errorTryAgain')
const continueHttpButton = document.getElementById("continueHttp")
const tryAgainButton = document.getElementById("errorTryAgain");
const continueHttpButton = document.getElementById("continueHttp");
// Go through each element and inject the values
document.title = queryMap.title;
tryAgainButton.innerHTML = queryMap.button;
continueHttpButton.innerHTML = queryMap.continueHttpButton;
document.getElementById("errorTitleText").innerHTML = queryMap.title;
document.getElementById("errorShortDesc").innerHTML = queryMap.description;
document.getElementById("advancedButton").innerHTML =
queryMap.badCertAdvanced;
document.getElementById("badCertTechnicalInfo").innerHTML =
queryMap.badCertTechInfo;
document.getElementById("advancedPanelBackButton").innerHTML =
queryMap.badCertGoBack;
document.getElementById("advancedPanelAcceptButton").innerHTML =
queryMap.badCertAcceptTemporary;
document.getElementById("advancedPanelAcceptButton").s =
queryMap.badCertAcceptTemporary;
// Go through each element and inject the values
document.title = queryMap.title
tryAgainButton.innerHTML = queryMap.button
continueHttpButton.innerHTML = queryMap.continueHttpButton
document.getElementById('errorTitleText').innerHTML = queryMap.title
document.getElementById('errorShortDesc').innerHTML = queryMap.description
document.getElementById('advancedButton').innerHTML = queryMap.badCertAdvanced
document.getElementById('badCertTechnicalInfo').innerHTML = queryMap.badCertTechInfo
document.getElementById('advancedPanelBackButton').innerHTML = queryMap.badCertGoBack
document.getElementById('advancedPanelAcceptButton').innerHTML = queryMap.badCertAcceptTemporary
document.getElementById('advancedPanelAcceptButton').s = queryMap.badCertAcceptTemporary
// If no image is passed in, remove the element so as not to leave an empty iframe
const errorImage = document.getElementById("errorImage");
if (!queryMap.image) {
errorImage.remove();
} else {
errorImage.src = "resource://android/assets/" + queryMap.image;
}
// If no image is passed in, remove the element so as not to leave an empty iframe
const errorImage = document.getElementById('errorImage');
if (!queryMap.image) {
errorImage.remove();
} else {
errorImage.src = "resource://android/assets/" + queryMap.image;
}
if (queryMap.showContinueHttp === "true") {
// On the "HTTPS-Only" error page "Try again" doesn't make sense since reloading the page
// will just show an error page again.
tryAgainButton.style.display = 'none';
} else {
continueHttpButton.style.display = 'none';
}
if (queryMap.showContinueHttp === "true") {
// On the "HTTPS-Only" error page "Try again" doesn't make sense since reloading the page
// will just show an error page again.
tryAgainButton.style.display = "none";
} else {
continueHttpButton.style.display = "none";
}
}
var advancedVisible = false;
@ -58,65 +62,75 @@ var advancedVisible = false;
* Used to show or hide the "advanced" button based on the validity of the SSL certificate
*/
function updateShowSSL(queryMap) {
/** @type {'true' | 'false'} */
const showSSL = queryMap.showSSL;
if (typeof document.addCertException === "undefined") {
document.getElementById('advancedButton').style.display='none';
/** @type {'true' | 'false'} */
const showSSL = queryMap.showSSL;
if (typeof document.addCertException === "undefined") {
document.getElementById("advancedButton").style.display = "none";
} else {
if (showSSL === "true") {
document.getElementById("advancedButton").style.display = "block";
} else {
if (showSSL === 'true') {
document.getElementById('advancedButton').style.display='block';
} else {
document.getElementById('advancedButton').style.display='none';
}
document.getElementById("advancedButton").style.display = "none";
}
}
}
/**
* Used to show or hide the "accept" button based for the HSTS error page
*/
function updateShowHSTS(queryMap) {
const showHSTS = queryMap.showHSTS;
if (showHSTS === 'true') {
document.getElementById('advancedButton').style.display='block';
document.getElementById('advancedPanelAcceptButton').style.display='none';
}
const showHSTS = queryMap.showHSTS;
if (showHSTS === "true") {
document.getElementById("advancedButton").style.display = "block";
document.getElementById("advancedPanelAcceptButton").style.display = "none";
}
}
/**
* Used to display information about the SSL certificate in `error_pages.html`
*/
function toggleAdvanced() {
if (advancedVisible) {
document.getElementById('badCertAdvancedPanel').style.display='none';
} else {
document.getElementById('badCertAdvancedPanel').style.display='block';
}
advancedVisible = !advancedVisible;
if (advancedVisible) {
document.getElementById("badCertAdvancedPanel").style.display = "none";
} else {
document.getElementById("badCertAdvancedPanel").style.display = "block";
}
advancedVisible = !advancedVisible;
}
/**
* Used to bypass an SSL pages in `error_pages.html`
*/
async function acceptAndContinue(temporary) {
try {
await document.addCertException(temporary);
location.reload();
} catch (error) {
console.error("Unexpected error: " + error)
}
try {
await document.addCertException(temporary);
location.reload();
} catch (error) {
console.error("Unexpected error: " + error);
}
}
document.addEventListener('DOMContentLoaded', function () {
if (window.history.length == 1) {
document.getElementById('advancedPanelBackButton').style.display = 'none';
} else {
document.getElementById('advancedPanelBackButton').addEventListener('click', () => window.history.back());
}
document.addEventListener("DOMContentLoaded", function () {
if (window.history.length == 1) {
document.getElementById("advancedPanelBackButton").style.display = "none";
} else {
document
.getElementById("advancedPanelBackButton")
.addEventListener("click", () => window.history.back());
}
document.getElementById('errorTryAgain').addEventListener('click', () => window.location.reload());
document.getElementById('advancedButton').addEventListener('click', toggleAdvanced);
document.getElementById('advancedPanelAcceptButton').addEventListener('click', () => acceptAndContinue(true));
document.getElementById('continueHttp').addEventListener('click', () => document.reloadWithHttpsOnlyException());
document
.getElementById("errorTryAgain")
.addEventListener("click", () => window.location.reload());
document
.getElementById("advancedButton")
.addEventListener("click", toggleAdvanced);
document
.getElementById("advancedPanelAcceptButton")
.addEventListener("click", () => acceptAndContinue(true));
document
.getElementById("continueHttp")
.addEventListener("click", () => document.reloadWithHttpsOnlyException());
});
parseQuery(document.documentURI);

View file

@ -5,54 +5,64 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width; user-scalable=false;" />
<meta http-equiv="Content-Security-Policy" content="default-src resource:; object-src 'none'" />
<link rel="stylesheet" type="text/css" href="error_style.css">
</head>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width; user-scalable=false;" />
<meta
http-equiv="Content-Security-Policy"
content="default-src resource:; object-src 'none'"
/>
<link rel="stylesheet" type="text/css" href="error_style.css" />
</head>
<body id="errorPage" dir="auto">
<!-- PAGE CONTAINER (for styling purposes only) -->
<div id="errorPageContainer">
<body id="errorPage" dir="auto">
<!-- PAGE CONTAINER (for styling purposes only) -->
<div id="errorPageContainer">
<!-- Error Image -->
<iframe id="errorImage" src="" frameborder="0"></iframe>
<!-- Error Image -->
<iframe id="errorImage" src="" frameborder="0"></iframe>
<!-- Error Title -->
<div id="errorTitle">
<h1 id="errorTitleText"></h1>
</div>
<!-- Error Title -->
<div id="errorTitle">
<h1 id="errorTitleText"></h1>
</div>
<!-- LONG CONTENT (the section most likely to require scrolling) -->
<div id="errorLongContent">
<div id="errorShortDesc"></div>
</div>
<!-- LONG CONTENT (the section most likely to require scrolling) -->
<div id="errorLongContent">
<div id="errorShortDesc"></div>
</div>
<!-- Retry Button -->
<button id="errorTryAgain"></button>
<!-- Retry Button -->
<button id="errorTryAgain"></button>
<!-- Advanced Button -->
<button id="advancedButton" class="buttonSecondary"></button>
<!-- Advanced Button -->
<button id="advancedButton" class="buttonSecondary"></button>
<!-- "Continue to HTTP site" Button (For HTTPS-Only error page only) -->
<button id="continueHttp" class="buttonSecondary"></button>
<!-- "Continue to HTTP site" Button (For HTTPS-Only error page only) -->
<button id="continueHttp" class="buttonSecondary"></button>
<div id="advancedPanelContainer">
<div id="badCertAdvancedPanel" class="advanced-panel">
<p id="badCertTechnicalInfo"></p>
<div id="advancedPanelBackButtonContainer" class="advancedPanelButtonContainer">
<button id="advancedPanelBackButton"></button>
</div>
<div id="advancedPanelAcceptButtonContainer" class="advancedPanelButtonContainer">
<button id="advancedPanelAcceptButton" class="buttonSecondary"></button>
</div>
</div>
</div>
<div id="advancedPanelContainer">
<div id="badCertAdvancedPanel" class="advanced-panel">
<p id="badCertTechnicalInfo"></p>
<div
id="advancedPanelBackButtonContainer"
class="advancedPanelButtonContainer"
>
<button id="advancedPanelBackButton"></button>
</div>
<div
id="advancedPanelAcceptButtonContainer"
class="advancedPanelButtonContainer"
>
<button
id="advancedPanelAcceptButton"
class="buttonSecondary"
></button>
</div>
</div>
</div>
</div>
</body>
</body>
<!-- Each consumer that uses a unique HTML error page must implement a parsing script-->
<script src="./errorPageScripts.js"></script>
<!-- Each consumer that uses a unique HTML error page must implement a parsing script-->
<script src="./errorPageScripts.js"></script>
</html>

View file

@ -2,80 +2,81 @@
* 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/. */
/*
* This web extension looks for known icon tags, collects URLs and available
* meta data (e.g. sizes) and passes that to the app code.
*/
/*
* This web extension looks for known icon tags, collects URLs and available
* meta data (e.g. sizes) and passes that to the app code.
*/
/**
* Takes a DOMTokenList and returns a String array.
*/
function sizesToList(sizes) {
if (sizes == null) {
return []
}
if (sizes == null) {
return [];
}
if (!(sizes instanceof DOMTokenList)) {
return []
}
if (!(sizes instanceof DOMTokenList)) {
return [];
}
return Array.from(sizes)
return Array.from(sizes);
}
function collect_link_icons(icons, rel) {
document.querySelectorAll('link[rel="' + rel + '"]').forEach(
function(currentValue, currentIndex, listObj) {
icons.push({
'type': rel,
'href': currentValue.href,
'sizes': sizesToList(currentValue.sizes),
'mimeType': currentValue.type
});
})
document
.querySelectorAll('link[rel="' + rel + '"]')
.forEach(function (currentValue, currentIndex, listObj) {
icons.push({
type: rel,
href: currentValue.href,
sizes: sizesToList(currentValue.sizes),
mimeType: currentValue.type,
});
});
}
function collect_meta_property_icons(icons, property) {
document.querySelectorAll('meta[property="' + property + '"]').forEach(
function(currentValue, currentIndex, listObj) {
icons.push({
'type': property,
'href': currentValue.content
})
}
)
document
.querySelectorAll('meta[property="' + property + '"]')
.forEach(function (currentValue, currentIndex, listObj) {
icons.push({
type: property,
href: currentValue.content,
});
});
}
function collect_meta_name_icons(icons, name) {
document.querySelectorAll('meta[name="' + name + '"]').forEach(
function(currentValue, currentIndex, listObj) {
icons.push({
'type': name,
'href': currentValue.content
})
}
)
document
.querySelectorAll('meta[name="' + name + '"]')
.forEach(function (currentValue, currentIndex, listObj) {
icons.push({
type: name,
href: currentValue.content,
});
});
}
let icons = [];
collect_link_icons(icons, 'icon');
collect_link_icons(icons, 'shortcut icon');
collect_link_icons(icons, 'fluid-icon')
collect_link_icons(icons, 'apple-touch-icon')
collect_link_icons(icons, 'image_src')
collect_link_icons(icons, 'apple-touch-icon image_src')
collect_link_icons(icons, 'apple-touch-icon-precomposed')
collect_link_icons(icons, "icon");
collect_link_icons(icons, "shortcut icon");
collect_link_icons(icons, "fluid-icon");
collect_link_icons(icons, "apple-touch-icon");
collect_link_icons(icons, "image_src");
collect_link_icons(icons, "apple-touch-icon image_src");
collect_link_icons(icons, "apple-touch-icon-precomposed");
collect_meta_property_icons(icons, 'og:image')
collect_meta_property_icons(icons, 'og:image:url')
collect_meta_property_icons(icons, 'og:image:secure_url')
collect_meta_property_icons(icons, "og:image");
collect_meta_property_icons(icons, "og:image:url");
collect_meta_property_icons(icons, "og:image:secure_url");
collect_meta_name_icons(icons, 'twitter:image')
collect_meta_name_icons(icons, 'msapplication-TileImage')
collect_meta_name_icons(icons, "twitter:image");
collect_meta_name_icons(icons, "msapplication-TileImage");
let message = {
'url': document.location.href,
'icons': icons
}
url: document.location.href,
icons: icons,
};
browser.runtime.sendNativeMessage("MozacBrowserIcons", message);

View file

@ -1,8 +1,8 @@
<html>
<head>
<head>
<title>Restore Test</title>
</head>
<body>
</head>
<body>
<h1>Hello World</h1>
</body>
</body>
</html>

View file

@ -5,33 +5,42 @@
"display": "standalone",
"background_color": "#ffffff",
"description": "A simply readable Hacker News app.",
"icons": [{
"src": "images/touch/homescreen48.png",
"sizes": "48x48",
"type": "image/png"
}, {
"src": "images/touch/homescreen72.png",
"sizes": "72x72",
"type": "image/png"
}, {
"src": "images/touch/homescreen96.png",
"sizes": "96x96",
"type": "image/png"
}, {
"src": "images/touch/homescreen144.png",
"sizes": "144x144",
"type": "image/png"
}, {
"src": "images/touch/homescreen168.png",
"sizes": "168x168",
"type": "image/png"
}, {
"src": "images/touch/homescreen192.png",
"sizes": "192x192",
"type": "image/png"
}],
"related_applications": [{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb"
}]
"icons": [
{
"src": "images/touch/homescreen48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "images/touch/homescreen72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "images/touch/homescreen96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "images/touch/homescreen144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "images/touch/homescreen168.png",
"sizes": "168x168",
"type": "image/png"
},
{
"src": "images/touch/homescreen192.png",
"sizes": "192x192",
"type": "image/png"
}
],
"related_applications": [
{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=cheeaun.hackerweb"
}
]
}

View file

@ -4,17 +4,21 @@
"name": "Super Racer 3000",
"description": "The ultimate futuristic racing game from the future!",
"short_name": "Racer3K",
"icons": [{
"src": "icon/lowres.webp",
"sizes": "64x64",
"type": "image/webp"
},{
"src": "icon/lowres.png",
"sizes": "64x64"
}, {
"src": "icon/hd_hi",
"sizes": "128x128"
}],
"icons": [
{
"src": "icon/lowres.webp",
"sizes": "64x64",
"type": "image/webp"
},
{
"src": "icon/lowres.png",
"sizes": "64x64"
},
{
"src": "icon/hd_hi",
"sizes": "128x128"
}
],
"scope": "/racer/",
"start_url": "/racer/start.html",
"display": "fullscreen",
@ -26,26 +30,34 @@
"scope": "/racer/",
"update_via_cache": "none"
},
"screenshots": [{
"src": "screenshots/in-game-1x.jpg",
"sizes": "640x480",
"type": "image/jpeg"
},{
"src": "screenshots/in-game-2x.jpg",
"sizes": "1280x920",
"type": "image/jpeg"
}],
"related_applications": [{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=com.example.app1",
"id": "com.example.app1",
"min_version": "2",
"fingerprints": [{
"type": "sha256_cert",
"value": "92:5A:39:05:C5:B9:EA:BC:71:48:5F:F2"
}]
}, {
"platform": "itunes",
"url": "https://itunes.apple.com/app/example-app1/id123456789"
}]
"screenshots": [
{
"src": "screenshots/in-game-1x.jpg",
"sizes": "640x480",
"type": "image/jpeg"
},
{
"src": "screenshots/in-game-2x.jpg",
"sizes": "1280x920",
"type": "image/jpeg"
}
],
"related_applications": [
{
"platform": "play",
"url": "https://play.google.com/store/apps/details?id=com.example.app1",
"id": "com.example.app1",
"min_version": "2",
"fingerprints": [
{
"type": "sha256_cert",
"value": "92:5A:39:05:C5:B9:EA:BC:71:48:5F:F2"
}
]
},
{
"platform": "itunes",
"url": "https://itunes.apple.com/app/example-app1/id123456789"
}
]
}

View file

@ -1 +1,28 @@
{"background_color":"#ffffff","description":"It's what's happening. From breaking news and entertainment, sports and politics, to big events and everyday interests.","display":"standalone","gcm_sender_id":"49625052041","gcm_user_visible_only":true,"icons":[{"src":"https://abs.twimg.com/responsive-web/web/icon-default.604e2486a34a2f6e1.png","sizes":"192x192","type":"image/png"},{"src":"https://abs.twimg.com/responsive-web/web/icon-default.604e2486a34a2f6e1.png","sizes":"512x512","type":"image/png"}],"name":"Twitter","share_target":{"action":"compose/tweet","params":{"title":"title","text":"text","url":"url"}},"short_name":"Twitter","start_url":"/","theme_color":"#ffffff","scope":"/"}
{
"background_color": "#ffffff",
"description": "It's what's happening. From breaking news and entertainment, sports and politics, to big events and everyday interests.",
"display": "standalone",
"gcm_sender_id": "49625052041",
"gcm_user_visible_only": true,
"icons": [
{
"src": "https://abs.twimg.com/responsive-web/web/icon-default.604e2486a34a2f6e1.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "https://abs.twimg.com/responsive-web/web/icon-default.604e2486a34a2f6e1.png",
"sizes": "512x512",
"type": "image/png"
}
],
"name": "Twitter",
"share_target": {
"action": "compose/tweet",
"params": { "title": "title", "text": "text", "url": "url" }
},
"short_name": "Twitter",
"start_url": "/",
"theme_color": "#ffffff",
"scope": "/"
}

View file

@ -10,12 +10,12 @@ let port = browser.runtime.connectNative(WEB_CHANNEL_BACKGROUND_MESSAGING_ID);
/*
Handle messages from native application, register content script for specific url.
*/
port.onMessage.addListener( event => {
if(event.type == "overrideFxAServer"){
port.onMessage.addListener(event => {
if (event.type == "overrideFxAServer") {
browser.contentScripts.register({
"matches": [ event.url+"/*" ],
"js": [{file: "fxawebchannel.js"}],
"runAt": "document_start"
matches: [event.url + "/*"],
js: [{ file: "fxawebchannel.js" }],
runAt: "document_start",
});
port.disconnect();
}

View file

@ -10,16 +10,18 @@ let port = browser.runtime.connectNative("mozacWebchannel");
/*
Handle messages from native application, dispatch them to FxA via an event.
*/
port.onMessage.addListener((event) => {
window.dispatchEvent(new CustomEvent('WebChannelMessageToContent', {
detail: JSON.stringify(event)
}));
port.onMessage.addListener(event => {
window.dispatchEvent(
new CustomEvent("WebChannelMessageToContent", {
detail: JSON.stringify(event),
})
);
});
/*
Handle messages from FxA. Messages are posted to the native application for processing.
*/
window.addEventListener('WebChannelMessageToChrome', function (e) {
window.addEventListener("WebChannelMessageToChrome", function (e) {
const detail = JSON.parse(e.detail);
port.postMessage(detail);
});

View file

@ -17,12 +17,8 @@
],
"average_daily_users": 6229783,
"categories": {
"android": [
"security-privacy"
],
"firefox": [
"privacy-security"
]
"android": ["security-privacy"],
"firefox": ["privacy-security"]
},
"contributions_url": "",
"created": "2015-04-25T07:26:22Z",
@ -110,93 +106,54 @@
{
"id": 238546,
"caption": "The popup panel: default mode",
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238546.png?modified=1622132421",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238546.jpg?modified=1622132421"
},
{
"id": 238548,
"caption": "The dashboard: stock filter lists",
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238548.png?modified=1622132423",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238548.jpg?modified=1622132423"
},
{
"id": 238547,
"caption": "The popup panel: default-deny mode",
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238547.png?modified=1622132425",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238547.jpg?modified=1622132425"
},
{
"id": 238549,
"caption": "The dashboard: settings",
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238549.png?modified=1622132426",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238549.jpg?modified=1622132426"
},
{
"id": 238552,
"caption": "The popup panel in Firefox Preview: default mode with more blocking options revealed",
"image_size": [
970,
1800
],
"image_size": [970, 1800],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238552.png?modified=1622132430",
"thumbnail_size": [
216,
400
],
"thumbnail_size": [216, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238552.jpg?modified=1622132430"
},
{
"id": 230370,
"caption": "The unified logger tells you all that uBO is seeing and doing",
"image_size": [
800,
600
],
"image_size": [800, 600],
"image_url": "https://addons.mozilla.org/user-media/previews/full/230/230370.png?modified=1622132432",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/230/230370.jpg?modified=1622132432"
}
],
"promoted": {
"apps": [
"firefox",
"android"
],
"apps": ["firefox", "android"],
"category": "recommended"
},
"ratings": {

View file

@ -17,12 +17,8 @@
],
"average_daily_users": 6229783,
"categories": {
"android": [
"security-privacy"
],
"firefox": [
"privacy-security"
]
"android": ["security-privacy"],
"firefox": ["privacy-security"]
},
"contributions_url": "",
"created": "2015-04-25T07:26:22Z",
@ -192,15 +188,9 @@
"caption": {
"en-US": "The popup panel: default mode"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238546.png?modified=1622132421",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238546.jpg?modified=1622132421"
},
{
@ -208,15 +198,9 @@
"caption": {
"en-US": "The dashboard: stock filter lists"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238548.png?modified=1622132423",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238548.jpg?modified=1622132423"
},
{
@ -224,15 +208,9 @@
"caption": {
"en-US": "The popup panel: default-deny mode"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238547.png?modified=1622132425",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238547.jpg?modified=1622132425"
},
{
@ -240,15 +218,9 @@
"caption": {
"en-US": "The dashboard: settings"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238549.png?modified=1622132426",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238549.jpg?modified=1622132426"
},
{
@ -256,15 +228,9 @@
"caption": {
"en-US": "The popup panel in Firefox Preview: default mode with more blocking options revealed"
},
"image_size": [
970,
1800
],
"image_size": [970, 1800],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238552.png?modified=1622132430",
"thumbnail_size": [
216,
400
],
"thumbnail_size": [216, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238552.jpg?modified=1622132430"
},
{
@ -272,23 +238,14 @@
"caption": {
"en-US": "The unified logger tells you all that uBO is seeing and doing"
},
"image_size": [
800,
600
],
"image_size": [800, 600],
"image_url": "https://addons.mozilla.org/user-media/previews/full/230/230370.png?modified=1622132432",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/230/230370.jpg?modified=1622132432"
}
],
"promoted": {
"apps": [
"firefox",
"android"
],
"apps": ["firefox", "android"],
"category": "recommended"
},
"ratings": {
@ -378,12 +335,8 @@
],
"average_daily_users": 111124,
"categories": {
"android": [
"other"
],
"firefox": [
"search-tools"
]
"android": ["other"],
"firefox": ["search-tools"]
},
"contributions_url": "",
"created": "2017-10-31T15:35:56Z",
@ -653,9 +606,7 @@
},
"previews": [],
"promoted": {
"apps": [
"android"
],
"apps": ["android"],
"category": "recommended"
},
"ratings": {

View file

@ -17,12 +17,8 @@
],
"average_daily_users": 6229783,
"categories": {
"android": [
"security-privacy"
],
"firefox": [
"privacy-security"
]
"android": ["security-privacy"],
"firefox": ["privacy-security"]
},
"contributions_url": "",
"created": "2015-04-25T07:26:22Z",
@ -192,15 +188,9 @@
"caption": {
"en-US": "The popup panel: default mode"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238546.png?modified=1622132421",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238546.jpg?modified=1622132421"
},
{
@ -208,15 +198,9 @@
"caption": {
"en-US": "The dashboard: stock filter lists"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238548.png?modified=1622132423",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238548.jpg?modified=1622132423"
},
{
@ -224,15 +208,9 @@
"caption": {
"en-US": "The popup panel: default-deny mode"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238547.png?modified=1622132425",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238547.jpg?modified=1622132425"
},
{
@ -240,15 +218,9 @@
"caption": {
"en-US": "The dashboard: settings"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238549.png?modified=1622132426",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238549.jpg?modified=1622132426"
},
{
@ -256,15 +228,9 @@
"caption": {
"en-US": "The popup panel in Firefox Preview: default mode with more blocking options revealed"
},
"image_size": [
970,
1800
],
"image_size": [970, 1800],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238552.png?modified=1622132430",
"thumbnail_size": [
216,
400
],
"thumbnail_size": [216, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238552.jpg?modified=1622132430"
},
{
@ -272,23 +238,14 @@
"caption": {
"en-US": "The unified logger tells you all that uBO is seeing and doing"
},
"image_size": [
800,
600
],
"image_size": [800, 600],
"image_url": "https://addons.mozilla.org/user-media/previews/full/230/230370.png?modified=1622132432",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/230/230370.jpg?modified=1622132432"
}
],
"promoted": {
"apps": [
"firefox",
"android"
],
"apps": ["firefox", "android"],
"category": "recommended"
},
"ratings": {

View file

@ -18,12 +18,8 @@
],
"average_daily_users": 6229783,
"categories": {
"android": [
"security-privacy"
],
"firefox": [
"privacy-security"
]
"android": ["security-privacy"],
"firefox": ["privacy-security"]
},
"contributions_url": "",
"created": "2015-04-25T07:26:22Z",
@ -193,15 +189,9 @@
"caption": {
"en-US": "The popup panel: default mode"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238546.png?modified=1622132421",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238546.jpg?modified=1622132421"
},
{
@ -209,15 +199,9 @@
"caption": {
"en-US": "The dashboard: stock filter lists"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238548.png?modified=1622132423",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238548.jpg?modified=1622132423"
},
{
@ -225,15 +209,9 @@
"caption": {
"en-US": "The popup panel: default-deny mode"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238547.png?modified=1622132425",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238547.jpg?modified=1622132425"
},
{
@ -241,15 +219,9 @@
"caption": {
"en-US": "The dashboard: settings"
},
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238549.png?modified=1622132426",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238549.jpg?modified=1622132426"
},
{
@ -257,15 +229,9 @@
"caption": {
"en-US": "The popup panel in Firefox Preview: default mode with more blocking options revealed"
},
"image_size": [
970,
1800
],
"image_size": [970, 1800],
"image_url": "https://addons.mozilla.org/user-media/previews/full/238/238552.png?modified=1622132430",
"thumbnail_size": [
216,
400
],
"thumbnail_size": [216, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/238/238552.jpg?modified=1622132430"
},
{
@ -273,23 +239,14 @@
"caption": {
"en-US": "The unified logger tells you all that uBO is seeing and doing"
},
"image_size": [
800,
600
],
"image_size": [800, 600],
"image_url": "https://addons.mozilla.org/user-media/previews/full/230/230370.png?modified=1622132432",
"thumbnail_size": [
533,
400
],
"thumbnail_size": [533, 400],
"thumbnail_url": "https://addons.mozilla.org/user-media/previews/thumbs/230/230370.jpg?modified=1622132432"
}
],
"promoted": {
"apps": [
"firefox",
"android"
],
"apps": ["firefox", "android"],
"category": "recommended"
},
"ratings": {

View file

@ -162,15 +162,9 @@
"caption": {
"en-US": "Default mode"
},
"image_size": [
640,
480
],
"image_size": [640, 480],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/157/157572.png?modified=1543520531",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/157/157572.png?modified=1543520531"
},
{
@ -178,15 +172,9 @@
"caption": {
"en-US": "The dashboard: stock filter lists"
},
"image_size": [
640,
480
],
"image_size": [640, 480],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/157/157576.png?modified=1543520531",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/157/157576.png?modified=1543520531"
},
{
@ -194,15 +182,9 @@
"caption": {
"en-US": "Dynamic filtering allows default-deny mode"
},
"image_size": [
640,
480
],
"image_size": [640, 480],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/157/157592.png?modified=1543520532",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/157/157592.png?modified=1543520532"
},
{
@ -210,15 +192,9 @@
"caption": {
"en-US": "The dashboard: settings"
},
"image_size": [
640,
480
],
"image_size": [640, 480],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/159/159634.png?modified=1543520533",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/159/159634.png?modified=1543520533"
},
{
@ -226,15 +202,9 @@
"caption": {
"en-US": "Unified logger"
},
"image_size": [
700,
525
],
"image_size": [700, 525],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/158/158734.png?modified=1543520534",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/158/158734.png?modified=1543520534"
}
],

View file

@ -19,12 +19,8 @@
],
"average_daily_users": 5060298,
"categories": {
"android": [
"security-privacy"
],
"firefox": [
"privacy-security"
]
"android": ["security-privacy"],
"firefox": ["privacy-security"]
},
"contributions_url": "",
"created": "2015-04-25T07:26:22Z",
@ -110,93 +106,54 @@
{
"id": 238546,
"caption": "The popup panel: default mode",
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/238/238546.png?modified=1590420038",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/238/238546.png?modified=1590420038"
},
{
"id": 238548,
"caption": "The dashboard: stock filter lists",
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/238/238548.png?modified=1590420038",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/238/238548.png?modified=1590420038"
},
{
"id": 238547,
"caption": "The popup panel: default-deny mode",
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/238/238547.png?modified=1590420038",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/238/238547.png?modified=1590420038"
},
{
"id": 238549,
"caption": "The dashboard: settings",
"image_size": [
1011,
758
],
"image_size": [1011, 758],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/238/238549.png?modified=1590420038",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/238/238549.png?modified=1590420038"
},
{
"id": 238552,
"caption": "The popup panel in Firefox Preview: default mode with more blocking options revealed",
"image_size": [
970,
1800
],
"image_size": [970, 1800],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/238/238552.png?modified=1590420044",
"thumbnail_size": [
259,
480
],
"thumbnail_size": [259, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/238/238552.png?modified=1590420044"
},
{
"id": 230370,
"caption": "The unified logger tells you all that uBO is seeing and doing",
"image_size": [
800,
600
],
"image_size": [800, 600],
"image_url": "https://addons.cdn.mozilla.net/user-media/previews/full/230/230370.png?modified=1590420038",
"thumbnail_size": [
640,
480
],
"thumbnail_size": [640, 480],
"thumbnail_url": "https://addons.cdn.mozilla.net/user-media/previews/thumbs/230/230370.png?modified=1590420038"
}
],
"promoted": {
"apps": [
"firefox",
"android"
],
"apps": ["firefox", "android"],
"category": "recommended"
},
"ratings": {

View file

@ -10,7 +10,10 @@
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["readability/readability-readerable-0.4.2.js", "readerview-content.js"],
"js": [
"readability/readability-readerable-0.4.2.js",
"readerview-content.js"
],
"run_at": "document_idle"
}
],

View file

@ -7,16 +7,16 @@
browser.runtime.onMessage.addListener(message => {
switch (message.action) {
case 'addSerializedDoc':
browser.storage.session.set({ [message.id]: message.doc });
return Promise.resolve();
case 'getSerializedDoc':
return (async () => {
let doc = await browser.storage.session.get(message.id);
browser.storage.session.remove(message.id);
return doc[message.id];
})();
default:
console.error(`Received unsupported action ${message.action}`);
}
case "addSerializedDoc":
browser.storage.session.set({ [message.id]: message.doc });
return Promise.resolve();
case "getSerializedDoc":
return (async () => {
let doc = await browser.storage.session.get(message.id);
browser.storage.session.remove(message.id);
return doc[message.id];
})();
default:
console.error(`Received unsupported action ${message.action}`);
}
});

View file

@ -17,43 +17,53 @@ const blockedHosts = [
"pinterest.com",
"reddit.com",
"twitter.com",
"youtube.com"
"youtube.com",
];
function isReaderable() {
if (!supportedProtocols.includes(location.protocol)) {
return false;
}
if (!supportedProtocols.includes(location.protocol)) {
return false;
}
if (blockedHosts.some(blockedHost => location.hostname.endsWith(blockedHost))) {
return false;
}
if (
blockedHosts.some(blockedHost => location.hostname.endsWith(blockedHost))
) {
return false;
}
if (location.pathname == "/") {
return false;
}
if (location.pathname == "/") {
return false;
}
return isProbablyReaderable(document, _isNodeVisible);
return isProbablyReaderable(document, _isNodeVisible);
}
function _isNodeVisible(node) {
return node.clientHeight > 0 && node.clientWidth > 0;
return node.clientHeight > 0 && node.clientWidth > 0;
}
function connectNativePort() {
let port = browser.runtime.connectNative("mozacReaderview");
port.onMessage.addListener((message) => {
switch (message.action) {
case 'cachePage':
let serializedDoc = new XMLSerializer().serializeToString(document);
browser.runtime.sendMessage({action: "addSerializedDoc", doc: serializedDoc, id: message.id});
break;
case 'checkReaderState':
port.postMessage({type: 'checkReaderState', baseUrl: browser.runtime.getURL("/"), readerable: isReaderable()});
break;
default:
console.error(`Received unsupported action ${message.action}`);
}
port.onMessage.addListener(message => {
switch (message.action) {
case "cachePage":
let serializedDoc = new XMLSerializer().serializeToString(document);
browser.runtime.sendMessage({
action: "addSerializedDoc",
doc: serializedDoc,
id: message.id,
});
break;
case "checkReaderState":
port.postMessage({
type: "checkReaderState",
baseUrl: browser.runtime.getURL("/"),
readerable: isReaderable(),
});
break;
default:
console.error(`Received unsupported action ${message.action}`);
}
});
return port;
@ -65,11 +75,11 @@ let port = connectNativePort();
// do want to connect a new native port to trigger a new readerable check and
// apply the same logic (as on page load) in our feature class (e.g. updating the
// toolbar etc.)
window.addEventListener("pageshow", (event) => {
port = (port != null)? port : connectNativePort();
window.addEventListener("pageshow", event => {
port = port != null ? port : connectNativePort();
});
window.addEventListener("pagehide", (event) => {
window.addEventListener("pagehide", event => {
port.disconnect();
port = null;
});

View file

@ -4,14 +4,14 @@
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width; user-scalable=0" />
<meta http-equiv="cache-control" content="no-store" />
<meta content="text/html; charset=UTF-8" http-equiv="content-type" />
<meta name="viewport" content="width=device-width; user-scalable=0" />
<meta http-equiv="cache-control" content="no-store" />
<link rel="stylesheet" href="readerview.css" />
<link rel="stylesheet" href="readerview.css" />
<script src="readability/JSDOMParser-0.4.2.js"></script>
<script src="readability/readability-0.4.2.js"></script>
<script src="readerview.js"></script>
<script src="readability/JSDOMParser-0.4.2.js"></script>
<script src="readability/readability-0.4.2.js"></script>
<script src="readerview.js"></script>
</head>
</html>

View file

@ -15,11 +15,10 @@ const preservedClasses = [
"visuallyhidden",
"wp-caption",
"wp-caption-text",
"wp-smiley"
"wp-smiley",
];
class ReaderView {
static get MIN_FONT_SIZE() {
return 1;
}
@ -37,18 +36,24 @@ class ReaderView {
* @param url the url of the article.
* @param options the fontSize, fontType and colorScheme to use.
*/
show(doc, url, options = {fontSize: 4, fontType: "sans-serif", colorScheme: "light"}) {
let result = new Readability(doc, {classesToPreserve: preservedClasses}).parse();
show(
doc,
url,
options = { fontSize: 4, fontType: "sans-serif", colorScheme: "light" }
) {
let result = new Readability(doc, {
classesToPreserve: preservedClasses,
}).parse();
result.language = doc.documentElement.lang;
document.title = result.title;
let article = Object.assign(
result,
{url: new URL(url)},
{readingTime: this.getReadingTime(result.length, result.language)},
{byline: this.getByline(result)},
{dir: this.getTextDirection(result)},
{title: this.getTitle(result)}
{ url: new URL(url) },
{ readingTime: this.getReadingTime(result.length, result.language) },
{ byline: this.getByline(result) },
{ dir: this.getTextDirection(result) },
{ title: this.getTitle(result) }
);
document.body.outerHTML = this.createHtmlBody(article);
@ -57,7 +62,7 @@ class ReaderView {
this.setFontType(options.fontType);
this.setColorScheme(options.colorScheme);
if (options.scrollY) {
window.scrollTo({top: options.scrollY, left: 0, behavior: "instant"});
window.scrollTo({ top: options.scrollY, left: 0, behavior: "instant" });
}
}
@ -68,7 +73,10 @@ class ReaderView {
* @param changeAmount e.g. +1, or -1.
*/
changeFontSize(changeAmount) {
var size = Math.max(ReaderView.MIN_FONT_SIZE, Math.min(ReaderView.MAX_FONT_SIZE, this.fontSize + changeAmount));
var size = Math.max(
ReaderView.MIN_FONT_SIZE,
Math.min(ReaderView.MAX_FONT_SIZE, this.fontSize + changeAmount)
);
this.setFontSize(size);
}
@ -79,7 +87,7 @@ class ReaderView {
* and ReaderView.MAX_FONT_SIZE.
*/
setFontSize(fontSize) {
let size = (10 + 2 * fontSize) + "px";
let size = 10 + 2 * fontSize + "px";
let readerView = document.getElementById("mozac-readerview-container");
readerView.style.setProperty("font-size", size);
this.fontSize = fontSize;
@ -108,8 +116,8 @@ class ReaderView {
* or sepia.
*/
setColorScheme(colorScheme) {
if(!['light', 'sepia', 'dark'].includes(colorScheme)) {
console.error(`Invalid color scheme specified: ${colorScheme}`)
if (!["light", "sepia", "dark"].includes(colorScheme)) {
console.error(`Invalid color scheme specified: ${colorScheme}`);
return;
}
@ -152,7 +160,7 @@ class ReaderView {
</div>
</div>
</body>
`
`;
}
/**
@ -162,17 +170,21 @@ class ReaderView {
* @param optional language of the article, defaults to en.
*/
getReadingTime(length, lang = "en") {
const [readingSpeed, readingSpeedLang] = this.getReadingSpeedForLanguage(lang);
const [readingSpeed, readingSpeedLang] =
this.getReadingSpeedForLanguage(lang);
const charactersPerMinuteLow = readingSpeed.cpm - readingSpeed.variance;
const charactersPerMinuteHigh = readingSpeed.cpm + readingSpeed.variance;
const readingTimeMinsSlow = Math.ceil(length / charactersPerMinuteLow);
const readingTimeMinsFast = Math.ceil(length / charactersPerMinuteHigh);
const readingTimeMinsFast = Math.ceil(length / charactersPerMinuteHigh);
// Construct a localized and "humanized" reading time in minutes.
// If we have both a fast and slow reading time we'll show both e.g.
// "2 - 4 minutes", otherwise we'll just show "4 minutes".
try {
var parts = new Intl.RelativeTimeFormat(readingSpeedLang).formatToParts(readingTimeMinsSlow, 'minute');
var parts = new Intl.RelativeTimeFormat(readingSpeedLang).formatToParts(
readingTimeMinsSlow,
"minute"
);
if (parts.length == 3) {
// No need to use part[0] which represents the literal "in".
var readingTime = parts[1].value; // reading time in minutes
@ -183,8 +195,7 @@ class ReaderView {
}
return readingTimeString;
}
}
catch(error) {
} catch (error) {
console.error(`Failed to format reading time: ${error}`);
}
@ -202,60 +213,62 @@ class ReaderView {
*/
getReadingSpeedForLanguage(lang) {
const readingSpeed = new Map([
[ "en", {cpm: 987, variance: 118 } ],
[ "ar", {cpm: 612, variance: 88 } ],
[ "de", {cpm: 920, variance: 86 } ],
[ "es", {cpm: 1025, variance: 127 } ],
[ "fi", {cpm: 1078, variance: 121 } ],
[ "fr", {cpm: 998, variance: 126 } ],
[ "he", {cpm: 833, variance: 130 } ],
[ "it", {cpm: 950, variance: 140 } ],
[ "jw", {cpm: 357, variance: 56 } ],
[ "nl", {cpm: 978, variance: 143 } ],
[ "pl", {cpm: 916, variance: 126 } ],
[ "pt", {cpm: 913, variance: 145 } ],
[ "ru", {cpm: 986, variance: 175 } ],
[ "sk", {cpm: 885, variance: 145 } ],
[ "sv", {cpm: 917, variance: 156 } ],
[ "tr", {cpm: 1054, variance: 156 } ],
[ "zh", {cpm: 255, variance: 29 } ],
["en", { cpm: 987, variance: 118 }],
["ar", { cpm: 612, variance: 88 }],
["de", { cpm: 920, variance: 86 }],
["es", { cpm: 1025, variance: 127 }],
["fi", { cpm: 1078, variance: 121 }],
["fr", { cpm: 998, variance: 126 }],
["he", { cpm: 833, variance: 130 }],
["it", { cpm: 950, variance: 140 }],
["jw", { cpm: 357, variance: 56 }],
["nl", { cpm: 978, variance: 143 }],
["pl", { cpm: 916, variance: 126 }],
["pt", { cpm: 913, variance: 145 }],
["ru", { cpm: 986, variance: 175 }],
["sk", { cpm: 885, variance: 145 }],
["sv", { cpm: 917, variance: 156 }],
["tr", { cpm: 1054, variance: 156 }],
["zh", { cpm: 255, variance: 29 }],
]);
return readingSpeed.has(lang) ? [readingSpeed.get(lang), lang] : [readingSpeed.get("en"), "en"];
}
return readingSpeed.has(lang)
? [readingSpeed.get(lang), lang]
: [readingSpeed.get("en"), "en"];
}
getByline(article) {
return article.byline || "";
}
getByline(article) {
return article.byline || "";
}
/**
* Attempts to read the optional text direction from the article and uses
* language mapping to detect rtl, if missing.
*/
getTextDirection(article) {
if (article.dir) {
return article.dir;
}
/**
* Attempts to read the optional text direction from the article and uses
* language mapping to detect rtl, if missing.
*/
getTextDirection(article) {
if (article.dir) {
return article.dir;
}
if (["ar", "fa", "he", "ug", "ur"].includes(article.language)) {
return "rtl";
}
if (["ar", "fa", "he", "ug", "ur"].includes(article.language)) {
return "rtl";
}
return "ltr";
}
return "ltr";
}
getTitle(article) {
return article.title || "";
}
getTitle(article) {
return article.title || "";
}
escapeHTML(text) {
return text
.replace(/\&/g, "&amp;")
.replace(/\</g, "&lt;")
.replace(/\>/g, "&gt;")
.replace(/\"/g, "&quot;")
.replace(/\'/g, "&#039;");
}
escapeHTML(text) {
return text
.replace(/\&/g, "&amp;")
.replace(/\</g, "&lt;")
.replace(/\>/g, "&gt;")
.replace(/\"/g, "&quot;")
.replace(/\'/g, "&#039;");
}
}
function fetchDocument(url) {
@ -282,16 +295,16 @@ function fetchDocument(url) {
function getPreparedDocument(id, url) {
return new Promise((resolve, reject) => {
browser.runtime.sendMessage({action: "getSerializedDoc", id: id}).then((serializedDoc) => {
browser.runtime
.sendMessage({ action: "getSerializedDoc", id: id })
.then(serializedDoc => {
if (serializedDoc) {
let doc = new JSDOMParser().parse(serializedDoc, url);
resolve(doc);
} else {
reject();
}
}
);
});
});
}
@ -306,23 +319,26 @@ function connectNativePort() {
let baseUrl = browser.runtime.getURL("/");
let port = browser.runtime.connectNative("mozacReaderviewActive");
port.onMessage.addListener((message) => {
port.onMessage.addListener(message => {
switch (message.action) {
case 'show':
case "show":
async function showAsync(options) {
try {
let doc;
if (typeof Promise.any === "function") {
doc = await Promise.any([fetchDocument(articleUrl), getPreparedDocument(id, articleUrl)]);
doc = await Promise.any([
fetchDocument(articleUrl),
getPreparedDocument(id, articleUrl),
]);
} else {
try {
doc = await getPreparedDocument(id, articleUrl);
} catch(e) {
} catch (e) {
doc = await fetchDocument(articleUrl);
}
}
readerView.show(doc, articleUrl, options);
} catch(e) {
} catch (e) {
console.log(e);
// We weren't able to find the prepared document and also
// failed to fetch it. Let's load the original page which
@ -332,19 +348,23 @@ function connectNativePort() {
}
showAsync(message.value);
break;
case 'hide':
case "hide":
window.location.href = articleUrl;
case 'setColorScheme':
case "setColorScheme":
readerView.setColorScheme(message.value.toLowerCase());
break;
case 'changeFontSize':
case "changeFontSize":
readerView.changeFontSize(message.value);
break;
case 'setFontType':
case "setFontType":
readerView.setFontType(message.value.toLowerCase());
break;
case 'checkReaderState':
port.postMessage({baseUrl: baseUrl, activeUrl: articleUrl, readerable: true});
case "checkReaderState":
port.postMessage({
baseUrl: baseUrl,
activeUrl: articleUrl,
readerable: true,
});
break;
default:
console.error(`Received invalid action ${message.action}`);

View file

@ -10,12 +10,12 @@
* to the native application.
*/
function sendCurrentState() {
let message = {
'url': document.location.href,
'urls': getLinks(),
'cookies': getCookies()
};
browser.runtime.sendNativeMessage("MozacBrowserAdsMessage", message);
let message = {
url: document.location.href,
urls: getLinks(),
cookies: getCookies(),
};
browser.runtime.sendNativeMessage("MozacBrowserAdsMessage", message);
}
/**
@ -24,17 +24,17 @@ function sendCurrentState() {
* @return {Array<string>} containing all current links in the current page.
*/
function getLinks() {
let urls = [];
let urls = [];
let anchors = document.getElementsByTagName("a");
for (let anchor of anchors) {
if (!anchor.href) {
continue;
}
urls.push(anchor.href);
let anchors = document.getElementsByTagName("a");
for (let anchor of anchors) {
if (!anchor.href) {
continue;
}
urls.push(anchor.href);
}
return urls;
return urls;
}
/**
@ -43,40 +43,38 @@ function getLinks() {
* @return {Array<{name: string, value: string}>} containing all cookies.
*/
function getCookies() {
let cookiesList = document.cookie.split("; ");
let result = [];
let cookiesList = document.cookie.split("; ");
let result = [];
cookiesList.forEach(cookie => {
var [name, ...value] = cookie.split('=');
// For that special cases where the value contains '='.
value = value.join("=")
cookiesList.forEach(cookie => {
var [name, ...value] = cookie.split("=");
// For that special cases where the value contains '='.
value = value.join("=");
result.push({
"name" : name,
"value" : value
});
result.push({
name: name,
value: value,
});
});
return result;
return result;
}
// Whenever a page is first accessed or when loaded from cache
// send all needed data about the ads provider to the app.
const events = ["pageshow", "load"];
const eventLogger = event => {
switch (event.type) {
switch (event.type) {
case "load":
sendCurrentState();
break;
sendCurrentState();
break;
case "pageshow":
if (event.persisted) {
sendCurrentState();
}
break;
if (event.persisted) {
sendCurrentState();
}
break;
default:
console.log('Event:', event.type);
}
console.log("Event:", event.type);
}
};
events.forEach(eventName =>
window.addEventListener(eventName, eventLogger)
);
events.forEach(eventName => window.addEventListener(eventName, eventLogger));

View file

@ -9,11 +9,11 @@
* to the native application.
*/
function sendCurrentState() {
let message = {
'url': document.location.href,
'cookies': getCookies()
};
browser.runtime.sendNativeMessage("MozacBrowserSearchMessage", message);
let message = {
url: document.location.href,
cookies: getCookies(),
};
browser.runtime.sendNativeMessage("MozacBrowserSearchMessage", message);
}
/**
@ -22,40 +22,38 @@ function sendCurrentState() {
* @return {Array<{name: string, value: string}>} containing all cookies.
*/
function getCookies() {
let cookiesList = document.cookie.split("; ");
let result = [];
let cookiesList = document.cookie.split("; ");
let result = [];
cookiesList.forEach(cookie => {
var [name, ...value] = cookie.split('=');
// For that special cases where the cookie value contains '='.
value = value.join("=");
cookiesList.forEach(cookie => {
var [name, ...value] = cookie.split("=");
// For that special cases where the cookie value contains '='.
value = value.join("=");
result.push({
"name" : name,
"value" : value
});
result.push({
name: name,
value: value,
});
});
return result;
return result;
}
// Whenever a page is first accessed or when loaded from cache
// send all needed data about the search provider to the app.
const events = ["pageshow", "load"];
const eventLogger = event => {
switch (event.type) {
switch (event.type) {
case "load":
sendCurrentState();
break;
sendCurrentState();
break;
case "pageshow":
if (event.persisted) {
sendCurrentState();
}
break;
if (event.persisted) {
sendCurrentState();
}
break;
default:
console.log('Event:', event.type);
}
console.log("Event:", event.type);
}
};
events.forEach(eventName =>
window.addEventListener(eventName, eventLogger)
);
events.forEach(eventName => window.addEventListener(eventName, eventLogger));

View file

@ -27,18 +27,11 @@
"96": "icons/lightbulb.svg",
"128": "icons/lightbulb.svg"
},
"permissions": [
"geckoViewAddons",
"nativeMessaging",
"tabs",
"<all_urls>"
],
"permissions": ["geckoViewAddons", "nativeMessaging", "tabs", "<all_urls>"],
"background": {
"persistent": false,
"type": "module",
"scripts": [
"background.js"
]
"scripts": ["background.js"]
},
"page_action": {
"browser_style": true,

View file

@ -1,44 +1,44 @@
{
"recommendations": [
{
"category": "general",
"url": "https://getpocket.com/explore/item/how-to-remember-anything-you-really-want-to-remember-backed-by-science",
"title": "How to Remember Anything You Really Want to Remember, Backed by Science",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fpocket-image-cache.com%2F1200x%2Ffilters%3Aformat(jpg)%3Aextract_focal()%2Fhttps%253A%252F%252Fwww.incimages.com%252Fuploaded_files%252Fimage%252F1920x1080%252Fgetty-862457080_394628.jpg",
"publisher": "Pocket",
"timeToRead": 3
},
{
"category": "general",
"url": "https://www.thecut.com/article/i-dont-want-to-be-like-a-family-with-my-co-workers.html",
"title": "I Dont Want to Be Like a Family With My Co-Workers",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fpyxis.nymag.com%2Fv1%2Fimgs%2Fac8%2Fd22%2F315cd0cf1e3a43edfe0e0548f2edbcb1a1-ask-a-boss.1x.rsocial.w1200.jpg",
"publisher": "The Cut",
"timeToRead": 5
},
{
"category": "general",
"url": "https://www.newyorker.com/news/q-and-a/how-america-failed-in-afghanistan",
"title": "How America Failed in Afghanistan",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fmedia.newyorker.com%2Fphotos%2F6119484157b611aec9c99b43%2F16%3A9%2Fw_1280%2Cc_limit%2FChotiner-Afghanistan01.jpg",
"publisher": "The New Yorker",
"timeToRead": 14
},
{
"category": "general",
"url": "https://www.technologyreview.com/2021/08/15/1031804/digital-beauty-filters-photoshop-photo-editing-colorism-racism/",
"title": "How digital beauty filters perpetuate colorism",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fwp.technologyreview.com%2Fwp-content%2Fuploads%2F2021%2F08%2FBeautyScoreColorism.jpg%3Fresize%3D1200%2C600",
"publisher": "MIT Technology Review",
"timeToRead": 11
},
{
"category": "general",
"url": "https://getpocket.com/explore/item/how-to-get-rid-of-black-mold-naturally",
"title": "How to Get Rid of Black Mold Naturally",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fpocket-image-cache.com%2F1200x%2Ffilters%3Aformat(jpg)%3Aextract_focal()%2Fhttps%253A%252F%252Fpocket-syndicated-images.s3.amazonaws.com%252Farticles%252F6757%252F1628024495_6109ae86db6cc.png",
"publisher": "Pocket",
"timeToRead": 4
}
]
"recommendations": [
{
"category": "general",
"url": "https://getpocket.com/explore/item/how-to-remember-anything-you-really-want-to-remember-backed-by-science",
"title": "How to Remember Anything You Really Want to Remember, Backed by Science",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fpocket-image-cache.com%2F1200x%2Ffilters%3Aformat(jpg)%3Aextract_focal()%2Fhttps%253A%252F%252Fwww.incimages.com%252Fuploaded_files%252Fimage%252F1920x1080%252Fgetty-862457080_394628.jpg",
"publisher": "Pocket",
"timeToRead": 3
},
{
"category": "general",
"url": "https://www.thecut.com/article/i-dont-want-to-be-like-a-family-with-my-co-workers.html",
"title": "I Dont Want to Be Like a Family With My Co-Workers",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fpyxis.nymag.com%2Fv1%2Fimgs%2Fac8%2Fd22%2F315cd0cf1e3a43edfe0e0548f2edbcb1a1-ask-a-boss.1x.rsocial.w1200.jpg",
"publisher": "The Cut",
"timeToRead": 5
},
{
"category": "general",
"url": "https://www.newyorker.com/news/q-and-a/how-america-failed-in-afghanistan",
"title": "How America Failed in Afghanistan",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fmedia.newyorker.com%2Fphotos%2F6119484157b611aec9c99b43%2F16%3A9%2Fw_1280%2Cc_limit%2FChotiner-Afghanistan01.jpg",
"publisher": "The New Yorker",
"timeToRead": 14
},
{
"category": "general",
"url": "https://www.technologyreview.com/2021/08/15/1031804/digital-beauty-filters-photoshop-photo-editing-colorism-racism/",
"title": "How digital beauty filters perpetuate colorism",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fwp.technologyreview.com%2Fwp-content%2Fuploads%2F2021%2F08%2FBeautyScoreColorism.jpg%3Fresize%3D1200%2C600",
"publisher": "MIT Technology Review",
"timeToRead": 11
},
{
"category": "general",
"url": "https://getpocket.com/explore/item/how-to-get-rid-of-black-mold-naturally",
"title": "How to Get Rid of Black Mold Naturally",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fpocket-image-cache.com%2F1200x%2Ffilters%3Aformat(jpg)%3Aextract_focal()%2Fhttps%253A%252F%252Fpocket-syndicated-images.s3.amazonaws.com%252Farticles%252F6757%252F1628024495_6109ae86db6cc.png",
"publisher": "Pocket",
"timeToRead": 4
}
]
}

View file

@ -1,12 +1,12 @@
{
"recommendations": [
{
"category": "science",
"url": "https://getpocket.com/explore/item/you-think-you-know-what-blue-is-but-you-have-no-idea",
"title": "You Think You Know What Blue Is, But You Have No Idea",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fpocket-image-cache.com%2F1200x%2Ffilters%3Aformat(jpg)%3Aextract_focal()%2Fhttps%253A%252F%252Fpocket-syndicated-images.s3.amazonaws.com%252Farticles%252F3713%252F1584373694_GettyImages-83522858.jpg",
"publisher": "Pocket",
"timeToRead": 3
}
]
"recommendations": [
{
"category": "science",
"url": "https://getpocket.com/explore/item/you-think-you-know-what-blue-is-but-you-have-no-idea",
"title": "You Think You Know What Blue Is, But You Have No Idea",
"imageUrl": "https://img-getpocket.cdn.mozilla.net/{wh}/filters:format(jpeg):quality(60):no_upscale():strip_exif()/https%3A%2F%2Fpocket-image-cache.com%2F1200x%2Ffilters%3Aformat(jpg)%3Aextract_focal()%2Fhttps%253A%252F%252Fpocket-syndicated-images.s3.amazonaws.com%252Farticles%252F3713%252F1584373694_GettyImages-83522858.jpg",
"publisher": "Pocket",
"timeToRead": 3
}
]
}

View file

@ -2,22 +2,24 @@
<div class="wrapper">
<a class="site-title" rel="author" href="/">Mozilla Android Components</a>
<nav class="site-nav">
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger">
<span class="menu-icon">
<svg viewBox="0 0 18 15" width="18px" height="15px">
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
</svg>
</span>
</label>
<nav class="site-nav">
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger">
<span class="menu-icon">
<svg viewBox="0 0 18 15" width="18px" height="15px">
<path
d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"
/>
</svg>
</span>
</label>
<div class="trigger">
<a class="page-link" href="/components/">Components</a>
<a class="page-link" href="/changelog/">Changelog</a>
<a class="page-link" href="/blog/">Blog</a>
<a class="page-link" href="/contributing/">Contributing</a>
</div>
</nav>
<div class="trigger">
<a class="page-link" href="/components/">Components</a>
<a class="page-link" href="/changelog/">Changelog</a>
<a class="page-link" href="/blog/">Blog</a>
<a class="page-link" href="/contributing/">Contributing</a>
</div>
</nav>
</div>
</header>

View file

@ -1,16 +1,16 @@
<h1 class="entry-title">
<!--<a href="{{ root_url }}{{ page.url }}">{{ page.title }}</a>-->
<!--<a href="{{ root_url }}{{ page.url }}">{{ page.title }}</a>-->
</h1>
<ul>
{% if post.title %}
<li>
{{ post.date | date: '%B %d, %Y' }}
<br/>
{% if post.external_url %}
<a href="{{ post.external_url }}">{{ post.title | escape }}</a>
{% else %}
<a href="{{ post.url | relative_url }}">{{ post.title | escape }}</a>
{% endif %}
</li>
{% if post.title %}
<li>
{{ post.date | date: '%B %d, %Y' }}
<br />
{% if post.external_url %}
<a href="{{ post.external_url }}">{{ post.title | escape }}</a>
{% else %}
<a href="{{ post.url | relative_url }}">{{ post.title | escape }}</a>
{% endif %}
</li>
{% endif %}
</ul>

View file

@ -1,38 +1,53 @@
---
layout: default
---
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
<article
class="post h-entry"
itemscope
itemtype="http://schema.org/BlogPosting"
>
<header class="post-header">
<h1 class="post-title p-name" itemprop="name headline">{{ page.title | escape }}</h1>
<h1 class="post-title p-name" itemprop="name headline">
{{ page.title | escape }}
</h1>
<p class="post-meta">
<time class="dt-published" datetime="{{ page.date | date_to_xmlschema }}" itemprop="datePublished">
{%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%}
{{ page.date | date: date_format }}
<time
class="dt-published"
datetime="{{ page.date | date_to_xmlschema }}"
itemprop="datePublished"
>
{%- assign date_format = site.minima.date_format | default: "%b %-d, %Y"
-%} {{ page.date | date: date_format }}
</time>
{%- if page.author -%}
-
{% assign author = site.data.authors[page.author] %}
<span itemprop="author" itemscope itemtype="http://schema.org/Person">
<span class="p-author h-card" itemprop="name">
<img src="{{ author.image }}" width="20" height="20" style="margin:5px;" />
{{ author.name }}
{%- if author.twitter -%}
<a href="{{ author.twitter }}"><svg class="svg-icon" style="margin-left:10px;"><use xlink:href="{{ '/assets/minima-social-icons.svg#twitter' | relative_url }}"></use></svg></a>
{%- endif -%}
</span>
</span>
{%- if page.author -%} - {% assign author = site.data.authors[page.author]
%}
<span itemprop="author" itemscope itemtype="http://schema.org/Person">
<span class="p-author h-card" itemprop="name">
<img
src="{{ author.image }}"
width="20"
height="20"
style="margin: 5px"
/>
{{ author.name }} {%- if author.twitter -%}
<a href="{{ author.twitter }}"
><svg class="svg-icon" style="margin-left: 10px">
<use
xlink:href="{{ '/assets/minima-social-icons.svg#twitter' | relative_url }}"
></use></svg
></a>
{%- endif -%}
</span>
</span>
{%- endif -%}
</p>
</header>
<div class="post-content e-content" itemprop="articleBody">
{{ content }}
</div>
<div class="post-content e-content" itemprop="articleBody">{{ content }}</div>
{%- if site.disqus.shortname -%}
{%- include disqus_comments.html -%}
{%- endif -%}
{%- if site.disqus.shortname -%} {%- include disqus_comments.html -%} {%-
endif -%}
<a class="u-url" href="{{ page.url | relative_url }}" hidden></a>
</article>

View file

@ -3,11 +3,11 @@
* @return {Element}
*/
function htmlToElement(html) {
let template = document.createElement('template');
html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = html;
//firstChild may be a comment so we must use firstElementChild to avoid picking it
return template.content.firstElementChild;
let template = document.createElement("template");
html = html.trim(); // Never return a text node of whitespace as the result
template.innerHTML = html;
//firstChild may be a comment so we must use firstElementChild to avoid picking it
return template.content.firstElementChild;
}
/**
@ -17,81 +17,90 @@ function htmlToElement(html) {
* @returns {String} The same string but in the standard SVG representation
*/
function androidSVGtoNormalSVG(s) {
s = s.replace(/<\?xml version="1\.0" encoding="utf-8"\?>/g, '');
s = s.replace(/<vector xmlns:android="http:\/\/schemas.android.com\/apk\/res\/android"/g, '<svg xmlns="http://www.w3.org/2000/svg"');
s = s.replace(/<\/vector>/g, '</svg>');
s = s.replace(/android:(height|width)="(\d+)dp"/g, '');
s = s.replace(/android:viewportHeight="(\d+\.?\d+)"/g, 'height="$1"');
s = s.replace(/android:viewportWidth="(\d+\.?\d+)"/g, 'width="$1"');
s = s.replace(/android:fillColor=/g, 'fill=');
s = s.replace(/android:pathData=/g, 'd=');
//s = s.replace(/android:/g, '');
return s;
s = s.replace(/<\?xml version="1\.0" encoding="utf-8"\?>/g, "");
s = s.replace(
/<vector xmlns:android="http:\/\/schemas.android.com\/apk\/res\/android"/g,
'<svg xmlns="http://www.w3.org/2000/svg"'
);
s = s.replace(/<\/vector>/g, "</svg>");
s = s.replace(/android:(height|width)="(\d+)dp"/g, "");
s = s.replace(/android:viewportHeight="(\d+\.?\d+)"/g, 'height="$1"');
s = s.replace(/android:viewportWidth="(\d+\.?\d+)"/g, 'width="$1"');
s = s.replace(/android:fillColor=/g, "fill=");
s = s.replace(/android:pathData=/g, "d=");
//s = s.replace(/android:/g, '');
return s;
}
function addToTable(name, svg) {
let table = document.querySelector("#preview_table > tbody");
let row = htmlToElement("<tr></tr>");
row.appendChild(htmlToElement("<td>" + name + "</td>"));
let td = htmlToElement("<td></td>");
td.appendChild(svg);
row.appendChild(td);
table.appendChild(row);
let table = document.querySelector("#preview_table > tbody");
let row = htmlToElement("<tr></tr>");
row.appendChild(htmlToElement("<td>" + name + "</td>"));
let td = htmlToElement("<td></td>");
td.appendChild(svg);
row.appendChild(td);
table.appendChild(row);
}
function addSingleItemToTable(str) {
let table = document.querySelector("#preview_table > tbody");
table.append(htmlToElement("<tr><td colspan='2'>" + str + "</td></tr>"))
let table = document.querySelector("#preview_table > tbody");
table.append(htmlToElement("<tr><td colspan='2'>" + str + "</td></tr>"));
}
function getFile(iconName, downloadUrl) {
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest();
request.open('GET', downloadUrl, true);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
let androidXmlText = request.responseText;
androidXmlText = androidSVGtoNormalSVG(androidXmlText);
resolve([iconName, androidXmlText]);
} else if (request.readyState === 4) {
//Request completed with an error
resolve([iconName, "<span>Error during download</span>"]);
}
};
request.send(null);
});
return new Promise((resolve, reject) => {
let request = new XMLHttpRequest();
request.open("GET", downloadUrl, true);
request.onreadystatechange = function () {
if (request.readyState === 4 && request.status === 200) {
let androidXmlText = request.responseText;
androidXmlText = androidSVGtoNormalSVG(androidXmlText);
resolve([iconName, androidXmlText]);
} else if (request.readyState === 4) {
//Request completed with an error
resolve([iconName, "<span>Error during download</span>"]);
}
};
request.send(null);
});
}
// This function recovers all icons inside the drawable folder via github API
(function getIcons() {
let request = new XMLHttpRequest();
request.open("GET", "https://api.github.com/repos/mozilla-mobile/android-components/contents/components/ui/icons/src/main/res/drawable", true);
//Explicit request of the V3 version of the API
request.setRequestHeader("Accept", "application/vnd.github.v3+json");
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE && request.status === 200) {
let response = JSON.parse(request.response);
if (response.message) {
//Something went wrong
addSingleItemToTable("Error: " + response.message);
return;
}
addSingleItemToTable("Loading");
let promises = [];
for (let i = 0; i < response.length; i++) {
let iconName = response[i]['name'].substr(0, response[i]['name'].length - 4);
promises.push(getFile(iconName, response[i]['download_url']));
}
Promise.all(promises).then((values) => {
document.querySelector("#preview_table > tbody").innerHTML = "";
for (let i = 0; i < values.length; i++) {
let name = values[i][0], svg = values[i][1];
addToTable(name, htmlToElement(svg));
}
});
let request = new XMLHttpRequest();
request.open(
"GET",
"https://api.github.com/repos/mozilla-mobile/android-components/contents/components/ui/icons/src/main/res/drawable",
true
);
//Explicit request of the V3 version of the API
request.setRequestHeader("Accept", "application/vnd.github.v3+json");
request.onreadystatechange = function () {
if (request.readyState === XMLHttpRequest.DONE && request.status === 200) {
let response = JSON.parse(request.response);
if (response.message) {
//Something went wrong
addSingleItemToTable("Error: " + response.message);
return;
}
addSingleItemToTable("Loading");
let promises = [];
for (let i = 0; i < response.length; i++) {
let iconName = response[i]["name"].substr(
0,
response[i]["name"].length - 4
);
promises.push(getFile(iconName, response[i]["download_url"]));
}
Promise.all(promises).then(values => {
document.querySelector("#preview_table > tbody").innerHTML = "";
for (let i = 0; i < values.length; i++) {
let name = values[i][0],
svg = values[i][1];
addToTable(name, htmlToElement(svg));
}
};
request.send(null);
});
}
};
request.send(null);
})();

View file

@ -1,5 +1,5 @@
<html>
<body>
<h1 id="website_title">Hello World!</h1>
</body>
<body>
<h1 id="website_title">Hello World!</h1>
</body>
</html>

View file

@ -2,4 +2,4 @@
* 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/. */
document.body.style.border = "5px solid red";
document.body.style.border = "5px solid red";

View file

@ -6,7 +6,7 @@
* inadvertently match elements in the article content. */
// Counts to three and sends a greeting via the browser action of a newly created tab.
browser.tabs.onCreated.addListener((tab) => {
browser.tabs.onCreated.addListener(tab => {
let counter = 0;
let intervalId = setInterval(() => {
var message;
@ -16,9 +16,12 @@ browser.tabs.onCreated.addListener((tab) => {
message = "Hi!";
clearInterval(intervalId);
}
browser.browserAction.setBadgeTextColor({tabId: tab.id, color: "#FFFFFF"});
browser.browserAction.setBadgeText({tabId: tab.id, text: message});
browser.browserAction.setBadgeTextColor({
tabId: tab.id,
color: "#FFFFFF",
});
browser.browserAction.setBadgeText({ tabId: tab.id, text: message });
}, 1000);
});
browser.browserAction.setBadgeBackgroundColor({color: "#AAAAAA"});
browser.browserAction.setBadgeBackgroundColor({ color: "#AAAAAA" });

View file

@ -16,7 +16,5 @@
"default_title": "Test",
"default_popup": "popup.html"
},
"permissions": [
"tabs"
]
"permissions": ["tabs"]
}

View file

@ -1,17 +1,17 @@
<html>
<head>
<meta name="viewport" content="width=device-width">
<head>
<meta name="viewport" content="width=device-width" />
<title>Address_Form</title>
</head>
<body>
</head>
<body>
<form>
<p>Street Address: <input id="streetAddress" type="text"></p>
<p>City: <input id="city" type="text"></p>
<p>Zip Code: <input id="zipCode" type="text"></p>
<p>Country: <input id="country" type="text"></p>
<p>Telephone: <input id="telephone" type="text"></p>
<p>Email: <input id="email" type="text"></p>
<p>Apartment, suite, etc. <input id="apartment" type="text"></p>
<p>Street Address: <input id="streetAddress" type="text" /></p>
<p>City: <input id="city" type="text" /></p>
<p>Zip Code: <input id="zipCode" type="text" /></p>
<p>Country: <input id="country" type="text" /></p>
<p>Telephone: <input id="telephone" type="text" /></p>
<p>Email: <input id="email" type="text" /></p>
<p>Apartment, suite, etc. <input id="apartment" type="text" /></p>
</form>
</body>
</body>
</html>

View file

@ -1,13 +1,13 @@
<html>
<head>
<head>
<title>Audio_Test_Page</title>
</head>
<body>
<p id="testContent">Page content: audio player</p>
<div class="audioPlayer">
<audio id="audioSample" controls loop>
<source src="../resources/audioSample.mp3">
</audio>
</div>
</body>
</head>
<body>
<p id="testContent">Page content: audio player</p>
<div class="audioPlayer">
<audio id="audioSample" controls loop>
<source src="../resources/audioSample.mp3" />
</audio>
</div>
</body>
</html>

View file

@ -1,17 +1,31 @@
<html>
<head>
<meta name="viewport" content="width=device-width">
<head>
<meta name="viewport" content="width=device-width" />
<title>Credit_Card_Form</title>
</head>
<body>
</head>
<body>
<form>
<p>Card information</p>
<p>Card Number: <input id="cardNumber" type="text" placeholder="1234 1234 1234 1234"></p>
<p>Name on card: <input id="nameOnCard"type="text" placeholder="Name on card"></p>
<p> Expiry date:
<input id="expiryMonthAndYear" inputmode="numerical" placeholder="MM / YYYY" type="text" />
</p>
<p><input type="submit" id="submit" value="Submit" aria-label="submit"/></p>
<p>Card information</p>
<p>
Card Number:
<input id="cardNumber" type="text" placeholder="1234 1234 1234 1234" />
</p>
<p>
Name on card:
<input id="nameOnCard" type="text" placeholder="Name on card" />
</p>
<p>
Expiry date:
<input
id="expiryMonthAndYear"
inputmode="numerical"
placeholder="MM / YYYY"
type="text"
/>
</p>
<p>
<input type="submit" id="submit" value="Submit" aria-label="submit" />
</p>
</form>
</body>
</body>
</html>

View file

@ -1,15 +1,19 @@
<html>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
<!-- 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/. -->
<!-- This asset is using the code behind
<!-- This asset is using the code behind
- https://www.mozilla-anti-tracking.com/test/dfpi/storage_access_api.html
- test page.
- Source repository: https://github.com/mozilla/anti-tracking-test-pages -->
<body>
<h2>Cross-site cookies storage access test</h2>
<h3>anti-tracker-test.com</h3>
<h4>different site, cross-origin iframe</h4>
<iframe width=500 height=1000 src="https://mozilla-mobile.github.io/testapp/anti-tracker-test_set_storage_with_sa_api.html"></iframe>
</body>
<body>
<h2>Cross-site cookies storage access test</h2>
<h3>anti-tracker-test.com</h3>
<h4>different site, cross-origin iframe</h4>
<iframe
width="500"
height="1000"
src="https://mozilla-mobile.github.io/testapp/anti-tracker-test_set_storage_with_sa_api.html"
></iframe>
</body>
</html>

View file

@ -1,29 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<head>
<title>Html_Control_Form</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
</head>
<p>Misc Link Types</p>
<section>
<p>Misc Link Types</p>
<section>
<a href="mailto://example@example.com">Email link</a>
</section>
</section>
<section>
<section>
<a href="tel://1234567890">Telephone link</a>
</section>
</section>
<section>
<section>
<a href="vnd.youtube://@Mozilla">Youtube schema link</a>
</section>
</section>
<section>
<section>
<a href="https://m.youtube.com/user/mozilla?cbrd=1">Youtube full link</a>
</section>
</section>
<section>
<a href="http://play.google.com/store/apps/details?id=org.mozilla.firefox">Playstore link</a>
</section>
<section>
<a href="http://play.google.com/store/apps/details?id=org.mozilla.firefox"
>Playstore link</a
>
</section>
</html>

View file

@ -1,10 +1,10 @@
<html>
<head>
<head>
<title>Test_Page_1</title>
</head>
<body>
<h1>
<p id="testContent">Page content: 1</p>
</h1>
</body>
</head>
<body>
<h1>
<p id="testContent">Page content: 1</p>
</h1>
</body>
</html>

View file

@ -1,10 +1,10 @@
<html>
<head>
<head>
<title>Test_Page_2</title>
</head>
<body>
<h1>
<p id="testContent">Page content: 2</p>
</h1>
</body>
</head>
<body>
<h1>
<p id="testContent">Page content: 2</p>
</h1>
</body>
</html>

View file

@ -1,16 +1,19 @@
<html>
<head>
<head>
<title>Test_Page_3</title>
</head>
<body>
<h1>
<p id="testContent">Page content: 3</p>
<p>
<a href="https://play.google.com/store/apps/details?id=org.mozilla.fenix">Mozilla Playstore link</a>
</p>
<p>
</head>
<body>
<h1>
<p id="testContent">Page content: 3</p>
<p>
<a
href="https://play.google.com/store/apps/details?id=org.mozilla.fenix"
>Mozilla Playstore link</a
>
</p>
<p>
<a href="../resources/pdfForm.pdf">PDF form file</a>
</p>
</h1>
</body>
</p>
</h1>
</body>
</html>

View file

@ -1,20 +1,20 @@
<html>
<head>
<head>
<meta name="viewport" content="width=device-width" />
<title>Test_Page_4</title>
</head>
<body>
</head>
<body>
<p id="testContent">Page content: 4</p>
<a href="generic1.html">Link 1</a>
<a href="generic2.html">Link 2</a>
<a href="generic3.html">Link 3</a>
<p>
<a href="../resources/rabbit.jpg">
<img src="../resources/rabbit.jpg" alt="test_link_image">
</a>
<a href="../resources/rabbit.jpg">
<img src="../resources/rabbit.jpg" alt="test_link_image" />
</a>
</p>
<p>
<img src="../resources/rabbit.jpg" alt="test_no_link_image">
<img src="../resources/rabbit.jpg" alt="test_no_link_image" />
</p>
</body>
</body>
</html>

View file

@ -1,15 +1,14 @@
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width">
<body>
<script type = "text/javascript" >
const gpcValue = navigator.globalPrivacyControl
if (gpcValue) {
document.write('<p>GPC is enabled.</p>');
} else {
document.write('<p>GPC not enabled.</p>');
}
</script>
</body>
<meta name="viewport" content="width=device-width" />
<body>
<script type="text/javascript">
const gpcValue = navigator.globalPrivacyControl;
if (gpcValue) {
document.write("<p>GPC is enabled.</p>");
} else {
document.write("<p>GPC not enabled.</p>");
}
</script>
</body>
</html>

View file

@ -1,36 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod tempor invidunt
</title>
<meta content="width=device-width, initial-scale=1" name="viewport" />
</head>
<head>
<meta charset="utf-8"/>
<title>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod tempor invidunt</title>
<meta content="width=device-width, initial-scale=1"
name="viewport"/>
</head>
<body>
<p id="testContent">Page content: lorem ipsum</p>
<body>
<p id="testContent">Page content: lorem ipsum</p>
<h1>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor
sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor
sit amet.
</p>
</body>
<h1>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod tempor invidunt
</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit
amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed
diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.
Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor
sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam
erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea
rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum
dolor sit amet.
</p>
</body>
</html>

View file

@ -1,49 +1,51 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<!-- 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/. -->
<html>
<head>
<head>
<title>Muted_Video_Test_Page</title>
</head>
<body>
<p id="testContent">Page content: muted video player</p>
<div class="playbackState">
<p>Media file not playing</p>
</div>
<div id="video-container" style="text-align:center">
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="fullscreen()">Full Screen</button>
<br><br>
<video id="mutedVideo" width="420" autoplay muted controls loop>
<source src="../resources/clip.mp4" type="video/mp4">
</head>
<body>
<p id="testContent">Page content: muted video player</p>
<div class="playbackState">
<p>Media file not playing</p>
</div>
<div id="video-container" style="text-align: center">
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="fullscreen()">Full Screen</button>
<br /><br />
<video id="mutedVideo" width="420" autoplay muted controls loop>
<source src="../resources/clip.mp4" type="video/mp4" />
Your browser does not support HTML video.
</video>
</div>
</video>
</div>
<script>
const mutedVideo = document.getElementById("mutedVideo");
<script>
const mutedVideo = document.getElementById("mutedVideo");
function play() {
function play() {
mutedVideo.play();
}
}
function pause() {
function pause() {
mutedVideo.pause();
}
}
function fullscreen() {
function fullscreen() {
mutedVideo.requestFullscreen();
}
}
mutedVideo.addEventListener('playing', (event) => {
document.querySelector('.playbackState').innerHTML="Media file is playing";
});
mutedVideo.addEventListener("playing", event => {
document.querySelector(".playbackState").innerHTML =
"Media file is playing";
});
mutedVideo.addEventListener('pause', (event) => {
document.querySelector('.playbackState').innerHTML="Media file is paused";
});
</script>
</body>
mutedVideo.addEventListener("pause", event => {
document.querySelector(".playbackState").innerHTML =
"Media file is paused";
});
</script>
</body>
</html>

View file

@ -1,22 +1,23 @@
<html>
<head>
<meta name="viewport" content="width=device-width" />
</head>
<head>
<meta name="viewport" content="width=device-width">
</head>
<body aria-label="body">
<form method="GET" action="passwordsubmit.html">
<p>Username: <input id="username" type="text" value="test@example.com"></p>
<p>Password: <input id="password" type="password" value="verysecret"></p>
<p><input type="submit" id="submit" value="Login" aria-label="submit"/></p>
</form>
</body>
<script>
document.getElementById("password").value = Math.random().toString();
</script>
<body aria-label="body">
<form method="GET" action="passwordsubmit.html">
<p>
Username: <input id="username" type="text" value="test@example.com" />
</p>
<p>
Password: <input id="password" type="password" value="verysecret" />
</p>
<p>
<input type="submit" id="submit" value="Login" aria-label="submit" />
</p>
</form>
</body>
<script>
document.getElementById("password").value = Math.random().toString();
</script>
</html>

View file

@ -1,8 +1,8 @@
<html>
<head>
<meta name="viewport" content="width=device-width">
</head>
<body aria-label="body">
<p>Password submitted. Nope just a test.</p>
</body>
<head>
<meta name="viewport" content="width=device-width" />
</head>
<body aria-label="body">
<p>Password submitted. Nope just a test.</p>
</body>
</html>

View file

@ -1,44 +1,41 @@
<html>
<script>
function setCookie(newVal){
window.document.cookie = "pageStatus = " + newVal + ";";
<script>
function setCookie(newVal) {
window.document.cookie = "pageStatus = " + newVal + ";";
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
var nameEQ = name + "=";
var ca = document.cookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == " ") c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
function valSwap(){
currentCookie = readCookie("pageStatus");
if(currentCookie == null) {
setCookie("DEFAULT");
}
function valSwap() {
currentCookie = readCookie("pageStatus");
if (currentCookie == null) {
setCookie("DEFAULT");
}
if (currentCookie.localeCompare("REFRESHED") == 0) {
setCookie("DEFAULT");
return "DEFAULT";
} else {
setCookie("REFRESHED");
return "REFRESHED";
}
if (currentCookie.localeCompare("REFRESHED") == 0) {
setCookie("DEFAULT");
return "DEFAULT";
} else {
setCookie("REFRESHED");
return "REFRESHED";
}
}
var textToShow = valSwap();
window.addEventListener('DOMContentLoaded', (event) => {
document.querySelector('h1').innerHTML = textToShow;
window.addEventListener("DOMContentLoaded", event => {
document.querySelector("h1").innerHTML = textToShow;
});
</script>
<body>
<h1>DEFAULT</h1>
</body>
</script>
<body>
<h1>DEFAULT</h1>
</body>
</html>

View file

@ -1,23 +1,21 @@
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width">
<body>
<meta name="viewport" content="width=device-width" />
<body>
<h1>Storage check</h1>
<h1>Storage check</h1>
<script type="text/javascript">
if (sessionStorage.getItem("sessionTest") == "session storage") {
document.write("<p>Session storage has value</p>");
} else {
document.write("<p>Session storage empty</p>");
}
<script type="text/javascript">
if (sessionStorage.getItem('sessionTest') == 'session storage') {
document.write('<p>Session storage has value</p>');
} else {
document.write('<p>Session storage empty</p>');
}
if (localStorage.getItem('localTest') == 'local storage') {
document.write('<p>Local storage has value</p>');
} else {
document.write('<p>Local storage empty</p>');
}
</script>
</body>
if (localStorage.getItem("localTest") == "local storage") {
document.write("<p>Local storage has value</p>");
} else {
document.write("<p>Local storage empty</p>");
}
</script>
</body>
</html>

View file

@ -1,28 +1,30 @@
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width">
<body>
<meta name="viewport" content="width=device-width" />
<body>
<h1>Storage Write</h1>
<h1>Storage Write</h1>
<p id="cookies"></p>
<button id="setCookies">Set cookies</button>
<p id="cookies"></p>
<button id="setCookies">Set cookies</button>
<script type="text/javascript">
(function () {
document.getElementById("cookies").textContent = document.cookie
? document.cookie
: "No cookies set";
})();
<script type="text/javascript">
(function() {
document.getElementById("cookies").textContent = document.cookie?document.cookie:"No cookies set";
})();
document
.getElementById("setCookies")
.addEventListener("click", function () {
document.cookie = "user=android";
document.getElementById("cookies").textContent = document.cookie;
});
document.getElementById("setCookies").addEventListener("click", function() {
document.cookie = "user=android";
document.getElementById("cookies").textContent = document.cookie;
});
sessionStorage.setItem("sessionTest", "session storage");
localStorage.setItem("localTest", "local storage");
sessionStorage.setItem('sessionTest', 'session storage');
localStorage.setItem('localTest', 'local storage');
document.write('<p>Values written to storage</p>');
</script>
</body>
document.write("<p>Values written to storage</p>");
</script>
</body>
</html>

View file

@ -1,49 +1,51 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<!-- 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/. -->
<html>
<head>
<head>
<title>Video_Test_Page</title>
</head>
<body>
<p id="testContent">Page content: video player</p>
<div class="playbackState">
<p>Media file not playing</p>
</div>
<div id="video-container" style="text-align:center">
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="fullscreen()">Full Screen</button>
<br><br>
<video id="video" width="420" autoplay controls loop>
<source src="../resources/clip.mp4" type="video/mp4">
</head>
<body>
<p id="testContent">Page content: video player</p>
<div class="playbackState">
<p>Media file not playing</p>
</div>
<div id="video-container" style="text-align: center">
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="fullscreen()">Full Screen</button>
<br /><br />
<video id="video" width="420" autoplay controls loop>
<source src="../resources/clip.mp4" type="video/mp4" />
Your browser does not support HTML video.
</video>
</div>
</video>
</div>
<script>
const video = document.getElementById("video");
<script>
const video = document.getElementById("video");
function play() {
function play() {
video.play();
}
}
function pause() {
function pause() {
video.pause();
}
}
function fullscreen() {
function fullscreen() {
video.requestFullscreen();
}
}
video.addEventListener('playing', (event) => {
document.querySelector('.playbackState').innerHTML="Media file is playing";
});
video.addEventListener("playing", event => {
document.querySelector(".playbackState").innerHTML =
"Media file is playing";
});
video.addEventListener('pause', (event) => {
document.querySelector('.playbackState').innerHTML="Media file is paused";
});
</script>
</body>
video.addEventListener("pause", event => {
document.querySelector(".playbackState").innerHTML =
"Media file is paused";
});
</script>
</body>
</html>

View file

@ -8,19 +8,17 @@
*/
EnableEngines(["bookmarks"]);
var phases = { "phase1": "profile1" };
var phases = { phase1: "profile1" };
// expected bookmark state
var bookmarksCreated = {
"mobile": [{
uri: "http://www.example.com/",
title: "Example Domain"}]
mobile: [
{
uri: "http://www.example.com/",
title: "Example Domain",
},
],
};
// sync and verify bookmarks
Phase("phase1", [
[Sync],
[Bookmarks.add, bookmarksCreated],
[Sync]
]);
Phase("phase1", [[Sync], [Bookmarks.add, bookmarksCreated], [Sync]]);

View file

@ -8,18 +8,17 @@
*/
EnableEngines(["bookmarks"]);
var phases = { "phase1": "profile1" };
var phases = { phase1: "profile1" };
// expected bookmark state
var bookmarksExpected = {
"mobile": [{
uri: "http://www.example.com/",
title: "Example Domain"}]
mobile: [
{
uri: "http://www.example.com/",
title: "Example Domain",
},
],
};
// sync and verify bookmarks
Phase("phase1", [
[Sync],
[Bookmarks.verify, bookmarksExpected],
]);
Phase("phase1", [[Sync], [Bookmarks.verify, bookmarksExpected]]);

View file

@ -8,26 +8,18 @@
*/
EnableEngines(["history"]);
var phases = { "phase1": "profile1" };
var phases = { phase1: "profile1" };
// expected history state
var historyCreated = [
{ uri: "http://www.example.com/",
visits: [
{ type: 1 ,
date: 0
},
{ type: 2,
date: -1
}
]
}
{
uri: "http://www.example.com/",
visits: [
{ type: 1, date: 0 },
{ type: 2, date: -1 },
],
},
];
// sync and verify history
Phase("phase1", [
[Sync],
[History.add, historyCreated],
[Sync]
]);
Phase("phase1", [[Sync], [History.add, historyCreated], [Sync]]);

View file

@ -8,21 +8,12 @@
*/
EnableEngines(["history"]);
var phases = { "phase1": "profile1" };
var phases = { phase1: "profile1" };
// expected history state
var historyExpected = [
{ uri: "http://www.example.com/",
visits: [
{ type: 1 },
{ type: 2 }
]
}
{ uri: "http://www.example.com/", visits: [{ type: 1 }, { type: 2 }] },
];
// sync and verify history
Phase("phase1", [
[Sync],
[History.verify, historyExpected]
]);
Phase("phase1", [[Sync], [History.verify, historyExpected]]);

View file

@ -8,11 +8,11 @@
*/
EnableEngines(["passwords"]);
var phases = { "phase1": "profile1" };
var phases = { phase1: "profile1" };
// expected tabs state
var password_list = [{
var password_list = [
{
hostname: "https://accounts.google.com",
submitURL: "https://accounts.google.com/signin/challenge/sl/password",
realm: null,
@ -20,11 +20,8 @@ var password_list = [{
password: "test15mz",
usernameField: "Email",
passwordField: "Passwd",
}];
},
];
// sync and verify tabs
Phase("phase1", [
[Sync],
[Passwords.add, password_list],
[Sync]
]);
Phase("phase1", [[Sync], [Passwords.add, password_list], [Sync]]);

View file

@ -6,37 +6,39 @@
* Handles the parsing of the ErrorPages URI and then passes them to injectValues
*/
function parseQuery(queryString) {
if (queryString[0] === '?') {
queryString = queryString.substr(1);
}
const query = Object.fromEntries(new URLSearchParams(queryString).entries());
injectValues(query);
};
if (queryString[0] === "?") {
queryString = queryString.substr(1);
}
const query = Object.fromEntries(new URLSearchParams(queryString).entries());
injectValues(query);
}
/**
* Updates the HTML elements based on the queryMap
*/
function injectValues(queryMap) {
// Go through each element and inject the values
document.title = queryMap.title;
document.getElementById('errorTitleText').innerHTML = queryMap.title;
document.getElementById('errorShortDesc').innerHTML = queryMap.description;
// Go through each element and inject the values
document.title = queryMap.title;
document.getElementById("errorTitleText").innerHTML = queryMap.title;
document.getElementById("errorShortDesc").innerHTML = queryMap.description;
// If no image is passed in, remove the element so as not to leave an empty iframe
const errorImage = document.getElementById('errorImage');
if (!queryMap.image) {
errorImage.remove();
} else {
errorImage.src = "resource://android/assets/" + queryMap.image;
}
// If no image is passed in, remove the element so as not to leave an empty iframe
const errorImage = document.getElementById("errorImage");
if (!queryMap.image) {
errorImage.remove();
} else {
errorImage.src = "resource://android/assets/" + queryMap.image;
}
}
document.addEventListener('DOMContentLoaded', function () {
if (window.history.length == 1) {
document.getElementById('backButton').style.display = 'none';
} else {
document.getElementById('backButton').addEventListener('click', () => window.history.back() );
}
document.addEventListener("DOMContentLoaded", function () {
if (window.history.length == 1) {
document.getElementById("backButton").style.display = "none";
} else {
document
.getElementById("backButton")
.addEventListener("click", () => window.history.back());
}
});
parseQuery(document.documentURI);

View file

@ -8,7 +8,10 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width; user-scalable=false;" />
<meta http-equiv="Content-Security-Policy" content="default-src resource:; object-src 'none'" />
<meta
http-equiv="Content-Security-Policy"
content="default-src resource:; object-src 'none'"
/>
<link rel="stylesheet" type="text/css" href="shared_error_style.css" />
<link rel="stylesheet" type="text/css" href="high_risk_error_style.css" />
</head>

View file

@ -6,52 +6,56 @@
* Handles the parsing of the ErrorPages URI and then passes them to injectValues
*/
function parseQuery(queryString) {
if (queryString[0] === '?') {
queryString = queryString.substr(1);
}
const query = Object.fromEntries(new URLSearchParams(queryString).entries());
injectValues(query);
updateShowSSL(query);
updateShowHSTS(query);
};
if (queryString[0] === "?") {
queryString = queryString.substr(1);
}
const query = Object.fromEntries(new URLSearchParams(queryString).entries());
injectValues(query);
updateShowSSL(query);
updateShowHSTS(query);
}
/**
* Updates the HTML elements based on the queryMap
*/
function injectValues(queryMap) {
const tryAgainButton = document.getElementById('errorTryAgain');
const continueHttpButton = document.getElementById("continueHttp");
const backFromHttpButton = document.getElementById('backFromHttp');
const tryAgainButton = document.getElementById("errorTryAgain");
const continueHttpButton = document.getElementById("continueHttp");
const backFromHttpButton = document.getElementById("backFromHttp");
// Go through each element and inject the values
document.title = queryMap.title;
tryAgainButton.innerHTML = queryMap.button;
continueHttpButton.innerHTML = queryMap.continueHttpButton;
backFromHttpButton.innerHTML = queryMap.badCertGoBack;
document.getElementById('errorTitleText').innerHTML = queryMap.title;
document.getElementById('errorShortDesc').innerHTML = queryMap.description;
document.getElementById('advancedButton').innerHTML = queryMap.badCertAdvanced;
document.getElementById('badCertTechnicalInfo').innerHTML = queryMap.badCertTechInfo;
document.getElementById('advancedPanelBackButton').innerHTML = queryMap.badCertGoBack;
document.getElementById('advancedPanelAcceptButton').innerHTML = queryMap.badCertAcceptTemporary;
// Go through each element and inject the values
document.title = queryMap.title;
tryAgainButton.innerHTML = queryMap.button;
continueHttpButton.innerHTML = queryMap.continueHttpButton;
backFromHttpButton.innerHTML = queryMap.badCertGoBack;
document.getElementById("errorTitleText").innerHTML = queryMap.title;
document.getElementById("errorShortDesc").innerHTML = queryMap.description;
document.getElementById("advancedButton").innerHTML =
queryMap.badCertAdvanced;
document.getElementById("badCertTechnicalInfo").innerHTML =
queryMap.badCertTechInfo;
document.getElementById("advancedPanelBackButton").innerHTML =
queryMap.badCertGoBack;
document.getElementById("advancedPanelAcceptButton").innerHTML =
queryMap.badCertAcceptTemporary;
// If no image is passed in, remove the element so as not to leave an empty iframe
const errorImage = document.getElementById('errorImage');
if (!queryMap.image) {
errorImage.remove();
} else {
errorImage.src = "resource://android/assets/" + queryMap.image;
}
// If no image is passed in, remove the element so as not to leave an empty iframe
const errorImage = document.getElementById("errorImage");
if (!queryMap.image) {
errorImage.remove();
} else {
errorImage.src = "resource://android/assets/" + queryMap.image;
}
if (queryMap.showContinueHttp === "true") {
// On the "HTTPS-Only" error page "Try again" doesn't make sense since reloading the page
// will just show an error page again.
tryAgainButton.style.display = 'none';
} else {
continueHttpButton.style.display = 'none';
backFromHttpButton.style.display = 'none';
}
};
if (queryMap.showContinueHttp === "true") {
// On the "HTTPS-Only" error page "Try again" doesn't make sense since reloading the page
// will just show an error page again.
tryAgainButton.style.display = "none";
} else {
continueHttpButton.style.display = "none";
backFromHttpButton.style.display = "none";
}
}
let advancedVisible = false;
@ -59,88 +63,98 @@ let advancedVisible = false;
* Used to show or hide the "accept" button based on the validity of the SSL certificate
*/
function updateShowSSL(queryMap) {
/** @type {'true' | 'false'} */
const showSSL = queryMap.showSSL;
if (typeof document.addCertException === 'undefined') {
document.getElementById('advancedButton').style.display='none';
/** @type {'true' | 'false'} */
const showSSL = queryMap.showSSL;
if (typeof document.addCertException === "undefined") {
document.getElementById("advancedButton").style.display = "none";
} else {
if (showSSL === "true") {
document.getElementById("advancedButton").style.display = "block";
} else {
if (showSSL === 'true') {
document.getElementById('advancedButton').style.display='block';
} else {
document.getElementById('advancedButton').style.display='none';
}
document.getElementById("advancedButton").style.display = "none";
}
};
}
}
/**
* Used to show or hide the "accept" button based for the HSTS error page
*/
function updateShowHSTS(queryMap) {
const showHSTS = queryMap.showHSTS;
if (showHSTS === 'true') {
document.getElementById('advancedButton').style.display='block';
document.getElementById('advancedPanelAcceptButton').style.display='none';
}
};
const showHSTS = queryMap.showHSTS;
if (showHSTS === "true") {
document.getElementById("advancedButton").style.display = "block";
document.getElementById("advancedPanelAcceptButton").style.display = "none";
}
}
/**
* Used to display information about the SSL certificate in `error_pages.html`
*/
function toggleAdvancedAndScroll() {
const advancedPanel = document.getElementById('badCertAdvancedPanel');
if (advancedVisible) {
advancedPanel.style.display='none';
} else {
advancedPanel.style.display='block';
}
advancedVisible = !advancedVisible;
const advancedPanel = document.getElementById("badCertAdvancedPanel");
if (advancedVisible) {
advancedPanel.style.display = "none";
} else {
advancedPanel.style.display = "block";
}
advancedVisible = !advancedVisible;
const horizontalLine = document.getElementById("horizontalLine");
const advancedPanelAcceptButton = document.getElementById(
"advancedPanelAcceptButton"
);
const badCertAdvancedPanel = document.getElementById(
"badCertAdvancedPanel"
);
const horizontalLine = document.getElementById("horizontalLine");
const advancedPanelAcceptButton = document.getElementById(
"advancedPanelAcceptButton"
);
const badCertAdvancedPanel = document.getElementById("badCertAdvancedPanel");
// We know that the button is being displayed
if (badCertAdvancedPanel.style.display === "block") {
horizontalLine.hidden = false;
advancedPanelAcceptButton.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest",
});
} else {
horizontalLine.hidden = true;
}
};
// We know that the button is being displayed
if (badCertAdvancedPanel.style.display === "block") {
horizontalLine.hidden = false;
advancedPanelAcceptButton.scrollIntoView({
behavior: "smooth",
block: "center",
inline: "nearest",
});
} else {
horizontalLine.hidden = true;
}
}
/**
* Used to bypass an SSL pages in `error_pages.html`
*/
async function acceptAndContinue(temporary) {
try {
await document.addCertException(temporary);
location.reload();
} catch (error) {
console.error("Unexpected error: " + error);
}
};
try {
await document.addCertException(temporary);
location.reload();
} catch (error) {
console.error("Unexpected error: " + error);
}
}
document.addEventListener('DOMContentLoaded', function () {
if (window.history.length == 1) {
document.getElementById('advancedPanelBackButton').style.display = 'none';
document.getElementById('backFromHttp').style.display = 'none';
} else {
document.getElementById('advancedPanelBackButton').addEventListener('click', () => window.history.back());
document.getElementById('backFromHttp').addEventListener('click', () => window.history.back());
}
document.addEventListener("DOMContentLoaded", function () {
if (window.history.length == 1) {
document.getElementById("advancedPanelBackButton").style.display = "none";
document.getElementById("backFromHttp").style.display = "none";
} else {
document
.getElementById("advancedPanelBackButton")
.addEventListener("click", () => window.history.back());
document
.getElementById("backFromHttp")
.addEventListener("click", () => window.history.back());
}
document.getElementById('errorTryAgain').addEventListener('click', () => window.location.reload());
document.getElementById('advancedButton').addEventListener('click', toggleAdvancedAndScroll);
document.getElementById('advancedPanelAcceptButton').addEventListener('click', () => acceptAndContinue(true));
document.getElementById('continueHttp').addEventListener('click', () => document.reloadWithHttpsOnlyException());
document
.getElementById("errorTryAgain")
.addEventListener("click", () => window.location.reload());
document
.getElementById("advancedButton")
.addEventListener("click", toggleAdvancedAndScroll);
document
.getElementById("advancedPanelAcceptButton")
.addEventListener("click", () => acceptAndContinue(true));
document
.getElementById("continueHttp")
.addEventListener("click", () => document.reloadWithHttpsOnlyException());
});
parseQuery(document.documentURI);

View file

@ -8,7 +8,10 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width; user-scalable=false;" />
<meta http-equiv="Content-Security-Policy" content="default-src resource:; object-src 'none'" />
<meta
http-equiv="Content-Security-Policy"
content="default-src resource:; object-src 'none'"
/>
<link rel="stylesheet" type="text/css" href="shared_error_style.css" />
<link
rel="stylesheet"
@ -37,10 +40,7 @@
<button id="errorTryAgain"></button>
<!-- Advanced Button -->
<button
id="advancedButton"
class="buttonSecondary hidden"
></button>
<button id="advancedButton" class="buttonSecondary hidden"></button>
<!-- "Go back" Button (For HTTPS-Only error page only) -->
<button id="backFromHttp"></button>
@ -56,9 +56,7 @@
id="advancedPanelBackButtonContainer"
class="advancedPanelButtonContainer"
>
<button
id="advancedPanelBackButton"
></button>
<button id="advancedPanelBackButton"></button>
</div>
<div
id="advancedPanelAcceptButtonContainer"
@ -76,7 +74,7 @@
<script type="text/javascript">
if (window.history.length == 1) {
document.getElementById('advancedPanelBackButton').style.display = 'none';
document.getElementById("advancedPanelBackButton").style.display = "none";
}
function toggleAdvancedAndScroll() {
@ -104,5 +102,5 @@
}
</script>
<script src="./lowMediumErrorPages.js"></script>
<script src="./lowMediumErrorPages.js"></script>
</html>

View file

@ -1,37 +1,36 @@
<html>
<head>
<head>
<title>Audio_Test_Page</title>
</head>
<body>
<p id="testContent">Page content: audio player</p>
</head>
<body>
<p id="testContent">Page content: audio player</p>
<div class="audioPlayer">
<audio id="audioSample" controls loop>
<source src="resources/audioSample.mp3">
</audio>
</div>
<div class="audioPlayer">
<audio id="audioSample" controls loop>
<source src="resources/audioSample.mp3" />
</audio>
</div>
<div class="playbackState">
</div>
<div class="playbackState"></div>
<script>
const audio = document.querySelector('audio');
var showPlayingAlert=true;
<script>
const audio = document.querySelector("audio");
var showPlayingAlert = true;
audio.addEventListener('playing', (event) => {
<!--document.querySelector('.playbackState').innerText="Media file is playing"-->
<!--Need this hack to verify that the video is playing,-->
<!--the test cannot currently verify the text displayed on the page-->
if(showPlayingAlert===true){
showPlayingAlert=false;
alert("Media file is playing");
}
});
audio.addEventListener("playing", event => {
<!--document.querySelector('.playbackState').innerText="Media file is playing"-->
<!--Need this hack to verify that the video is playing,-->
<!--the test cannot currently verify the text displayed on the page-->
if (showPlayingAlert === true) {
showPlayingAlert = false;
alert("Media file is playing");
}
});
audio.addEventListener('pause', (event) => {
audio.addEventListener("pause", event => {
<!--document.querySelector('.playbackState').innerText="Media file is paused"-->
alert("Media file is paused");
});
</script>
</body>
});
</script>
</body>
</html>

View file

@ -1,12 +1,16 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<!-- 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/. -->
<html>
<meta name="viewport" content="width=device-width">
<body>
<h3>known-tracker.englehardt-tracker.com</h3>
<h4>different site, cross-origin iframe, on blocklist</h4>
<iframe width=500 height=600 src="https://known-tracker.englehardt-tracker.com/set_storage_simple.html"></iframe>
</body>
<meta name="viewport" content="width=device-width" />
<body>
<h3>known-tracker.englehardt-tracker.com</h3>
<h4>different site, cross-origin iframe, on blocklist</h4>
<iframe
width="500"
height="600"
src="https://known-tracker.englehardt-tracker.com/set_storage_simple.html"
></iframe>
</body>
</html>

View file

@ -1,21 +1,22 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<!-- 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/. -->
<html dir="ltr" xml:lang="en-US" lang="en-US">
<meta name="viewport" content="width=device-width">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<head>
<meta charset="UTF-8" />
<title>adsTrackers</title>
</head>
<body>
<!--Level 1 Tracker blocking with separate lists (social-track-digest256,ads-track-digest256,analytics-track-digest256).-->
<!--using the https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html test page-->
<p>ads trackers:</p>
<p>if you can read this, then: </p>
<p>ads trackers not blocked</p>
<img
src="https://ads-track-digest256.dummytracker.org/test_not_blocked.png"
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';alert('ads trackers blocked')">
</body>
</head>
<body>
<!--Level 1 Tracker blocking with separate lists (social-track-digest256,ads-track-digest256,analytics-track-digest256).-->
<!--using the https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html test page-->
<p>ads trackers:</p>
<p>if you can read this, then:</p>
<p>ads trackers not blocked</p>
<img
src="https://ads-track-digest256.dummytracker.org/test_not_blocked.png"
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';alert('ads trackers blocked')"
/>
</body>
</html>

View file

@ -1,21 +1,22 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<!-- 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/. -->
<html dir="ltr" xml:lang="en-US" lang="en-US">
<meta name="viewport" content="width=device-width">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<head>
<meta charset="UTF-8" />
<title>analyticsTrackers</title>
</head>
<body>
<!--Level 1 Tracker blocking with separate lists (social-track-digest256,ads-track-digest256,analytics-track-digest256).-->
<!--using the https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html test page-->
<p>analytics trackers</p>
<p>if you can read this, then: </p>
<p>analytics trackers not blocked</p>
<img
src="https://analytics-track-digest256.dummytracker.org/test_not_blocked.png"
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';alert('analytics trackers blocked')">
</body>
</head>
<body>
<!--Level 1 Tracker blocking with separate lists (social-track-digest256,ads-track-digest256,analytics-track-digest256).-->
<!--using the https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html test page-->
<p>analytics trackers</p>
<p>if you can read this, then:</p>
<p>analytics trackers not blocked</p>
<img
src="https://analytics-track-digest256.dummytracker.org/test_not_blocked.png"
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';alert('analytics trackers blocked')"
/>
</body>
</html>

View file

@ -1,22 +1,23 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<!-- 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/. -->
<html dir="ltr" xml:lang="en-US" lang="en-US">
<meta name="viewport" content="width=device-width">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<head>
<meta charset="UTF-8" />
<title>otherTrackers</title>
</head>
<body>
<!--Level 1 Tracker blocking with separate lists (social-track-digest256,ads-track-digest256,analytics-track-digest256).-->
<!--using the https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html test page-->
<h3>Level 2 (Strict List) Tracker Blocking</h3>
<p>other content trackers</p>
<p>if you can read this, then: </p>
<p>other content trackers not blocked</p>
<img
src="https://content-track-digest256.dummytracker.org/test_not_blocked.png"
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';alert('other content trackers blocked')">
</body>
</head>
<body>
<!--Level 1 Tracker blocking with separate lists (social-track-digest256,ads-track-digest256,analytics-track-digest256).-->
<!--using the https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html test page-->
<h3>Level 2 (Strict List) Tracker Blocking</h3>
<p>other content trackers</p>
<p>if you can read this, then:</p>
<p>other content trackers not blocked</p>
<img
src="https://content-track-digest256.dummytracker.org/test_not_blocked.png"
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';alert('other content trackers blocked')"
/>
</body>
</html>

View file

@ -1,21 +1,22 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<!-- 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/. -->
<html dir="ltr" xml:lang="en-US" lang="en-US">
<meta name="viewport" content="width=device-width">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<head>
<meta charset="UTF-8" />
<title>socialTrackers</title>
</head>
<body>
<!--Level 1 Tracker blocking with separate lists (social-track-digest256,ads-track-digest256,analytics-track-digest256).-->
<!--using the https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html test page-->
<p>social trackers</p>
<p>if you can read this, then: </p>
<p>social trackers not blocked</p>
<img
src="https://social-track-digest256.dummytracker.org/test_not_blocked.png"
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';alert('social trackers blocked')">
</body>
</head>
<body>
<!--Level 1 Tracker blocking with separate lists (social-track-digest256,ads-track-digest256,analytics-track-digest256).-->
<!--using the https://senglehardt.com/test/trackingprotection/test_pages/tracking_protection.html test page-->
<p>social trackers</p>
<p>if you can read this, then:</p>
<p>social trackers not blocked</p>
<img
src="https://social-track-digest256.dummytracker.org/test_not_blocked.png"
onerror="this.onerror=null;this.src='https://not-a-tracker.dummytracker.org/test_blocked.png';alert('social trackers blocked')"
/>
</body>
</html>

View file

@ -1,15 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<head>
<meta charset="UTF-8" />
<!-- random words that should not end up on disk -->
<title>GenericPage</title>
</head>
<body>
<h1 id="header">focus test page</h1>
<!-- More random words that should not end up on disk -->
<p>groovy rabbits</p>
<p>This test page does nothing.</p>
</body>
</head>
<body>
<h1 id="header">focus test page</h1>
<!-- More random words that should not end up on disk -->
<p>groovy rabbits</p>
<p>This test page does nothing.</p>
</body>
</html>

View file

@ -1,15 +1,14 @@
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width">
<body>
<script type = "text/javascript" >
const gpcValue = navigator.globalPrivacyControl
if (gpcValue) {
document.write('<p>GPC is enabled.</p>');
} else {
document.write('<p>GPC not enabled.</p>');
}
</script>
</body>
<meta name="viewport" content="width=device-width" />
<body>
<script type="text/javascript">
const gpcValue = navigator.globalPrivacyControl;
if (gpcValue) {
document.write("<p>GPC is enabled.</p>");
} else {
document.write("<p>GPC not enabled.</p>");
}
</script>
</body>
</html>

View file

@ -1,43 +1,45 @@
<!DOCTYPE html>
<html>
<head>
<head>
<title>Html_Control_Form</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
</head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
</head>
<p>Misc Link Types</p>
<section>
<p>Misc Link Types</p>
<section>
<a href="https://duckduckgo.com/">External link</a>
</section>
</section>
<section>
<section>
<a href="mailto://example@example.com">Email link</a>
<a href="tel://1234567890">Telephone link</a>
</section>
</section>
<p>Drop-down Form</p>
<select id="dropDown">
<p>Drop-down Form</p>
<select id="dropDown">
<option type="text" text="The Only Ones">The Only Ones</option>
<option type="text" text="The National">The National</option>
</select>
<button onclick="printOption()" id="submitOption"> Submit drop down option </button>
<div id="displayOption"></div>
</select>
<button onclick="printOption()" id="submitOption">
Submit drop down option
</button>
<div id="displayOption"></div>
<section>
<p>Copy <input type="text" placeholder="and Paste" id="textInput"> me</p>
<button onclick="printInput()" id="submitInput"> Submit input </button>
<section>
<p>Copy <input type="text" placeholder="and Paste" id="textInput" /> me</p>
<button onclick="printInput()" id="submitInput">Submit input</button>
<div id="displayInput"></div>
</section>
</section>
<p>Calendar Form</p>
<section>
<input type="date" id="calendar">
<button onclick="printDate()" id="submitDate"> Submit date </button>
<p>Calendar Form</p>
<section>
<input type="date" id="calendar" />
<button onclick="printDate()" id="submitDate">Submit date</button>
<div id="displayDate"></div>
</section>
</section>
<script>
<script>
function printOption() {
let dropDown = document.querySelector("#dropDown");
let displayOption = document.querySelector("#displayOption");
@ -46,7 +48,7 @@
}
</script>
<script>
<script>
function printInput() {
let textInput = document.querySelector("#textInput");
let displayInput = document.querySelector("#displayInput");
@ -55,7 +57,7 @@
}
</script>
<script>
<script>
function printDate() {
let calendar = document.querySelector("#calendar");
let displayDate = document.querySelector("#displayDate");

View file

@ -1,20 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<head>
<meta charset="UTF-8" />
<!-- random words that should not end up on disk -->
<title>gigantic experience</title>
</head>
<body>
<h1 id="header">focus test page</h1>
</head>
<body>
<h1 id="header">focus test page</h1>
<!-- More random words that should not end up on disk -->
<p>groovy rabbits</p>
<img id="rabbitImage" src="rabbit.jpg" alt="rabbit.jpg" width="251" height="201">
<!-- More random words that should not end up on disk -->
<p>groovy rabbits</p>
<img
id="rabbitImage"
src="rabbit.jpg"
alt="rabbit.jpg"
width="251"
height="201"
/>
<a id="download" href="download.jpg" download="mozillaLogo">
<img border="0" src="download.jpg" alt="download icon" width="104" height="142">
</a>
</body>
<a id="download" href="download.jpg" download="mozillaLogo">
<img
border="0"
src="download.jpg"
alt="download icon"
width="104"
height="142"
/>
</a>
</body>
</html>

View file

@ -1,53 +1,52 @@
<html>
<head>
<head>
<title>Muted_Video_Test_Page</title>
</head>
<body>
<p id="testContent">Page content: muted video player</p>
<div class="playbackState">
</div>
<div id="video-container" style="text-align:center">
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="fullscreen()">Full Screen</button>
<br><br>
<video id="mutedVideo" width="420" autoplay muted controls loop>
<source src="resources/clip.mp4" type="video/mp4">
</head>
<body>
<p id="testContent">Page content: muted video player</p>
<div class="playbackState"></div>
<div id="video-container" style="text-align: center">
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="fullscreen()">Full Screen</button>
<br /><br />
<video id="mutedVideo" width="420" autoplay muted controls loop>
<source src="resources/clip.mp4" type="video/mp4" />
Your browser does not support HTML video.
</video>
</div>
</video>
</div>
<script>
const mutedVideo = document.getElementById("mutedVideo");
<script>
const mutedVideo = document.getElementById("mutedVideo");
function play() {
function play() {
mutedVideo.play();
}
}
function pause() {
function pause() {
mutedVideo.pause();
}
}
function fullscreen() {
function fullscreen() {
mutedVideo.requestFullscreen();
}
}
var showPlayAlert=true;
var showPlayAlert = true;
mutedVideo.addEventListener('playing', (event) => {
<!-- document.querySelector('.playbackState').innerHTML="Media file is playing";-->
<!-- Need this hack to verify that the video is playing, -->
<!-- the test cannot currently verify the text displayed on the page-->
if(showPlayAlert===true){
showPlayAlert=false;
alert("Media file is playing");
}
});
mutedVideo.addEventListener("playing", event => {
<!-- document.querySelector('.playbackState').innerHTML="Media file is playing";-->
<!-- Need this hack to verify that the video is playing, -->
<!-- the test cannot currently verify the text displayed on the page-->
if (showPlayAlert === true) {
showPlayAlert = false;
alert("Media file is playing");
}
});
mutedVideo.addEventListener('pause', (event) => {
// document.querySelector('.playbackState').innerHTML="Media file is paused";
alert("Media file is paused");
});
</script>
</body>
mutedVideo.addEventListener("pause", event => {
// document.querySelector('.playbackState').innerHTML="Media file is paused";
alert("Media file is paused");
});
</script>
</body>
</html>

View file

@ -1,125 +1,139 @@
<!DOCTYPE HTML>
<!DOCTYPE html>
<!-- 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/. -->
<html lang="en-US" dir="ltr">
<head>
<meta name="viewport" content="width=device-width">
<script src="https://cdn.jsdelivr.net/npm/idb-keyval@3/dist/idb-keyval-iife.min.js"></script>
</head>
<body>
<button onclick="setAllStorageLocations();">Rerun Tests</button>
<br>
<h4>cookies</h4>
<pre id="cookie_message"></pre>
<head>
<meta name="viewport" content="width=device-width" />
<script src="https://cdn.jsdelivr.net/npm/idb-keyval@3/dist/idb-keyval-iife.min.js"></script>
</head>
<body>
<button onclick="setAllStorageLocations();">Rerun Tests</button>
<br />
<h4>cookies</h4>
<pre id="cookie_message"></pre>
<h4>localStorage</h4>
<pre id="ls_message"></pre>
<h4>localStorage</h4>
<pre id="ls_message"></pre>
<!--
<!--
<h4>sessionStorage</h4>
<pre id="ss_message"></pre>
<h4>Indexed DB</h4>
<pre id="idb_message"></pre>
-->
<!-- Storage access API -->
<br />
<h4>Storage Access API</h4>
<button onclick='requestSA()'>requestStorageAccess()</button><br />
<p>Return value of requestStorageAccess():</p><pre id='request_storage_access'>not yet called</pre><br />
<button onclick='hasSA()'>hasStorageAccess()</button><br />
<p>Return value of hasStorageAccess():</p><pre id='has_storage_access'>not yet called</pre><br />
<!-- Storage access API -->
<br />
<h4>Storage Access API</h4>
<button onclick="requestSA()">requestStorageAccess()</button><br />
<p>Return value of requestStorageAccess():</p>
<pre id="request_storage_access">not yet called</pre>
<br />
<button onclick="hasSA()">hasStorageAccess()</button><br />
<p>Return value of hasStorageAccess():</p>
<pre id="has_storage_access">not yet called</pre>
<br />
<script>
var newRandVal = Math.random();
<script>
var newRandVal = Math.random();
function outputResult(value, output_id) {
var msg = document.getElementById(output_id);
document.hasStorageAccess().then(
(hasStorageAccess) => {
if (hasStorageAccess === false) {
msg.innerHTML = "BLOCKED";
} else if (value === "" & hasStorageAccess === true) {
msg.innerHTML = "UNEXPECTED. We have storage access but value is empty...";
} else if (hasStorageAccess === true) {
msg.innerHTML = "UNRESTRICTED";
}
},
(reason) => {msg.innerHTML = 'promise rejected for reason' + reason}
);
}
function setCookies() {
var cookies = document.cookie;
if (cookies === "") {
document.cookie = 'foo='+newRandVal+'; SameSite=None; Secure';
cookies = document.cookie;
}
outputResult(cookies, 'cookie_message');
}
function setLocalStorage() {
try {
var foo = window.localStorage.getItem('foo');
if (foo === null) {
window.localStorage.setItem('foo', newRandVal);
foo = window.localStorage.getItem('foo');
function outputResult(value, output_id) {
var msg = document.getElementById(output_id);
document.hasStorageAccess().then(
hasStorageAccess => {
if (hasStorageAccess === false) {
msg.innerHTML = "BLOCKED";
} else if ((value === "") & (hasStorageAccess === true)) {
msg.innerHTML =
"UNEXPECTED. We have storage access but value is empty...";
} else if (hasStorageAccess === true) {
msg.innerHTML = "UNRESTRICTED";
}
} catch (error) {
foo = "";
},
reason => {
msg.innerHTML = "promise rejected for reason" + reason;
}
outputResult(foo, 'ls_message');
}
function setSessionStorage() {
try {
var foo = window.sessionStorage.getItem('foo');
if (foo === null) {
window.sessionStorage.setItem('foo', newRandVal);
foo = window.sessionStorage.getItem('foo');
}
} catch (error) {
foo = "";
}
outputResult(foo, 'ss_message');
}
async function setIndexedDB() {
try {
var foo = await idbKeyval.get('foo');
if (foo === undefined) {
await idbKeyval.set('foo', newRandVal);
foo = await idbKeyval.get('foo');
}
} catch (error) {
foo = "";
}
outputResult(foo, 'idb_message');
}
function setAllStorageLocations() {
setCookies();
setLocalStorage();
//setSessionStorage();
//setIndexedDB();
}
setAllStorageLocations();
);
}
// Storage Access API
function requestSA() {
var result = document.getElementById('request_storage_access');
document.requestStorageAccess().then(
() => {result.innerHTML = 'access granted'},
() => {result.innerHTML = 'access denied'}
);
function setCookies() {
var cookies = document.cookie;
if (cookies === "") {
document.cookie = "foo=" + newRandVal + "; SameSite=None; Secure";
cookies = document.cookie;
}
outputResult(cookies, "cookie_message");
}
function setLocalStorage() {
try {
var foo = window.localStorage.getItem("foo");
if (foo === null) {
window.localStorage.setItem("foo", newRandVal);
foo = window.localStorage.getItem("foo");
}
} catch (error) {
foo = "";
}
outputResult(foo, "ls_message");
}
function setSessionStorage() {
try {
var foo = window.sessionStorage.getItem("foo");
if (foo === null) {
window.sessionStorage.setItem("foo", newRandVal);
foo = window.sessionStorage.getItem("foo");
}
} catch (error) {
foo = "";
}
outputResult(foo, "ss_message");
}
async function setIndexedDB() {
try {
var foo = await idbKeyval.get("foo");
if (foo === undefined) {
await idbKeyval.set("foo", newRandVal);
foo = await idbKeyval.get("foo");
}
} catch (error) {
foo = "";
}
outputResult(foo, "idb_message");
}
function setAllStorageLocations() {
setCookies();
setLocalStorage();
//setSessionStorage();
//setIndexedDB();
}
setAllStorageLocations();
function hasSA() {
var result = document.getElementById('has_storage_access');
document.hasStorageAccess().then(
(hasAccess) => {result.innerHTML = hasAccess},
(reason) => {result.innerHTML = 'promise rejected for reason' + reason}
);
}
hasSA();
</script>
</body>
// Storage Access API
function requestSA() {
var result = document.getElementById("request_storage_access");
document.requestStorageAccess().then(
() => {
result.innerHTML = "access granted";
},
() => {
result.innerHTML = "access denied";
}
);
}
function hasSA() {
var result = document.getElementById("has_storage_access");
document.hasStorageAccess().then(
hasAccess => {
result.innerHTML = hasAccess;
},
reason => {
result.innerHTML = "promise rejected for reason" + reason;
}
);
}
hasSA();
</script>
</body>
</html>

View file

@ -1,23 +1,21 @@
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width">
<body>
<meta name="viewport" content="width=device-width" />
<body>
<h1>Storage check</h1>
<h1>Storage check</h1>
<script type="text/javascript">
if (sessionStorage.getItem("focusSessionTest") == "caterpillar") {
document.write("<p>Session storage has value</p>");
} else {
document.write("<p>Session storage empty</p>");
}
<script type="text/javascript">
if (sessionStorage.getItem('focusSessionTest') == 'caterpillar') {
document.write('<p>Session storage has value</p>');
} else {
document.write('<p>Session storage empty</p>');
}
if (localStorage.getItem('focusLocalTest') == 'caterpillar') {
document.write('<p>Local storage has value</p>');
} else {
document.write('<p>Local storage empty</p>');
}
</script>
</body>
if (localStorage.getItem("focusLocalTest") == "caterpillar") {
document.write("<p>Local storage has value</p>");
} else {
document.write("<p>Local storage empty</p>");
}
</script>
</body>
</html>

View file

@ -1,28 +1,30 @@
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width">
<body>
<meta name="viewport" content="width=device-width" />
<body>
<h1>Storage Start</h1>
<h1>Storage Start</h1>
<p id="cookies"></p>
<button id="setCookies">Set cookies</button>
<p id="cookies"></p>
<button id="setCookies">Set cookies</button>
<script type="text/javascript">
(function () {
document.getElementById("cookies").textContent = document.cookie
? document.cookie
: "No cookies set";
})();
<script type="text/javascript">
(function() {
document.getElementById("cookies").textContent = document.cookie?document.cookie:"No cookies set";
})();
document
.getElementById("setCookies")
.addEventListener("click", function () {
document.cookie = "user=android";
document.getElementById("cookies").textContent = document.cookie;
});
document.getElementById("setCookies").addEventListener("click", function() {
document.cookie = "user=android";
document.getElementById("cookies").textContent = document.cookie;
});
sessionStorage.setItem("focusSessionTest", "caterpillar");
localStorage.setItem("focusLocalTest", "butterfly");
sessionStorage.setItem('focusSessionTest', 'caterpillar');
localStorage.setItem('focusLocalTest', 'butterfly');
document.write('<p>Values written to storage</p>');
</script>
</body>
document.write("<p>Values written to storage</p>");
</script>
</body>
</html>

View file

@ -1,11 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>tab1</title>
</head>
<body>
</head>
<body>
<h1 id="content">Tab 1</h1>
<a href="tab2.html" id="tab2">Tab 2</a>
@ -14,16 +14,17 @@
<!-- here we display if the page is in mobile or desktop view mode -->
<p id="viewMode"></p>
</body>
<script>
window.mobileCheck = function() {
let check = false;
(function(a){
if (a.includes("Android"))
check = true;
}) (navigator.userAgent)
return check;
};
document.getElementById('viewMode').textContent=mobileCheck()? "mobile-site":"desktop-site";
</script>
</body>
<script>
window.mobileCheck = function () {
let check = false;
(function (a) {
if (a.includes("Android")) check = true;
})(navigator.userAgent);
return check;
};
document.getElementById("viewMode").textContent = mobileCheck()
? "mobile-site"
: "desktop-site";
</script>
</html>

View file

@ -1,16 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<head>
<meta charset="UTF-8" />
<title>tab2</title>
</head>
<body>
</head>
<body>
<h1 id="content">Tab 2</h1>
<a href="tab1.html" id="tab1">Tab 1</a>
<a href="tab3.html" id="tab3">Tab 3</a>
</body>
</body>
</html>

View file

@ -1,11 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<head>
<meta charset="UTF-8" />
<title>tab3</title>
</head>
<body>
</head>
<body>
<h1 id="content">Tab 3</h1>
<a href="tab2.html" id="tab1">Tab 1</a>
@ -13,8 +12,9 @@
<a href="tab3.html" id="tab2">Tab 2</a>
<p>
<a href="https://www.youtube.com/c/MozillaChannel/videos">Mozilla Youtube link</a>
<a href="https://www.youtube.com/c/MozillaChannel/videos"
>Mozilla Youtube link</a
>
</p>
</body>
</body>
</html>

View file

@ -1,38 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<head>
<meta charset="UTF-8" />
<!-- random words that should not end up on disk -->
<title>gigantic experience</title>
</head>
<body>
<h1>focus test page</h1>
<!-- More random words that should not end up on disk -->
<p>groovy rabbits</p>
<p>This test page installs a service worker and saves a cookie.</p>
</head>
<body>
<h1>focus test page</h1>
<!-- More random words that should not end up on disk -->
<p>groovy rabbits</p>
<p>This test page installs a service worker and saves a cookie.</p>
<h2 id="cookieHeading">Cookie</h2>
<p>
Initial:
<script type="text/javascript">
document.write(document.cookie);
</script>
</p>
<p>
<!-- Setting a cookie -->
<script type="text/javascript">
document.cookie =
"birthday=armchair; expires=Tue, 18 Dec 2035 12:00:00 UTC; path=/";
document.write("Cookie saved");
</script>
</p>
<p>
Afterwards:
<script type="text/javascript">
document.write(document.cookie);
</script>
</p>
<h2>Service worker</h2>
<p id="status"></p>
<h2 id="cookieHeading">Cookie</h2>
<p>Initial: <script type="text/javascript">document.write(document.cookie);</script></p>
<p>
<!-- Setting a cookie -->
<script type="text/javascript">
document.cookie = "birthday=armchair; expires=Tue, 18 Dec 2035 12:00:00 UTC; path=/";
document.write("Cookie saved");
</script>
</p>
<p>Afterwards: <script type="text/javascript">document.write(document.cookie);</script></p>
// Add a key value pair to local storage. This is required by WebViewDataTest which asserts
// that the local storage directory should exist
var script = document.createElement("script");
script.src = "service-worker.js";
<h2>Service worker</h2>
<p id="status"></p>
<script type="text/javascript">
// Add a key value pair to local storage. This is required by WebViewDataTest which asserts
// that the local storage directory should exist
var script = document.createElement('script');
script.src = "service-worker.js";
document.head.appendChild(script); //or something of the likes
document.head.appendChild(script); //or something of the likes
</script>
</body>
</body>
</html>

View file

@ -1,53 +1,52 @@
<html>
<head>
<head>
<title>Video_Test_Page</title>
</head>
<body>
<p id="testContent">Page content: video player</p>
<div class="playbackState">
</div>
<div id="video-container" style="text-align:center">
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="fullscreen()">Full Screen</button>
<br><br>
<video id="video" width="420" autoplay controls loop>
<source src="resources/clip.mp4" type="video/mp4">
</head>
<body>
<p id="testContent">Page content: video player</p>
<div class="playbackState"></div>
<div id="video-container" style="text-align: center">
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="fullscreen()">Full Screen</button>
<br /><br />
<video id="video" width="420" autoplay controls loop>
<source src="resources/clip.mp4" type="video/mp4" />
Your browser does not support HTML video.
</video>
</div>
</video>
</div>
<script>
const video = document.getElementById("video");
<script>
const video = document.getElementById("video");
function play() {
function play() {
video.play();
}
}
function pause() {
function pause() {
video.pause();
}
}
function fullscreen() {
function fullscreen() {
video.requestFullscreen();
}
}
var showPlayingAlert=true;
var showPlayingAlert = true;
video.addEventListener('playing', (event) => {
<!-- document.querySelector('.playbackState').innerHTML="Media file is playing";-->
<!-- Need this hack to verify that the video is playing, -->
<!-- the test cannot currently verify the text displayed on the page-->
if(showPlayingAlert===true){
showPlayingAlert=false;
alert("Media file is playing");
}
});
video.addEventListener("playing", event => {
<!-- document.querySelector('.playbackState').innerHTML="Media file is playing";-->
<!-- Need this hack to verify that the video is playing, -->
<!-- the test cannot currently verify the text displayed on the page-->
if (showPlayingAlert === true) {
showPlayingAlert = false;
alert("Media file is playing");
}
});
video.addEventListener('pause', (event) => {
// document.querySelector('.playbackState').innerHTML="Media file is paused";
alert("Media file is paused");
});
</script>
</body>
video.addEventListener("pause", event => {
// document.querySelector('.playbackState').innerHTML="Media file is paused";
alert("Media file is paused");
});
</script>
</body>
</html>

View file

@ -1,55 +1,60 @@
<!doctype html>
<!DOCTYPE html>
<!-- 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/. -->
<head>
<meta name="viewport" charset="utf-8" content="width=device-width, initial-scale=1">
<style>
body, html {
background: #221F1F;
color: #FFFFFF;
font-family: sans-serif;
line-height: 24px;
font-size: 14px;
<meta
name="viewport"
charset="utf-8"
content="width=device-width, initial-scale=1"
/>
<style>
body,
html {
background: #221f1f;
color: #ffffff;
font-family: sans-serif;
line-height: 24px;
font-size: 14px;
}
body{
padding-left: 24px;
padding-right: 24px;
margin-left: 0px;
margin-right: 0px;
body {
padding-left: 24px;
padding-right: 24px;
margin-left: 0px;
margin-right: 0px;
}
a {
color: #0A9AF4;
color: #0a9af4;
}
/* Make only about page links ("learn more") white */
.about a {
color: #FFFFFF;
color: #ffffff;
}
p.subtitle {
text-align: center;
opacity: .7;
margin: 0;
text-align: center;
opacity: 0.7;
margin: 0;
}
img#wordmark {
/* We need to set the dp size here, because by default webview assumes the image is not
/* We need to set the dp size here, because by default webview assumes the image is not
density specific (but since it's an android resource, we get a density specific version). */
width: 180px;
display: block;
margin-left: auto;
margin-right: auto;
padding-top: 24px;
width: 180px;
display: block;
margin-left: auto;
margin-right: auto;
padding-top: 24px;
}
</style>
</style>
</head>
<html>
<body class="about" dir="%dir%">
<img src="%wordmark%" id="wordmark"/>
<p class="subtitle">%about-version%</p>
%about-content%
</body>
<body class="about" dir="%dir%">
<img src="%wordmark%" id="wordmark" />
<p class="subtitle">%about-version%</p>
%about-content%
</body>
</html>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,56 +1,62 @@
<!doctype html>
<!DOCTYPE html>
<!-- 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/. -->
<head>
<meta name="viewport" charset="utf-8" content="width=device-width, initial-scale=1"><style>
body, html {
background: #221F1F;
color: #FFFFFF;
font-family: sans-serif;
line-height: 24px;
font-size: 14px;
<meta
name="viewport"
charset="utf-8"
content="width=device-width, initial-scale=1"
/>
<style>
body,
html {
background: #221f1f;
color: #ffffff;
font-family: sans-serif;
line-height: 24px;
font-size: 14px;
}
body{
padding-left: 24px;
padding-right: 24px;
margin-left: 0px;
margin-right: 0px;
body {
padding-left: 24px;
padding-right: 24px;
margin-left: 0px;
margin-right: 0px;
}
a {
color: #0A9AF4;
color: #0a9af4;
}
/* Make only about page links ("learn more") white */
.about a {
color: #FFFFFF;
color: #ffffff;
}
p.subtitle {
text-align: center;
opacity: .7;
margin: 0;
text-align: center;
opacity: 0.7;
margin: 0;
}
img#wordmark {
/* We need to set the dp size here, because by default webview assumes the image is not
/* We need to set the dp size here, because by default webview assumes the image is not
density specific (but since it's an android resource, we get a density specific version). */
width: 180px;
display: block;
margin-left: auto;
margin-right: auto;
padding-top: 24px;
width: 180px;
display: block;
margin-left: auto;
margin-right: auto;
padding-top: 24px;
}
</style>
</style>
</head>
<html>
<body dir="%dir%">
<body dir="%dir%">
<p id="first">%your-rights-content1%</p>
<p>%your-rights-content2%</p>
<p>%your-rights-content3%</p>
<p>%your-rights-content4%</p>
<p>%your-rights-content5%</p>
</body>
</body>
</html>

View file

@ -23,8 +23,6 @@ dom/tests/ajax/mochikit/
intl/components/src/UnicodeScriptCodes.h
intl/unicharutil/util/nsSpecialCasingData.cpp
intl/unicharutil/util/nsUnicodePropertyData.cpp
mobile/locales/l10n-changesets.json
mobile/locales/l10n-onchange-changesets.json
mobile/android/**/.build-cache
mobile/android/**/.gradle
mobile/android/**/build
@ -32,6 +30,12 @@ mobile/android/**/bin
mobile/android/**/generated
mobile/android/**\/local.properties
mobile/android/**\/manifest.json
mobile/android/android-components/components/feature/search/src/main/assets/search/search_telemetry_v2.json
mobile/android/android-components/samples/glean/src/main/res/raw/initial_experiments.json
mobile/android/fenix/app/src/debug/res/raw/initial_experiments.json
mobile/android/fenix/app/src/main/res/raw/initial_experiments.json
mobile/locales/l10n-changesets.json
mobile/locales/l10n-onchange-changesets.json
node_modules/
python/mozperftest/mozperftest/tests/data/
security/manager/tools/KnownRootHashes.json

View file

@ -135,6 +135,9 @@ media/openmax_il/
media/webrtc/signaling/gtest/MockCall.h
mfbt/double-conversion/double-conversion/
mfbt/lz4/.*
mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readability/JSDOMParser-0.4.2.js
mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readability/readability-0.4.2.js
mobile/android/android-components/components/feature/readerview/src/main/assets/extensions/readerview/readability/readability-readerable-0.4.2.js
mobile/android/exoplayer2/
modules/brotli/
modules/fdlibm/