XT v2.1.3

- Embed x.com links.
- Settings no longer close when the mouse ends up outside of the modal when selecting text in an input or textarea.
This commit is contained in:
Tuxedo Takodachi 2023-08-21 20:11:24 +02:00
parent 144143e2b0
commit d8c74f02ca
9 changed files with 23056 additions and 23037 deletions

View File

@ -3,6 +3,11 @@
4chan XT uses a different user script namespace, so to migrate you need to export settings from 4chan X, and import them
in XT.
### XT v2.1.3 (2023-08-21)
- Embed x.com links.
- Settings no longer close when the mouse ends up outside of the modal when selecting text in an input or textarea.
### XT v2.1.2 (2023-07-22)
- Fix inlining/previewing of archive links like quote links. [#5](https://github.com/TuxedoTako/4chan-xt/issues/5)

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
// ==UserScript==
// @name 4chan XT
// @version XT 2.1.2
// @version XT 2.1.3
// @minGMVer 1.14
// @minFFVer 74
// @namespace 4chan-XT
@ -187,7 +187,7 @@
!function(){"use strict";var e={name:"4chan XT",path:"4chan-XT",fork:"TuxedoTako",page:"https://github.com/TuxedoTako/4chan-xt",downloads:"https://github.com/TuxedoTako/4chan-xt/releases",oldVersions:"https://raw.githubusercontent.com/ccd0/4chan-x/",faq:"https://github.com/ccd0/4chan-x/wiki/Frequently-Asked-Questions",captchaFAQ:"https://github.com/ccd0/4chan-x/wiki/Captcha-FAQ",cssGuide:"https://github.com/ccd0/4chan-x/wiki/Styling-Guide",license:"https://github.com/TuxedoTako/4chan-xt/blob/project-XT/LICENSE",changelog:"https://github.com/TuxedoTako/4chan-xt/blob/project-XT/CHANGELOG.md",issues:"https://github.com/TuxedoTako/4chan-xt/issues",newIssue:"https://github.com/TuxedoTako/4chan-xt/issues",newIssueMaxLength:8181,alternatives:"https://www.4chan-x.net/4chan_alternatives.html",appid:"lacclbnghgdicfifcamcmcnilckjamag",appidGecko:"4chan-x@4chan-x.net",chromeStoreID:"ohnjgmpcibpbafdlkimncjhflgedgpam",recaptchaKey:"6Ldp2bsSAAAAAAJ5uyx_lx34lJeEpTLVkP5k04qc",distBranch:"gh-pages",
includes_only:["*://boards.4chan.org/*","*://sys.4chan.org/*","*://www.4chan.org/*","*://boards.4channel.org/*","*://sys.4channel.org/*","*://www.4channel.org/*","*://i.4cdn.org/*","*://is.4chan.org/*","*://is2.4chan.org/*","*://is.4channel.org/*","*://is2.4channel.org/*"],matches_only:["*://*.4chan.org/*","*://*.4channel.org/*","*://*.4cdn.org/*"],
matches:["https://erischan.org/*","https://www.erischan.org/*","https://fufufu.moe/*","https://gnfos.com/*","https://himasugi.blog/*","https://www.himasugi.blog/*","https://kakashinenpo.com/*","https://www.kakashinenpo.com/*","https://kissu.moe/*","https://www.kissu.moe/*","https://lainchan.org/*","https://www.lainchan.org/*","https://merorin.com/*","https://ota-ch.com/*","https://www.ota-ch.com/*","https://ponyville.us/*","https://www.ponyville.us/*","https://smuglo.li/*","https://notso.smuglo.li/*","https://smugloli.net/*","https://smug.nepu.moe/*","https://sportschan.org/*","https://www.sportschan.org/*","https://sushigirl.us/*","https://www.sushigirl.us/*","https://tvch.moe/*"],matches_extra:[],exclude_matches:["*://www.4chan.org/advertise","*://www.4chan.org/advertise?*","*://www.4chan.org/donate","*://www.4chan.org/donate?*","*://www.4channel.org/advertise","*://www.4channel.org/advertise?*","*://www.4channel.org/donate","*://www.4channel.org/donate?*"],
grants:["GM_getValue","GM_setValue","GM_deleteValue","GM_listValues","GM_addValueChangeListener","GM_openInTab","GM_xmlhttpRequest","GM.getValue","GM.setValue","GM.deleteValue","GM.listValues","GM.openInTab","GM.xmlHttpRequest"],min:{chrome:"80",firefox:"74",greasemonkey:"1.14"}};const t=Object.create(null),n={VERSION:"XT 2.1.2",NAMESPACE:e.name,sites:Object.create(null),boards:Object.create(null)},o=function(){const e={"&":"&amp;","'":"&#039;",'"':"&quot;","<":"&lt;",">":"&gt;"},t=/[&"'<>]/g,n=function(t){return e[t]},o=function(e){return e.toString().replace(t,n)};return o.cat=function(e){let t="";for(let n=0;n<e.length;n++)t+=e[n].innerHTML;return t},o}(),a=document,i=a.documentElement,r=console,s=function(){return i};class l{static initClass(){this.Post=new l("Post"),this.Thread=new l("Thread"),this.CatalogThread=new l("Catalog Thread"),this.CatalogThreadNative=new l("Catalog Thread")}constructor(e){this.type=e,this.keys=[]}push({name:e,cb:t}){return this[e]||this.keys.push(e),
grants:["GM_getValue","GM_setValue","GM_deleteValue","GM_listValues","GM_addValueChangeListener","GM_openInTab","GM_xmlhttpRequest","GM.getValue","GM.setValue","GM.deleteValue","GM.listValues","GM.openInTab","GM.xmlHttpRequest"],min:{chrome:"80",firefox:"74",greasemonkey:"1.14"}};const t=Object.create(null),n={VERSION:"XT 2.1.3",NAMESPACE:e.name,sites:Object.create(null),boards:Object.create(null)},o=function(){const e={"&":"&amp;","'":"&#039;",'"':"&quot;","<":"&lt;",">":"&gt;"},t=/[&"'<>]/g,n=function(t){return e[t]},o=function(e){return e.toString().replace(t,n)};return o.cat=function(e){let t="";for(let n=0;n<e.length;n++)t+=e[n].innerHTML;return t},o}(),a=document,i=a.documentElement,r=console,s=function(){return i};class l{static initClass(){this.Post=new l("Post"),this.Thread=new l("Thread"),this.CatalogThread=new l("Catalog Thread"),this.CatalogThreadNative=new l("Catalog Thread")}constructor(e){this.type=e,this.keys=[]}push({name:e,cb:t}){return this[e]||this.keys.push(e),
this[e]=t}execute(e,t=this.keys,n=!1){let o;if(!e.callbacksExecuted||n){for(var a of(e.callbacksExecuted=!0,t))try{this[a]?.call(e)}catch(t){o||(o=[]),o.push({message:['"',a,'" crashed on node ',this.type," No.",e.ID," (",e.board,")."].join(""),error:t,html:e.nodes?.root?.outerHTML})}return o?Ot.handleErrors(o):void 0}}}l.initClass();const c={main:{Miscellaneous:{"Redirect to HTTPS":[!0,"Redirect to the HTTPS version of 4chan."],"JSON Index":[!0,"Replace the original board index with one supporting searching, sorting, infinite scrolling, and a catalog mode."],[`Use ${e.name} Catalog`]:[!0,`Link to ${e.name}'s catalog instead of the native 4chan one.`,1],"Index Refresh Notifications":[!1,"Show a notice at the top of the page when the index is refreshed.",1],"Follow Cursor":[!0,"Image Hover and Quote Preview move with the mouse cursor."],"Open Threads in New Tab":[!1,`Make links to threads in the index / ${e.name} catalog open in a new tab.`],
"External Catalog":[!1,"Link to external catalog instead of the internal one."],"Catalog Links":[!1,"Add toggle link in header menu to turn Navigation links into links to each board's catalog."],"Announcement Hiding":[!0,"Add button to hide 4chan announcements."],"Desktop Notifications":[!0,`Enables desktop notifications across various ${e.name} features.`],"404 Redirect":[!0,"Redirect dead threads and images to the archives."],"Archive Report":[!0,"Enable reporting posts to supported archives."],"Exempt Archives from Encryption":[!0,"Permit loading content from, and warningless redirects to, HTTP-only archives from HTTPS pages."],Keybinds:[!0,"Bind actions to keyboard shortcuts."],"Time Formatting":[!0,"Localize and format timestamps."],"Relative Post Dates":[!0,'Display dates like "3 minutes ago". Tooltip shows the timestamp.'],"Relative Date Title":[!0,"Show Relative Post Date only when hovering over dates.",1],
"Comment Expansion":[!0,"Expand comments that are too long to display on the index. Not applicable with JSON Index."],"File Info Formatting":[!0,"Reformat the file information."],"Thread Expansion":[!0,"Add buttons to expand threads."],"Index Navigation":[!1,"Add buttons to navigate between threads."],"Reply Navigation":[!1,"Add buttons to navigate to top / bottom of thread."],"Unique ID and Capcode Navigation":[!1,"Add buttons to navigate to posts having the same unique ID or capcode."],"Custom Board Titles":[!0,"Allow editing of the board title and subtitle by ctrl/⌘+clicking them."],"Persistent Custom Board Titles":[!1,"Force custom board titles to be persistent, even if the board titles are updated.",1],"Show Updated Notifications":[!0,`Show notifications when ${e.name} is successfully updated.`],"Color User IDs":[!0,"Assign unique colors to user IDs on boards that use them"],"Count Posts by ID":[!0,"Display number of posts in the thread when hovering over an ID."],
@ -426,11 +426,11 @@ Ve.event("ThreadUpdate",{404:!0,threadID:Re.thread.fullID})),error:e=>(304===e.s
;n.SITE.Build.spoilerRange[h]=d.custom_spoiler,c.setStatus("Archived",!!d.archived),Re.updateThreadStatus("Sticky",!!d.sticky),Re.updateThreadStatus("Closed",!!d.closed),c.postLimit=!!d.bumplimit,c.fileLimit=!!d.imagelimit,null!=d.unique_ips&&(c.ipCount=d.unique_ips);const p=[],g=[],f=[],m=[];for(var b of l)if(o=b.no,g.push(o),b.fsize&&f.push(o),!(o<=u))if(!(s=c.posts.get(o))||s.isFetchedQuote){m.push(`${h}.${o}`);var A=n.SITE.Build.postFromObject(b,h.ID);p.push(new H(A,c,h)),Re.postID===o&&delete Re.postID}else s.resurrect();const v=[];for(o of Re.postIDs)g.includes(o)||(c.posts.get(o).kill(),v.push(`${h}.${o}`));Re.postIDs=g;const w=[];for(o of Re.fileIDs)f.includes(o)||v.includes(`${h}.${o}`)||(c.posts.get(o).kill(!0),w.push(`${h}.${o}`));if(Re.fileIDs=f,p.length){Re.set("status",`+${p.length}`,"new"),Re.outdateCount=0;const e=ee.posts?.size,n=ee.postsQuotingYou?.size;Ot.callbackNodes("Post",p),
!a.hidden&&a.hasFocus()||(t["Beep Quoting You"]&&ee.postsQuotingYou?.size>n?(Re.playBeep(),t.Beep&&Re.playBeep()):t.Beep&&ee.posts?.size>0&&0===e&&Re.playBeep());const o=t["Auto Scroll"]&&Re.scrollBG()&&Re.root.getBoundingClientRect().bottom-i.clientHeight<25;let r=null;for(s of p)Te.insert(s)||(r||(r=s.nodes.root),Ve.add(Re.root,s.nodes.root));Ve.event("PostsInserted",null,Re.root),o&&(t["Bottom Scroll"]?window.scrollTo(0,a.body.clientHeight):r&&Ke.scrollTo(r))}else Re.set("status","");return null!=d.unique_ips&&(r=Ve.id("unique-ips"))&&(r.textContent=d.unique_ips,r.previousSibling.textContent=r.previousSibling.textContent.replace(/\b(?:is|are)\b/,1===d.unique_ips?"is":"are"),r.nextSibling.textContent=r.nextSibling.textContent.replace(/\bposters?\b/,1===d.unique_ips?"poster":"posters")),Ve.event("ThreadUpdate",{404:!1,threadID:c.fullID,newPosts:m,deletedPosts:v,deletedFiles:w,postCount:d.replies+1,fileCount:d.images+!!d.fsize,ipCount:d.unique_ips})}},Be={dialog:void 0,init(){
const o=Ve.el("a",{className:"settings-link",textContent:"🔧︎",title:`${e.name} Settings`,href:"javascript:;"});Ve.on(o,"click",Be.open),Ke.addShortcut("settings",o,820);const i=this.addSection;if(i("Main",this.main),i("Filter",this.filter),i("Sauce",this.sauce),i("Advanced",this.advanced),i("Keybinds",this.keybinds),Ve.on(a,"AddSettingsSection",Be.addSection),Ve.on(a,"OpenSettings",(e=>Be.open(e.detail))),"yotsuba"===n.SITE.software&&t["Disable Native Extension"])return Ve.hasStorage?Ve.global((function(){try{const e=JSON.parse(localStorage.getItem("4chan-settings"))||{};if(e.disableAll)return;return e.disableAll=!0,localStorage.setItem("4chan-settings",JSON.stringify(e))}catch(e){return Object.defineProperty(window,"Config",{value:{disableAll:!0}})}})):Ve.global((()=>Object.defineProperty(window,"Config",{value:{disableAll:!0}})))},open(e){let t,n;if(Be.dialog)return;Ve.event("CloseMenu"),Be.dialog=t=Ve.el("div",{id:"overlay"},fe),Ve.on(Ve(".export",t),"click",Be.export),
Ve.on(Ve(".import",t),"click",Be.import),Ve.on(Ve(".reset",t),"click",Be.reset),Ve.on(Ve("input",t),"change",Be.onImport);const o=[];for(var i of Be.sections){var r=Ve.el("a",{className:`tab-${i.hyphenatedTitle}`,textContent:i.title,href:"javascript:;"});Ve.on(r,"click",Be.openSection.bind(i)),o.push(r,Ve.tn(" | ")),i.title===e&&(n=r)}return o.pop(),Ve.add(Ve(".sections-list",t),o),"none"!==e&&(n||o[0]).click(),Ve.on(Ve(".close",t),"click",Be.close),Ve.on(window,"beforeunload",Be.close),Ve.on(t,"click",Be.close),Ve.on(t.firstElementChild,"click",(e=>e.stopPropagation())),Ve.add(a.body,t),Ve.event("OpenSettings",null,t)},close(){if(Be.dialog)return a.activeElement?.blur(),Ve.rm(Be.dialog),delete Be.dialog},sections:[],addSection(e,t){"string"!=typeof e&&({title:e,open:t}=e.detail);const n=e.toLowerCase().replace(/\s+/g,"-");return Be.sections.push({title:e,hyphenatedTitle:n,open:t})},openSection(){let e;(e=Ve(".tab-selected",Be.dialog))&&Ve.rmClass(e,"tab-selected"),
Ve.addClass(Ve(`.tab-${this.hyphenatedTitle}`,Be.dialog),"tab-selected");const t=Ve("section",Be.dialog);return Ve.rmAll(t),t.className=`section-${this.hyphenatedTitle}`,this.open(t,n),t.scrollTop=0,Ve.event("OpenSettings",null,t)},warnings:{localStorage(t){if(Ve.cantSync){const n=Ve.cantSet?"save your settings":"synchronize settings between tabs";return t(Ve.el("li",{textContent:`${e.name} needs local storage to ${n}.\nEnable it on boards.${location.hostname.split(".")[1]}.org in your browser's privacy settings (may be listed as part of "local data" or "cookies").`}))}},ads:e=>Ve.onExists(i,".adg-rects > .desktop",(t=>Ve.onExists(t,"iframe",(function(){const t=Ze.to("thread",{boardID:"qa",threadID:362590});return e(Ve.el("li",le(se,null,"To protect yourself from ",le("a",{href:t,target:"_blank"},"malicious ads"),", you should ",le("a",{href:"https://github.com/gorhill/uBlock#ublock-origin",target:"_blank"},"block ads")," on 4chan.")))}))))},main(o){let a;const i=Ve.el("fieldset",{
hidden:!0},{innerHTML:"<legend>Warnings</legend><ul></ul>"}),r=function(e){return Ve.add(Ve("ul",i),e),i.hidden=!1};for(a in Be.warnings){(0,Be.warnings[a])(r)}Ve.add(o,i);const s=m(),l=m(),d=function(e,n){const o=[e];return(()=>{const e=[];for(a in n){var i=n[a];if(i instanceof Array){var r=i[1],d=Ve.el("div",{innerHTML:`<label><input type="checkbox" name="${a}">${a}</label><span class="description">: ${r}</span>`});d.dataset.name=a;var c=Ve("input",d);Ve.on(c,"change",Ve.cb.checked),Ve.on(c,"change",(function(){return this.parentNode.parentNode.dataset.checked=this.checked})),s[a]=t[a],l[a]=c;var h=i[2]||0;if(o.length<=h){var u=Ve.el("div",{className:"suboption-list"});Ve.add(o[o.length-1].lastElementChild,u),o[h]=u}else o.length>h+1&&o.splice(h+1,o.length-(h+1));e.push(Ve.add(o[h],d))}}return e})()};for(var h in c.main){var u=c.main[h],p=Ve.el("fieldset",{innerHTML:`<legend>${h}</legend>`});d(p,u),"Posting and Captchas"===h&&Ve.add(p,Ve.el("p",{
innerHTML:'For more info on captcha options and issues, see the <a href="'+e.captchaFAQ+'" target="_blank">captcha FAQ</a>.'})),Ve.add(o,p)}d(Ve('div[data-name="JSON Index"] > .suboption-list',o),c.Index),"gecko"!==Ve.engine&&(Ve('div[data-name="Remember QR Size"]',o).hidden=!0),(Ve.perProtocolSettings||"https:"!==location.protocol)&&(Ve('div[data-name="Redirect to HTTPS"]',o).hidden=!0),"crx"!==x&&(Ve('div[data-name="Work around CORB Bug"]',o).hidden=!0),Ve.get(s,(function(e){for(a in e){var t=e[a];l[a].checked=t,l[a].parentNode.parentNode.dataset.checked=t}}));const g=Ve.el("div",{innerHTML:'<button></button><span class="description">: Clear manually-hidden threads and posts on all boards. Reload the page to apply.'}),f=Ve("button",g);return Ve.get({hiddenThreads:m(),hiddenPosts:m()},(function({hiddenThreads:e,hiddenPosts:t}){let n,o,a,i,r=0;for(o in e)if(a=e[o],"boards"!==o)for(o in a.boards)n=a.boards[o],r+=Object.keys(n).length;for(o in e.boards)n=e.boards[o],
r+=Object.keys(n).length;for(o in t)if(a=t[o],"boards"!==o)for(o in a.boards)for(o in n=a.boards[o],n)i=n[o],r+=Object.keys(i).length;for(o in t.boards)for(o in n=t.boards[o],n)i=n[o],r+=Object.keys(i).length;return f.textContent=`Hidden: ${r}`})),Ve.on(f,"click",(function(){return this.textContent="Hidden: 0",Ve.get("hiddenThreads",m(),(function({hiddenThreads:e}){if(Ve.hasStorage&&"yotsuba"===n.SITE.software){let t;for(t in e["4chan.org"]?.boards)localStorage.removeItem(`4chan-hide-t-${t}`);for(t in e.boards)localStorage.removeItem(`4chan-hide-t-${t}`)}return Ve.delete(["hiddenThreads","hiddenPosts"])}))})),Ve.after(Ve('input[name="Stubs"]',o).parentNode.parentNode,g)},export(){const e=m();return Ve.extend(e,t),Ve.get(e,(function(e){return delete e.boardConfig,Be.downloadExport({version:n.VERSION,date:Date.now(),Conf:e})}))},downloadExport(t){const o=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),a=URL.createObjectURL(o),i=Ve.el("a",{
Ve.on(Ve(".import",t),"click",Be.import),Ve.on(Ve(".reset",t),"click",Be.reset),Ve.on(Ve("input",t),"change",Be.onImport);const o=[];for(var i of Be.sections){var r=Ve.el("a",{className:`tab-${i.hyphenatedTitle}`,textContent:i.title,href:"javascript:;"});Ve.on(r,"click",Be.openSection.bind(i)),o.push(r,Ve.tn(" | ")),i.title===e&&(n=r)}return o.pop(),Ve.add(Ve(".sections-list",t),o),"none"!==e&&(n||o[0]).click(),Ve.on(Ve(".close",t),"click",Be.close),Ve.on(window,"beforeunload",Be.close),Ve.on(t,"click",(()=>{"INPUT"!==a.activeElement?.tagName&&"TEXTAREA"!==a.activeElement?.tagName&&Be.close()})),Ve.on(t.firstElementChild,"click",(e=>e.stopPropagation())),Ve.add(a.body,t),Ve.event("OpenSettings",null,t)},close(){if(Be.dialog)return a.activeElement?.blur(),Ve.rm(Be.dialog),delete Be.dialog},sections:[],addSection(e,t){"string"!=typeof e&&({title:e,open:t}=e.detail);const n=e.toLowerCase().replace(/\s+/g,"-");return Be.sections.push({title:e,hyphenatedTitle:n,open:t})},openSection(){let e
;(e=Ve(".tab-selected",Be.dialog))&&Ve.rmClass(e,"tab-selected"),Ve.addClass(Ve(`.tab-${this.hyphenatedTitle}`,Be.dialog),"tab-selected");const t=Ve("section",Be.dialog);return Ve.rmAll(t),t.className=`section-${this.hyphenatedTitle}`,this.open(t,n),t.scrollTop=0,Ve.event("OpenSettings",null,t)},warnings:{localStorage(t){if(Ve.cantSync){const n=Ve.cantSet?"save your settings":"synchronize settings between tabs";return t(Ve.el("li",{textContent:`${e.name} needs local storage to ${n}.\nEnable it on boards.${location.hostname.split(".")[1]}.org in your browser's privacy settings (may be listed as part of "local data" or "cookies").`}))}},ads:e=>Ve.onExists(i,".adg-rects > .desktop",(t=>Ve.onExists(t,"iframe",(function(){const t=Ze.to("thread",{boardID:"qa",threadID:362590});return e(Ve.el("li",le(se,null,"To protect yourself from ",le("a",{href:t,target:"_blank"},"malicious ads"),", you should ",le("a",{href:"https://github.com/gorhill/uBlock#ublock-origin",target:"_blank"
},"block ads")," on 4chan.")))}))))},main(o){let a;const i=Ve.el("fieldset",{hidden:!0},{innerHTML:"<legend>Warnings</legend><ul></ul>"}),r=function(e){return Ve.add(Ve("ul",i),e),i.hidden=!1};for(a in Be.warnings){(0,Be.warnings[a])(r)}Ve.add(o,i);const s=m(),l=m(),d=function(e,n){const o=[e];return(()=>{const e=[];for(a in n){var i=n[a];if(i instanceof Array){var r=i[1],d=Ve.el("div",{innerHTML:`<label><input type="checkbox" name="${a}">${a}</label><span class="description">: ${r}</span>`});d.dataset.name=a;var c=Ve("input",d);Ve.on(c,"change",Ve.cb.checked),Ve.on(c,"change",(function(){return this.parentNode.parentNode.dataset.checked=this.checked})),s[a]=t[a],l[a]=c;var h=i[2]||0;if(o.length<=h){var u=Ve.el("div",{className:"suboption-list"});Ve.add(o[o.length-1].lastElementChild,u),o[h]=u}else o.length>h+1&&o.splice(h+1,o.length-(h+1));e.push(Ve.add(o[h],d))}}return e})()};for(var h in c.main){var u=c.main[h],p=Ve.el("fieldset",{innerHTML:`<legend>${h}</legend>`});d(p,u),
"Posting and Captchas"===h&&Ve.add(p,Ve.el("p",{innerHTML:'For more info on captcha options and issues, see the <a href="'+e.captchaFAQ+'" target="_blank">captcha FAQ</a>.'})),Ve.add(o,p)}d(Ve('div[data-name="JSON Index"] > .suboption-list',o),c.Index),"gecko"!==Ve.engine&&(Ve('div[data-name="Remember QR Size"]',o).hidden=!0),(Ve.perProtocolSettings||"https:"!==location.protocol)&&(Ve('div[data-name="Redirect to HTTPS"]',o).hidden=!0),"crx"!==x&&(Ve('div[data-name="Work around CORB Bug"]',o).hidden=!0),Ve.get(s,(function(e){for(a in e){var t=e[a];l[a].checked=t,l[a].parentNode.parentNode.dataset.checked=t}}));const g=Ve.el("div",{innerHTML:'<button></button><span class="description">: Clear manually-hidden threads and posts on all boards. Reload the page to apply.'}),f=Ve("button",g);return Ve.get({hiddenThreads:m(),hiddenPosts:m()},(function({hiddenThreads:e,hiddenPosts:t}){let n,o,a,i,r=0;for(o in e)if(a=e[o],"boards"!==o)for(o in a.boards)n=a.boards[o],r+=Object.keys(n).length
;for(o in e.boards)n=e.boards[o],r+=Object.keys(n).length;for(o in t)if(a=t[o],"boards"!==o)for(o in a.boards)for(o in n=a.boards[o],n)i=n[o],r+=Object.keys(i).length;for(o in t.boards)for(o in n=t.boards[o],n)i=n[o],r+=Object.keys(i).length;return f.textContent=`Hidden: ${r}`})),Ve.on(f,"click",(function(){return this.textContent="Hidden: 0",Ve.get("hiddenThreads",m(),(function({hiddenThreads:e}){if(Ve.hasStorage&&"yotsuba"===n.SITE.software){let t;for(t in e["4chan.org"]?.boards)localStorage.removeItem(`4chan-hide-t-${t}`);for(t in e.boards)localStorage.removeItem(`4chan-hide-t-${t}`)}return Ve.delete(["hiddenThreads","hiddenPosts"])}))})),Ve.after(Ve('input[name="Stubs"]',o).parentNode.parentNode,g)},export(){const e=m();return Ve.extend(e,t),Ve.get(e,(function(e){return delete e.boardConfig,Be.downloadExport({version:n.VERSION,date:Date.now(),Conf:e})}))},downloadExport(t){const o=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),a=URL.createObjectURL(o),i=Ve.el("a",{
download:`${e.name} v${n.VERSION}-${t.date}.json`,href:a}),r=Ve(".imp-exp-result",Be.dialog);return Ve.rmAll(r),Ve.add(r,i),i.click()},import(){return Ve("input[type=file]",this.parentNode).click()},onImport(){let e;if(!(e=this.files[0]))return;this.value=null;const t=Ve(".imp-exp-result");if(!confirm("Your current settings will be entirely overwritten, are you sure?"))return void(t.textContent="Import aborted.");const n=new FileReader;return n.onload=function(e){try{return Be.loadSettings(m.json(e.target.result),(function(e){return e?t.textContent="Import failed due to an error.":confirm("Import successful. Reload now?")?window.location.reload():void 0}))}catch(e){const n=e;return t.textContent="Import failed due to an error.",r.error(n.stack)}},n.readAsText(e)},convertFrom:{loadletter(e){for(var t in"Always CDN"in(e=function(e,t){for(var n in t){var o=t[n];o&&(e.Conf[o]=e.Conf[n]),delete e.Conf[n]}return e}(e,{"Disable 4chan's extension":"Disable Native Extension",
"Comment Auto-Expansion":"","Remove Slug":"","Always HTTPS":"Redirect to HTTPS","Check for Updates":"","Recursive Filtering":"Recursive Hiding","Reply Hiding":"Reply Hiding Buttons","Thread Hiding":"Thread Hiding Buttons","Show Stubs":"Stubs","Image Auto-Gif":"Replace GIF","Expand All WebM":"Expand videos","Reveal Spoilers":"Reveal Spoiler Thumbnails","Expand From Current":"Expand from here","Current Page":"Page Count in Stats","Current Page Position":"","Alternative captcha":"Use Recaptcha v1","Alt index captcha":"Use Recaptcha v1 on Index","Auto Submit":"Post on Captcha Completion","Open Reply in New Tab":"Open Post in New Tab","Remember QR size":"Remember QR Size","Remember Subject":"","Quote Inline":"Quote Inlining","Quote Preview":"Quote Previewing","Indicate OP quote":"Mark OP Quotes","Indicate You quote":"Mark Quotes of You","Indicate Cross-thread Quotes":"Mark Cross-thread Quotes",uniqueid:"uniqueID",mod:"capcode",email:"",country:"flag",md5:"MD5",openEmptyQR:"Open empty QR",
openQR:"Open QR",openOptions:"Open settings",close:"Close",spoiler:"Spoiler tags",sageru:"Toggle sage",code:"Code tags",sjis:"SJIS tags",submit:"Submit QR",watch:"Watch",update:"Update",unreadCountTo0:"",expandAllImages:"Expand images",expandImage:"Expand image",zero:"Front page",nextPage:"Next page",previousPage:"Previous page",nextThread:"Next thread",previousThread:"Previous thread",expandThread:"Expand thread",openThreadTab:"Open thread",openThread:"Open thread tab",nextReply:"Next reply",previousReply:"Previous reply",hide:"Hide",Scrolling:"Auto Scroll",Verbose:""})).Conf&&(e.Conf.fourchanImageHost=e.Conf["Always CDN"]?"i.4cdn.org":"",delete e.Conf["Always CDN"]),e.Conf.sauces=e.Conf.sauces.replace(/\$\d/g,(function(e){switch(e){case"$1":return"%TURL";case"$2":return"%URL";case"$3":return"%MD5";case"$4":return"%board";default:return e}})),c.hotkeys)c.hotkeys[t],
@ -485,7 +485,7 @@ regExp:/^\w+:\/\/(?:www\.)?loopvid.appspot.com\/#?((?:pf|kd|lv|gd|gh|db|dx|nn|cp
return[`https://dl.dropboxusercontent.com/u/${l}`];case"dx":return[`https://dl.dropboxusercontent.com/${l}`];case"nn":return[`https://kastden.org/_loopvid_media/nn/${l}`];case"cp":return[`https://copy.com/${l}`];case"wu":return[`http://webmup.com/${l}/vid.webm`];case"ig":return[`https://i.imgur.com/${l}`];case"ky":return[`https://kastden.org/_loopvid_media/ky/${l}`];case"mf":return[`https://kastden.org/_loopvid_media/mf/${l}`,`https://web.archive.org/web/2/https://d.maxfile.ro/${l}`];case"m2":return[`https://kastden.org/_loopvid_media/m2/${l}`];case"pc":return[`https://kastden.org/_loopvid_media/pc/${l}`,`https://web.archive.org/web/2/http://a.pomf.cat/${l}`];case"1c":return[`http://b.1339.cf/${l}`];case"pi":return[`https://kastden.org/_loopvid_media/pi/${l}`,`https://web.archive.org/web/2/https://u.pomf.is/${l}`];case"ni":return[`https://kastden.org/_loopvid_media/ni/${l}`,`https://web.archive.org/web/2/https://u.nya.is/${l}`];case"wl":return[`http://webm.land/media/${l}`];case"ko":
return[`https://kordy.kastden.org/loopvid/${l}`];case"mm":return[`https://kastden.org/_loopvid_media/mm/${l}`,`https://web.archive.org/web/2/https://my.mixtape.moe/${l}`];case"ic":return[`https://media.8ch.net/file_store/${l}`];case"fc":return[`//${O.host()}/${l}.webm`];case"gc":return[`https://${s}.gfycat.com/${r}.webm`]}})();for(var c of d)Ve.add(t,Ve.el("source",{src:c}))}return t}},{key:"Openings.moe",regExp:/^\w+:\/\/openings.moe\/\?video=([^.&=]+)/,style:"width: 1280px; height: 720px; max-width: 80vw; max-height: 80vh;",el(e){const t=Ve.el("iframe",{src:`https://openings.moe/?video=${e.dataset.uid}`});return t.setAttribute("allowfullscreen","true"),t}},{key:"Pastebin",regExp:/^\w+:\/\/(?:\w+\.)?pastebin\.com\/(?!u\/)(?:[\w.]+(?:\/|\?i\=))?(\w+)/,el:e=>Ve.el("iframe",{src:`//pastebin.com/embed_iframe.php?i=${e.dataset.uid}`})},{key:"SoundCloud",regExp:/^\w+:\/\/(?:www\.)?(?:soundcloud\.com\/|snd\.sc\/)([\w\-\/]+)/,style:"border: 0; width: 500px; height: 400px;",
el:e=>Ve.el("iframe",{src:`https://w.soundcloud.com/player/?visual=true&show_comments=false&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(e.dataset.uid)}`}),title:{api:e=>`${location.protocol}//soundcloud.com/oembed?format=json&url=https%3A%2F%2Fsoundcloud.com%2F${encodeURIComponent(e)}`,text:e=>e.title}},{key:"StrawPoll",regExp:/^\w+:\/\/(?:www\.)?strawpoll\.me\/(?:embed_\d+\/)?(\d+(?:\/r)?)/,style:"border: 0; width: 600px; height: 406px;",el:e=>Ve.el("iframe",{src:`https://www.strawpoll.me/embed_1/${e.dataset.uid}`})},{key:"Streamable",regExp:/^\w+:\/\/(?:www\.)?streamable\.com\/(\w+)/,el(e){const t=Ve.el("iframe",{src:`https://streamable.com/o/${e.dataset.uid}`});return t.setAttribute("allowfullscreen","true"),t},title:{api:e=>`https://api.streamable.com/oembed?url=https://streamable.com/${e}`,text:e=>e.title}},{key:"TwitchTV",regExp:/^\w+:\/\/(?:www\.|secure\.|clips\.|m\.)?twitch\.tv\/(\w[^#\&\?]*)/,el(e){
let t,n=e.dataset.href.match(/^\w+:\/\/(?:(clips\.)|\w+\.)?twitch\.tv\/(?:\w+\/)?(clip\/)?(\w[^#\&\?]*)/);if(n[1]||n[2])t=`//clips.twitch.tv/embed?clip=${n[3]}&parent=${location.hostname}`;else{let o;n=e.dataset.uid.match(/(\w+)(?:\/(?:v\/)?(\d+))?/),t=`//player.twitch.tv/?${n[2]?`video=v${n[2]}`:`channel=${n[1]}`}&autoplay=false&parent=${location.hostname}`,(o=e.dataset.href.match(/\bt=(\w+)/))&&(t+=`&time=${o[1]}`)}const o=Ve.el("iframe",{src:t});return o.setAttribute("allowfullscreen","true"),o}},{key:"Twitter",regExp:/^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/,style:"border: none; width: 550px; height: 250px; overflow: hidden; resize: both;",el(e){const t=Ve.el("iframe");Ve.on(t,"load",(function(){return this.contentWindow.postMessage({element:"t",query:"height"},"https://twitframe.com")}));var n=function(e){if(e.source===t.contentWindow&&"https://twitframe.com"===e.origin)return Ve.off(window,"message",n),
let t,n=e.dataset.href.match(/^\w+:\/\/(?:(clips\.)|\w+\.)?twitch\.tv\/(?:\w+\/)?(clip\/)?(\w[^#\&\?]*)/);if(n[1]||n[2])t=`//clips.twitch.tv/embed?clip=${n[3]}&parent=${location.hostname}`;else{let o;n=e.dataset.uid.match(/(\w+)(?:\/(?:v\/)?(\d+))?/),t=`//player.twitch.tv/?${n[2]?`video=v${n[2]}`:`channel=${n[1]}`}&autoplay=false&parent=${location.hostname}`,(o=e.dataset.href.match(/\bt=(\w+)/))&&(t+=`&time=${o[1]}`)}const o=Ve.el("iframe",{src:t});return o.setAttribute("allowfullscreen","true"),o}},{key:"Twitter",regExp:/^\w+:\/\/(?:www\.|mobile\.)?(?:twitter|x)\.com\/(\w+\/status\/\d+)/,style:"border: none; width: 550px; height: 250px; overflow: hidden; resize: both;",el(e){const t=Ve.el("iframe");Ve.on(t,"load",(function(){return this.contentWindow.postMessage({element:"t",query:"height"},"https://twitframe.com")}));var n=function(e){if(e.source===t.contentWindow&&"https://twitframe.com"===e.origin)return Ve.off(window,"message",n),
(o||t).style.height=+Ve.minmax(e.data.height,250,.8*i.clientHeight)+"px"};if(Ve.on(window,"message",n),t.src=`https://twitframe.com/show?url=https://twitter.com/${e.dataset.uid}`,"gecko"===Ve.engine){t.style.cssText="border: none; width: 100%; height: 100%;";var o=Ve.el("div");return Ve.add(o,t),o}return t}},{key:"VidLii",regExp:/^\w+:\/\/(?:www\.)?vidlii\.com\/watch\?v=(\w{11})/,style:"border: none; width: 640px; height: 392px;",el(e){const t=Ve.el("iframe",{src:`https://www.vidlii.com/embed?v=${e.dataset.uid}&a=0`});return t.setAttribute("allowfullscreen","true"),t}},{key:"Vimeo",regExp:/^\w+:\/\/(?:www\.)?vimeo\.com\/(\d+)/,el(e){const t=Ve.el("iframe",{src:`//player.vimeo.com/video/${e.dataset.uid}?wmode=opaque`});return t.setAttribute("allowfullscreen","true"),t},title:{api:e=>`https://vimeo.com/api/oembed.json?url=https://vimeo.com/${e}`,text:e=>e.title}},{key:"Vine",regExp:/^\w+:\/\/(?:www\.)?vine\.co\/v\/(\w+)/,style:"border: none; width: 500px; height: 500px;",
el:e=>Ve.el("iframe",{src:`https://vine.co/v/${e.dataset.uid}/card`})},{key:"Vocaroo",regExp:/^\w+:\/\/(?:(?:www\.|old\.)?vocaroo\.com|voca\.ro)\/((?:i\/)?\w+)/,style:"",el(e){const t=Ve.el("iframe");return t.width=300,t.height=60,t.setAttribute("frameborder",0),t.src=`https://vocaroo.com/embed/${e.dataset.uid.replace(/^i\//,"")}?autoplay=0`,t}},{key:"YouTube",regExp:/^\w+:\/\/(?:youtu.be\/|[\w.]*youtube[\w.]*\/.*(?:v=|\bembed\/|\bv\/|live\/))([\w\-]{11})(.*)/,el(e){let t=e.dataset.options.match(/\b(?:star)?t\=(\w+)/);t&&(t=t[1]),t&&!/^\d+$/.test(t)&&(t+=" 0h0m0s",t=3600*t.match(/(\d+)h/)[1]+60*t.match(/(\d+)m/)[1]+1*t.match(/(\d+)s/)[1]);const n=Ve.el("iframe",{src:`//www.youtube.com/embed/${e.dataset.uid}?rel=0&wmode=opaque${t?"&start="+t:""}`});return n.setAttribute("allowfullscreen","true"),n},title:{api:e=>`https://www.youtube.com/oembed?url=https%3A//www.youtube.com/watch%3Fv%3D${e}&format=json`,text:e=>e.title,status(e){if(e.error){const t=e.error.match(/^(\d*)\s*(.*)/)
;return[+t[1],t[2]]}return[200,"OK"]}},preview:{url:e=>`https://img.youtube.com/vi/${e}/0.jpg`,height:360}}]},Fe={init(){if(t.Keybinds){for(var e in c.hotkeys)Ve.sync(e,Fe.sync);var n=function(){for(var e of(Ve.off(a,"4chanXInitFinished",n),Ve.on(a,"keydown",Fe.keydown),u("[accesskey]")))e.removeAttribute("accesskey")};return Ve.on(a,"4chanXInitFinished",n)}},sync:(e,n)=>t[n]=e,keydown(e){let o,a,i,r,s;if(!(o=Fe.keyCode(e)))return;const{target:l}=e;if(!["INPUT","TEXTAREA"].includes(l.nodeName)||/(Esc|Alt|Ctrl|Meta|Shift\+\w{2,})/.test(o)&&!/^Alt\+(\d|Up|Down|Left|Right)$/.test(o)){switch(["index","thread"].includes(n.VIEW)&&(i=F.getThread(),a=ze.threadFromRoot(i)),o){case t["Toggle board list"]:if(!t["Custom Board Navigation"])return;Ke.toggleBoardList();break;case t["Toggle header"]:Ke.toggleBarVisibility();break;case t["Open empty QR"]:if(!$e.postingIsEnabled)return;Fe.qr();break;case t["Open QR"]:if(!$e.postingIsEnabled||!i)return;Fe.qr(i);break;case t["Open settings"]:Be.open()

File diff suppressed because one or more lines are too long

View File

@ -1,6 +1,6 @@
{
"name": "4chan XT",
"version": "XT 2.1.2",
"version": "XT 2.1.3",
"manifest_version": 2,
"description": "4chan XT is a script that adds various features to anonymous imageboards.",
"icons": {

View File

@ -79,8 +79,8 @@
'use strict';
var version = {
"version": "XT 2.1.2",
"date": "2023-07-22T15:46:24.103Z"
"version": "XT 2.1.3",
"date": "2023-08-21T18:04:11.719Z"
};
var meta = {
@ -15129,7 +15129,12 @@ $\
}
$$1.on($$1('.close', dialog), 'click', Settings.close);
$$1.on(window, 'beforeunload', Settings.close);
$$1.on(dialog, 'click', Settings.close);
$$1.on(dialog, 'click', () => {
// Do not close when the mouse ends up outside the modal when selecting text in an input.
if (d$1.activeElement?.tagName === 'INPUT' || d$1.activeElement?.tagName === 'TEXTAREA')
return;
Settings.close();
});
$$1.on(dialog.firstElementChild, 'click', e => e.stopPropagation());
$$1.add(d$1.body, dialog);
return $$1.event('OpenSettings', null, dialog);
@ -17523,7 +17528,7 @@ vp-replace
}
, {
key: 'Twitter',
regExp: /^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/,
regExp: /^\w+:\/\/(?:www\.|mobile\.)?(?:twitter|x)\.com\/(\w+\/status\/\d+)/,
style: 'border: none; width: 550px; height: 250px; overflow: hidden; resize: both;',
el(a) {
const el = $$1.el('iframe');

View File

@ -109,7 +109,11 @@ var Settings = {
$.on($('.close', dialog), 'click', Settings.close);
$.on(window, 'beforeunload', Settings.close);
$.on(dialog, 'click', Settings.close);
$.on(dialog, 'click', () => {
// Do not close when the mouse ends up outside the modal when selecting text in an input.
if (d.activeElement?.tagName === 'INPUT' || d.activeElement?.tagName === 'TEXTAREA') return;
Settings.close();
});
$.on(dialog.firstElementChild, 'click', e => e.stopPropagation());
$.add(d.body, dialog);

View File

@ -592,7 +592,7 @@ var Embedding = {
}
, {
key: 'Twitter',
regExp: /^\w+:\/\/(?:www\.|mobile\.)?twitter\.com\/(\w+\/status\/\d+)/,
regExp: /^\w+:\/\/(?:www\.|mobile\.)?(?:twitter|x)\.com\/(\w+\/status\/\d+)/,
style: 'border: none; width: 550px; height: 250px; overflow: hidden; resize: both;',
el(a) {
const el = $.el('iframe');

View File

@ -1,4 +1,4 @@
{
"version": "XT 2.1.2",
"date": "2023-07-22T15:46:24.103Z"
"version": "XT 2.1.3",
"date": "2023-08-21T18:04:11.719Z"
}