操作性を見直して一部修正 

前ページの「巡回表示 / 選択置換」のコード変更は、かなりの前進と感じます。 細かな問題は、もっと突つかないと出て来ない時がありますが。

 

従来は検索を開始した位置を保存し、「検索文字」「置換文字」「置換チェック」と進んだ場合も、「Esc」などで「検索」前の状態に戻した際に、元の位置を表示する様にしていました。 当初は良い案に思ったのですが、「元の位置」へのジャンプは不要に思い始めました。

 

ジャンプを極力抑える 

現在のコードは「検索文字確定」以降の全ての操作で「巡回」が可能です。 巡回操作は文書の各所へ素早く移動できますが、これは便利な反面、ユーザーが文書のどの場所を見ているかが判り難くなります。

 

またこれまでのコードは、「ハイライト要素」を渡り歩く「フォーカス要素」が、「検索文字」「置換文字」「一括置換」「選択置換」の各プロセスでころころ変わり、「見ている場所の把握」をより邪魔します。

 

その反省から、ジャンプを極力減らし、「巡回表示」「置換チェック」「選択置換」などで「フォーカス要素」を移動させても、続く別プロセスにその位置が引き継がれる様にしました。 最初に検索を始めた場所に戻る機能は、ユーザーが想定しないジャンプになりかねないので廃止しました。

 

「フォーカス要素」のインデックス引継ぎを担うのが「native_hk」の変数です。スクリプト起動時と「検索文字」が未決定になった時は、「native_hk」に「-1」を設定して初期化し、他の場合は「フォーカス要素」のインデックスを保持します。

 

また、「選択置換」はインデックスを先頭に戻していましたが、これを廃止しました。 文書の最初に戻るのは「⇧」キーを使えば一瞬ですから、現在の場所をできるだけ勝手に変えない様に改めています。

 

これで、操作と表示される画面の統一感は、かなり良くなったと思います。

 

「置換チェック画面」のショートカット対策 

「置換チェック画面」は、「HTML表示」ボタンや「下書き」「全員に公開」等のボタンを押せなくする事、また「検索→置換」の段階で文書の編集を出来ない様にする事を目的としています。

 

この画面を作った段階より処理が改善して、現在は「HTML」を開いたり「公開」をしても、「ハイライト要素」「フォーカス要素」の「muタグ」が残ったままになる事はありません。 しかし「画像挿入」や「一部のスクリプトツール」を使った場合を意図的に実験すると、一時的に「怪しい状態」が生じる事があります。

 

やはり、「置換チェック画面」は必要という結果です。 ただ、ショートカット排除のコードを一部変更しました。

 

これまでは、「Ctrl」「Shift」「Alt」「Pause」「Tab」「Esc」のキーを触ると、「置換チェック画面」が終了する安全策でした。 しかし、「選択置換」の処理途中で「Ctrl」などに触れて、意図せずに「設定」が無化される可能性があります。

 

そこで、「UNDO」ボタンの代理キーとして「Esc」のみ残し、他は「無効」で何も生じないコードに変更しました。 これで、誤操作の危険は改善されます。

 

処理の流れとキー操作 

以下が現在の操作体系の纏めです。

 

検索・置換処理フロー図

 

◎「検索文字確定」以降の全てのプロセスで「巡回表示」が可能です。

「フォーカス要素」の移動操作は「⇦⇧⇩⇨」の方向キーを使います。 また、画面内をクリックしないホイール操作でスクロール可能です。

 

◎「置換チェック」以外のプロセスで、編集画面のクリックをすると「検索」処理は初期状態にリセットされます。

 

◎ 上記の状態で「Tab」キーを押すと「検索文字枠」にカーソルの復帰が可能です。

 

◎「選択置換」では「Space」キーで「置換設定」「置換設定キャンセル」を選択できます。

 

◎「置換チェック画面」で「OK」を押す事で、初めて「置換」が実行されます。

 

 

「S-R in Editor」 ver. 1.7 

「S-R in Editor」は、アメーバブログ編集画面専用の「検索 / 置換」ツールです。

「検索語入力」「TEXTヒット文字列の巡回」「HTMLコードの一括置換」「TEXTの一括置換」「TEXTの選択置換」「それぞれの置換チェック」「UNDO」が可能です。

 

