跳转到内容

User:Saimmx/SATG.js

维基百科,自由的百科全书
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google ChromeFirefoxMicrosoft EdgeSafari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
//Written by Saimmx
//Date: 2026-03-09
//<nowiki>
mw.util.addPortlet( 'p-codex', 'Codex小工具', '#p-interaction' );
const dialogTrigger = mw.util.addPortletLink( 'p-tb', '#', '可靠來源評估產生器', 'p-codex-dialog' );

mw.loader.using( '@wikimedia/codex' ).then( function( require ) {
	const Vue = require( 'vue' );
	const Codex = require( '@wikimedia/codex' );
	const mountPoint = document.body.appendChild( document.createElement( 'div' ) );
	/*
	 * https://vuejs.org/api/options-misc#components
	 * https://doc.wikimedia.org/codex/latest/components/overview.html
	 * cdx-accordion => CdxAccordion
	 * cdx-combobox => CdxCombobox 
	 * 寫起來有點北爛就是了
	*/
	const VueComponentComponents = {
		CdxButton: Codex.CdxButton,
		CdxDialog: Codex.CdxDialog,
		CdxLabel: Codex.CdxLabel,
		CdxTextInput: Codex.CdxTextInput,
		CdxSelect: Codex.CdxSelect,
	}
	/*
	 * Because "No .vue single-file component support; you must define components in plain .js files", sooo...
	 * @see: [https://www.mediawiki.org/wiki/Codex/en#Using_Codex_in_userscripts Codex]
	*/
	const VueComponentTemplate = `<cdx-dialog
		v-model:open="showDialog"
		title="可靠來源評估產生器"
		close-button-label="關閉"
		:use-close-button="true"
		:default-action="defaultAction"
		@default="open = false"
	>
		<div class="satg-app">
			<p>
				以下程式為評估<a :href="anchorLink.GNG" target="_blank">{{ anchorTitle.GNG }}</a>來源的產生程式。
				靈感取自<a :href="anchorLink.EGardnerCodex" target="_blank">{{ anchorTitle.EGardnerCodex }}</a>
				與<a :href="anchorLink.DannyS712SATG" target="_blank">{{ anchorTitle.DannyS712SATG }}</a>。
			</p>
			<hr />
			<div class="satg-app-source">
				<cdx-label>這個來源是哪裡?</cdx-label>
				<cdx-text-input v-model="sourceAccess.source" aria-label="來源說明"></cdx-text-input>
			</div>
			<div class="satg-app-reliable">
				<cdx-label>來源是否可靠?</cdx-label>
				<cdx-select v-model:selected="sourceAccess.rel" :menu-items="accessOptions" aria-label="來源可靠評價" default-label="請評價" />
				<cdx-label>為什麼?</cdx-label>
				<cdx-text-input v-model="sourceAccess.rel_just" aria-label="來源可靠理由"></cdx-text-input>
			</div>
			<div class="satg-app-coverage">
				<cdx-label>來源是否有效介绍?</cdx-label>
				<cdx-select v-model:selected="sourceAccess.sig" :menu-items="accessOptions" aria-label="有效介绍評價" default-label="請評價" />
				<cdx-label>為什麼?</cdx-label>
				<cdx-text-input v-model="sourceAccess.sig_just" aria-label="有效介绍理由"></cdx-text-input>
			</div>
			<div class="satg-app-independent">
				<cdx-label>來源是否獨立於主題實體?</cdx-label>
				<cdx-select v-model:selected="sourceAccess.ind" :menu-items="accessOptions" aria-label="獨立於主題實體評價" default-label="請評價" />
				<cdx-label>為什麼?</cdx-label>
				<cdx-text-input v-model="sourceAccess.ind_just" aria-label="獨立於主題實體理由"></cdx-text-input>
			</div>
			<hr />
			<div class="satg-app-control">
				<cdx-button action="progressive" @click="addSource(sourceAccess)">新增此來源</cdx-button>
				<cdx-button action="destructive" @click="resetSource">重設來源</cdx-button>
			</div>
			<hr />
			<div class="satg-app-sources-preview">
				<cdx-label>簡易來源檢查</cdx-label>
				<ol v-show="sourcesPreview.length > 0">
					<li v-for="(item, index) in sources" :key="index">
						{{ item.source }}
						<cdx-button action="destructive" @click="deleteSource(index)">Delete source</cdx-button>
					</li>
				</ol>
			</div>
			<hr />
			<div class="satg-app-result">
				<cdx-label>檢查結果</cdx-label>
				{{ sourceAccessResult }}
			</div>
		</div>
	</cdx-dialog>`;
	
	// components:
	// .component( 'cdx-button', Codex.CdxButton )
	// .component( 'cdx-dialog', Codex.CdxDialog )
	Vue.createMwApp( {
		components: VueComponentComponents,
		template: VueComponentTemplate,
		data: function() {
			return {
				showDialog: false,
				showResult: false,
				sources: [],
				links: {
					GNG: {
						href: "WP:GNG",
						title: "通用收錄標準"
					},
					EGardnerCodex: {
						href: "en:User:EGardner (WMF)/codex-hello-world.js",
						title: "User:EGardner (WMF)/codex-hello-world.js"
					},
					DannyS712SATG: {
						href: "en:User:DannyS712/SATG.js",
						title: "User:DannyS712/SATG.js"
					},
				},
				GNGConditions: [
					{
						id: "reliable",
						summary: "可靠来源",
					},
					{
						id: "coverage" ,
						summary: "有效介绍",
					},
					{
						id: "independent" ,
						summary: "獨立於主題實體",
					},
				],
				sourceAccess: {
					source: "",
					rel: null,
					sig: null,
					ind: null,
					rel_just: "",
					sig_just: "",
					ind_just: "",
				},
				accessOptions: [
					{ value: "y", label: "是" },
					{ value: "n", label: "否" },
					{ value: "-", label: "部份" },
					{ value: "?", label: "不知道" },
				],
			};
		},
		computed: {
			anchorLink() {
				const getLink = (link = { href: "WP:5P", title: "五大支柱" }) => `https://zh.wikipedia.org/wiki/${link.href}`;
				return {
					GNG: getLink(this.links.GNG),
					EGardnerCodex: getLink(this.links.EGardnerCodex),
					DannyS712SATG: getLink(this.links.DannyS712SATG),
				};
			},
			anchorTitle() {
				const getLink = (link = { href: "WP:5P", title: "五大支柱" }) => link.title;
				return {
					GNG: getLink(this.links.GNG),
					EGardnerCodex: getLink(this.links.EGardnerCodex),
					DannyS712SATG: getLink(this.links.DannyS712SATG),
				};
			},
			sourcesPreview() {
				const inited_source = { source: "", rel: "", sig: "", ind: "", rel_just: "", sig_just: "", ind_just: "", };
				return this.sources.map( (item = inited_source, index = 0) => ({ index, ...item }) );
			},
			sourceAccessTemplate() {
				const inited_source = { source: "", rel: "", sig: "", ind: "", rel_just: "", sig_just: "", ind_just: "", };
				return this.sources.map( (item = inited_source, index = 0) => `
					{{ source assess
						|source=${item.source}
						|rel=${item.rel}
						|sig=${item.sig}
						|ind=${item.ind}
						|rel_just=${item.rel_just}
						|sig_just=${item.sig_just}
						|ind_just=${item.ind_just}
					}} \n
				`);
			},
			sourceAccessResult() {
				return `{{ source assess table | user=Example |
					${ this.sourceAccessTemplate }
				}}`;
			}
		},
		methods: {
			openDialog () {
				this.showDialog = true;
			},
			addSource(sourceAccess = { source: "", rel: "", sig: "", ind: "", rel_just: "", sig_just: "", ind_just: "", }) {
				this.sources.push( sourceAccess );
				this.resetSource();
			},
			resetSource() {
				this.sourceAccess = {
					source: "",
					rel: "",
					sig: "",
					ind: "",
					rel_just: "",
					sig_just: "",
					ind_just: "",
				};
			},
			deleteItemFromIndex(ary, index) {
			  if (index < 0 || index >= ary.length) {
			    return ary;
			  }
			  ary.splice(index, 1);
			  return ary;
			},
			deleteSource(index = 0) {
				this.sources = this.deleteItemFromIndex(this.sources, index);
			},
			toggleShowResult() {
				this.showResult = !this.showResult;
			},
		},
		mounted() {
			dialogTrigger.addEventListener( 'click', this.openDialog );
		},
		unMounted() {
			dialogTrigger.removeEventListener( this.openDialog );
		}
	} )
	.mount( mountPoint );
} );
//</nowiki>