mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 08:57:10 -06:00
Drop support for iOS < 15.7 (#19847)
https://meta.discourse.org/t/224747
This commit is contained in:
parent
0fea826f42
commit
624f4a7de9
@ -51,7 +51,7 @@ Discourse supports the **latest, stable releases** of all major browsers and pla
|
|||||||
| Microsoft Edge | | |
|
| Microsoft Edge | | |
|
||||||
| Mozilla Firefox | | |
|
| Mozilla Firefox | | |
|
||||||
|
|
||||||
Additionally, we aim to support Safari on iOS 12.5+ until January 2023 (Discourse 3.0).
|
Additionally, we aim to support Safari on iOS 15.7+.
|
||||||
|
|
||||||
## Built With
|
## Built With
|
||||||
|
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
import I18n from "I18n";
|
|
||||||
import { withPluginApi } from "discourse/lib/plugin-api";
|
|
||||||
|
|
||||||
function setupMessage(api) {
|
|
||||||
const isSafari = navigator.vendor === "Apple Computer, Inc.";
|
|
||||||
if (!isSafari) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let safariMajorVersion = navigator.userAgent.match(/Version\/(\d+)\./)?.[1];
|
|
||||||
safariMajorVersion = safariMajorVersion
|
|
||||||
? parseInt(safariMajorVersion, 10)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
if (safariMajorVersion && safariMajorVersion <= 13) {
|
|
||||||
api.addGlobalNotice(
|
|
||||||
I18n.t("safari_13_warning"),
|
|
||||||
"browser-deprecation-warning",
|
|
||||||
{ dismissable: true, dismissDuration: moment.duration(1, "week") }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "safari-13-deprecation",
|
|
||||||
|
|
||||||
initialize() {
|
|
||||||
withPluginApi("0.8.37", setupMessage);
|
|
||||||
},
|
|
||||||
};
|
|
@ -10,8 +10,7 @@ const browsers = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
if (isCI || isProduction) {
|
if (isCI || isProduction) {
|
||||||
// https://meta.discourse.org/t/224747
|
browsers.push("Safari 15");
|
||||||
browsers.push("Safari 12");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
/* eslint-disable no-var */ // `let` is not supported in very old browsers
|
/* eslint-disable no-var */ // `let` is not supported in very old browsers
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
if (!window.WeakMap || !window.Promise || typeof globalThis === "undefined") {
|
if (
|
||||||
|
!window.WeakMap ||
|
||||||
|
!window.Promise ||
|
||||||
|
typeof globalThis === "undefined" ||
|
||||||
|
!String.prototype.replaceAll ||
|
||||||
|
!CSS.supports ||
|
||||||
|
!CSS.supports("aspect-ratio: 1")
|
||||||
|
) {
|
||||||
window.unsupportedBrowser = true;
|
window.unsupportedBrowser = true;
|
||||||
} else {
|
} else {
|
||||||
// Some implementations of `WeakMap.prototype.has` do not accept false
|
// Some implementations of `WeakMap.prototype.has` do not accept false
|
||||||
|
@ -1,325 +1,5 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
|
||||||
// Needed for iOS <= 13.3
|
// Polyfills for old browsers can be added here
|
||||||
if (!String.prototype.replaceAll) {
|
|
||||||
String.prototype.replaceAll = function (
|
|
||||||
pattern,
|
|
||||||
replacementStringOrFunction
|
|
||||||
) {
|
|
||||||
let regex;
|
|
||||||
|
|
||||||
if (
|
|
||||||
Object.prototype.toString.call(pattern).toLowerCase() ===
|
|
||||||
"[object regexp]"
|
|
||||||
) {
|
|
||||||
regex = pattern;
|
|
||||||
} else {
|
|
||||||
const escapedStr = pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
||||||
regex = new RegExp(escapedStr, "g");
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.replace(regex, replacementStringOrFunction);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Needed for Safari 15.2 and below
|
|
||||||
// from: https://github.com/iamdustan/smoothscroll
|
|
||||||
(function () {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
function e() {
|
|
||||||
var e = window;
|
|
||||||
var t = document;
|
|
||||||
if (
|
|
||||||
"scrollBehavior" in t.documentElement.style &&
|
|
||||||
e.__forceSmoothScrollPolyfill__ !== true
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var o = e.HTMLElement || e.Element;
|
|
||||||
var r = 1.8;
|
|
||||||
var l = {
|
|
||||||
scroll: e.scroll || e.scrollTo,
|
|
||||||
scrollBy: e.scrollBy,
|
|
||||||
elementScroll: o.prototype.scroll || s,
|
|
||||||
scrollIntoView: o.prototype.scrollIntoView,
|
|
||||||
};
|
|
||||||
var n =
|
|
||||||
e.performance && e.performance.now
|
|
||||||
? e.performance.now.bind(e.performance)
|
|
||||||
: Date.now;
|
|
||||||
|
|
||||||
function i(e) {
|
|
||||||
var t = ["MSIE ", "Trident/", "Edge/"];
|
|
||||||
return new RegExp(t.join("|")).test(e);
|
|
||||||
}
|
|
||||||
var f = i(e.navigator.userAgent) ? 1 : 0;
|
|
||||||
|
|
||||||
function s(e, t) {
|
|
||||||
this.scrollLeft = e;
|
|
||||||
this.scrollTop = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
function c(e) {
|
|
||||||
return 0.5 * (1 - Math.cos(Math.PI * e));
|
|
||||||
}
|
|
||||||
|
|
||||||
function a(e) {
|
|
||||||
if (
|
|
||||||
e === null ||
|
|
||||||
typeof e !== "object" ||
|
|
||||||
e.behavior === undefined ||
|
|
||||||
e.behavior === "auto" ||
|
|
||||||
e.behavior === "instant"
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (typeof e === "object" && e.behavior === "smooth") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
throw new TypeError(
|
|
||||||
"behavior member of ScrollOptions " +
|
|
||||||
e.behavior +
|
|
||||||
" is not a valid value for enumeration ScrollBehavior."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function u(e, t) {
|
|
||||||
if (t === "Y") {
|
|
||||||
return e.clientHeight + f < e.scrollHeight;
|
|
||||||
}
|
|
||||||
if (t === "X") {
|
|
||||||
return e.clientWidth + f < e.scrollWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function d(t, o) {
|
|
||||||
var r = e.getComputedStyle(t, null)["overflow" + o];
|
|
||||||
return r === "auto" || r === "scroll";
|
|
||||||
}
|
|
||||||
|
|
||||||
function p(e) {
|
|
||||||
var t = u(e, "Y") && d(e, "Y");
|
|
||||||
var o = u(e, "X") && d(e, "X");
|
|
||||||
return t || o;
|
|
||||||
}
|
|
||||||
|
|
||||||
function h(e) {
|
|
||||||
while (e !== t.body && p(e) === false) {
|
|
||||||
e = e.parentNode || e.host;
|
|
||||||
}
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
function v(e, t) {
|
|
||||||
var o = r / t;
|
|
||||||
var l = Math.pow(1.16, Math.max(e / 80, 1));
|
|
||||||
return o * e * (1 / l);
|
|
||||||
}
|
|
||||||
|
|
||||||
function y(t) {
|
|
||||||
var o = n();
|
|
||||||
var r = e.devicePixelRatio;
|
|
||||||
var l;
|
|
||||||
var i;
|
|
||||||
var f;
|
|
||||||
var s;
|
|
||||||
var a = v(Math.abs(t.x - t.startX), r);
|
|
||||||
var u = v(Math.abs(t.y - t.startY), r);
|
|
||||||
var d = (o - t.startTime) / a;
|
|
||||||
var p = (o - t.startTime) / u;
|
|
||||||
d = d > 1 ? 1 : d;
|
|
||||||
p = p > 1 ? 1 : p;
|
|
||||||
l = c(d);
|
|
||||||
i = c(p);
|
|
||||||
f = t.startX + (t.x - t.startX) * l;
|
|
||||||
s = t.startY + (t.y - t.startY) * i;
|
|
||||||
t.method.call(t.scrollable, f, s);
|
|
||||||
if (f !== t.x || s !== t.y) {
|
|
||||||
e.requestAnimationFrame(y.bind(e, t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function m(o, r, i) {
|
|
||||||
var f;
|
|
||||||
var c;
|
|
||||||
var a;
|
|
||||||
var u;
|
|
||||||
var d = n();
|
|
||||||
if (o === t.body) {
|
|
||||||
f = e;
|
|
||||||
c = e.scrollX || e.pageXOffset;
|
|
||||||
a = e.scrollY || e.pageYOffset;
|
|
||||||
u = l.scroll;
|
|
||||||
} else {
|
|
||||||
f = o;
|
|
||||||
c = o.scrollLeft;
|
|
||||||
a = o.scrollTop;
|
|
||||||
u = s;
|
|
||||||
}
|
|
||||||
y({
|
|
||||||
scrollable: f,
|
|
||||||
method: u,
|
|
||||||
startTime: d,
|
|
||||||
startX: c,
|
|
||||||
startY: a,
|
|
||||||
x: r,
|
|
||||||
y: i,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
e.scroll = e.scrollTo = function () {
|
|
||||||
if (arguments[0] === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (a(arguments[0]) === true) {
|
|
||||||
l.scroll.call(
|
|
||||||
e,
|
|
||||||
arguments[0].left !== undefined
|
|
||||||
? arguments[0].left
|
|
||||||
: typeof arguments[0] !== "object"
|
|
||||||
? arguments[0]
|
|
||||||
: e.scrollX || e.pageXOffset,
|
|
||||||
arguments[0].top !== undefined
|
|
||||||
? arguments[0].top
|
|
||||||
: arguments[1] !== undefined
|
|
||||||
? arguments[1]
|
|
||||||
: e.scrollY || e.pageYOffset
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m.call(
|
|
||||||
e,
|
|
||||||
t.body,
|
|
||||||
arguments[0].left !== undefined
|
|
||||||
? ~~arguments[0].left
|
|
||||||
: e.scrollX || e.pageXOffset,
|
|
||||||
arguments[0].top !== undefined
|
|
||||||
? ~~arguments[0].top
|
|
||||||
: e.scrollY || e.pageYOffset
|
|
||||||
);
|
|
||||||
};
|
|
||||||
e.scrollBy = function () {
|
|
||||||
if (arguments[0] === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (a(arguments[0])) {
|
|
||||||
l.scrollBy.call(
|
|
||||||
e,
|
|
||||||
arguments[0].left !== undefined
|
|
||||||
? arguments[0].left
|
|
||||||
: typeof arguments[0] !== "object"
|
|
||||||
? arguments[0]
|
|
||||||
: 0,
|
|
||||||
arguments[0].top !== undefined
|
|
||||||
? arguments[0].top
|
|
||||||
: arguments[1] !== undefined
|
|
||||||
? arguments[1]
|
|
||||||
: 0
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m.call(
|
|
||||||
e,
|
|
||||||
t.body,
|
|
||||||
~~arguments[0].left + (e.scrollX || e.pageXOffset),
|
|
||||||
~~arguments[0].top + (e.scrollY || e.pageYOffset)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
o.prototype.scroll = o.prototype.scrollTo = function () {
|
|
||||||
if (arguments[0] === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (a(arguments[0]) === true) {
|
|
||||||
if (typeof arguments[0] === "number" && arguments[1] === undefined) {
|
|
||||||
throw new SyntaxError("Value could not be converted");
|
|
||||||
}
|
|
||||||
l.elementScroll.call(
|
|
||||||
this,
|
|
||||||
arguments[0].left !== undefined
|
|
||||||
? ~~arguments[0].left
|
|
||||||
: typeof arguments[0] !== "object"
|
|
||||||
? ~~arguments[0]
|
|
||||||
: this.scrollLeft,
|
|
||||||
arguments[0].top !== undefined
|
|
||||||
? ~~arguments[0].top
|
|
||||||
: arguments[1] !== undefined
|
|
||||||
? ~~arguments[1]
|
|
||||||
: this.scrollTop
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var e = arguments[0].left;
|
|
||||||
var t = arguments[0].top;
|
|
||||||
m.call(
|
|
||||||
this,
|
|
||||||
this,
|
|
||||||
typeof e === "undefined" ? this.scrollLeft : ~~e,
|
|
||||||
typeof t === "undefined" ? this.scrollTop : ~~t
|
|
||||||
);
|
|
||||||
};
|
|
||||||
o.prototype.scrollBy = function () {
|
|
||||||
if (arguments[0] === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (a(arguments[0]) === true) {
|
|
||||||
l.elementScroll.call(
|
|
||||||
this,
|
|
||||||
arguments[0].left !== undefined
|
|
||||||
? ~~arguments[0].left + this.scrollLeft
|
|
||||||
: ~~arguments[0] + this.scrollLeft,
|
|
||||||
arguments[0].top !== undefined
|
|
||||||
? ~~arguments[0].top + this.scrollTop
|
|
||||||
: ~~arguments[1] + this.scrollTop
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.scroll({
|
|
||||||
left: ~~arguments[0].left + this.scrollLeft,
|
|
||||||
top: ~~arguments[0].top + this.scrollTop,
|
|
||||||
behavior: arguments[0].behavior,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
o.prototype.scrollIntoView = function () {
|
|
||||||
if (a(arguments[0]) === true) {
|
|
||||||
l.scrollIntoView.call(
|
|
||||||
this,
|
|
||||||
arguments[0] === undefined ? true : arguments[0]
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var o = h(this);
|
|
||||||
var r = o.getBoundingClientRect();
|
|
||||||
var n = this.getBoundingClientRect();
|
|
||||||
if (o !== t.body) {
|
|
||||||
m.call(
|
|
||||||
this,
|
|
||||||
o,
|
|
||||||
o.scrollLeft + n.left - r.left,
|
|
||||||
o.scrollTop + n.top - r.top
|
|
||||||
);
|
|
||||||
if (e.getComputedStyle(o).position !== "fixed") {
|
|
||||||
e.scrollBy({
|
|
||||||
left: r.left,
|
|
||||||
top: r.top,
|
|
||||||
behavior: "smooth",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
e.scrollBy({
|
|
||||||
left: n.left,
|
|
||||||
top: n.top,
|
|
||||||
behavior: "smooth",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (typeof exports === "object" && typeof module !== "undefined") {
|
|
||||||
module.exports = {
|
|
||||||
polyfill: e,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
e();
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
@ -6,7 +6,7 @@ require "json_schemer"
|
|||||||
class Theme < ActiveRecord::Base
|
class Theme < ActiveRecord::Base
|
||||||
include GlobalPath
|
include GlobalPath
|
||||||
|
|
||||||
BASE_COMPILER_VERSION = 69
|
BASE_COMPILER_VERSION = 70
|
||||||
|
|
||||||
attr_accessor :child_components
|
attr_accessor :child_components
|
||||||
|
|
||||||
|
@ -3987,8 +3987,6 @@ en:
|
|||||||
|
|
||||||
browser_update: 'Unfortunately, <a href="https://www.discourse.org/faq/#browser">your browser is unsupported</a>. Please <a href="https://browsehappy.com">switch to a supported browser</a> to view rich content, log in and reply.'
|
browser_update: 'Unfortunately, <a href="https://www.discourse.org/faq/#browser">your browser is unsupported</a>. Please <a href="https://browsehappy.com">switch to a supported browser</a> to view rich content, log in and reply.'
|
||||||
|
|
||||||
safari_13_warning: This site will soon remove support for iOS and Safari versions 13 and below. A simplified read-only version will remain available. (<a href="https://meta.discourse.org/t/224747">more information</a>)
|
|
||||||
|
|
||||||
permission_types:
|
permission_types:
|
||||||
full: "Create / Reply / See"
|
full: "Create / Reply / See"
|
||||||
create_post: "Reply / See"
|
create_post: "Reply / See"
|
||||||
|
@ -6,22 +6,12 @@ class DiscourseJsProcessor
|
|||||||
class TranspileError < StandardError
|
class TranspileError < StandardError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# To generate a list of babel plugins used by ember-cli, set
|
||||||
|
# babel: { debug: true } in ember-cli-build.js, then run `yarn ember build -prod`
|
||||||
DISCOURSE_COMMON_BABEL_PLUGINS = [
|
DISCOURSE_COMMON_BABEL_PLUGINS = [
|
||||||
"proposal-optional-chaining",
|
|
||||||
["proposal-decorators", { legacy: true }],
|
["proposal-decorators", { legacy: true }],
|
||||||
"transform-template-literals",
|
|
||||||
"proposal-class-properties",
|
|
||||||
"proposal-class-static-block",
|
"proposal-class-static-block",
|
||||||
"proposal-private-property-in-object",
|
|
||||||
"proposal-private-methods",
|
|
||||||
"proposal-numeric-separator",
|
|
||||||
"proposal-logical-assignment-operators",
|
|
||||||
"proposal-nullish-coalescing-operator",
|
|
||||||
"proposal-json-strings",
|
|
||||||
"proposal-optional-catch-binding",
|
|
||||||
"transform-parameters",
|
"transform-parameters",
|
||||||
"proposal-async-generator-functions",
|
|
||||||
"proposal-object-rest-spread",
|
|
||||||
"proposal-export-namespace-from",
|
"proposal-export-namespace-from",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@ module MobileDetection
|
|||||||
|
|
||||||
MODERN_MOBILE_REGEX =
|
MODERN_MOBILE_REGEX =
|
||||||
%r{
|
%r{
|
||||||
\(.*iPhone\ OS\ 1[3-9].*\)|
|
\(.*iPhone\ OS\ 1[5-9].*\)|
|
||||||
\(.*iPad.*OS\ 1[3-9].*\)|
|
\(.*iPad.*OS\ 1[5-9].*\)|
|
||||||
Chrome\/8[89]|
|
Chrome\/8[89]|
|
||||||
Chrome\/9[0-9]|
|
Chrome\/9[0-9]|
|
||||||
Chrome\/1[0-9][0-9]|
|
Chrome\/1[0-9][0-9]|
|
||||||
|
@ -37,6 +37,45 @@ RSpec.describe DiscourseJsProcessor do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "passes through modern JS syntaxes which are supported in our target browsers" do
|
||||||
|
script = <<~JS.chomp
|
||||||
|
optional?.chaining;
|
||||||
|
const template = func`test`;
|
||||||
|
class MyClass {
|
||||||
|
classProperty = 1;
|
||||||
|
#privateProperty = 1;
|
||||||
|
#privateMethod() {
|
||||||
|
console.log("hello world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let numericSeparator = 100_000_000;
|
||||||
|
logicalAssignment ||= 2;
|
||||||
|
nullishCoalescing ?? 'works';
|
||||||
|
try {
|
||||||
|
"optional catch binding";
|
||||||
|
} catch {
|
||||||
|
"works";
|
||||||
|
}
|
||||||
|
async function* asyncGeneratorFunction() {
|
||||||
|
yield await Promise.resolve('a');
|
||||||
|
}
|
||||||
|
let a = {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
...spreadRest
|
||||||
|
};
|
||||||
|
JS
|
||||||
|
|
||||||
|
result = DiscourseJsProcessor.transpile(script, "blah", "blah/mymodule")
|
||||||
|
expect(result).to eq <<~JS.strip
|
||||||
|
define("blah/mymodule", [], function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
#{script.indent(2)}
|
||||||
|
});
|
||||||
|
JS
|
||||||
|
end
|
||||||
|
|
||||||
it "correctly transpiles widget hbs" do
|
it "correctly transpiles widget hbs" do
|
||||||
result = DiscourseJsProcessor.transpile(<<~JS, "blah", "blah/mymodule")
|
result = DiscourseJsProcessor.transpile(<<~JS, "blah", "blah/mymodule")
|
||||||
import hbs from "discourse/widgets/hbs-compiler";
|
import hbs from "discourse/widgets/hbs-compiler";
|
||||||
|
@ -10,6 +10,8 @@ RSpec.describe MobileDetection do
|
|||||||
Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25
|
Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25
|
||||||
Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Mobile Safari/537.36 (comp
|
Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Mobile Safari/537.36 (comp
|
||||||
Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.3626.121 Mobile Safari/537.36 (comp
|
Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.3626.121 Mobile Safari/537.36 (comp
|
||||||
|
Mozilla/5.0 (iPhone; CPU iPhone OS 14_8_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1
|
||||||
|
Mozilla/5.0 (iPhone; CPU iPhone OS 14_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/99.0.4844.59 Mobile/15E148 Safari/604.1
|
||||||
STR
|
STR
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -17,7 +19,6 @@ RSpec.describe MobileDetection do
|
|||||||
(<<~STR).split("\n")
|
(<<~STR).split("\n")
|
||||||
Mozilla/5.0 (iPhone; CPU iPhone OS 15_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Mobile/15E148 Safari/604.1
|
Mozilla/5.0 (iPhone; CPU iPhone OS 15_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.3 Mobile/15E148 Safari/604.1
|
||||||
Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Mobile Safari/537.36 (compatible;
|
Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Mobile Safari/537.36 (compatible;
|
||||||
Mozilla/5.0 (iPhone; CPU iPhone OS 14_8_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.2 Mobile/15E148 Safari/604.1
|
|
||||||
Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Mobile Safari/537.36 (compatible
|
Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Mobile Safari/537.36 (compatible
|
||||||
Mozilla/5.0 (Android 12; Mobile; rv:98.0) Gecko/98.0 Firefox/98.0
|
Mozilla/5.0 (Android 12; Mobile; rv:98.0) Gecko/98.0 Firefox/98.0
|
||||||
Mozilla/5.0 (iPad; CPU OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/99.0.4844.59 Mobile/15E148 Safari/604.1
|
Mozilla/5.0 (iPad; CPU OS 15_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/99.0.4844.59 Mobile/15E148 Safari/604.1
|
||||||
@ -26,7 +27,6 @@ RSpec.describe MobileDetection do
|
|||||||
Mozilla/5.0 (iPhone; CPU iPhone OS 15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DiscourseHub
|
Mozilla/5.0 (iPhone; CPU iPhone OS 15_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DiscourseHub
|
||||||
Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36
|
Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36
|
||||||
Mozilla/5.0 (Android 12; Mobile; rv:99.0) Gecko/99.0 Firefox/99.0
|
Mozilla/5.0 (Android 12; Mobile; rv:99.0) Gecko/99.0 Firefox/99.0
|
||||||
Mozilla/5.0 (iPhone; CPU iPhone OS 14_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/99.0.4844.59 Mobile/15E148 Safari/604.1
|
|
||||||
Mozilla/5.0 (Linux; Android 12; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36
|
Mozilla/5.0 (Linux; Android 12; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36
|
||||||
Mozilla/5.0 (Linux; Android 12; Pixel 4a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36
|
Mozilla/5.0 (Linux; Android 12; Pixel 4a) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.88 Mobile Safari/537.36
|
||||||
Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Mobile Safari/537.36
|
Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.60 Mobile Safari/537.36
|
||||||
@ -36,11 +36,17 @@ Mozilla/5.0 (iPhone; CPU iPhone OS 14_8 like Mac OS X) AppleWebKit/605.1.15 (KHT
|
|||||||
|
|
||||||
it "detects modern browsers correctly" do
|
it "detects modern browsers correctly" do
|
||||||
modern_user_agents.each do |agent|
|
modern_user_agents.each do |agent|
|
||||||
expect(MobileDetection.modern_mobile_device?(agent)).to eq(true)
|
expect(MobileDetection.modern_mobile_device?(agent)).to(
|
||||||
|
eq(true),
|
||||||
|
"Failed User Agent: '#{agent}'",
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
old_user_agents.each do |agent|
|
old_user_agents.each do |agent|
|
||||||
expect(MobileDetection.modern_mobile_device?(agent)).to eq(false)
|
expect(MobileDetection.modern_mobile_device?(agent)).to(
|
||||||
|
eq(false),
|
||||||
|
"Failed User Agent: '#{agent}'",
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user