// ==UserScript== // @name GitHub in Pale Moon // @namespace https://github.com/SeaHOH // @version 0.1.3 // @description Tweaks for GitHub work in Pale Moon (v33.*) browser. // @author SeaHOH // @license MIT // @include /^https://github.com// // @grant none // @run-at document-start // @icon https://raw.githubusercontent.com/SeaHOH/gmscripts/83aa48a40d90e9e9fcc5b8494cd5753b281eaf43/icon/favicon.svg // @homepageURL https://github.com/SeaHOH/gmscripts // @downloadURL https://raw.githubusercontent.com/SeaHOH/gmscripts/main/github.com/github-in-pale-moon.user.js // @updateURL https://raw.githubusercontent.com/SeaHOH/gmscripts/main/github.com/github-in-pale-moon.user.js // @description:zh-CN 调整 Github 以工作于苍月浏览器 (v33.*)。 // ==/UserScript== (function() { 'use strict'; function log() { //console.log(...arguments); } /* The customElements.define hook */ function setMap(m, k, ...v) { let vl = m.get(k); if (vl === undefined) vl = [], m.set(k, vl); vl.splice(-1, 0, ...v); } const customElementsDefine = customElements.define; const customElementsFilters = new Map; customElements.define = function (name, cls, ...args) { for (const filter of customElementsFilters.get(name) || []) { filter(cls); } customElementsFilters.delete(name); return customElementsDefine.call(customElements, name, cls, ...args); }; /* Disable Turbo (now v7.2.9) navigation to prevent memory leaks. https://github.com/martok/palefill/issues/50 Another method is just block the following URL, but will lost some functions. https://github.githubassets.com/assets/vendors-node_modules_github_turbo_dist_turbo_es2017-esm_js-e3cbe28f1638.js "es2017-esm_js-e3cbe28f1638" is the version. */ function _disableTurbo() { log(i, document.readyState, window.Turbo); if (turboDisabled) return; turboDisabled = true; const turboSession = Turbo.session; turboSession.drive = false; turboSession.enabled = false; turboSession.formMode = 'off'; turboSession.formLinkClickObserver.stop(); turboSession.linkClickObserver.stop(); turboSession.formSubmitObserver.stop(); turboSession.frameRedirector.stop(); turboSession.history.stop(); turboSession.elementIsNavigatable = dummyFun; } function disableTurbo() { window.Turbo ? _disableTurbo() : i++ < 100 && setTimeout(disableTurbo, i); } let i = 0, turboDisabled = false, dummyFun = ()=>false; setMap(customElementsFilters, 'turbo-frame', ({delegateConstructor:FrameController}) => { const FrameControllerConnect = FrameController.prototype.connect; FrameController.prototype.shouldInterceptNavigation = dummyFun; FrameController.prototype.connect = function connect() { FrameControllerConnect.call(this); this.formLinkClickObserver.stop(); this.linkInterceptor.stop(); this.formSubmitObserver.stop(); }; }); // Before defer scripts running. document.addEventListener('readystatechange', disableTurbo, {once: true}); // After defer scripts running. document.addEventListener('DOMContentLoaded', _disableTurbo, {once: true}); document.addEventListener('unload', () => { Turbo.session.stop(); Turbo.cache.clear(); }); /* Create issues fails (dqsa) in new experience, caused by tag is not supported. Replace CSS pseudo-class `:modal` with attribute `[aria-modal="true"]`. */ try { document.querySelector(':modal') } catch(_) { const {querySelector:eqs, querySelectorAll:eqsa, closest:ecs, matches:ems} = Element.prototype; const {querySelector:dqs, querySelectorAll:dqsa} = Document.prototype; //const {querySelector:dfqs, querySelectorAll:dfqsa} = DocumentFragment.prototype; function queryFunc(query, selector) { try { return query.call(this, selector); } catch(e) { log(selector, this); if (selector.includes(':modal')) { return query.call(this, selector.replaceAll(':modal', '[aria-modal="true"]')); } else { throw e; } } } //Element.prototype.querySelector = function querySelector(selector) { // return queryFunc.call(this, eqs, selector); //} //Element.prototype.querySelectorAll = function querySelectorAll(selector) { // return queryFunc.call(this, eqsa, selector); //} //Element.prototype.closest = function closest(selector) { // return queryFunc.call(this, ecs, selector); //} Element.prototype.matches = function matches(selector) { return queryFunc.call(this, ems, selector); } //Document.prototype.querySelector = function querySelector(selector) { // return queryFunc.call(this, dqs, selector); //} if (/^\/[^/]+\/[^/]+\/issues/.test(location.pathname)) { Document.prototype.querySelectorAll = function querySelectorAll(selector) { return queryFunc.call(this, dqsa, selector); } } //DocumentFragment.prototype.querySelector = function querySelector(selector) { // return queryFunc.call(this, dfqs, selector); //} //DocumentFragment.prototype.querySelectorAll = function querySelectorAll(selector) { // return queryFunc.call(this, dfqsa, selector); //} } /* Mention & Emoji suggesters' filling fails. If it works (e.g. commit pages), user avatar shuild be shown. Here only fixed the filling , avatar still not be shown. */ if (location.pathname.length > 1) { document.addEventListener('DOMContentLoaded', () => { if (!document.querySelector('body').className.includes('logged-in')) return; const prompts = ['@', ':']; new MutationObserver(([{addedNodes:[node]}]) => { if (node && node.localName === 'ul' && node.classList.contains('suggester-container')) { const comment = node.parentNode.querySelector('textarea, input'); if (!comment) return; log(node); node.addEventListener('mousedown', (e) => { if (e.button !== 0) return; e.stopPropagation(); let c, suggest = e.target; switch (suggest.localName) { case 'span': case 'g-emoji': break; case 'li': suggest = suggest.children[0]; break; case 'img': suggest = suggest.parentNode; break; default: suggest = suggest.parentNode.children[0]; } log(suggest); do { c = comment.value.charAt(--comment.selectionStart); } while (comment.selectionStart && !prompts.includes(c)) if (prompts.includes(c)) { suggest = suggest.innerText || suggest.getAttribute('alias') + ':'; if (comment.value.charAt(comment.selectionEnd) !== ' ') suggest += ' '; comment.focus(); comment.setRangeText(suggest, comment.selectionStart+1, comment.selectionEnd, 'end'); setTimeout(()=>{comment.focus()}, 10); } }, {once: true, capture: true}) } }).observe(document, {childList: true, subtree: true}); }, {once: true}); } /* The context menu of code view has been disabled. Restore it by block "mouseup" event on the