Content deleted Content added
(bot/CD) |
(bot/CD) |
||
Line 51:
*//*!
* @package @chlodalejandro/parsoid
* @version 2.0.
* @license MIT
* @author Chlod Alejandro
Line 344:
has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),
}));
var version = "0.4.2";
var gitAbbrevHash = "7cb48de";
var gitBranch = "main";
var gitDate = "Mon, 28 Aug 2023 12:20:43 +0800";
var gitVersion = "0.4.2+g7cb48de";
/**
Line 355 ⟶ 361:
var _a;
return (_a = this._action) !== null && _a !== void 0 ? _a : (this._action = new mw.Api({
ajax: {
headers: {
'Api-User-Agent': `Deputy/${version} (https://w.wiki/5k$q; User:Chlod; wiki@chlod.net)`
}
},
parameters: {
format: 'json',
Line 373 ⟶ 384:
}
}
MwApi.USER_AGENT = `Deputy/${version} (https://w.wiki/5k$q; User:Chlod; wiki@chlod.net)`;
/**
Line 3,661 ⟶ 3,673:
});
}
/**
Line 9,775 ⟶ 9,781:
* Encodes text for an API parameter. This performs both an encodeURIComponent
* and a string replace to change spaces into underscores.
* @param {string} text
* @
*/
function encodeAPIComponent(text) {
Line 9,784 ⟶ 9,789:
/**
* Clones a regular expression.
* @param regex The regular expression to clone.
* @
*/
function cloneRegex(regex) {
Line 9,796 ⟶ 9,800:
*/
class ParsoidTransclusionTemplateNode {
/**
* Creates a new ParsoidTransclusionTemplateNode. Can be used later on to add a template
* into wikitext. To have this node show up in wikitext, append the node's element (using
* {@link ParsoidTransclusionTemplateNode.element}) to the document of a ParsoidDocument.
* @param document The document used to generate this node.
* @param template The template to create. If you wish to generate wikitext as a block-type
Line 9,828 ⟶ 9,810:
* @param parameters The parameters to the template.
* @param autosave
* @
*/
static fromNew(document, template, parameters, autosave) {
Line 9,855 ⟶ 9,837:
}));
return new ParsoidTransclusionTemplateNode(document, el, data, data.i, autosave);
}
/**
* Create a new ParsoidTransclusionTemplateNode.
* @param {ParsoidDocument} parsoidDocument
* The document handling this transclusion node.
* @param {HTMLElement} originalElement
* The original element where the `data-mw` of this node is found.
* @param {*} data
* The `data-mw` `part.template` of this node.
* @param {number} i
* The `i` property of this node.
* @param {boolean} autosave
* Whether to automatically save parameter and target changes or not.
*/
constructor(parsoidDocument, originalElement, data, i, autosave = true) {
this.parsoidDocument = parsoidDocument;
this.element = originalElement;
this.data = data;
this.i = i;
this.autosave = autosave;
}
/**
* Gets the target of this node.
* @returns {object} The target of this node, in wikitext and href (for links).
*/
getTarget() {
Line 9,866 ⟶ 9,867:
/**
* Sets the target of this template (in wikitext).
* @param {string} wikitext
* The target template (in wikitext, e.g. `Test/{{FULLPAGENAME}}`).
Line 9,886:
/**
* Gets the parameters of this node.
* @returns {{[key:string]:{wt:string}}} The parameters of this node, in wikitext.
*/
getParameters() {
Line 9,894 ⟶ 9,893:
/**
* Checks if a template has a parameter.
* @param {string} key The key of the parameter to check.
* @
*/
hasParameter(key) {
Line 9,903 ⟶ 9,901:
/**
* Gets the value of a parameter.
* @param {string} key The key of the parameter to check.
* @
*/
getParameter(key) {
Line 9,914 ⟶ 9,911:
* Sets the value for a specific parameter. If `value` is null or undefined,
* the parameter is removed.
* @param {string} key The parameter key to set.
* @param {string} value The new value of the parameter.
Line 9,931 ⟶ 9,927:
/**
* Removes a parameter from the template.
* @param key The parameter key to remove.
*/
Line 9,958 ⟶ 9,953:
* Removes this node from its element. This will prevent the node from being saved
* again.
* @param eraseLine For block templates. Setting this to `true` will also erase a newline
* that immediately succeeds this template, if one exists. This is useful in ensuring that
Line 10,022 ⟶ 10,016:
*/
class ParsoidDocument extends EventTarget {
/**
* Create a new ParsoidDocument instance from a page on-wiki.
* @param {string} page The page to load.
* @param {
* @param {boolean} options.reload
* Whether the current page should be discarded and reloaded.
Line 10,092 ⟶ 10,032:
/**
* Create a new ParsoidDocument instance from plain HTML.
* @param {string} page The name of the page.
* @param {string} html The HTML to use.
Line 10,108 ⟶ 10,047:
/**
* Creates a new ParsoidDocument from a blank page.
* @param {string} page The name of the page.
* @param restBaseUri
Line 10,119 ⟶ 10,057:
/**
* Creates a new ParsoidDocument from wikitext.
* @param {string} page The page of the document.
* @param {string} wikitext The wikitext to load.
Line 10,130 ⟶ 10,067:
}
/**
*
* Extend this class to modify this.
* @protected
*/
getRequestOptions() {
return {
headers: {
'Api-User-Agent': 'parsoid-document/2.0.0 (https://github.com/ChlodAlejandro/parsoid-document; chlod@chlod.net)'
}
};
}
/**
* @returns `true` if the page is a redirect. `false` if otherwise.
*/
get redirect() {
return this.document &&
this.document.querySelector("[rel='mw:PageProp/redirect']") !== null;
}
/**
* Create a new ParsoidDocument instance.
*/
constructor() {
super();
this.iframe = document.createElement('iframe');
Object.assign(this.iframe.style, {
width: '0',
height: '0',
border: '0',
position: 'fixed',
top: '0',
left: '0'
});
this.iframe.addEventListener('load', () => {
if (this.iframe.contentWindow.document.___URL === 'about:blank') {
// Blank document loaded. Ignore.
return;
}
/**
* The document of this ParsoidDocument's IFrame.
* @type {Document}
* @protected
*/
this.document = this.iframe.contentWindow.document;
this.$document = $(this.document);
this.setupJquery(this.$document);
this.buildIndex();
if (this.observer) {
// This very much assumes that the MutationObserver is still connected.
// Yes, this is quite an assumption, but should not be a problem during normal use.
// If only MutationObserver had a `.connected` field...
this.observer.disconnect();
}
this.observer = new MutationObserver(() => {
this.buildIndex();
});
this.observer.observe(this.document.getElementsByTagName('body')[0], {
// Listen for ALL DOM mutations.
attributes: true,
childList: true,
subtree: true
});
// Replace the page title. Handles redirects.
if (this.document.title) {
this.page = (mw === null || mw === void 0 ? void 0 : mw.Title) ?
new mw.Title(this.document.title).getPrefixedText() :
this.document.title;
}
});
document.getElementsByTagName('body')[0].appendChild(this.iframe);
}
/**
* Set up a JQuery object for this window.
* @param $doc The JQuery object to set up.
* @
*/
setupJquery($doc) {
Line 10,158:
/**
* Processes an element and extracts its transclusion parts.
* @param {HTMLElement} element Element to process.
* @
*/
function process(element) {
Line 10,185 ⟶ 10,184:
/**
* Notify the user of a document loading error.
* @param {Error} error An error object.
*/
Line 10,210 ⟶ 10,208:
/**
* Loads a wiki page with this ParsoidDocument.
* @param {string} page The page to load.
* @param {object} options Options for frame loading.
* @param {boolean} options.reload
* Whether the current page should be discarded and reloaded.
Line 10,220 ⟶ 10,216:
* @param options.restBaseUri
* A relative or absolute URI to the wiki's RESTBase root. This is
* `/api/rest_` by default, though the `window.restBaseRoot` variable
* can modify it.
* @param options.requestOptions
* Options to pass to the `fetch` request.
Line 10,226 ⟶ 10,224:
*/
async loadPage(page, options = {}) {
var _a, _b, _c;
if (this.document && options.reload !== true) {
throw new Error('Attempted to reload an existing frame.');
}
this.restBaseUri = (_a = options.restBaseUri) !== null && _a !== void 0 ? _a : restBaseRoot;
return fetch(`${this.restBaseUri}v1/page/html/${encodeAPIComponent(page)}?stash=true&redirect=${options.followRedirects !== false ? 'true' : 'false'}&t=${Date.now()}`, Object.assign(
cache: 'no-cache'
}, (_b =
.then((data) => {
/**
* The ETag of this iframe's content.
* @type {string}
*/
Line 10,257 ⟶ 10,254:
/**
* Load a document from wikitext.
* @param {string} page The page title of this document.
* @param {string} wikitext The wikitext to load.
Line 10,263 ⟶ 10,259:
*/
async loadWikitext(page, wikitext, restBaseUri) {
var _a;
this.restBaseUri = restBaseUri !== null && restBaseUri !== void 0 ? restBaseUri : restBaseRoot;
return fetch(`${this.restBaseUri}v1/transform/wikitext/to/html/${encodeAPIComponent(page)}?t=${Date.now()}`, Object.assign((_a = this.getRequestOptions()) !== null && _a !== void 0 ? _a : {}, {
cache: 'no-cache',
method: 'POST',
Line 10,273 ⟶ 10,270:
return formData;
})()
}))
.then((data) => {
/**
* The ETag of this iframe's content.
* @type {string}
*/
Line 10,289 ⟶ 10,285:
/**
* Load a document from HTML.
* @param {string} page The loaded page's name.
* @param {string} html The page's HTML.
Line 10,368 ⟶ 10,363:
/**
* Gets the `<section>` HTMLElement given a section ID.
* @param id The ID of the section
* @
*/
getSection(id) {
Line 10,377 ⟶ 10,371:
/**
* Finds a template in the loaded document.
* @param {string|RegExp} templateName The name of the template to look for.
* @param {boolean} hrefMode Use the href instead of the wikitext to search for templates.
* @
*/
findTemplate(templateName, hrefMode = false) {
Line 10,423 ⟶ 10,416:
* Finds the element with the "data-mw" attribute containing the element
* passed into the function.
* @param {HTMLElement} element
* The element to find the parent of. This must be a member of the
* ParsoidDocument's document.
* @
*/
findParsoidNode(element) {
Line 10,443 ⟶ 10,435:
* Get HTML elements that are associated to a specific Parsoid node using its
* `about` attribute.
* @param node The node to get the elements of
* @
*/
getNodeElements(node) {
Line 10,455 ⟶ 10,446:
* This effectively deletes an element, be it a transclusion set, file, section,
* or otherwise.
* @param element
*/
Line 10,471 ⟶ 10,461:
/**
* Converts the contents of this document to wikitext.
* @returns {Promise<string>} The wikitext of this document.
*/
async toWikitext() {
var _a;
// this.restBaseUri should be set.
let target = `${this.restBaseUri}v1/transform/html/to/wikitext/${encodeAPIComponent(this.page)}`;
Line 10,480 ⟶ 10,470:
target += `/${+(/(\d+)$/.exec(this.document.documentElement.getAttribute('about'))[1])}`;
}
return fetch(target, Object.assign(requestOptions, {
method: 'POST',
headers: Object.assign((_a = requestOptions.headers) !== null && _a !== void 0 ? _a : {}, { 'If-Match': this.fromExisting ? this.etag : undefined }),
body: (() => {
const data = new FormData();
Line 10,492 ⟶ 10,481:
return data;
})()
})).then((data) => data.text());
}
/**
* Get the {@link Document} object of this ParsoidDocument.
* @returns {Document} {@link ParsoidDocument#document}
*/
getDocument() {
Line 10,504 ⟶ 10,492:
/**
* Get the JQuery object associated with this ParsoidDocument.
* @returns {*} {@link ParsoidDocument#$document}
*/
getJQuery() {
Line 10,512 ⟶ 10,499:
/**
* Get the IFrame element of this ParsoidDocument.
* @returns {HTMLIFrameElement} {@link ParsoidDocument#iframe}
*/
getIframe() {
Line 10,520 ⟶ 10,506:
/**
* Get the page name of the currently-loaded page.
* @returns {string} {@link ParsoidDocument#page}
*/
getPage() {
Line 10,528 ⟶ 10,513:
/**
* Get the element index of this ParsoidDocument.
* @returns {{ [p: string]: HTMLElement[] }} {@link ParsoidDocument#elementIndex}
*/
getElementIndex() {
Line 10,536 ⟶ 10,520:
/**
* Check if this element exists on-wiki or not.
* @returns {boolean} {@link ParsoidDocument#fromExisting}
*/
isFromExisting() {
Line 10,546 ⟶ 10,529:
/**
* A blank Parsoid document, with a section 0.
* @type {string}
*/
Line 10,552 ⟶ 10,534:
/**
* The default document to create if a page was not found.
* @type {string}
*/
Line 10,777 ⟶ 10,758:
}
});
}
/**
* @inheritDoc
* @protected
*/
getRequestOptions() {
var _a, _b;
const ro = super.getRequestOptions();
return {
headers: {
'Api-User-Agent': `${MwApi.USER_AGENT} ${(_b = (_a = ro.headers) === null || _a === void 0 ? void 0 : _a['Api-User-Agent']) !== null && _b !== void 0 ? _b : ''}`
}
};
}
/**
Line 10,808 ⟶ 10,802:
return notices;
}
/**
* Find all notices which have rows using their 'href' fields.
*
* @return All found {@link RowedAttributionNotice}s
*/
findRowedNoticesByHref() {
return organize(this.findNotices().filter(v => v instanceof RowedAttributionNotice), (v) => v.node.getTarget().href);
|