Wikipedia:Reference desk/Archives/Computing/2022 August 17

From Wikipedia, the free encyclopedia
Computing desk
< August 16 << Jul | August | Sep >> Current desk >
Welcome to the Wikipedia Computing Reference Desk Archives
The page you are currently viewing is a transcluded archive page. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages.


August 17[edit]

Need help interpreting JavaScript code[edit]

I am currently learning HTML and I was viewing the source code of my website that I had pre-built using a web hosting service. Included in the source code was the following JavaScript:

(function () { var on = addEventListener, $ = function (q) { return document.querySelector(q) }, $$ = function (q) { return document.querySelectorAll(q) }, $body = document.body, $inner = $('.inner'), client = (function () { var o = { browser: 'other', browserVersion: 0, os: 'other', osVersion: 0, mobile: false, canUse: null, flags: { lsdUnits: false, }, }, ua = navigator.userAgent, a, i; a = [['firefox', /Firefox\/([0-9\.]+)/], ['edge', /Edge\/([0-9\.]+)/], ['safari', /Version\/([0-9\.]+).+Safari/], ['chrome', /Chrome\/([0-9\.]+)/], ['chrome', /CriOS\/([0-9\.]+)/], ['ie', /Trident\/.+rv:([0-9]+)/]]; for (i = 0; i < a.length; i++) { if (ua.match(a[i][1])) { o.browser = a[i][0]; o.browserVersion = parseFloat(RegExp.$1); break; } } a = [['ios', /([0-9_]+) like Mac OS X/, function (v) { return v.replace('_', '.').replace('_', ''); }], ['ios', /CPU like Mac OS X/, function (v) { return 0 }], ['ios', /iPad; CPU/, function (v) { return 0 }], ['android', /Android ([0-9\.]+)/, null], ['mac', /Macintosh.+Mac OS X ([0-9_]+)/, function (v) { return v.replace('_', '.').replace('_', ''); }], ['windows', /Windows NT ([0-9\.]+)/, null], ['undefined', /Undefined/, null],]; for (i = 0; i < a.length; i++) { if (ua.match(a[i][1])) { o.os = a[i][0]; o.osVersion = parseFloat(a[i][2] ? (a[i][2])(RegExp.$1) : RegExp.$1); break; } } if (o.os == 'mac' && ('ontouchstart' in window) && ((screen.width == 1024 && screen.height == 1366) || (screen.width == 834 && screen.height == 1112) || (screen.width == 810 && screen.height == 1080) || (screen.width == 768 && screen.height == 1024))) o.os = 'ios'; o.mobile = (o.os == 'android' || o.os == 'ios'); var _canUse = document.createElement('div'); o.canUse = function (property, value) { var style; style = _canUse.style; if (!(property in style)) return false; if (typeof value !== 'undefined') { style[property] = value; if (style[property] == '') return false; } return true; }; o.flags.lsdUnits = o.canUse('width', '100dvw'); return o; }()), trigger = function (t) { dispatchEvent(new Event(t)); }, cssRules = function (selectorText) { var ss = document.styleSheets, a = [], f = function (s) { var r = s.cssRules, i; for (i = 0; i < r.length; i++) { if (r[i] instanceof CSSMediaRule && matchMedia(r[i].conditionText).matches) (f)(r[i]); else if (r[i] instanceof CSSStyleRule && r[i].selectorText == selectorText) a.push(r[i]); } }, x, i; for (i = 0; i < ss.length; i++)f(ss[i]); return a; }, thisHash = function () { var h = location.hash ? location.hash.substring(1) : null, a; if (!h) return null; if (h.match(/\?/)) { a = h.split('?'); h = a[0]; history.replaceState(undefined, undefined, '#' + h); window.location.search = a[1]; } if (h.length > 0 && !h.match(/^[a-zA-Z]/)) h = 'x' + h; if (typeof h == 'string') h = h.toLowerCase(); return h; }, scrollToElement = function (e, style, duration) { var y, cy, dy, start, easing, offset, f; if (!e) y = 0; else { offset = (e.dataset.scrollOffset ? parseInt(e.dataset.scrollOffset) : 0) * parseFloat(getComputedStyle(document.documentElement).fontSize); switch (e.dataset.scrollBehavior ? e.dataset.scrollBehavior : 'default') { case 'default': default: y = e.offsetTop + offset; break; case 'center': if (e.offsetHeight < window.innerHeight) y = e.offsetTop - ((window.innerHeight - e.offsetHeight) / 2) + offset; else y = e.offsetTop - offset; break; case 'previous': if (e.previousElementSibling) y = e.previousElementSibling.offsetTop + e.previousElementSibling.offsetHeight + offset; else y = e.offsetTop + offset; break; } } if (!style) style = 'smooth'; if (!duration) duration = 750; if (style == 'instant') { window.scrollTo(0, y); return; } start = Date.now(); cy = window.scrollY; dy = y - cy; switch (style) { case 'linear': easing = function (t) { return t }; break; case 'smooth': easing = function (t) { return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1 }; break; }f = function () { var t = Date.now() - start; if (t >= duration) window.scroll(0, y); else { window.scroll(0, cy + (dy * easing(t / duration))); requestAnimationFrame(f); } }; f(); }, scrollToTop = function () { scrollToElement(null); }, loadElements = function (parent) { var a, e, x, i; a = parent.querySelectorAll('iframe[data-src]:not([data-src=""])'); for (i = 0; i < a.length; i++) { a[i].src = a[i].dataset.src; a[i].dataset.src = ""; } a = parent.querySelectorAll('video[autoplay]'); for (i = 0; i < a.length; i++) { if (a[i].paused) a[i].play(); } e = parent.querySelector('[data-autofocus="1"]'); x = e ? e.tagName : null; switch (x) { case 'FORM': e = e.querySelector('.field input, .field select, .field textarea'); if (e) e.focus(); break; default: break; } }, unloadElements = function (parent) { var a, e, x, i; a = parent.querySelectorAll('iframe[data-src=""]'); for (i = 0; i < a.length; i++) { if (a[i].dataset.srcUnload === '0') continue; a[i].dataset.src = a[i].src; a[i].src = ''; } a = parent.querySelectorAll('video'); for (i = 0; i < a.length; i++) { if (!a[i].paused) a[i].pause(); } e = $(':focus'); if (e) e.blur(); }; window._scrollToTop = scrollToTop; var thisURL = function () { return window.location.href.replace(window.location.search, '').replace(/#$/, ''); }; var getVar = function (name) { var a = window.location.search.substring(1).split('&'), b, k; for (k in a) { b = a[k].split('='); if (b[0] == name) return b[1]; } return null; }; var errors = { handle: function (handler) { window.onerror = function (message, url, line, column, error) { (handler)(error.message); return true; }; }, unhandle: function () { window.onerror = null; } }; loadElements(document.body); var style, sheet, rule; style = document.createElement('style'); style.appendChild(document.createTextNode('')); document.head.appendChild(style); sheet = style.sheet; if (client.mobile) { (function () { if (client.flags.lsdUnits) { document.documentElement.style.setProperty('--viewport-height', '100dvh'); document.documentElement.style.setProperty('--background-height', '100lvh'); } else { var f = function () { document.documentElement.style.setProperty('--viewport-height', window.innerHeight + 'px'); document.documentElement.style.setProperty('--background-height', (window.innerHeight + 250) + 'px'); }; on('load', f); on('resize', f); on('orientationchange', function () { setTimeout(function () { (f)(); }, 100); }); } })(); } if (client.os == 'android') { (function () { sheet.insertRule('body::after { }', 0); rule = sheet.cssRules[0]; var f = function () { rule.style.cssText = 'height: ' + (Math.max(screen.width, screen.height)) + 'px'; }; on('load', f); on('orientationchange', f); on('touchmove', f); })(); $body.classList.add('is-touch'); } else if (client.os == 'ios') { if (client.osVersion <= 11) (function () { sheet.insertRule('body::after { }', 0); rule = sheet.cssRules[0]; rule.style.cssText = '-webkit-transform: scale(1.0)'; })(); if (client.osVersion <= 11) (function () { sheet.insertRule('body.ios-focus-fix::before { }', 0); rule = sheet.cssRules[0]; rule.style.cssText = 'height: calc(100% + 60px)'; on('focus', function (event) { $body.classList.add('ios-focus-fix'); }, true); on('blur', function (event) { $body.classList.remove('ios-focus-fix'); }, true); })(); $body.classList.add('is-touch'); } })();

I don't think there is anything on my website that would require JavaScript and so naturally I am very confused. I am not very proficient at JavaScript and I was wondering if someone more knowledgeable than me could help me to interpret this code.

What does it do? Would my website still work if it was removed? Any comment is greatly appreciated.

-- WongSeo (talk to me!) 23:49, 17 August 2022 (UTC)[reply]

TLDR: Pretty much harmless, unless it starts messing with Resource Loader or something that isn't supposed to be spitting out JavaScript.
WongSeo, I pasted your code into an unminifier. It basically is:
  • A bunch of variable declarations. (I have omitted some unused functions for brevity.)
    • on is basically window.addEventListener,
    • $ is basically document.querySelector,
    • $body is basically the <body> tag of the document
    • client is a function:
      • From the code, it looks like it's trying to detect the browser.
      • It initializes an object o to the value { browser: "other", browserVersion: 0, os: "other", osVersion: 0, mobile: false, canUse: null, flags: { lsdUnits: false } }
      • It sets the variable ua to the User Agent string, which is something like Mozilla/5.0 (X11; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0
      • Note: I'm saying "guess" because the user agent string can be faked and is not to be trusted. I actually fake my user agent when connecting to Wikipedia.
      • It then tries a bunch of regexes on the user agent to try to guess if it is Firefox, Microsoft Edge, Safari, Google Chrome (note two regexes), or Internet Explorer.
      • If any of those match, it searches for the first capturing group to guess the version.
      • Then, it tries to guess the operating system name and version.
      • Compatibility with browser styles is guessed and the o object is modified and returned.
    • Then a bunch of unused functions
    • Then, scrollToElement, which is basically a hyped up version of element.scrollIntoView().
    • scrollToTop is basically scrolling to the top of the page.
    • loadElements is a very... let's say questionable function. Here's what it does in a nutshell:
      • Blanks all data-src attributes from iframes after setting their srcs to the data-srcs.
      • Attempts to play all paused autoplaying videos.
      • If the first element with a data-autofocus value of 1, it focuses the first text area, dropdown, or input inside that form.
    • unloadElements looks like an attempt to undo those.
  • It then runs loadElements on document.body.
  • It then inserts some weird CSS rules.
  • Some badly designed user agent sniffing: If the OS version is before 11, insert some kind of CSS fix for some kind of browser bug.
  • It sometimes adds is-touch classes, but I'm not sure when.
  • That's pretty much all there is to it!
Hope this helps, weeklyd3 (block | talk | contributions) 05:02, 18 August 2022 (UTC)[reply]
This is my first time posting at the reference desk so please tell me if I did something wrong. weeklyd3 (block | talk | contributions) 05:02, 18 August 2022 (UTC)[reply]
@Weeklyd3, thank you so much! This helps out a lot. WongSeo (talk to me!) 15:19, 18 August 2022 (UTC)[reply]
P.S. You did everything correctly. WongSeo (talk to me!) 15:19, 18 August 2022 (UTC)[reply]
Actually, I don't think it is harmless. It starts adding a bunch of weird CSS classes based on your screen, which could really screw up your styling if something is special about htem. weeklyd3 (block | talk | contributions) 22:25, 18 August 2022 (UTC)[reply]
"I don't think there is anything on my website that would require JavaScript and so naturally I am very confused." Virtually all modern websites use JavaScript. It's standard practice. A Quest For Knowledge (talk) 09:49, 19 August 2022 (UTC)[reply]
It's not compulsory and won't help with learning HTML. I use extensions when on a mobile browser to fake my user agent string and to prevent videos from autoplaying, and that's because of widespread excessive use of javascript like the above.  Card Zero  (talk) 14:00, 19 August 2022 (UTC)[reply]
Most websites have some javascript because most websites are based on a small number of templates that use javascript. Big Tech is happy to provide such templates, because it allows Big Tech to do Evil Things. The scripts are rarely useful to website visitors, but the sites are built in such a way that they don't work without. Also considering how often I must install security updates for the javascript engine, I wonder why our politicians have made laws regulating cookies (which are fairly easy to defeat with browser settings), but not against excessive use of scripts. Please note the sarcasm. I don't follow the conspiracy theories, but I do worry that some parties have gained too much power over the internet. PiusImpavidus (talk) 09:20, 20 August 2022 (UTC)[reply]
To be fair, if you want, say, a reply button that doesn't reload the page, you need Javascript. It does make it possible to manipulate a lot of things, unfortunately including people.  Card Zero  (talk) 12:08, 20 August 2022 (UTC)[reply]