Closed Thorin-Oakenpants closed 1 year ago
semi-inspired by this
fyi: @chris124567 - ps love your commercial bot detectors repo 👍
@abrahamjuliot interesting stats on Android versions - see the pic
Safari
While not necessary, I thought it would be nice to always try and get something different to gecko for both chrome and webkit.
Webkit collation was tough. I'm using FF60+ (for backwards compat) 104 items supported items (that way everything is supported and nothing falls back to undefined
-> system/app locale = could be anything) so the hash is stable. Everything in those 104 locales are supported in webkit.
But looking at what changes in FF: the only diff is no
(I'm sure they'll hook that up at some stage)
not in webkit (108)
- FF70+: no, tl
- FF78+: ff
- FF91+: br, sa,
- can't get any collation diffs: br (breton), sa (sanskrit), ff (fulah), tl (tagalog)
- leaves: no
So if isFF and is 70+ then I swap no
in for one of the others, so at least webkit comes up red x
This won't be such as issue with other constructors, since I won't need to rely on collation
@abrahamjuliot help me out
%
which is inside a string, as [object Object]
\%
and now \u0025
not supported
and a red X rather than blockedno
), but locale.compare shows two (the other being mt
. Both use the same locale lists. locale.compare is only using two chars, Intl.Collator a heaps of them. Seems like something in webkit (or gecko) is wired wrongFYI: Intl.Collator
FF60 (104)
af, am, ar, as, az, be, bg, bn, bo, bs, ca, cs, cy, da, de, dsb, dz, ee, el, en,
eo, es, et, fa, fi, fo, fr, ga, gl, gu, ha, haw, he, hi, hr, hsb, hu, hy, id, ig,
is, it, ja, ka, kk, kl, km, kn, ko, kok, ky, lb, ln, lo, lt, lv, mk, ml, mn, mr,
ms, mt, my, nb, ne, nl, nn, om, or, pa, pl, ps, pt, ro, ru, se, si, sk, sl, sq,
sr, sv, sw, ta, te, th, to, tr, ug, uk, ur, uz, vi, wo, yi, yo, zh, zh-Hans,
zh-Hant, zh-CN, zh-HK, zh-SG, zh-TW, zu
FF91+ (113)
br, ff, hye -> hy, ku, no, sa, tk, tl -> fil, xh,
BLINK (54) (excluding tl->fil and no, not in FF60)
am, ar, bg, bn, ca, cs, da, de, el, en, es, et, fa, fi, fr, gu, he, hi, hr, hu, id,
it, ja, kn, ko, lt, lv, ml, mr, ms, nb, nl, pl, pt, ro, ru, sk, sl, sr, sv, sw,
ta, te, th, tr, uk, vi, zh, zh-Hans, zh-Hant, zh-CN, zh-HK, zh-SG, zh-TW
WEBKIT (108)
af, am, ar, as, az, be, bg, bn, bo, bs, ca, cs, cy, da, de, dsb, dz, ee, el, en,
eo, es, et, fa, fi, fo, fr, ga, gl, gu, ha, haw, he, hi, hr, hsb, hu, hy, hye -> hy, id,
ig, is, it, ja, ka, kk, kl, km, kn, ko, kok, ku, ky, lb, ln, lo, lt, lv, mk, ml, mn,
mr, ms, mt, my, nb, ne, nl, nn, om, or, pa, pl, ps, pt, ro, ru, se, si, sk, sl, sq,
sr, sv, sw, ta, te, th, tk, to, tr, ug, uk, ur, uz, vi, wo, xh, yi, yo, zh, zh-Hans,
zh-Hant, zh-CN, zh-HK, zh-SG, zh-TW, zu
It looks like this is a unicode bug triggered by this specific unicode with the use of additional console.log
arguments.
¯\_(ツ)_/¯
console.log('...\u0025\n', [])
// ...[object Object]
As an alternative, we can make that additional argument a separate log:
console.log('...\u0025\n')
console.log([])
/*
...%
[]
*/
thanks.,not going to code around it, not worth it
not to be confused with Jose “Slowpoke” Rodriguez
hopefully impervious to extension fuckery and perf changes
let isFF = false
let tstart = performance.now()
let ff1 = Element.prototype.hasOwnProperty("mozMatchesSelector") // 0.014ms
let ff2 = CanvasRenderingContext2D.prototype.hasOwnProperty("mozTextStyle") // 0.133ms
let ff3 = ("boolean" === typeof document.mozFullScreenEnabled) // 0.015ms
let ff4 = ("object" === typeof Object.getOwnPropertyDescriptor(SVGElement.prototype, "onmozfullscreenchange")) // 0.024ms
let ff5 = ("object" === typeof Object.getOwnPropertyDescriptor(HTMLElement.prototype, "onmozfullscreenerror")) // 0.029ms
let ff6 = ("function" === typeof CSSMozDocumentRule) // 0.080ms // false FF52
let ff7 = ("function" === typeof document.mozSetImageElement) // 0.080ms
let ff8 = ("object" === typeof screen.onmozorientationchange) // 0.075ms
let res = [ff1, ff2, ff3, ff4, ff5, ff6, ff7, ff8]
let sum = ff1 + ff2 + ff3 + ff4 + ff5 + ff6 + ff7 + ff8
if (sum > 5) {isFF = true}
let tend = performance.now()
console.log(isFF, sum+"/"+res.length, (tend-tstart) +" ms")
^ PRO TIP
run in about:config so timing is not rounded to 1ms
I did a quick iteration through window props and sub prop names. There's a lot here.
I know - I just wasn't sure how to access some of them
I'll curate a few from there that are better: e.g. the screen.moz*
typeof could be fcked by an extension to return undefined
CSS2 properties are slow, and cause an error in chromium
do me a favor, and time them all :)
you can work around the CSS2 error in blink by doing
if ("function" === typeof CSS2Properties) {
res.push( CSS2Properties.prototype.hasOwnProperty("something")) )
res.push( CSS2Properties.prototype.hasOwnProperty("something_else")) )
}
time
0-1ms
in FF 80 and 1037ms
on Android 1212ms
on Android 5Android might only be slower due to the console site I use.
"function" === typeof CSS2Properties)
Nice. I like this. It bypasses fake properties with the wrong type.
Maybe this is faster than direct access to CSS2Properties.prototype
CSS.supports("-moz-box-align: initial")
cssDashProps = ["-moz-box-align"] // and more
missing = [
...cssDashProps.map(x => CSS.supports(`${x}: initial`)),
// other stuff
]
note
This is for the engine test page, not a super speedy gecko test
moz
items are this single functionwindow
("object") are "function"x
in windowhasOwnProperty
) are getOwnPropertyDescriptor
ToDo: test older versions / configs and return "n/a" where applicable for FF: e.g.
browser.cache.offline.enable
which has existed since Jesus 👼 OK, now for an improved isFF test: here's my DIRTY DOZEN
I don't need to spend 0.5
of a ms grabbing perf and shoving shit into arrays (only if no = should be non-FF and screw them), so this looks pretty fucking speedy to me
let t00 = performance.now()
let list = [
[DataTransfer, "DataTransfer", "mozSourceNode"],
[Document, "Document", "mozFullScreen"],
[HTMLCanvasElement, "HTMLCanvasElement", "mozPrintCallback"],
[HTMLElement, "HTMLElement", "onmozfullscreenerror"],
[HTMLInputElement, "HTMLInputElement", "mozIsTextField"],
[HTMLMediaElement, "HTMLMediaElement", "mozGetMetadata"],
[HTMLVideoElement, "HTMLVideoElement", "mozDecodedFrames"],
[IDBIndex, "IDBIndex", "mozGetAllKeys"],
[IDBObjectStore, "IDBObjectStore", "mozGetAll"],
[Navigator, "Navigator", "mozGetUserMedia"],
[Screen, "Screen", "mozOrientation"],
[SVGElement, "SVGElement", "onmozfullscreenchange"]
]
let tstart, perf, obj, prop, aYes = [], aNo = []
list.forEach(function(array) {
tstart = performance.now()
obj = array[0]
prop = array[2]
if ("function" === typeof obj
&& ("object" === typeof Object.getOwnPropertyDescriptor(obj.prototype, prop))
) {
perf = (performance.now() - tstart)
aYes.push([array[1], perf])
} else {
aNo.push(array[1])
}
})
let totalPerf = 0
aYes.forEach(function(array) {
totalPerf += array[1]
})
console.log("overall", (performance.now() - t00) +" ms")
console.log("loop", totalPerf +" ms")
console.log(aYes)
console.log(aNo)
actually the approx 0.4ms is the list, I guess it takes time to populate it. Damn, people will be heartbroken I couldn't keep this under 0.1ms
FYI: Navigator + mozGetUserMedia is no longer there if BOTH media.peerconnection.enabled
+ media.navigator.enabled
are false. Not worth coding around this as a false negative
dropped it as one of my isFF checks .. so now it's out of 11
FYI: actually, measuring them individually, it's more like this
let fftest
// 1
let t1 = performance.now()
fftest = ("function" === typeof DataTransfer
&& ("object" === typeof Object.getOwnPropertyDescriptor(DataTransfer.prototype, "mozSourceNode"))
)
console.log(fftest, "DataTransfer", (performance.now() - t1))
// 2
t1 = performance.now()
fftest = ("function" === typeof Document
&& ("object" === typeof Object.getOwnPropertyDescriptor(Document.prototype, "mozFullScreen"))
)
console.log(fftest, "Document", (performance.now() - t1))
// etc
true DataTransfer 0.06027405796885432
true Document 0.010726739128585905
true HTMLCanvasElement 0.04009757246240042
true HTMLElement 0.009705144926556386
true HTMLInputElement 0.010726739132223884
true HTMLMediaElement 0.14787576086382614
true HTMLVideoElement 0.045460942024874385
true IDBIndex 0.038309782608848764
true IDBObjectStore 0.03575579710013699
true Screen 0.0403529710129078
true SVGElement 0.023752065215376206
so you could get a single unspoofable?/unblockable? boolean in under 0.01ms (HTMLElement), so I think I'm done with my improved isFF test for TZP
heh https://bugzilla.mozilla.org/show_bug.cgi?id=1679474#c6
https://jsfiddle.net/d_toybox/tre1b4hm/2/ - just more weird shit that differs between engines
I was going to add resource://
and chrome://` checks, but can't be bothered
Can't believe it's only been 16 months .. still 90+ valid tests for FF102+ .. 80 if you count error messages as 1, is pretty much more than enough to get the point across for clientside JS
I was thinking of creating a more comprehensive test page for isEngine, just adding tests and returning values - especially
newFn
protected errors - a bit like versions. It would also show me if an extension is meddling with them (excludingnewFn
, maybe I could run a parallel construction set)edit: I don't want to return what your engine is, I just want to return the results, along with a green checkmark if it matches FF, just to show that you would have to cover all these for starters to fool anyone: i.e if one fail is game over - end edit
DONE
eval.toString().length
navigator.storage.estimate
- see belowtimeZone
addedcollation
,currency
can have differences but they are minimal and changes mean they could be the sameresource://
andchrome://
CAN'T BE F'KED
- enough is enoughTODO/IDEAS
this is interesting, firefox returns
fileName
,lineNumber
,columnNumber
, chrome doesn'tstorage estimates