mediawiki-extensions-Discus.../modules/modifier.js
Ed Sanders ccbbf386d2 Live preview
Change-Id: I1654e95e94686b27818cbc465d5a9e8600404634
2019-12-12 23:59:24 +00:00

88 lines
2.3 KiB
JavaScript

/* global $:off */
'use strict';
/**
* Adapted from MDN polyfill (CC0)
* https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
*
* @param {HTMLElement} el
* @param {string} selector
* @return {HTMLElement|null}
*/
function closest( el, selector ) {
var matches;
el = el.nodeType === Node.ELEMENT_NODE ? el : el.parentElement;
if ( Element.prototype.closest ) {
return el.closest( selector );
}
matches = Element.prototype.matches ||
Element.prototype.msMatchesSelector ||
Element.prototype.webkitMatchesSelector;
do {
if ( matches.call( el, selector ) ) {
return el;
}
el = el.parentElement || el.parentNode;
} while ( el !== null && el.nodeType === 1 );
return null;
}
function addListAtComment( comment ) {
var list, listType, lastReply, listItem, endNodeInAncestor,
tsNode = comment.range.endContainer;
if ( comment.replies.length ) {
lastReply = comment.replies[ comment.replies.length - 1 ];
list = closest( lastReply.range.endContainer, 'dl, ul, ol' );
} else {
listItem = closest( tsNode, 'li, dd' );
if ( listItem ) {
listType = closest( listItem, 'dl, ul, ol' ).tagName;
list = document.createElement( listType );
listItem.appendChild( list );
} else {
endNodeInAncestor = comment.range.endContainer;
while ( endNodeInAncestor.parentNode !== comment.range.commonAncestorContainer ) {
endNodeInAncestor = endNodeInAncestor.parentNode;
}
list = document.createElement( 'dl' );
comment.range.commonAncestorContainer.insertBefore(
list,
endNodeInAncestor.nextSibling
);
}
}
return list;
}
function addListItem( list ) {
var listItem = document.createElement( list.nodeName.toLowerCase() === 'dl' ? 'dd' : 'li' );
// HACK: Setting data-parsoid removes the whitespace after the list item,
// which makes nested lists work.
// This is undocumented behaviour and probably very fragile.
listItem.setAttribute( 'data-parsoid', '{}' );
list.appendChild( listItem );
return listItem;
}
function createWikitextNode( wt ) {
var span = document.createElement( 'span' );
span.setAttribute( 'typeof', 'mw:Transclusion' );
span.setAttribute( 'data-mw', JSON.stringify( { parts: [ wt ] } ) );
return span;
}
module.exports = {
closest: closest,
addListAtComment: addListAtComment,
addListItem: addListItem,
createWikitextNode: createWikitextNode
};