forked from AnYiEE/AwesomeGadgets
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
240 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import {type TargetElements, getTargetElements} from './modules/util/getTargetElements'; | ||
import {IS_IN_TARGET_SPECIAL_PAGE} from './modules/constant'; | ||
import {getBody} from 'ext.gadget.Util'; | ||
import {processElement} from './modules/processElement'; | ||
|
||
void getBody().then(function autoLink($body: JQuery<HTMLBodyElement>): void { | ||
if (!IS_IN_TARGET_SPECIAL_PAGE) { | ||
return; // Disabled in the other special pages | ||
} | ||
|
||
const targetElements: TargetElements = getTargetElements($body); | ||
|
||
processElement(targetElements); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* SPDX-License-Identifier: CC-BY-SA-4.0 | ||
* _addText: '{{Gadget Header|license=CC-BY-SA-4.0}}' | ||
* | ||
* @base {@link https://meta.wikimedia.org/wiki/MediaWiki:Gadget-autolink.js} | ||
* @base {@link https://en.wikipedia.org/wiki/Wikipedia:WikiProject_User_scripts/Scripts/Autolink} | ||
* @source {@link https://github.com/TopRealm/YsArxiv-Gadgets/tree/master/src/AutoLink} | ||
* @license CC-BY-SA-4.0 {@link https://www.qiuwenbaike.cn/wiki/H:CC-BY-SA-4.0} | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"enable": true, | ||
"description": "<span id=\"Gadget-AutoLink\"></span> 自动为[[Help:编辑摘要|编辑摘要]]中的[[Help:模板|模板]]、[[Help:链接|链接]]语法添加链接", | ||
"section": "browser", | ||
"dependencies": ["ext.gadget.Util", "mediawiki.util"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
const WG_ACTION: MediaWikiConfigMapWgAction = mw.config.get('wgAction'); | ||
const WG_CANONICAL_NAMESPACE: string = mw.config.get('wgCanonicalNamespace'); | ||
const WG_CANONICAL_SPECIAL_PAGE_NAME: string = mw.config.get('wgCanonicalSpecialPageName').toString(); | ||
|
||
const IS_DIFF_ACTION: boolean = !!mw.util.getParamValue('diff'); | ||
// Special crono pages where this script is enabled | ||
const IS_TARGET_SPECIAL_PAGE: boolean = [ | ||
'Contributions', | ||
'Log', | ||
'Newpages', | ||
'Recentchanges', | ||
'Recentchangeslinked', | ||
'Watchlist', | ||
].includes(WG_CANONICAL_SPECIAL_PAGE_NAME); | ||
const IS_IN_TARGET_SPECIAL_PAGE: boolean = WG_CANONICAL_NAMESPACE === 'Special' && IS_TARGET_SPECIAL_PAGE; | ||
const IS_WG_EDIT_OR_SUBMIT_ACTION: boolean = ['edit', 'submit'].includes(WG_ACTION); | ||
const IS_WG_HISTORY_ACTION: boolean = WG_ACTION === 'history'; | ||
|
||
const REGEX_INTERNAL_URL: RegExp = /([^=])([\s"'])((?:\/?w\/index\.php\?|\/?wiki\/)[\w!#%&()+./:=?@\\~-]+)\2/g; | ||
// External links (no wikicode) | ||
const REGEX_IMPORT_SCRIPT: RegExp = | ||
/([Ii]mport[Ss]cript(?:<span class="br0">)?\((?:<\/span><span class="st0">)?)('|")([^\n<>[\]{|}]+?)(\2(?:<\/span><span class="br0">)?\)(?:<\/span>)?)/g; | ||
// ImportScript | ||
const REGEX_TL: RegExp = /([^{]{{2}\s*[Tt]l\|)([^\n:<>[\]{|}]+)/g; | ||
// For {{tl}} | ||
const REGEX_URL: RegExp = | ||
/((?:[^"[]|[^=]")(?:<span class="diffchange">)?)((?:https?|ftps?):\/\/[\w!#%&()+./:=?@\\~-]+?)(?=(?:<\/span>)?[\s"')\]|}])/g; | ||
|
||
export { | ||
IS_DIFF_ACTION, | ||
IS_IN_TARGET_SPECIAL_PAGE, | ||
IS_TARGET_SPECIAL_PAGE, | ||
IS_WG_EDIT_OR_SUBMIT_ACTION, | ||
IS_WG_HISTORY_ACTION, | ||
REGEX_INTERNAL_URL, | ||
REGEX_IMPORT_SCRIPT, | ||
REGEX_TL, | ||
REGEX_URL, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
/** | ||
* Autolink [[wikilinks]], [external links] and {{templates}} | ||
*/ | ||
import { | ||
IS_DIFF_ACTION, | ||
IS_TARGET_SPECIAL_PAGE, | ||
IS_WG_EDIT_OR_SUBMIT_ACTION, | ||
IS_WG_HISTORY_ACTION, | ||
REGEX_IMPORT_SCRIPT, | ||
REGEX_INTERNAL_URL, | ||
REGEX_TL, | ||
REGEX_URL, | ||
} from './constant'; | ||
import type {TargetElements} from './util/getTargetElements'; | ||
|
||
const processElement = ({color, targetElements}: TargetElements): void => { | ||
let isActivateHTML: boolean = false; | ||
/* Regex (default for diffs) */ | ||
// Regex for diffs | ||
let regexURLinWikicodeWithoutLabel: RegExp = | ||
/((?:[^[]|^)\[\s*(?:<\/span>)?\s*(?:<span class="diffchange">)?\s*)((?:https?|ftps?):\/\/[\w!#%&()+./:=?@\\~-]+)((?:<\/span>)?(?:<span class="diffchange">)?)([\w!#%&()+./:=?@\\~-]*)((?:<\/span>)?(?:<span class="diffchange">)?)([\w!#%&()+./:=?@\\~-]*)([^\n\]]*])/gm; | ||
// External links (no wikicode) | ||
let regexSubstinWikicodeWithoutLabel: string = `$1<a class="external autolink" style="color:${color}" href="$2$4$6">$2</a>$3<a class="external autolink" style="color:${color}" href="$2$4$6">$4</a>$5<a class="external autolink" style="color:${color}" href="$2$4$6">$6</a>$7`; | ||
// External links in diff pages, wikicode without label | ||
let regexURLinWikicodeWithLabel: RegExp = regexURLinWikicodeWithoutLabel; | ||
// External links in diff pages, wikicode with label | ||
let regexSubstinWikicodeWithLabel: string = regexSubstinWikicodeWithoutLabel; | ||
// Other pages included in diff pages | ||
let regexOtherPages: RegExp = | ||
/((?:[^{]|^){{2}\s*(?:<\/span>)?\s*(?:<span class="diffchange">)?\s*(?:(?:[Ss][Uu][Bb][Ss][Tt]|[Mm][Ss][Gg]|[Mm][Ss][Gg][Nn][Ww])\s*:)?\s*(?:<\/span>)?\s*(?:<span class="diffchange">)?\s*)((?:[Ss]peciale?|[Qq](?:iuwen|[Ww])|[Ww][Pp]|[Tt]emplate|[Uu]ser)?\s*(?: ?[Tt]alk)?\s*:[^\n:<>[\]{|}]+)((?:<\/span>)?(?:<span class="diffchange">)?)([^\n:<>[\]{|}]*)((?:<\/span>)?(?:<span class="diffchange">)?)([^\n:<>[\]{|}]*)(\||}{2})/gm; | ||
let regexSubstinOtherPages: string = `$1<a class="autolink" style="color:${color}" href="/wiki/$2$4$6">$2</a>$3<a class="autolink" style="color:${color}" href="/wiki/$2$4$6">$4</a>$5<a class="autolink" style="color:${color}" href="/wiki/$2$4$6">$6</a>$7`; | ||
// Templates in diff pages | ||
let regexTemplate: RegExp = | ||
/((?:[^{]|^){{2}\s*(?:<\/span>)?\s*(?:<span class="diffchange">)?\s*(?:(?:[Ss][Uu][Bb][Ss][Tt]|[Mm][Ss][Gg]|[Mm][Ss][Gg][Nn][Ww])\s*:)?\s*(?:<\/span>)?\s*(?:<span class="diffchange">)?)([^\n:<>[\]{|}]+)((?:<\/span>)?(?:<span class="diffchange">)?)([^\n:<>[\]{|}]*)((?:<\/span>)?(?:<span class="diffchange">)?)([^\n:<>[\]{|}]*)(\||}{2}|:)/gm; | ||
let regexSubstinTemplate: string = `$1<a class="autolink" style="color:${color}" href="/wiki/Template:$2$4$6">$2</a>$3<a class="autolink" style="color:${color}" href="/wiki/Template:$2$4$6">$4</a>$5<a class="autolink" style="color:${color}" href="/wiki/Template:$2$4$6">$6</a>$7`; | ||
// Wikilinks in diff pages | ||
let regexWikilink1: RegExp = | ||
/(\[{2}\s*(?:<\/span>)?\s*(?:<span class="diffchange">)?\s*)([^\n<>[\]{|}]+)((?:<\/span>)?(?:<span class="diffchange">)?)([^\n<>[\]{|}]*)((?:<\/span>)?(?:<span class="diffchange">)?)([^\n<>[\]{|}]*)((?:[^\n\]]|][^\]])*]{2})/g; | ||
let regexSubstinWikilink1: string = `$1<a class="autolink" style="color:${color}" href="/wiki/$2$4$6">$2</a>$3<a class="autolink" style="color:${color}" href="/wiki/$2$4$6">$4</a>$5<a class="autolink" style="color:${color}" href="/wiki/$2$4$6">$6</a>$7`; | ||
let regexWikilink2: RegExp = regexWikilink1; | ||
let regexSubstinWikilink2: string = regexSubstinWikilink1; | ||
// Regex for comments or code sections | ||
if (!IS_DIFF_ACTION) { | ||
// Activate some HTML (inline) and wikicode for bold and italic | ||
isActivateHTML = true; | ||
// External links in comments or code sections, wikicode without label | ||
regexURLinWikicodeWithoutLabel = /([^[]|^)\[\s*((?:https?|ftps?):\/\/[\w!#%&()+./:=?@\\~-]+)\s*]/gm; | ||
regexSubstinWikicodeWithoutLabel = `$1<a class="external autolink" style="color:${color}" href="$2">$2</a>`; | ||
// External links in comments or code sections, wikicode with label (the URL will not be visible) | ||
regexURLinWikicodeWithLabel = /([^[]|^)\[\s*((?:https?|ftps?):\/\/[\w!#%&()+./:=?@\\~-]+)\s+([^\n]+?)\s*]/gm; | ||
regexSubstinWikicodeWithLabel = `$1<a class="external autolink" style="color:${color}" href="$2">$3</a>`; | ||
// Other pages included in comments or code sections | ||
regexOtherPages = | ||
/((?:[^{]|^){{2}\s*(?:(?:[Ss][Uu][Bb][Ss][Tt]|[Mm][Ss][Gg]|[Mm][Ss][Gg][Nn][Ww])\s*:)?\s*)((?:[Ss]pecial|[Qq](?:iuwen|Q)|[Ww][Pp]|[Tt]emplate|[Uu]ser)?\s*(?: ?[Tt]alk)?\s*:[^\n:<>[\]{|}]+)(\||}{2})/gm; | ||
regexSubstinOtherPages = `$1<a class="autolink" style="color:${color}" href="/wiki/$2">$2</a>$3`; | ||
// Templates in comments or code sections | ||
regexTemplate = | ||
/((?:[^{]|^){{2}\s*(?:(?:[Ss][Uu][Bb][Ss][Tt]|[Mm][Ss][Gg]|[Mm][Ss][Gg][Nn][Ww])\s*:)?\s*)([^\n:<>[\]{|}]+)(\||}{2}|:)/gm; | ||
regexSubstinTemplate = `$1<a class="autolink" style="color:${color}" href="/wiki/Template:$2">$2</a>$3`; | ||
// Wikilinks in code sections, with label | ||
regexWikilink1 = /\[{2}\s*([^\n<>[\]{|}]+?)\s*\|\s*(.+?)\s*]{2}/g; | ||
regexSubstinWikilink1 = `<a class="autolink" style="color:${color}" href="/wiki/$1">$2</a>`; | ||
// Wikilinks in code sections, without label | ||
regexWikilink2 = /\[{2}\s*([^\n<>[\]{|}]+?)\s*\|?\s*]{2}/g; | ||
regexSubstinWikilink2 = `<a class="autolink" style="color:${color}" href="/wiki/$1">$1</a>`; | ||
} | ||
|
||
for (const element of targetElements) { | ||
const {innerHTML: originHtml} = element; | ||
let html: string = originHtml; | ||
|
||
html = html.replace(/</g, '­<­'); | ||
html = html.replace(/>/g, '­>­'); | ||
// &lt; to &shy;<&shy; and &gt; to &shy;>&shy; (&shy; is a marker) | ||
html = html.replace(/&/g, '&'); | ||
// &amp; to & | ||
/* --- */ | ||
html = html.replace(REGEX_TL, `$1<a class="autolink" style="color:${color}" href="/wiki/Template:$2">$2</a>`); | ||
// For {{tl}}: make his argument into link | ||
html = html.replace(REGEX_URL, `$1<a class="external autolink" style="color:${color}" href="$2">$2</a>`); | ||
// Parse inactive external links (no wikicode) | ||
html = html.replace(regexURLinWikicodeWithoutLabel, regexSubstinWikicodeWithoutLabel); | ||
// Make external links in wikicode without label into links | ||
html = html.replace(regexURLinWikicodeWithLabel, regexSubstinWikicodeWithLabel); | ||
// Make external links in wikicode with label into links | ||
html = html.replace(regexOtherPages, regexSubstinOtherPages); | ||
// Make other pages included code into links | ||
html = html.replace(regexTemplate, regexSubstinTemplate); | ||
html = html.replace(/href="\/wiki\/Template:#/g, 'href="/wiki/Help:'); | ||
// Make template code into links | ||
html = html.replace(regexWikilink1, regexSubstinWikilink1); | ||
html = html.replace(regexWikilink2, regexSubstinWikilink2); | ||
// Make wikilink code into links | ||
html = html.replace( | ||
REGEX_INTERNAL_URL, | ||
`$1$2<a class="external autolink" style="color:${color}" href="$3">$3</a>$2` | ||
); | ||
// Parse inactive external links (no wikicode) | ||
html = html.replace( | ||
REGEX_IMPORT_SCRIPT, | ||
`$1$2<a class="autolink" style="color:${color}" href="/wiki/$3">$3</a>$4` | ||
); | ||
// Parse ImportScript | ||
html = html.replace(/­<­/g, '<'); | ||
html = html.replace(/­>­/g, '>'); | ||
// &shy;<&shy; to &lt; and &shy;>&shy; to &gt; (revert) | ||
if (isActivateHTML) { | ||
html = html.replace( | ||
/<(span|b|i|strong|small|tt|del|s|u|sub|sup)>(.*?)<\/(\1)>/g, | ||
'<$1>$2</$3>' | ||
); | ||
html = html.replace(/([^']|^)'{3}(.+?)'{3}([^']|$)/gm, '$1<b>$2</b>$3'); | ||
html = html.replace(/([^']|^)'{2}(.+?)'{2}([^']|$)/gm, '$1<i>$2</i>$3'); | ||
if (IS_WG_EDIT_OR_SUBMIT_ACTION || IS_WG_HISTORY_ACTION || IS_TARGET_SPECIAL_PAGE) { | ||
html = html.replace( | ||
/<i>(.*?)<\/i>/g, | ||
'<span title="italic" style="border:1px solid #c0c0c0;padding:2px">$1</span>' | ||
); | ||
} | ||
// I'm in a comment field (italic) | ||
} | ||
if (IS_DIFF_ACTION) { | ||
html = html.replace(/<a [^>]+><\/a>/g, ''); // Clean | ||
html = html.replace( | ||
/([^[]|^)\[\s*(<a [^>]+>)(?:https?|ftps?):\/\/[\w!#%&()+./:=?@\\~-]+(<\/a>)\s+([^\n\]]+)]/gm, | ||
'$1$2$4$3' | ||
); | ||
html = html.replace( | ||
/([^[]|^)\[\s*(<a [^>]+>)((?:https?|ftps?):\/\/[\w!#%&()+./:=?@\\~-]+)(<\/a>)\s*]/gm, | ||
'$1$2$3$4' | ||
); | ||
} | ||
|
||
if (html !== originHtml) { | ||
requestAnimationFrame((): void => { | ||
element.innerHTML = html; // Write it back | ||
}); | ||
} | ||
} | ||
}; | ||
|
||
export {processElement}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import {IS_DIFF_ACTION, IS_TARGET_SPECIAL_PAGE, IS_WG_EDIT_OR_SUBMIT_ACTION, IS_WG_HISTORY_ACTION} from '../constant'; | ||
|
||
interface TargetElements { | ||
color: string; | ||
targetElements: HTMLElement[]; | ||
} | ||
|
||
const getTargetElements = ($body: JQuery<HTMLBodyElement>): TargetElements => { | ||
let color: string = ''; // links color (coloured links) | ||
let targetElements: HTMLElement[] = []; | ||
|
||
if (IS_DIFF_ACTION) { | ||
// in diff pages | ||
color = 'inherit'; // not coloured links | ||
targetElements = [...$body.find('.diff,.firstrevisionheader')]; | ||
} else if (IS_WG_EDIT_OR_SUBMIT_ACTION || IS_WG_HISTORY_ACTION || IS_TARGET_SPECIAL_PAGE) { | ||
// in comments | ||
targetElements = [...$body.find('.comment')]; | ||
} else { | ||
// in code sections | ||
targetElements = [...$body.find('source,.css,.source-css,.javascript,.source-javascript')]; | ||
} | ||
|
||
return { | ||
color, | ||
targetElements, | ||
}; | ||
}; | ||
|
||
export {type TargetElements, getTargetElements}; |