Chrome版 / Firefox版の「Tampermonkey」の新規作成編集枠に、以下のスクリプトコードをコピー&ペーストする事で、このツールを利用することが出来ます。

 

〔コピー方法〕 軽量シンプルなツール「PreBox Button   」を使うと

  コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」

  の操作で、掲載コードのコピーが可能になります。

 

 

〔 S-R in Editor 〕 ver. 1.7

 

// ==UserScript==
// @name         S-R in Editor
// @namespace  http://tampermonkey.net/
// @version      1.7
// @description  通常編集枠で実行できる 検索 / 置換 ツール
// @author       Ameba Blog User
// @match        https://blog.ameba.jp/ucs/entry/srventry*
// @grant         none
// ==/UserScript==


window.addEventListener('load', function(){
    let p_flag; // Process
    let t_flag; // TEXT処理
    let count_t;
    let count_h;
    let buffer;
    let hk; // フォーカスしたハイライトのインデックス
    let native_hk;
    let editor_iframe;
    let iframe_doc;
    let iframe_html;
    let iframe_body;
    let js_cover;

    let search_box;
    let search_word;
    let search_word_es;
    let replace_box;
    let replace_word;
    let result_box;
    let s_1;
    let s_2;
    let s_3;
    let s_4;
    let s_5;

    let cke_1_contents=document.querySelector('#cke_1_contents'); // 監視 target
    let monitor=new MutationObserver(catch_key);
    monitor.observe(cke_1_contents, {childList: true}); // ショートカット待受け開始

    catch_key();


    function catch_key(){
        search_box=document.querySelector('#search_box');
        editor_iframe=document.querySelector('.cke_wysiwyg_frame');

        if(editor_iframe){ //「通常表示」の場合
            add_mu_style(); // mタグ用 styleをiframeに再設定

            search_box=document.querySelector('#search_box');
            if(search_box){
                search_box.disabled=false; }

            document.addEventListener("keydown", check_key); // documentは先に指定
            iframe_doc=editor_iframe.contentWindow.document;
            iframe_doc.addEventListener("keydown", check_key); // iframeは後に指定

            function check_key(event){
                if(event.ctrlKey==true){
                    if(event.keyCode==123){
                        event.preventDefault();
                        if(p_flag!=3){ // 置換チェック時でなければ「Ctrl+F12」でON/OFF
                            search_replace();
                            editor_iframe=document.querySelector('.cke_wysiwyg_frame');
                            if(!editor_iframe){
                                if_html(); }}}}
                if(event.keyCode==27){
                    if(p_flag==3){ // 置換チェック時に「Esc」で置換チェックを解除=UNDO
                        event.preventDefault();
                        out_p_flag3(); }}
                if(event.keyCode==9){
                    if(p_flag==0){ // 編集枠から「Tab」で検索に戻る
                        event.preventDefault();
                        search_box.focus(); }}
                if(event.keyCode==9 || event.keyCode==16 || event.keyCode==17 ||
                   event.keyCode==18 || event.keyCode==19){
                    if(p_flag==3){ // 置換チェック時に「Shift/Ctrl/Alt/Pause」を無効化
                        event.preventDefault(); }}}}

        else{ //「HTML表示」の場合
            if_html(); }


        function out_p_flag3(){ // 置換チェックを解除する
            js_cover.style.display='none';
            cke_1_contents.style.zIndex='0';
            if(iframe_body){
                iframe_body.contentEditable='true'; } // 編集可能にする
            iframe_body.innerHTML=buffer; // 置換処理をUNDO ⏹
            search_box.disabled=false;
            replace_box.disabled=false;
            s_2.style.display='none';
            s_3.style.display='none';
            s_4.style.display='none';
            s_5.style.display='none';
            replace_box.focus();
            if(t_flag==1 || t_flag==2){ //「buffer」を戻したので再度ハイライト表示
                t_flag=1;
                let rep_word='<mu>'+ search_word +'</mu>';
                iframe_body.innerHTML=
                    iframe_body.innerHTML.replace(new RegExp(search_word_es, 'g'), rep_word); // 🔳 RegExp
                next(hk); } // UNDO時の巡回表示
            p_flag=2; } // 2=置換入力

        function if_html(){ //「HTML表示」を開いた場合のクローズ処理
            if(search_box){
                search_box.disabled=true; }
            result_box.textContent=' ';
            s_1.style.display='none';
            replace_box.style.display='none';
            replace_box.value='';
            s_2.style.display='none';
            s_3.style.display='none';
            s_4.style.display='none';
            s_5.style.display='none';
            t_flag=0;
            p_flag=0; }
    } // catch_key


    function search_replace(){
        let i_body=document.querySelector('body.l-body');
        editor_iframe=document.querySelector('.cke_wysiwyg_frame');
        if(editor_iframe){ //「通常表示」の場合
            iframe_doc=editor_iframe.contentWindow.document;
            iframe_html=iframe_doc.querySelector('html');
            iframe_body=iframe_doc.querySelector('.cke_editable'); }

        let css=
            '#s_container {position: fixed; top: 12px; left: calc(50% - 490px); '+
            'background: #fff; border: 1px solid #aaa; border-radius: 4px; '+
            'padding: 6px 15px; min-width: 948px; z-index: 11;}'+
            '#search_box {width: 215px;} #replace_box {width: 215px; display: none;}'+
            '::placeholder {font-size: 15px; color: #bbb;}'+
            '#s_container input:disabled {color: #000; background: #eef1f3;}'+
            '#s_container input {font-size: 16px; padding: 2px 6px 0; -moz-appearance: none;}'+
            '#result {display: inline-block; min-width: 50px; padding: 4px 6px 2px; '+
            'margin-left: 5px; border: 1px solid #aaa; font-size: 16px;}'+
            '.s_sw {display: inline-block; vertical-align: -9px; font-size: 15px; '+
            'padding: 5px 8px 2px; border: 1px solid #aaa; overflow: hidden;}'+
            '.s_1 {margin: 0 15px; min-width: 4em; display: none;}'+
            '.s_2, .s_3, .s_4 {margin-left: 5px; color:#fff; background: #1e88e5; '+
            'cursor: pointer; display: none;}'+
            '.s_4 {margin-left: 15px; box-shadow: inset -45px 0 0 0 #b0bec5;}'+
            '.s_5 {margin-left: 5px; position: fixed; top: 70px; right: calc(50% - 490px); width: 155px; '+
            'padding: 7px 15px 4px 25px; border-radius: 4px; background: #e3f2fd; display: none;}'+
            '.js_cover {position: fixed; top: 0; width: 100%; height: 100%; '+
            'background: rgba(0, 0, 0, .6); z-index: 10; display: none;}';

        let style_tag=document.createElement("style"); // css設定styleタグ
        style_tag.type="text/css";
        style_tag.setAttribute("class", "ep");
        style_tag.appendChild(iframe_doc.createTextNode(css));
        if(i_body.querySelector('.ep')){
            i_body.querySelector('.ep').remove(); }
        i_body.appendChild(style_tag);

        js_cover=document.createElement("div"); // クリック操作のブロックカバー
        js_cover.setAttribute("class", "js_cover");
        if(i_body.querySelector('.js_cover')){
            i_body.querySelector('.js_cover').remove(); }
        document.querySelector('#js-container').appendChild(js_cover);


        let s_container=document.querySelector('#s_container');
        if(!s_container){ //#s_containerが無い場合 生成して開始
            let insert_node_d=document.createElement('div');
            insert_node_d.setAttribute('id', 's_container');
            i_body.appendChild(insert_node_d);
            insert_node_d.innerHTML=
                '<input id="search_box" placeholder=" 検索文字" autocomplete="off">'+
                '<span id="result"> </span>'+
                '<span class="s_sw s_1"> </span>'+
                '<input id="replace_box" placeholder=" 置換文字" autocomplete="off">'+
                '<span class="s_sw s_2">OK</span>'+
                '<span class="s_sw s_3">UNDO</span>'+
                '<span class="s_sw s_4">一括 選択</span>'+
                '<span class="s_sw s_5">⇦⇧⇩⇨:移動<br>'+
                'Space:設定 / 解除<br>OK:置換を確定する<br>UNDO:全て元に戻す</span>';

            search_box=document.querySelector('#search_box');
            result_box=document.querySelector('#result');
            replace_box=document.querySelector('#replace_box');
            s_1=document.querySelector('.s_1');
            s_2=document.querySelector('.s_2');
            s_3=document.querySelector('.s_3');
            s_4=document.querySelector('.s_4');
            s_5=document.querySelector('.s_5');


            p_flag=0; // 0=検索文字 未確定
            search_box.focus();
            search_box.onkeydown=function(event){ // 🔽 検索ツール操作の開始点
                if(event.keyCode==13){
                    if(p_flag==0){
                        event.preventDefault();
                        search_word=search_box.value; // 🟥 検索文字取得
                        native_hk=-1; // 初期化🅿
                        get_search();
                        rbox_disp(); }
                    else if(p_flag==1){
                        event.preventDefault();
                        if(search_box.value==search_word){
                            replace_box.style.display='inline-block';
                            replace_box.focus();
                            all_replace();
                            p_flag=2; } // 巡回ループを抜けて 置換入力へ
                        else{
                            iframe_body.innerHTML=buffer; // highlight を抜ける時はリセット ⏹
                            search_word=search_box.value; // 🟥 検索文字取得 変更
                            native_hk=-1; // 初期化🅿
                            result_box.textContent='⏎';
                            s_1.style.display='none';
                            p_flag=0; // 巡回ループを抜けて 検索文字 未確定へ
                            search_box.dispatchEvent( new KeyboardEvent( "keydown", {keyCode: 13})); }}}
                if(event.keyCode==9){ //「Tab」で置換入力へ
                    if(p_flag==0){
                        event.preventDefault(); } //「Tab」で入力枠外に出るのを抑止
                    else if(p_flag==1){
                        event.preventDefault();
                        replace_box.style.display='inline-block';
                        replace_box.focus();
                        all_replace();
                        p_flag=2; }} // 巡回ループを抜ける
                if(event.keyCode==27 ){ //「Esc」
                    if(p_flag==1 && t_flag==1){ //「巡回」表示をリセット
                        event.preventDefault();
                        result_box.textContent='T:'+count_t+'│-';
                        iframe_body.innerHTML=buffer; // highlight を抜ける時はリセット ⏹
                        p_flag=0; }}}

            search_box.onchange=function(){ //「Enter」を押さず移動した場合は検索語を再表示
                if(search_box.value!==search_word){
                    search_box.style.outline='2px solid #2196f3';
                    search_box.style.outlineOffset='-3px';
                    setTimeout(()=>{
                        search_box.style.outline='none';
                        search_box.value=search_word; }, 500); }}


            function get_search(){
                search_word_es=escapeRegExp(search_word); // 🔳 RegExp

                editor_iframe=document.querySelector('.cke_wysiwyg_frame'); // ここで取得
                if(editor_iframe){ //「通常表示」が実行条件
                    iframe_doc=editor_iframe.contentWindow.document;
                    iframe_body=iframe_doc.querySelector('.cke_editable');
                    buffer=iframe_body.innerHTML; // ハイライト表示のためソースコードを保存 🟦
                    let childs=searchNodes(iframe_body);
                    count_t=0; // テキストノードのヒット数
                    let result_t
                    for(let k=0; k<childs.length; k++){
                        if(childs[k].nodeType==3){
                            result_t=childs[k].textContent.match(new RegExp(search_word_es, 'g')); // 🔳 RegExp
                            if(result_t){
                                count_t+=result_t.length; }}}
                    count_h=0; // HTMLソース全体のヒット数
                    let result_h=iframe_body.innerHTML.match(new RegExp(search_word_es, 'g')); // 🔳 RegExp
                    if(result_h){
                        count_h=result_h.length; }}

                function searchNodes(root){ // 全子孫ノードリストを作成
                    var list=[];
                    var search=function (node){
                        while (node !=null){
                            list.push(node);
                            search(node.firstChild);
                            node=node.nextSibling; }}
                    search(root.firstChild);
                    return list; }}


            function rbox_disp(){
                t_flag=0; // t_flag リセット
                search_box.disabled=false;
                replace_box.disabled=false;
                s_1.style.display='inline-block';
                s_2.style.display='none';
                s_3.style.display='none';
                replace_box.style.display='none';
                replace_box.value='';

                if(count_t!=0 && count_h-count_t==0){
                    s_1.textContent='TEXT処理';
                    s_1.style.color='#000';
                    t_flag=1; // TEXT処理
                    p_flag=1; // 1=検索文字確定 処理開始
                    let rep_word='<mu>'+ search_word +'</mu>';
                    iframe_body.innerHTML=
                        iframe_body.innerHTML.replace(new RegExp(search_word_es, 'g'), rep_word); // 🔳 RegExp
                    next(hk); }

                if(count_t!=0 && count_h-count_t!=0){
                    result_box.textContent='T:'+count_t+' H:'+(count_h-count_t);
                    s_1.textContent='処理不能';
                    s_1.style.color='red';
                    p_flag=0; } // 0=検索文字未確定 検索前

                if(count_t==0 && count_h-count_t!=0){
                    result_box.textContent='H:'+(count_h-count_t);
                    s_1.textContent='HTML処理';
                    s_1.style.color='#000';
                    p_flag=1; // 1=検索文字確定 処理開始
                    all_replace(); }

                if(count_t==0 && count_h-count_t==0){
                    result_box.textContent='T:'+count_t+' H:'+(count_h-count_t);
                    s_1.textContent=' - - - ';
                    s_1.style.color='#000';
                    p_flag=0; } // 0=検索文字未確定 検索前

                search_box.onblur=function(){ //「検索枠」が focusを無くしたらリセット
                    setTimeout( ()=>{
                        if(replace_box.style.display=='none'){ //「置換」へ移動は除外
                            stop_out(); }}, 10); }

                replace_box.onblur=function(){ //「置換枠」が focusを無くしたらリセット
                    setTimeout( ()=>{
                        if(p_flag!=3){ //「置換確認画面」へ移行は除外
                            stop_out(); }}, 10); }

                function stop_out(){
                    if(p_flag==1 || p_flag==2){ // 1=検索文字入力枠 2=置換文字入力枠
                        if(t_flag==1 || t_flag==2){
                            result_box.textContent='T:'+count_t+'│-'; }
                        else{
                            result_box.textContent='H:'+(count_h-count_t); }
                        s_1.style.display='none';
                        replace_box.style.display='none';
                        replace_box.value='';
                        iframe_body.innerHTML=buffer; // highlight を抜ける時はリセット ⏹
                        native_hk=-1; // 初期化🅿
                        t_flag=0;
                        p_flag=0; }}} // rbox_disp()


            function all_replace(){ // 置換処理全般
                replace_box.focus();
                all_roop();

                function all_roop(){
                    replace_box.onkeydown=function(event){ // 🔽 置換操作の開始点
                        if(event.keyCode==13){
                            event.preventDefault();
                            replace_word=replace_box.value; // 🟥 置換文字取得
                            iframe_body.innerHTML=
                                iframe_body.innerHTML.replace(new RegExp(search_word_es, 'g'), replace_word); // 🔳 RegExp
                            if(t_flag==1 && p_flag==2){
                                next(hk); } //「一括置換」の「巡回表示」
                            js_cover.style.display='block';
                            cke_1_contents.style.zIndex='11';
                            iframe_body.contentEditable='false'; // 編集不可にする
                            search_box.disabled=true;
                            replace_box.disabled=true;
                            s_2.style.display='inline-block';
                            s_3.style.display='inline-block';
                            if(t_flag==1){
                                s_4.textContent='一括 選択';
                                s_4.style.display='inline-block';
                                s_4.style.boxShadow='inset -45px 0 0 0 #b0bec5'; }
                            p_flag=3; } // 3=置換処理

                        if(event.keyCode==9 || event.keyCode==27){ //「Tab」「Esc」で処理前に戻る
                            event.preventDefault();
                            result_box.textContent=' ';
                            s_1.style.display='none';
                            replace_box.style.display='none';
                            replace_box.value='';
                            if(t_flag==1){
                                iframe_body.innerHTML=buffer; } // 置換処理をUNDO ⏹
                            search_box.focus();
                            p_flag=0; }} // 0=検索文字 未確定

                    s_2.onclick=function(){ //「OK」ボタンで一括置換確定
                        cover_remove();
                        delete_mu(); // muタグを削除
                        result_box.textContent=' '; // 検索結果は変更される
                        s_1.style.display='none';
                        replace_box.style.display='none';
                        replace_box.value='';
                        search_box.focus();
                        native_hk=-1; // 初期化🅿
                        t_flag=0;
                        p_flag=0; } // 0=検索文字 未確定

                    s_3.onclick=function(){ //「UNDO」ボタン
                        cover_remove();
                        iframe_body.innerHTML=buffer; // 置換処理をUNDO ⏹
                        replace_box.focus();
                        if(t_flag==1 || t_flag==2){
                            t_flag=1;
                            let rep_word='<mu>'+ search_word +'</mu>';
                            iframe_body.innerHTML=
                                iframe_body.innerHTML.replace(new RegExp(search_word_es, 'g'), rep_word); // 🔳 RegExp
                            next(hk); } // UNDO時は「一括置換」の「巡回表示」
                        p_flag=2; } // 2=検索文字確定 置換文字入力 処理選択

                    s_4.onclick=function(){ //「一括・選択」ボタン
                        if(t_flag==1){
                            t_flag=2; //「選択置換」を指定
                            s_4.textContent='選択置換';
                            s_4.style.boxShadow='none';
                            s_5.style.display='inline-block';
                            select_replace(); }
                        else if(t_flag==2){ ; } //「一括置換」に戻るのは「OK」「UNDO」以外は不可

                        s_4.addEventListener('mouseover', ()=>{
                            if(t_flag==2){
                                s_5.innerHTML='「OK」「UNDO」で\u2000<br>\u2000置換チェック画面を'+
                                    '<br>\u2000終了してください';
                            }}, false);

                        s_4.addEventListener('mouseleave', ()=>{
                            if(t_flag==2){
                                s_5.innerHTML='⇦⇧⇩⇨:移動<br>'+
                                    'Space:設定 / 解除<br>OK:置換を確定する<br>UNDO:全て元に戻す';
                            }}, false); }

                    function cover_remove(){
                        js_cover.style.display='none';
                        cke_1_contents.style.zIndex='0';
                        iframe_body.contentEditable='true'; // 編集可能にする
                        search_box.disabled=false;
                        replace_box.disabled=false;
                        s_2.style.display='none';
                        s_3.style.display='none';
                        s_4.style.display='none';
                        s_5.style.display='none'; }} // all_roop()
            } // all_replace()


            function select_replace(){ //「選択置換処理」
                if(t_flag==2 && p_flag==3){
                    iframe_body.innerHTML=buffer; // 置換処理を一旦デフォルトに戻す ⏹
                    let rep_word='<mu>'+ search_word +'</mu>';
                    iframe_body.innerHTML=
                        iframe_body.innerHTML.replace(new RegExp(search_word_es, 'g'), rep_word); // 🔳 RegExp
                    let mark=iframe_body.querySelectorAll('mu');
                    next(hk); //「選択置換」の「巡回表示」
                }} // select_replace()

        } // #s_container が無い場合「Ctrl+F12」で開始

        else{ // #s_container がある場合は「Ctrl+F12」で終了  「muタグを削除」
            delete_mu();
            document.querySelector('#s_container').remove();
            native_hk=-1; } // 初期化🅿
    } // search_replace()



    function next(hk){ //「巡回表示」「選択置換」コード
        let mark=iframe_body.querySelectorAll('mu');

        if(native_hk==-1 || !native_hk){ // 初期インデックス生成🅿
            if(t_flag==1){
                if(mark.length==1){ hk=0; } // 1個なら即決定
                else{
                    let near_n; // 中央後方の要素のインデックス
                    let editor_hight=editor_iframe.clientHeight; // 編集枠の高さ
                    for(let k=1; k<mark.length; k++){ // スクロール位置中央を越えるmark[k]を取得
                        if(mark[k].getBoundingClientRect().top>editor_hight/2){
                            near_n=k;
                            break; }}
                    if(!near_n){ // スクロール位置中央より後方にmark[k]がない場合
                        hk=mark.length-1; }
                    else{ // 直前の mark[k]と比較して、近い方を採る
                        if(mark[near_n].getBoundingClientRect().top>
                           editor_hight-mark[near_n-1].getBoundingClientRect().top){
                            hk=near_n-1; }
                        else{
                            hk=near_n; }}}}}
        else if(native_hk!=-1){ // 基本的に前回のインデックスを再現🅿
            hk=native_hk; }

        view(hk);
        mark[hk].classList.add("h"); // 最初のハイライト色を変更
        result_box.textContent='T:'+count_t+'│'+(hk+1);

        document.addEventListener("keydown", check_key); // documentは先に指定
        iframe_doc=editor_iframe.contentWindow.document;
        iframe_doc.addEventListener("keydown", check_key); // iframeは後に指定

        function check_key(event){
            if(event.keyCode==37 || event.keyCode==38){ //「←」「↑」
                if(p_flag>0 && t_flag>0){
                    event.preventDefault();
                    if(hk>0){ // 標準のハイライト色に戻す
                        mark[hk].classList.remove("h");
                        hk-=1; }
                    else if(hk==0){
                        hk=0; }
                    result_box.textContent='T:'+count_t+'│'+(hk+1);
                    mark[hk].classList.add("h");
                    view(hk); }}
            if(event.keyCode==39 || event.keyCode==40){ //「→」「↓」
                if(p_flag>0 && t_flag>0){
                    event.preventDefault();
                    if(hk<mark.length-1){ // 標準のハイライト色に戻す
                        mark[hk].classList.remove("h");
                        hk+=1; }
                    else if(hk==mark.length-1){
                        hk=mark.length-1; }
                    result_box.textContent='T:'+count_t+'│'+(hk+1);
                    mark[hk].classList.add("h");
                    view(hk); }}

            if(event.keyCode==32){ //「Space」で個別に置換の設定/解除
                if(p_flag==3 && t_flag==2){
                    event.preventDefault();
                    if(mark[hk].textContent==search_word){
                        mark[hk].textContent=replace_word; }
                    else if(mark[hk].textContent==replace_word){
                        mark[hk].textContent=search_word; }}}

            native_hk=hk; }} // next() インデックス取得🅿


    function view(hk){
        let i_body=document.querySelector('body.l-body');
        let mark=iframe_body.querySelectorAll('mu');
        mark[hk].scrollIntoView({block: "center"});
        iframe_html.scrollBy(0, -12); // -1~-24  -12がクリープを無くす最適値
        i_body.scrollIntoView(); }


    function add_mu_style(){
        editor_iframe=document.querySelector('.cke_wysiwyg_frame');
        if(editor_iframe){ //「通常表示」の場合
            iframe_doc=editor_iframe.contentWindow.document;
            iframe_html=iframe_doc.querySelector('html');

            let css_iframe='.cke_editable mu {background: #ffcc00;} '+
                '.cke_editable mu.h { background: #85ff00; }'; // muタグの背景色指定

            let style_tag_iframe=iframe_doc.createElement("style");
            style_tag_iframe.type="text/css";
            style_tag_iframe.setAttribute("class", "ep");
            style_tag_iframe.appendChild(document.createTextNode(css_iframe));
            if(iframe_html.querySelector('.ep')){
                iframe_html.querySelector('.ep').remove(); }
            iframe_html.appendChild(style_tag_iframe); }}


    function delete_mu(){
        editor_iframe=document.querySelector('.cke_wysiwyg_frame');
        if(editor_iframe){ //「通常表示」の場合
            iframe_doc=editor_iframe.contentWindow.document;
            iframe_body=iframe_doc.querySelector('.cke_editable');
            if(iframe_body){
                let mark=iframe_body.querySelectorAll('mu');
                if(mark.length!=0){
                    iframe_body.innerHTML=
                        iframe_body.innerHTML.replace(new RegExp('<mu.*?>', 'g'), '' ); }}}} // 🔳 RegExp


    function escapeRegExp(string){
        let reRegExp=/[\\^$.*+?()[\]{}|]/g;
        let reHasRegExp=new RegExp(reRegExp.source);
        return (string && reHasRegExp.test(string))
            ? string.replace(reRegExp, '\\$&')
        : string; }

});

 

 

 

「S-R in Editor ⭐」最新版について 

旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。

 

●「S-R in Editor ⭐」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。