Remove the test/features
folder, since it's very out of date (issue 11954)
These tests, and their [accompanying Wiki page](https://github.com/mozilla/pdf.js/wiki/Required-Browser-Features), haven't received any real updates for *many years* and are sufficiently out of date to be effectively useless now. Providing *irrelevant* compatibility information seems overall worse than not providing any information, and as suggested in the issue it'd probably be better to use https://github.com/mozilla/pdf.js#online-demo for checking if a particular platform/browser is supported. Thanks to version control, it's easy to restore these files should the need ever arise. However, re-introducing these tests would essentially require updating every single test-case *and* a commitment to keeping them up to date with future code changes.
This commit is contained in:
parent
ba1b4097dc
commit
36bb4fa823
@ -1854,9 +1854,6 @@ gulp.task("gh-pages-prepare", function () {
|
|||||||
stripBOM: false,
|
stripBOM: false,
|
||||||
})
|
})
|
||||||
.pipe(gulp.dest(GH_PAGES_DIR + "legacy/")),
|
.pipe(gulp.dest(GH_PAGES_DIR + "legacy/")),
|
||||||
gulp
|
|
||||||
.src("test/features/**/*", { base: "test/" })
|
|
||||||
.pipe(gulp.dest(GH_PAGES_DIR)),
|
|
||||||
gulp
|
gulp
|
||||||
.src(JSDOC_BUILD_DIR + "**/*", { base: JSDOC_BUILD_DIR })
|
.src(JSDOC_BUILD_DIR + "**/*", { base: JSDOC_BUILD_DIR })
|
||||||
.pipe(gulp.dest(GH_PAGES_DIR + "api/draft/")),
|
.pipe(gulp.dest(GH_PAGES_DIR + "api/draft/")),
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--
|
|
||||||
Copyright 2012 Mozilla Foundation
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-->
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Required features testing for PDF.js</title>
|
|
||||||
<style>
|
|
||||||
body { font-family: sans-serif; }
|
|
||||||
#tests { width: 920px; border-collapse:collapse; margin: 20px 0; }
|
|
||||||
#tests td, #tests th { border: 1px solid black; }
|
|
||||||
.name { text-align: left; }
|
|
||||||
.test, .emu, .impact, .area { text-align: center; }
|
|
||||||
.test-Skipped { background-color: #C0C0C0; }
|
|
||||||
.test-Success { background-color: #C0FFC0; }
|
|
||||||
.test-Failed { background-color: #FFC0C0; }
|
|
||||||
.test-Failed.emu-Yes { background-color: #FFFFC0; }
|
|
||||||
</style>
|
|
||||||
<style id="fontFaces">
|
|
||||||
@font-face { font-family: 'plus'; src: url(data:font/opentype;base64,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); }
|
|
||||||
</style>
|
|
||||||
<script src="tests.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Required Features for PDF.js</h1>
|
|
||||||
<div>User Agent: <span id="userAgent"></span></div>
|
|
||||||
<script>
|
|
||||||
document.getElementById('userAgent').innerHTML = navigator.userAgent;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<table id="tests">
|
|
||||||
<caption>Tests Results</caption>
|
|
||||||
<thead>
|
|
||||||
<tr><th class="name">Name</th><th class="test">Test</th><th class="impact">Impact</th><th class="area">Area</th><th class="emu">Emulated</th><th></th></tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="output">
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div id="canvasHolder" style="display: none;">
|
|
||||||
</div>
|
|
||||||
<div id="plusfontusage" style="font-family: plus; visibility: hidden;">`</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
var wikiPageBase = 'https://github.com/mozilla/pdf.js/wiki/Required-Browser-Features#user-content-';
|
|
||||||
var output = document.getElementById('output');
|
|
||||||
// for some browser textContent is absent using innerHTML :/
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
|
||||||
var test = tests[i];
|
|
||||||
var row = document.createElement('tr');
|
|
||||||
row.id = 'test-results-' + test.id;
|
|
||||||
var nameTd = document.createElement('td');
|
|
||||||
nameTd.className = 'name';
|
|
||||||
nameTd.innerHTML = test.name;
|
|
||||||
row.appendChild(nameTd);
|
|
||||||
var testTd = document.createElement('td');
|
|
||||||
testTd.className = 'test';
|
|
||||||
testTd.innerHTML = 'Running...';
|
|
||||||
row.appendChild(testTd);
|
|
||||||
var impactTd = document.createElement('td');
|
|
||||||
impactTd.className = 'impact';
|
|
||||||
impactTd.innerHTML = test.impact;
|
|
||||||
row.appendChild(impactTd);
|
|
||||||
var areaTd = document.createElement('td');
|
|
||||||
areaTd.className = 'area';
|
|
||||||
areaTd.innerHTML = test.area;
|
|
||||||
row.appendChild(areaTd);
|
|
||||||
var emulatedTd = document.createElement('td');
|
|
||||||
emulatedTd.className = 'emu';
|
|
||||||
row.appendChild(emulatedTd);
|
|
||||||
output.appendChild(row);
|
|
||||||
var infoTd = document.createElement('td');
|
|
||||||
infoTd.className = 'emu';
|
|
||||||
var infoA = document.createElement('a');
|
|
||||||
infoA.href = wikiPageBase + test.id;
|
|
||||||
infoA.innerHTML = 'info';
|
|
||||||
infoTd.appendChild(infoA);
|
|
||||||
row.appendChild(infoTd);
|
|
||||||
output.appendChild(row);
|
|
||||||
|
|
||||||
var publish = (function(row, testTd, emulatedTd) {
|
|
||||||
return function (result) {
|
|
||||||
row.className = 'test-' + result.output + ' emu-' + result.emulated;
|
|
||||||
testTd.innerHTML = result.output;
|
|
||||||
emulatedTd.innerHTML = result.emulated;
|
|
||||||
};
|
|
||||||
})(row, testTd, emulatedTd);
|
|
||||||
|
|
||||||
var result;
|
|
||||||
try {
|
|
||||||
result = test.run();
|
|
||||||
} catch (e) {
|
|
||||||
console.error('test run failed: ' + e);
|
|
||||||
result = { output: 'Failed', emulated: '?' };
|
|
||||||
}
|
|
||||||
if (result.then)
|
|
||||||
result.then(publish);
|
|
||||||
else
|
|
||||||
publish(result);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,656 +0,0 @@
|
|||||||
/* Copyright 2012 Mozilla Foundation
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// simple and incomplete implementation of promises
|
|
||||||
function Promise() {}
|
|
||||||
Promise.prototype = {
|
|
||||||
then: function (callback) {
|
|
||||||
this.callback = callback;
|
|
||||||
if ('result' in this) callback(this.result);
|
|
||||||
},
|
|
||||||
resolve: function (result) {
|
|
||||||
if ('result' in this) return;
|
|
||||||
this.result = result;
|
|
||||||
if ('callback' in this) this.callback(result);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var isCanvasSupported = (function () {
|
|
||||||
try {
|
|
||||||
document.createElement('canvas').getContext('2d').fillStyle = '#FFFFFF';
|
|
||||||
return true;
|
|
||||||
} catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
var tests = [
|
|
||||||
{
|
|
||||||
id: 'canvas',
|
|
||||||
name: 'CANVAS element is present',
|
|
||||||
run: function () {
|
|
||||||
if (isCanvasSupported) {
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
} else {
|
|
||||||
return { output: 'Failed', emulated: 'No' };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'get-literal',
|
|
||||||
name: 'get-literal properties',
|
|
||||||
run: function () {
|
|
||||||
try {
|
|
||||||
var Test = eval('var Test = { get t() { return {}; } }; Test');
|
|
||||||
Test.t.test = true;
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
} catch (e) {
|
|
||||||
return { output: 'Failed', emulated: 'No' };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'addEventListener',
|
|
||||||
name: 'addEventListener() is present',
|
|
||||||
run: function () {
|
|
||||||
var div = document.createElement('div');
|
|
||||||
if (div.addEventListener)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'No' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Uint8Array',
|
|
||||||
name: 'Uint8Array is present',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Uint8Array !== 'undefined')
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Uint16Array',
|
|
||||||
name: 'Uint16Array is present',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Uint16Array !== 'undefined')
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Int32Array',
|
|
||||||
name: 'Int32Array is present',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Int32Array !== 'undefined')
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Float32Array',
|
|
||||||
name: 'Float32Array is present',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Float32Array !== 'undefined')
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Float64Array',
|
|
||||||
name: 'Float64Array is present',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Float64Array !== 'undefined')
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Object-create',
|
|
||||||
name: 'Object.create() is present',
|
|
||||||
run: function () {
|
|
||||||
if (Object.create instanceof Function)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Object-defineProperty',
|
|
||||||
name: 'Object.defineProperty() is present',
|
|
||||||
run: function () {
|
|
||||||
if (Object.defineProperty instanceof Function)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Object-defineProperty-DOM',
|
|
||||||
name: 'Object.defineProperty() can be used on DOM objects',
|
|
||||||
run: function () {
|
|
||||||
if (!(Object.defineProperty instanceof Function))
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
try {
|
|
||||||
// some browsers (e.g. safari) cannot use defineProperty() on DOM objects
|
|
||||||
// and thus the native version is not sufficient
|
|
||||||
Object.defineProperty(new Image(), 'id', { value: 'test' });
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
} catch (e) {
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Viewer'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'get-literal-redefine',
|
|
||||||
name: 'Defined via get-literal properties can be redefined',
|
|
||||||
run: function () {
|
|
||||||
if (!(Object.defineProperty instanceof Function))
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
try {
|
|
||||||
var TestGetter = eval('var Test = function () {}; Test.prototype = { get id() { } }; Test');
|
|
||||||
Object.defineProperty(new TestGetter(), 'id',
|
|
||||||
{ value: '', configurable: true, enumerable: true, writable: false });
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
} catch (e) {
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Object-keys',
|
|
||||||
name: 'Object.keys() is present',
|
|
||||||
run: function () {
|
|
||||||
if (Object.keys instanceof Function)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'FileReader',
|
|
||||||
name: 'FileReader is present',
|
|
||||||
run: function () {
|
|
||||||
if (typeof FileReader !== 'undefined')
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'No' };
|
|
||||||
},
|
|
||||||
impact: 'Normal',
|
|
||||||
area: 'Demo'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'FileReader-readAsArrayBuffer',
|
|
||||||
name: 'FileReader.prototype.readAsArrayBuffer() is present',
|
|
||||||
run: function () {
|
|
||||||
if (typeof FileReader === 'undefined')
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
if (FileReader.prototype.readAsArrayBuffer instanceof Function)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Normal',
|
|
||||||
area: 'Demo'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'XMLHttpRequest-overrideMimeType',
|
|
||||||
name: 'XMLHttpRequest.prototype.overrideMimeType() is present',
|
|
||||||
run: function () {
|
|
||||||
if (XMLHttpRequest.prototype.overrideMimeType instanceof Function)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Viewer'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'XMLHttpRequest-response',
|
|
||||||
name: 'XMLHttpRequest.prototype.response is present',
|
|
||||||
run: function () {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
if ('response' in xhr)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'bota',
|
|
||||||
name: 'btoa() is present',
|
|
||||||
run: function () {
|
|
||||||
if ('btoa' in window)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'atob',
|
|
||||||
name: 'atob() is present',
|
|
||||||
run: function () {
|
|
||||||
if ('atob' in window)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Function-bind',
|
|
||||||
name: 'Function.prototype.bind is present',
|
|
||||||
run: function () {
|
|
||||||
if (Function.prototype.bind instanceof Function)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'dataset',
|
|
||||||
name: 'dataset is present for HTML element',
|
|
||||||
run: function () {
|
|
||||||
var div = document.createElement('div');
|
|
||||||
if ('dataset' in div)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Viewer'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'classList',
|
|
||||||
name: 'classList is present for HTML element',
|
|
||||||
run: function () {
|
|
||||||
var div = document.createElement('div');
|
|
||||||
if ('classList' in div)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Viewer'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'console',
|
|
||||||
name: 'console object is present',
|
|
||||||
run: function () {
|
|
||||||
if ('console' in window)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'console-log-bind',
|
|
||||||
name: 'console.log is a bind-able function',
|
|
||||||
run: function () {
|
|
||||||
if (!('console' in window))
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
if ('bind' in console.log)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Critical',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'navigator-language',
|
|
||||||
name: 'navigator.language is present',
|
|
||||||
run: function () {
|
|
||||||
if ('language' in navigator)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Viewer'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'fillRule-evenodd',
|
|
||||||
name: 'evenodd fill rule is supported',
|
|
||||||
run: function () {
|
|
||||||
if (!isCanvasSupported)
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
var ctx = canvas.getContext('2d');
|
|
||||||
ctx.rect(1, 1, 50, 50);
|
|
||||||
ctx.rect(5, 5, 41, 41);
|
|
||||||
ctx.fill('evenodd');
|
|
||||||
|
|
||||||
var data = ctx.getImageData(0, 0, 50, 50).data;
|
|
||||||
var isEvenOddFill = data[20 * 4 + 20 * 200 + 3] == 0 &&
|
|
||||||
data[2 * 4 + 2 * 200 + 3] != 0;
|
|
||||||
|
|
||||||
if (isEvenOddFill)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'No' };
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'dash-array',
|
|
||||||
name: 'dashed line style is supported',
|
|
||||||
run: function () {
|
|
||||||
if (!isCanvasSupported)
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
var ctx = canvas.getContext('2d');
|
|
||||||
ctx.moveTo(0,5);
|
|
||||||
ctx.lineTo(50, 5);
|
|
||||||
ctx.lineWidth = 10;
|
|
||||||
|
|
||||||
if ('setLineDash' in ctx) {
|
|
||||||
ctx.setLineDash([10, 10]);
|
|
||||||
ctx.lineDashOffset = 0;
|
|
||||||
}
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
var data = ctx.getImageData(0, 0, 50, 50).data;
|
|
||||||
var isDashed = data[5 * 4 + 5 * 200 + 3] != 0 &&
|
|
||||||
data[15 * 4 + 5 * 200 + 3] == 0;
|
|
||||||
|
|
||||||
if (isDashed)
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'No' };
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'font-face',
|
|
||||||
name: '@font-face is supported/enabled',
|
|
||||||
run: function () {
|
|
||||||
if (!isCanvasSupported)
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
var promise = new Promise();
|
|
||||||
setTimeout(function() {
|
|
||||||
if (checkCanvas('plus'))
|
|
||||||
promise.resolve({ output: 'Success', emulated: '' });
|
|
||||||
else
|
|
||||||
promise.resolve({ output: 'Failed', emulated: 'No' });
|
|
||||||
}, 2000);
|
|
||||||
return promise;
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'font-face-sync',
|
|
||||||
name: '@font-face loading completion detection',
|
|
||||||
run: function () {
|
|
||||||
if (!isCanvasSupported)
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
|
|
||||||
// Add the font-face rule to the document
|
|
||||||
var rule = '@font-face { font-family: \'plus-loaded\'; src: url(data:font/opentype;base64,AAEAAAAOAIAAAwBgRkZUTWNJJVkAAAZEAAAAHEdERUYANQAkAAAGHAAAAChPUy8yVkDi7gAAAWgAAABgY21hcPAZ92QAAAHcAAABUmN2dCAAIQJ5AAADMAAAAARnYXNw//8AAwAABhQAAAAIZ2x5Zk7Cd0UAAANEAAAA8GhlYWT8fgSnAAAA7AAAADZoaGVhBuoD7QAAASQAAAAkaG10eAwCALUAAAHIAAAAFGxvY2EA5gCyAAADNAAAAA5tYXhwAEoAPQAAAUgAAAAgbmFtZWDR73sAAAQ0AAABnnBvc3RBBJyBAAAF1AAAAD4AAQAAAAEAAPbZ2E5fDzz1AB8D6AAAAADM3+BPAAAAAMzf4E8AIQAAA2sDJAAAAAgAAgAAAAAAAAABAAADJAAAAFoD6AAAAAADawABAAAAAAAAAAAAAAAAAAAABAABAAAABgAMAAIAAAAAAAIAAAABAAEAAABAAC4AAAAAAAQD6AH0AAUAAAKKArwAAACMAooCvAAAAeAAMQECAAACAAYJAAAAAAAAAAAAARAAAAAAAAAAAAAAAFBmRWQAwABg8DADIP84AFoDJAAAgAAAAQAAAAAAAAAAAAAAIAABA+gAIQAAAAAD6AAAA+gASgBKAEoAAAADAAAAAwAAABwAAQAAAAAATAADAAEAAAAcAAQAMAAAAAgACAACAAAAYPAA8DD//wAAAGDwAPAw////oxAED9UAAQAAAAAAAAAAAAABBgAAAQAAAAAAAAABAgAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACECeQAAACoAKgAqAEQAXgB4AAAAAgAhAAABKgKaAAMABwAusQEALzyyBwQA7TKxBgXcPLIDAgDtMgCxAwAvPLIFBADtMrIHBgH8PLIBAgDtMjMRIREnMxEjIQEJ6MfHApr9ZiECWAAAAQBKAAADawMkAAsAAAEzESEVBREjEQU1IQGakwE+/sKT/rABUAMk/qeHAv6+AUIBigAAAAEASgAAA2sDJAALAAABMxEhFQURIxEFNSEBmpMBPv7Ck/6wAVADJP6nhwL+vgFCAYoAAAABAEoAAANrAyQACwAAATMRIRUFESMRBTUhAZqTAT7+wpP+sAFQAyT+p4cC/r4BQgGKAAAAAAAOAK4AAQAAAAAAAAAHABAAAQAAAAAAAQAEACIAAQAAAAAAAgAGADUAAQAAAAAAAwAgAH4AAQAAAAAABAAEAKkAAQAAAAAABQAQANAAAQAAAAAABgAEAOsAAwABBAkAAAAOAAAAAwABBAkAAQAIABgAAwABBAkAAgAMACcAAwABBAkAAwBAADwAAwABBAkABAAIAJ8AAwABBAkABQAgAK4AAwABBAkABgAIAOEATQBvAHoAaQBsAGwAYQAATW96aWxsYQAAcABsAHUAcwAAcGx1cwAATQBlAGQAaQB1AG0AAE1lZGl1bQAARgBvAG4AdABGAG8AcgBnAGUAIAAyAC4AMAAgADoAIABwAGwAdQBzACAAOgAgADEALQAxADIALQAyADAAMQAyAABGb250Rm9yZ2UgMi4wIDogcGx1cyA6IDEtMTItMjAxMgAAcABsAHUAcwAAcGx1cwAAVgBlAHIAcwBpAG8AbgAgADAAMAAxAC4AMAAwADAAIAAAVmVyc2lvbiAwMDEuMDAwIAAAcABsAHUAcwAAcGx1cwAAAAACAAAAAAAA/4MAMgAAAAEAAAAAAAAAAAAAAAAAAAAAAAYAAAABAAIAQwECAQMHdW5pRjAwMAd1bmlGMDMwAAAAAAAB//8AAgABAAAADgAAABgAIAAAAAIAAQABAAUAAQAEAAAAAgAAAAEAAAABAAAAAAABAAAAAMmJbzEAAAAAzN/V8gAAAADM3+A1AA==); }';
|
|
||||||
|
|
||||||
var styleElement = document.getElementById('fontFaces');
|
|
||||||
var styleSheet = styleElement.sheet;
|
|
||||||
styleSheet.insertRule(rule, styleSheet.cssRules.length);
|
|
||||||
|
|
||||||
// checking if data urls are loaded synchronously
|
|
||||||
if (checkCanvas('plus-loaded'))
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
|
|
||||||
// TODO checking if data urls are loaded asynchronously
|
|
||||||
|
|
||||||
var usageElement = document.createElement('div');
|
|
||||||
usageElement.setAttribute('style', 'font-family: plus-loaded; visibility: hidden;');
|
|
||||||
usageElement.textContent = '`';
|
|
||||||
document.body.appendChild(usageElement);
|
|
||||||
|
|
||||||
// verify is font is loaded
|
|
||||||
var promise = new Promise();
|
|
||||||
setTimeout(function() {
|
|
||||||
if (checkCanvas('plus-loaded'))
|
|
||||||
promise.resolve({ output: 'Failed', emulated: 'Yes' });
|
|
||||||
else
|
|
||||||
promise.resolve({ output: 'Failed', emulated: 'No' });
|
|
||||||
}, 2000);
|
|
||||||
return promise;
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Worker',
|
|
||||||
name: 'Worker is present',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Worker != 'undefined')
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
else
|
|
||||||
return { output: 'Failed', emulated: 'No' };
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Worker-Uint8Array',
|
|
||||||
name: 'Worker can receive/send typed arrays',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Worker == 'undefined')
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
|
|
||||||
try {
|
|
||||||
var worker = new Worker('worker-stub.js');
|
|
||||||
|
|
||||||
var promise = new Promise();
|
|
||||||
var timeout = setTimeout(function () {
|
|
||||||
promise.resolve({ output: 'Failed', emulated: '?' });
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
worker.addEventListener('message', function (e) {
|
|
||||||
var data = e.data;
|
|
||||||
if (data.action == 'test' && data.result)
|
|
||||||
promise.resolve({ output: 'Success', emulated: '' });
|
|
||||||
else
|
|
||||||
promise.resolve({ output: 'Failed', emulated: 'Yes' });
|
|
||||||
}, false);
|
|
||||||
worker.postMessage({action: 'test',
|
|
||||||
data: new Uint8Array(60000000)}); // 60MB
|
|
||||||
return promise;
|
|
||||||
} catch (e) {
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Worker-transfers',
|
|
||||||
name: 'Worker can use transfers for postMessage',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Worker == 'undefined')
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
|
|
||||||
try {
|
|
||||||
var worker = new Worker('worker-stub.js');
|
|
||||||
|
|
||||||
var promise = new Promise();
|
|
||||||
var timeout = setTimeout(function () {
|
|
||||||
promise.resolve({ output: 'Failed', emulated: '?' });
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
worker.addEventListener('message', function (e) {
|
|
||||||
var data = e.data;
|
|
||||||
if (data.action == 'test-transfers' && data.result)
|
|
||||||
promise.resolve({ output: 'Success', emulated: '' });
|
|
||||||
else
|
|
||||||
promise.resolve({ output: 'Failed', emulated: 'Yes' });
|
|
||||||
}, false);
|
|
||||||
var testObj = new Uint8Array([255]);
|
|
||||||
worker.postMessage({action: 'test-transfers',
|
|
||||||
data: testObj}, [testObj.buffer]);
|
|
||||||
return promise;
|
|
||||||
} catch (e) {
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
impact: 'Normal',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Worker-xhr-response',
|
|
||||||
name: 'XMLHttpRequest supports the response property in web workers',
|
|
||||||
run: function () {
|
|
||||||
if (typeof Worker == 'undefined')
|
|
||||||
return { output: 'Skipped', emulated: '' };
|
|
||||||
|
|
||||||
try {
|
|
||||||
var worker = new Worker('worker-stub.js');
|
|
||||||
|
|
||||||
var promise = new Promise();
|
|
||||||
var timeout = setTimeout(function () {
|
|
||||||
promise.resolve({ output: 'Failed', emulated: '?' });
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
worker.addEventListener('message', function (e) {
|
|
||||||
var data = e.data;
|
|
||||||
if (data.action == 'xhr' && data.result)
|
|
||||||
promise.resolve({ output: 'Success', emulated: '' });
|
|
||||||
else
|
|
||||||
promise.resolve({ output: 'Failed', emulated: 'Yes' });
|
|
||||||
}, false);
|
|
||||||
worker.postMessage({action: 'xhr'});
|
|
||||||
return promise;
|
|
||||||
} catch (e) {
|
|
||||||
return { output: 'Failed', emulated: 'Yes' };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Core'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'Canvas Blend Mode',
|
|
||||||
name: 'Canvas supports extended blend modes',
|
|
||||||
run: function () {
|
|
||||||
var fail = { output: 'Failed', emulated: 'No' };
|
|
||||||
var ctx = document.createElement('canvas').getContext('2d');
|
|
||||||
ctx.canvas.width = 1;
|
|
||||||
ctx.canvas.height = 1;
|
|
||||||
var mode = 'difference';
|
|
||||||
ctx.globalCompositeOperation = mode;
|
|
||||||
if (ctx.globalCompositeOperation !== mode) {
|
|
||||||
return fail;
|
|
||||||
}
|
|
||||||
// Chrome supports setting the value, but it may not actually be
|
|
||||||
// implemented, so we have to actually test the blend mode.
|
|
||||||
ctx.fillStyle = 'red';
|
|
||||||
ctx.fillRect(0, 0, 1, 1);
|
|
||||||
ctx.fillStyle = 'blue';
|
|
||||||
ctx.fillRect(0, 0, 1, 1);
|
|
||||||
var pix = ctx.getImageData(0, 0, 1, 1).data;
|
|
||||||
if (pix[0] !== 255 || pix[1] !== 0 || pix[2] !== 255) {
|
|
||||||
return fail;
|
|
||||||
}
|
|
||||||
return { output: 'Success', emulated: '' };
|
|
||||||
},
|
|
||||||
impact: 'Important',
|
|
||||||
area: 'Core'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
function checkCanvas(font) {
|
|
||||||
var canvas = document.createElement('canvas');
|
|
||||||
var canvasHolder = document.getElementById('canvasHolder');
|
|
||||||
canvasHolder.appendChild(canvas);
|
|
||||||
var ctx = canvas.getContext('2d');
|
|
||||||
ctx.font = '40px \'' + font + '\'';
|
|
||||||
ctx.fillText('\u0060', 0, 40);
|
|
||||||
var data = ctx.getImageData(0, 0, 40, 40).data;
|
|
||||||
canvasHolder.removeChild(canvas);
|
|
||||||
|
|
||||||
// detects plus figure
|
|
||||||
var minx = 40, maxx = 0, miny = 40, maxy = 0;
|
|
||||||
for (var y = 0; y < 40; y++) {
|
|
||||||
for (var x = 0; x < 40; x++) {
|
|
||||||
if (data[x * 4 + y * 160 + 3] == 0) continue; // no color
|
|
||||||
minx = Math.min(minx, x); miny = Math.min(miny, y);
|
|
||||||
maxx = Math.max(maxx, x); maxy = Math.max(maxy, y);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var colors = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
|
|
||||||
var counts = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
|
|
||||||
for (var y = miny; y <= maxy; y++) {
|
|
||||||
for (var x = minx; x <= maxx; x++) {
|
|
||||||
var i = Math.floor((x - minx) * 3 / (maxx - minx + 1));
|
|
||||||
var j = Math.floor((y - miny) * 3 / (maxy - miny + 1));
|
|
||||||
counts[i][j]++;
|
|
||||||
if (data[x * 4 + y * 160 + 3] != 0)
|
|
||||||
colors[i][j]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var isPlus =
|
|
||||||
colors[0][0] * 3 < counts[0][0] &&
|
|
||||||
colors[0][1] * 3 > counts[0][1] &&
|
|
||||||
colors[0][2] * 3 < counts[0][2] &&
|
|
||||||
colors[1][0] * 3 > counts[1][0] &&
|
|
||||||
colors[1][1] * 3 > counts[1][1] &&
|
|
||||||
colors[1][2] * 3 > counts[1][2] &&
|
|
||||||
colors[2][0] * 3 < counts[2][0] &&
|
|
||||||
colors[2][1] * 3 > counts[2][1] &&
|
|
||||||
colors[2][2] * 3 < counts[2][2];
|
|
||||||
return isPlus;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/* Copyright 2012 Mozilla Foundation
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
onmessage = function (e) {
|
|
||||||
var data = e.data;
|
|
||||||
switch (data.action) {
|
|
||||||
case 'test':
|
|
||||||
postMessage({action: 'test', result: data.data instanceof Uint8Array});
|
|
||||||
break;
|
|
||||||
case 'test-transfers':
|
|
||||||
postMessage({action: 'test-transfers', result: data.data[0] === 255});
|
|
||||||
break;
|
|
||||||
case 'xhr':
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
var responseExists = 'response' in xhr;
|
|
||||||
// check if the property is actually implemented
|
|
||||||
try {
|
|
||||||
var dummy = xhr.responseType;
|
|
||||||
} catch (e) {
|
|
||||||
responseExists = false;
|
|
||||||
}
|
|
||||||
postMessage({action: 'xhr', result: responseExists});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
Loading…
x
Reference in New Issue
Block a user