2019-11-11 23:00:39 +01:00
|
|
|
/* 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/. */
|
|
|
|
(function(){
|
|
|
|
"use strict";
|
|
|
|
|
2019-11-28 01:26:35 +01:00
|
|
|
let scope;
|
2019-11-11 23:00:39 +01:00
|
|
|
if ((typeof exports) !== "undefined"){
|
|
|
|
scope = exports;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
scope = require.register("./modifiedScreenAPI", {});
|
|
|
|
}
|
|
|
|
|
2019-12-10 15:07:22 +01:00
|
|
|
const {checkerWrapper, setGetterProperties, getStatusByFlag} = require("./modifiedAPIFunctions");
|
2019-11-11 23:00:39 +01:00
|
|
|
|
|
|
|
const physical = {
|
|
|
|
width: Math.round(window.screen.width * window.devicePixelRatio),
|
|
|
|
height: Math.round(window.screen.height * window.devicePixelRatio)
|
|
|
|
};
|
|
|
|
if (!window.matchMedia(`(device-width: ${physical.width / window.devicePixelRatio}px`).matches){
|
|
|
|
let minWidth = Math.ceil((window.screen.width - 0.5) * window.devicePixelRatio);
|
|
|
|
let maxWidth = Math.floor((window.screen.width + 0.5) * window.devicePixelRatio);
|
|
|
|
for (let width = minWidth; width <= maxWidth; width += 1){
|
|
|
|
if (window.matchMedia(`(device-width: ${width / window.devicePixelRatio}px`).matches){
|
|
|
|
physical.width = width;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!window.matchMedia(`(device-height: ${physical.height / window.devicePixelRatio}px`).matches){
|
|
|
|
let minHeight = Math.ceil((window.screen.height - 0.5) * window.devicePixelRatio);
|
|
|
|
let maxHeight = Math.floor((window.screen.height + 0.5) * window.devicePixelRatio);
|
|
|
|
for (let height = minHeight; height <= maxHeight; height += 1){
|
|
|
|
if (window.matchMedia(`(device-height: ${height / window.devicePixelRatio}px`).matches){
|
|
|
|
physical.height = height;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const resolutions = {
|
|
|
|
portrait: [
|
|
|
|
{height: 1366, width: 768},
|
|
|
|
{height: 1440, width: 900},
|
|
|
|
{height: 1600, width: 900},
|
|
|
|
{height: 1920, width: 1080},
|
2019-11-22 08:23:45 +01:00
|
|
|
{height: 2560, width: 1440},
|
2019-11-11 23:00:39 +01:00
|
|
|
{height: 4096, width: 2160},
|
2019-11-22 08:23:45 +01:00
|
|
|
{height: 8192, width: 6144},
|
2019-11-11 23:00:39 +01:00
|
|
|
],
|
|
|
|
landscape: [
|
|
|
|
{width: 1366, height: 768},
|
|
|
|
{width: 1440, height: 900},
|
|
|
|
{width: 1600, height: 900},
|
|
|
|
{width: 1920, height: 1080},
|
2019-11-22 08:23:45 +01:00
|
|
|
{width: 2560, height: 1440},
|
2019-11-11 23:00:39 +01:00
|
|
|
{width: 4096, height: 2160},
|
2019-11-22 08:23:45 +01:00
|
|
|
{width: 8192, height: 6144},
|
2019-11-11 23:00:39 +01:00
|
|
|
]
|
|
|
|
};
|
|
|
|
|
|
|
|
function getScreenDimensions(prefs, window){
|
|
|
|
const screenSize = prefs("screenSize", window.location);
|
|
|
|
if (screenSize.match(/\s*\d+\s*x\s*\d+\s*$/)){
|
|
|
|
const [width, height] = screenSize.split("x").map(function(value){
|
|
|
|
return Math.round(parseFloat(value.trim()));
|
|
|
|
});
|
|
|
|
return {
|
|
|
|
width: width / window.devicePixelRatio,
|
|
|
|
height: height / window.devicePixelRatio
|
|
|
|
};
|
|
|
|
}
|
|
|
|
if (!prefs("fakeMinimalScreenSize", window.location)){
|
|
|
|
return window.screen;
|
|
|
|
}
|
|
|
|
const isLandscape = window.screen.width > window.screen.height;
|
|
|
|
// subtract 0.5 to adjust for potential rounding errors
|
|
|
|
const innerWidth = (window.innerWidth - 0.5) * window.devicePixelRatio;
|
|
|
|
const innerHeight = (window.innerHeight - 0.5) * window.devicePixelRatio;
|
|
|
|
for (let resolution of resolutions[isLandscape? "landscape": "portrait"]){
|
|
|
|
if (resolution.width >= innerWidth && resolution.height >= innerHeight){
|
|
|
|
return {
|
|
|
|
width: resolution.width / window.devicePixelRatio,
|
|
|
|
height: resolution.height / window.devicePixelRatio
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return window.screen;
|
|
|
|
}
|
|
|
|
|
2019-12-02 19:17:54 +01:00
|
|
|
function getFaker(dimension){
|
|
|
|
return function fake(args, check){
|
|
|
|
const {prefs, notify, window, original} = check;
|
2019-12-29 23:40:39 +01:00
|
|
|
const originalValue = original.call(this, ...args);
|
2019-12-02 19:17:54 +01:00
|
|
|
const returnValue = (typeof dimension) === "function"?
|
|
|
|
dimension(window):
|
|
|
|
dimension?
|
|
|
|
Math.round(getScreenDimensions(prefs, window)[dimension]):
|
|
|
|
0;
|
|
|
|
if (originalValue !== returnValue){
|
|
|
|
notify("fakedScreenReadout");
|
|
|
|
}
|
|
|
|
return returnValue;
|
|
|
|
};
|
2019-12-01 01:25:39 +01:00
|
|
|
}
|
|
|
|
|
2019-11-11 23:00:39 +01:00
|
|
|
scope.changedGetters = [
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window.Screen && window.Screen.prototype;}],
|
|
|
|
name: "width",
|
|
|
|
getterGenerator: function(checker){
|
|
|
|
const temp = {
|
|
|
|
get width(){
|
2019-12-02 19:17:54 +01:00
|
|
|
return checkerWrapper(checker, this, arguments, getFaker("width"));
|
2019-11-11 23:00:39 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "width").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window.Screen && window.Screen.prototype;}],
|
|
|
|
name: "height",
|
|
|
|
getterGenerator: function(checker){
|
|
|
|
const temp = {
|
|
|
|
get height(){
|
2019-12-02 19:17:54 +01:00
|
|
|
return checkerWrapper(checker, this, arguments, getFaker("height"));
|
2019-11-11 23:00:39 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "height").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window.Screen && window.Screen.prototype;}],
|
|
|
|
name: "availWidth",
|
|
|
|
getterGenerator: function(checker){
|
|
|
|
const temp = {
|
|
|
|
get availWidth(){
|
2019-12-02 19:17:54 +01:00
|
|
|
return checkerWrapper(checker, this, arguments, getFaker("width"));
|
2019-11-11 23:00:39 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "availWidth").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window.Screen && window.Screen.prototype;}],
|
|
|
|
name: "availHeight",
|
|
|
|
getterGenerator: function(checker){
|
|
|
|
const temp = {
|
|
|
|
get availHeight(){
|
2019-12-02 19:17:54 +01:00
|
|
|
return checkerWrapper(checker, this, arguments, getFaker("height"));
|
2019-11-11 23:00:39 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "availHeight").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window.Screen && window.Screen.prototype;}],
|
|
|
|
name: "availLeft",
|
|
|
|
getterGenerator: function(checker){
|
|
|
|
const temp = {
|
|
|
|
get availLeft(){
|
2019-12-02 19:17:54 +01:00
|
|
|
return checkerWrapper(checker, this, arguments, getFaker(0));
|
2019-11-11 23:00:39 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "availLeft").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window.Screen && window.Screen.prototype;}],
|
|
|
|
name: "availTop",
|
|
|
|
getterGenerator: function(checker){
|
|
|
|
const temp = {
|
|
|
|
get availTop(){
|
2019-12-02 19:17:54 +01:00
|
|
|
return checkerWrapper(checker, this, arguments, getFaker(0));
|
2019-11-11 23:00:39 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "availTop").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window;}],
|
|
|
|
name: "outerWidth",
|
|
|
|
getterGenerator: function(checker){
|
|
|
|
const temp = {
|
|
|
|
get outerWidth(){
|
2019-12-02 19:17:54 +01:00
|
|
|
return checkerWrapper(checker, this, arguments, getFaker(window => window.innerWidth));
|
2019-11-11 23:00:39 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "outerWidth").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window;}],
|
|
|
|
name: "outerHeight",
|
|
|
|
getterGenerator: function(checker){
|
|
|
|
const temp = {
|
|
|
|
get outerHeight(){
|
2019-12-02 19:17:54 +01:00
|
|
|
return checkerWrapper(checker, this, arguments, getFaker(window => window.innerHeight));
|
2019-11-11 23:00:39 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "outerHeight").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
objectGetters: [function(window){return window.MediaQueryList && window.MediaQueryList.prototype;}],
|
|
|
|
name: "matches",
|
|
|
|
getterGenerator: function(checker){
|
2019-12-29 00:18:05 +01:00
|
|
|
function getAlteredMedia(originalMedia, prefs, window){
|
|
|
|
const dimensions = getScreenDimensions(prefs, window);
|
|
|
|
return originalMedia.replace(
|
|
|
|
/\(\s*(?:(min|max)-)?device-(width|height):\s+(\d+\.?\d*)px\s*\)/,
|
|
|
|
function(m, type, dimension, value){
|
|
|
|
value = parseFloat(value);
|
|
|
|
let newCompareValue = value;
|
|
|
|
switch (type){
|
|
|
|
case "min":
|
|
|
|
if (value <= dimensions[dimension]){
|
|
|
|
newCompareValue = 0;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
newCompareValue = 2 * physical[dimension];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "max":
|
|
|
|
if (value >= dimensions[dimension]){
|
|
|
|
newCompareValue = 2 * physical[dimension];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
newCompareValue = 0;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (
|
|
|
|
Math.round(value * 100) ===
|
|
|
|
Math.round(dimensions[dimension] * 100)
|
|
|
|
){
|
|
|
|
newCompareValue = physical[dimension];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
newCompareValue = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "(" + (type? type + "-": "") +
|
|
|
|
"device-" + dimension + ": " +
|
|
|
|
(
|
|
|
|
newCompareValue /
|
|
|
|
window.devicePixelRatio
|
|
|
|
) + "px)";
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
2019-11-11 23:00:39 +01:00
|
|
|
const temp = {
|
|
|
|
get matches(){
|
|
|
|
return checkerWrapper(checker, this, arguments, function(args, check){
|
|
|
|
const {prefs, notify, window, original} = check;
|
2019-12-29 23:40:39 +01:00
|
|
|
const originalValue = original.call(this, ...args);
|
2019-11-11 23:00:39 +01:00
|
|
|
const screenSize = prefs("screenSize", window.location);
|
|
|
|
if (
|
|
|
|
(
|
|
|
|
screenSize.match(/\s*\d+\s*x\s*\d+\s*$/) ||
|
|
|
|
prefs("fakeMinimalScreenSize", window.location)
|
|
|
|
) &&
|
|
|
|
this.media.match(/device-(width|height)/)
|
|
|
|
){
|
|
|
|
const originalMedia = this.media;
|
2019-12-29 00:18:05 +01:00
|
|
|
const alteredMedia = getAlteredMedia(originalMedia, prefs, window);
|
2019-11-11 23:00:39 +01:00
|
|
|
if (alteredMedia !== originalMedia){
|
|
|
|
const alteredQuery = window.matchMedia(alteredMedia);
|
|
|
|
const fakedValue = original.call(alteredQuery);
|
|
|
|
if (originalValue !== fakedValue){
|
|
|
|
notify("fakedScreenReadout");
|
|
|
|
}
|
|
|
|
return fakedValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return originalValue;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return Object.getOwnPropertyDescriptor(temp, "matches").get;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2019-12-10 15:07:22 +01:00
|
|
|
setGetterProperties(scope.changedGetters, {
|
|
|
|
type: "readout",
|
|
|
|
getStatus: getStatusByFlag("protectScreen"),
|
|
|
|
api: "screen"
|
2019-11-11 23:00:39 +01:00
|
|
|
});
|
|
|
|
}());
|