parent
a5f6d8625b
commit
bd702ae657
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "interlanguage-checker",
|
||||
"version": "1.4.3",
|
||||
"version": "1.5.0",
|
||||
"description": "Check the consistency of MediaWiki interlanguage links in a simple overview.",
|
||||
"author": "Felix W. Dekker",
|
||||
"browser": "bundle.js",
|
||||
|
|
|
@ -168,24 +168,6 @@ export class MessageHandler {
|
|||
* @property pages {Page[]} the pages in the network
|
||||
*/
|
||||
export class InterlangTable extends Component {
|
||||
/**
|
||||
* Determines whether the given source links to the given destination, potentially through a redirect.
|
||||
*
|
||||
* @param source {Page} the source page of which to check the links
|
||||
* @param destination {Page} the destination that could be linked to
|
||||
* @param redirects {Redirect[]} the redirects to follow
|
||||
* @returns {"present"|"absent"|"redirect"} the status of the link
|
||||
*/
|
||||
_checkIfLinksTo(source, destination, redirects) {
|
||||
if (source.langLinks.some(it => it.equals(destination.link)))
|
||||
return "present";
|
||||
|
||||
if (source.langLinks.some(link => redirects.some(it => it.equals(new Redirect(link, destination.link)))))
|
||||
return "redirect";
|
||||
|
||||
return "absent";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an appropriate label for the given page.
|
||||
*
|
||||
|
@ -222,21 +204,19 @@ export class InterlangTable extends Component {
|
|||
/**
|
||||
* Generates the head of the table generated by `#toTable`.
|
||||
*
|
||||
* @param pages {Page[]} a list of all pages
|
||||
* @param network {InterlangNetwork} the network to generate the head for
|
||||
* @return {VNode} the head of the table generated by `#toTable`
|
||||
*/
|
||||
_generateTableHead(pages) {
|
||||
const uniquePages = pages.filter((page, i) => pages.findIndex(it => it.urlEquals(page)) === i);
|
||||
|
||||
_generateTableHead(network) {
|
||||
const topRow = html`
|
||||
<tr>
|
||||
<th class="sourceLabel" rowspan="2">Source</th>
|
||||
<th colspan="${uniquePages.length}">Destination</th>
|
||||
<th colspan="${network.pages.length}">Destination</th>
|
||||
</tr>
|
||||
`;
|
||||
const bottomRow = html`
|
||||
<tr>
|
||||
${uniquePages.map(page => html`<th>${this._generateLabel(pages, page)}</th>`)}
|
||||
${network.pages.map(page => html`<th>${this._generateLabel(network.pages, page)}</th>`)}
|
||||
</tr>
|
||||
`;
|
||||
|
||||
|
@ -246,22 +226,15 @@ export class InterlangTable extends Component {
|
|||
/**
|
||||
* Generates the body of the table generated by `#toTable`.
|
||||
*
|
||||
* @param pages {Page[]} a list of all pages
|
||||
* @param redirects {Redirect[]} the redirects in the network
|
||||
* @param network {InterlangNetwork} the network to generate the body for
|
||||
* @return {HTMLElement} the body of the table generated by `#toTable`
|
||||
*/
|
||||
_generateTableBody(pages, redirects) {
|
||||
const uniquePages = pages.filter((page, i) => pages.findIndex(it => it.urlEquals(page)) === i);
|
||||
|
||||
const rows = uniquePages.map(srcPage => {
|
||||
const label = html`<th class="sourceLabel">${this._generateLabel(pages, srcPage)}</th>`;
|
||||
const cells = uniquePages.map(dstPage => {
|
||||
_generateTableBody(network) {
|
||||
const rows = network.pages.map(srcPage => {
|
||||
const label = html`<th class="sourceLabel">${this._generateLabel(network.pages, srcPage)}</th>`;
|
||||
const cells = network.pages.map(dstPage => {
|
||||
let type, icon, title;
|
||||
const status = pages.filter(it => it.urlEquals(dstPage))
|
||||
.reduce((status, it) => {
|
||||
const newStatus = this._checkIfLinksTo(srcPage, it, redirects);
|
||||
return newStatus === "absent" ? status : newStatus;
|
||||
}, "absent");
|
||||
const status = network.checkIfLinksTo(srcPage, dstPage);
|
||||
switch (status) {
|
||||
case "present":
|
||||
[type, icon, title] = ["correct", "check", "Present"];
|
||||
|
@ -293,16 +266,14 @@ export class InterlangTable extends Component {
|
|||
* Renders the the table describing the interlanguage network.
|
||||
*
|
||||
* @param props {Object} the element's rendering properties
|
||||
* @param props.network {InterlangNetwork} the network of pages to render
|
||||
* @return {VNode} the generated table
|
||||
*/
|
||||
render(props) {
|
||||
const pages = props.pages.sort((a, b) => a.link.toString().localeCompare(b.link.toString()));
|
||||
const redirects = props.redirects;
|
||||
|
||||
return html`
|
||||
<table id="${props.id}">
|
||||
${this._generateTableHead(pages)}
|
||||
${this._generateTableBody(pages, redirects)}
|
||||
${this._generateTableHead(props.network)}
|
||||
${this._generateTableBody(props.network)}
|
||||
</table>
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import {html, render} from "htm/preact";
|
||||
import {InterlangTable, MessageHandler, ValidatableInput} from "./DOM";
|
||||
import {discoverNetwork, MediaWiki, MediaWikiManager} from "./MediaWiki";
|
||||
import {discoverNetwork, InterlangNetwork, MediaWiki, MediaWikiManager} from "./MediaWiki";
|
||||
import {$, doAfterLoad} from "./Shared";
|
||||
|
||||
|
||||
|
@ -71,12 +71,13 @@ doAfterLoad(async () => {
|
|||
|
||||
// Discover
|
||||
discoverNetwork(mwm, pageInput.getValue(), progressHandler.handle.bind(progressHandler))
|
||||
.then(({pages, redirects}) => {
|
||||
.then(({pages, redirects}) => new InterlangNetwork(pages, redirects))
|
||||
.then(network => {
|
||||
progressHandler.handle("Creating table");
|
||||
|
||||
const form = $("#networkTableForm");
|
||||
form.textContent = "";
|
||||
render(html`<${InterlangTable} id="networkTable" pages=${pages} redirects=${redirects} />`, form);
|
||||
render(html`<${InterlangTable} id="networkTable" network=${network} />`, form);
|
||||
|
||||
progressHandler.handle();
|
||||
})
|
||||
|
|
|
@ -162,6 +162,82 @@ export class Page {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A network of pages linking to each other.
|
||||
*
|
||||
* @property pages {Page[]} the pages linking to each other, sorted alphabetically
|
||||
* @properties redirects {Redirect[]} the redirects in the network
|
||||
*/
|
||||
export class InterlangNetwork {
|
||||
/**
|
||||
* Constructs a new `InterlangNetwork`.
|
||||
*
|
||||
* @param pages {Page[]} the pages linking to each other
|
||||
* @param redirects {Redirect[]} the redirects in the network
|
||||
*/
|
||||
constructor(pages, redirects) {
|
||||
this.pages = pages.sort((a, b) => a.link.toString().localeCompare(b.link.toString()));
|
||||
this.redirects = redirects;
|
||||
|
||||
this._coerceWikis();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the state of this network such that there are no duplicate wikis.
|
||||
*
|
||||
* In particular, if there are two interwikis with the same URL but a different name, then one name will be chosen
|
||||
* and all instances of the other name will be removed from the wiki.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_coerceWikis() {
|
||||
const uniquePages = [];
|
||||
const duplicatePages = [];
|
||||
this.pages.forEach((page, i) => {
|
||||
if (this.pages.findIndex(it => it.urlEquals(page)) === i)
|
||||
uniquePages.push(page);
|
||||
else
|
||||
duplicatePages.push(page);
|
||||
});
|
||||
this.pages = uniquePages;
|
||||
|
||||
const renameLink = ((link, {from, to}) => {
|
||||
if (link.lang === from)
|
||||
return new InterlangLink(to, link.title);
|
||||
return link;
|
||||
});
|
||||
|
||||
duplicatePages
|
||||
.map(page => ({
|
||||
from: page.link.lang,
|
||||
to: uniquePages.find(it => it.urlEquals(page)).link.lang
|
||||
}))
|
||||
.forEach(rename => {
|
||||
this.redirects = this.redirects.map(redirect =>
|
||||
new Redirect(renameLink(redirect.from, rename), renameLink(redirect.to, rename)));
|
||||
this.pages.forEach(page => page.langLinks = page.langLinks.map(it => renameLink(it, rename)));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given source links to the given destination, potentially through a redirect.
|
||||
*
|
||||
* @param source {Page} the source page of which to check the links
|
||||
* @param destination {Page} the destination that could be linked to
|
||||
* @returns {"present"|"absent"|"redirect"} the status of the link
|
||||
*/
|
||||
checkIfLinksTo(source, destination) {
|
||||
if (source.langLinks.some(it => it.equals(destination.link)))
|
||||
return "present";
|
||||
|
||||
if (source.langLinks.some(link => this.redirects.some(it => it.equals(new Redirect(link, destination.link)))))
|
||||
return "redirect";
|
||||
|
||||
return "absent";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Interacts with the API in an asynchronous manner.
|
||||
|
|
Loading…
Reference in New Issue