LLWiki正在建设中,欢迎加入我们

User:Bhsd/photrans.js

来自LLWiki
跳转到导航 跳转到搜索

注意:在保存之后,您可能需要清除浏览器缓存才能看到所作出的变更的影响。

  • Firefox或Safari:按住Shift的同时单击刷新,或按Ctrl-F5Ctrl-R(Mac为⌘-R
  • Google Chrome:Ctrl-Shift-R(Mac为⌘-Shift-R
  • Internet Explorer:按住Ctrl的同时单击刷新,或按Ctrl-F5
  • Opera:前往菜单 → 设置(Mac为Opera → Preferences),然后隐私和安全 → 清除浏览数据 → 缓存的图片和文件
//<nowiki>
(() => {
let dialog;
$('.Lyrics_box').on('contextmenu', '.Lyrics_original', e => {
    e.preventDefault();
    const selection = getSelection(),
        node = selection.anchorNode,
        offset = selection.anchorOffset,
        focus = selection.focusOffset;
    if (!node || selection.focusNode != node) { return; }
    switch (node.parentNode.nodeName) {
    case 'SPAN':
    case 'DIV':
        OO.ui.prompt('请输入注音:').then(str => {
            if (!str) { return; }
            const text = node.splitText(offset < focus ? offset : focus);
            text.splitText(offset < focus ? focus - offset : offset - focus);
            $(text).replaceWith( $('<ruby>', {html: [$('<rb>', {text: text.textContent}), $('<rt>', {text: str})]}) );
        });
        break;
    case 'RB':
        OO.ui.prompt('请输入注音:').then(str => {
            if (str) { $(node).closest( 'ruby' ).children( 'rt' ).text( str ); }
        });
    }
}).on('dblclick', '.Lyrics_original', e => {
    const message = $('<div>', {text: [...$(e.delegateTarget).find( '.Lyrics_original' ).map(function(i) {
        const node = this.cloneNode( true );
        // 以下所有replaceWith均使用vanilla JS,因为jQuery需要额外转义且不会立即执行
        [...node.getElementsByTagName( 'ruby' )].forEach(ele => {
            ele.replaceWith( `|${ ele.firstChild.textContent }_${ele.querySelector( 'rt' ).textContent}|` );
        });
        let color = false;
        [...node.children].forEach(ele => {
            let text = ele.textContent;
            if (text.includes( '_' )) {
                text = `{{photrans|${text}}}`.replace(/(\s+)/g, '}}$1{{photrans|').replaceAll('||', '|')
                    .replaceAll('|}}', '}}').replace(/{{photrans\|([^_]*?)}}/g, '$1').replaceAll('{{photrans}}', '');
            }
            if (ele.className) {
                color = true;
                ele.replaceWith( `@${[...ele.classList].filter(c => c.endsWith( '-lyrics' ))
                    .map(c => c.slice(0, -7)).join()
                }@${text}` );
            } else {
                ele.replaceWith( `${color ? '@@' : ''}${text}` );
                color = false;
            }
        });
        return node.textContent || (i === 0 ? '<nowiki/>' : '');
    })].join( '\n' ), contentEditable: true});
    if (!dialog) {
        dialog = new OO.ui.MessageDialog({id: 'photrans-dialog'});
        mw.loader.addStyleTag( '#photrans-dialog .oo-ui-messageDialog-message { white-space: pre-wrap; }' );
    }
    mw.dialog(dialog, [{label: '好的'}], message, '请复制以下代码', {size: 'large'});
}).attr('contentEditable', true);

let $div;
const $span = $('<span>', {contentEditable: true}),
    $handler = $('<div>').css({height: '1em', cursor: 'move'});
mw.photrans = (line) => {
    const lyrics = [...line.children].map(ele =>
        ele.innerHTML.replace(/<ruby>(.+)<rp>\[<\/rp><rt>(.+)<\/rt><rp>]<\/rp><\/ruby>/, '|$1_$2|')
    ).join( '' );
    if (!$div) {
        mw.loader.using( 'jquery.ui' ).then(() => {
            $div = $('<div>', {class: 'inspector-field', html: [$handler, $span.text( lyrics )]})
                .appendTo( document.body ).draggable({handle: $handler});
        });
    } else { $span.text( lyrics ); }
};
}) ();
//</nowiki>