by Sheepy
2021-06-23 13:43
//以下源碼實作 Froala Editor 的 <ruby> 支援。
// Froala Editor <ruby> support by Sheepy. Tested on editor version 3.1.0. // CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0/ ( () => { 'use strict'; const f = FroalaEditor; if ( f.COMMANDS.rubyBtn ) return; // Ruby button f.DefineIconTemplate( 'rubySvg', '<svg class="fr-svg" viewBox="0 0 24 24" style="fill:#333"><text y="22" x="6" font-size="18px">R</text><text y="6" x="5" font-size="8px">abc</text></svg>' ); f.DefineIcon( 'rubyIco', { template:'rubySvg' } ); f.RegisterCommand( 'rubyBtn', { title:'Ruby', icon:'rubyIco', callback: function () { this.rubyPlugin.showPopup() } } ); f.RegisterShortcut( 192, 'rubyBtn', '', '`' ); // Ruby popup f.POPUP_TEMPLATES.rubyPopup = '<div class="fr-link-insert-layer fr-layer" style="display:block"><div class="fr-input-line"><input id="fr-ruby-rt" type="text" class="fr-link-attr" tabindex="1"><label for="fr-ruby-rt">Annotation</label></div><div class="fr-input-line"><input id="fr-ruby" type="text" class="fr-link-attr"><label for="fr-ruby">Text</label></div><div class="fr-action-buttons"><button id="fr-ruby-add" class="fr-command fr-submit" type="button">Insert</button></div></div>'; f.PLUGINS.rubyPlugin = function ( editor ) { const { format, html, popups, selection } = editor; function qs ( e, query = '' ) { return ( query ? e : document ).querySelector( query || e ); } function getRubyInput () { return qs( '#fr-ruby-rt' ); } function getTextInput () { return qs( '#fr-ruby' ); } function getAddButton () { return qs( '#fr-ruby-add' ); } function showPopup () { if ( ! popups.get( 'rubyPopup' ) ) { popups.create( 'rubyPopup' ); popups.onRefresh( 'rubyPopup', refreshPopup ); getAddButton().addEventListener( 'click', () => { hidePopup(); insert( getRubyInput().value, getTextInput().value ); } ); } popups.setContainer( 'rubyPopup', editor.$tb ); popups.refresh( 'rubyPopup' ); const btn = editor.$tb.find( '.fr-command[data-cmd="rubyBtn"]' ); const top = btn.offset().top + ( editor.opts.toolbarBottom ? 10 : btn.outerHeight() - 10 ); popups.show( 'rubyPopup', btn.offset().left, top, btn.outerHeight() ); getRubyInput().select(); } function hidePopup () { popups.hide('rubyPopup') }; function refreshPopup () { function setValue ( sel, val ) { sel.value = val; sel.classList[ val ? 'add' : 'remove' ]( 'fr-not-empty' ); } const r = selection.element().querySelector( 'rt' ); setValue( getRubyInput(), r ? r.textContent : '' ); setValue( getTextInput(), selection.text() ); } function insert ( rt, txt = null ) { const rprt = '<rp>(</rp><rt></rt><rp>)</rp>'; if ( txt === null ) txt = selection.text(); if ( ! txt ) return; if ( txt !== selection.text() ) { // Insert new text with or without ruby. const ruby = document.createElement( 'ruby' ); ruby.textContent = txt; if ( rt ) { ruby.insertAdjacentHTML( 'beforeend', rprt ); ruby.querySelector( 'rt' ).textContent = rt; } html.insert( ruby[ rt ? 'outerHTML' : 'innerHTML' ], false ); } else { // Remove old ruby. for ( let blk of selection.blocks() ) for ( let e of blk.querySelectorAll( 'rp, rt' ) ) e.remove(); format.remove( 'ruby' ); if ( rt === '' ) return; // Apply new ruby. format.apply( 'ruby' ); selection.element().insertAdjacentHTML( 'beforeend', rprt ); selection.element().querySelector( 'rt' ).textContent = rt; } } return { showPopup, hidePopup, insert, remove: () => insert( '' ) }; } } )();
//以下源碼會重整本站的發帖編輯器,加入 Ruby 按鍵。
( () => { const e = window.editor, ae = e.artEditor, { opts } = ae; opts.toolbarButtons[0].push( 'rubyBtn' ); opts.pluginsEnabled.push( 'rubyPlugin' ); ae.destroy(); e.artEditor = new FroalaEditor( "#artEditor", opts ); } )();