「記事デザイン」はHTML編集を開くと失調する
最近の編集環境で、HTML編集を開くとおかしな事になるのが目につきます。 3月に差し戻された更新編集画面は、HTML編集を一旦開いて通常表示に戻ると、全く無関係のリンクカードが分解する致命的なバグがありました。
それより少し前の2月中旬にリリースされた「記事デザイン」も、HTML編集に1度入ると「失調」する部分があります。 問題は軽微ですが、インターフェイスとしてはいまいちです。
テキスト部分の「自動選択」が無効になる
最初に編集パレットでデザインを選択してクリックすると、編集枠にデザイン枠が生成されます。 この時、「テキストを入力」というサンプルの文字列が反転選択された状態になっています。
反転表示で入力部が判り易くなり、この状態でキーボードから入力すると、「テキストを入力」の文字が消えます。 この反転選択の状態は「テキストを入力」の文字を消し易くする目的があるのかも知れません。 また、飾り枠内にコピーして来た「文字列」「画像」「動画」などを貼り付ける操作が簡単になると言えます。
編集枠内の他の場所のクリックで反転状態は解除されますが、「テキストを入力」をクリックすると、再び反転選択になります。 この部分は「自動選択」が設定されてるわけですが、それが一度でも「HTML編集」を開くと無効になります。
下は、「HTML編集」を開いていない場合です。
下は、一度「HTML編集」を開いた場合です。
一度「HTML編集」を開くと、「テキストを入力」をクリックしても選択されなくなります。 新しく飾り枠を生成すると最初は反転しているので、殆ど問題にならないと考えて、そのままにしたのかも知れませんが。
対策コード
「テキストを入力」の部分を反転選択するには、「selection」「range」等を使う必要があります。 これは何度やってもややこしいですね。
問題の部分は、「記事デザイン」に共通で「data-entrydesign-content」の属性が指定されてます。 これをクリックすれば反転選択になるスクリプトを作りました。
後半の関数「get()」は、引数「elem」を選択状態にし、マウスを左クリックしながらドラッグして反転選択するのと、全く同結果になります。
上記のコードだけでは、未だ少し問題があります。「Rep Heading ⭐」のメイン機能の「h要素」変換を行うと、直後は要素が書換えられて選択状態が解除されます。 これは、変換後にすぐに再取得して、反転選択する必要があります。
この再取得は前ページの「ver. 0.2」で既に対応していますが、要素を「click」して反転選択にする少々不完全なコードで、今回は「get()」に改めました。
下は、「見出しの記事デザイン」の処理直後に実行する関数です。 2行目で、デザイン処理対象の全てを再取得し、変更した対象のインデックス「n」は変わらないので、それを使って取得した変更後の対象に「get()」を実行しています。
一方「テキストの記事デザイン」は、処理が異なります。 こちらは、書換え処理を飾り枠の一番低い階層で行うので、変換した要素の再取得が簡単です。(2行目)
その後半のコードは、「h要素」の既定の大きな文字サイズ等のリセット処理で、最後に「get()」で、変換後の要素を反転選択しています。
以上の 3個のコードによって、反転選択の状態は良好に維持されます。
「記事デザイン」の扱いについて
「テキストを入力」の部分の反転選択について細かな補完をしたのですが、ここに文字を書く際に、「Delete」「Backspace」は用心して使わないと「記事デザイン」の飾り枠全体が削除されてしまいます。 枠が生成されたら、反転選択は文字入力の1文字目で消える事に慣れた方が良さそうです。
「Rep Heading ⭐」を利用するには
このツールは Chrome / Edge / Firefox版の拡張機能「Tampermonkey」上で動作します。 以下に、このツールの導入手順を簡単に説明します。
❶「Tampermonkey」を導入します
◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。
既に「Tampermonkey」を導入している場合は、この手順 ❶ は不要です。
拡張機能の導入については、以下のページに簡単な説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
◎「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 軽量シンプルなツール「PreBox Button 」を使うと
コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」
の操作で、掲載コードのコピーが可能になります。
◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 Rep Heading ⭐ 〕 ver. 0.3
// ==UserScript== // @name Rep Heading ⭐ // @namespace http://tampermonkey.net/ // @version 0.3 // @description 記事デザインの「h2」「h3」「テキスト」を「Ctrl+左Click」で変換する // @author Ameba Blog User // @match https://blog.ameba.jp/ucs/entry/srventry* // @exclude https://blog.ameba.jp/ucs/entry/srventrylist.do* // @grant none // ==/UserScript== let retry=0; let interval=setInterval(wait_target, 100); function wait_target(){ retry++; if(retry>10){ // リトライ制限 10回 1sec clearInterval(interval); } let target=document.getElementById('cke_1_contents'); // 監視 target if(target){ main(); }} function main(){ let target=document.getElementById('cke_1_contents'); // 監視 target let monitor=new MutationObserver(tag_manager); monitor.observe(target, {childList: true}); tag_manager(); } // main() function tag_manager(){ let style= '<style class="rep_head">h2::before { content: "h2"; position: absolute; left: -36px; '+ 'padding: 2px 4px 0; height: 18px; font: bold 16px/19px Meiryo; '+ 'border: 1px solid #aaa; background: #fff; color: red; } '+ 'h3::before { content: "h3"; position: absolute; left: -36px; '+ 'padding: 2px 4px 0; height: 18px; font: bold 16px/19px Meiryo; '+ 'border: 1px solid #aaa; background: #fff; color: #000; } '+ 'h4::before { content: "h4"; position: absolute; left: -36px; '+ 'padding: 2px 4px 0; height: 18px; font: bold 16px/19px Meiryo; '+ 'border: 1px solid #aaa; background: #fff; color: #888; }</style>'; let editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ let iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ if(!iframe_doc.querySelector('.rep_head')){ iframe_doc.documentElement.insertAdjacentHTML('beforeend', style); }}} if(editor_iframe){ let iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ let target=iframe_doc.body; // 監視 target if(target){ let monitor=new MutationObserver(replace_tag); monitor.observe(target, {childList: true}); }}} replace_tag(); } // tag_manager() function replace_tag(){ let editor_iframe=document.querySelector('.cke_wysiwyg_frame'); if(editor_iframe){ let iframe_doc=editor_iframe.contentWindow.document; if(iframe_doc){ let h_elem=iframe_doc.querySelectorAll('[data-entrydesign-type="heading"]'); for(let k=0; k<h_elem.length; k++){ h_elem[k].onclick=function(event){ if(event.ctrlKey){ event.stopImmediatePropagation(); rep_tag(h_elem[k]); rep_tag_mend(k); }}} function rep_tag(element){ let alt_elem=element.outerHTML.toString(); if(witch_h(element)==2){ alt_elem=alt_elem.replace(/^<h2/, '<h3').replace(/h2>$/, 'h3>'); } else if(witch_h(element)==3){ alt_elem=alt_elem.replace(/^<h3/, '<div').replace(/h3>$/, 'div>'); } else if(witch_h(element)==0){ alt_elem=alt_elem.replace(/^<div/, '<h2').replace(/div>$/, 'h2>'); } element.outerHTML=alt_elem; } // rep_tag() h2➔h3➔div の書換 function rep_tag_mend(n){ let h_elem=iframe_doc.querySelectorAll('[data-entrydesign-type="heading"]'); if(h_elem[n]){ let content=h_elem[n].querySelector('[data-entrydesign-content]'); if(content){ get(content); }}} let hd_elem=iframe_doc.querySelectorAll('[data-entrydesign-type="block"]'); for(let k=0; k<hd_elem.length; k++){ hd_elem[k].onclick=function(event){ if(event.ctrlKey){ event.stopImmediatePropagation(); rep_ptag(hd_elem[k]); rep_ptag_mend(hd_elem[k]); }}} function rep_ptag(element){ let p_elem=element.querySelector('[data-entrydesign-content] :last-child'); if(p_elem){ let alt_elem=p_elem.outerHTML.toString(); if(witch_h(p_elem)==2){ alt_elem=alt_elem.replace(/^<h2/, '<h3').replace(/h2>$/, 'h3>'); } else if(witch_h(p_elem)==3){ alt_elem=alt_elem.replace(/^<h3/, '<p').replace(/h3>$/, 'p>'); } else if(witch_h(p_elem)==0){ alt_elem=alt_elem.replace(/^<p/, '<h2').replace(/p>$/, 'h2>'); } p_elem.outerHTML=alt_elem; }} // rep_ptag() h2➔h3➔p の書換 function rep_ptag_mend(element){ let p_elem=element.querySelector('[data-entrydesign-content] :last-child'); if(p_elem){ p_elem.style.margin='0'; p_elem.style.lineHeight='inherit'; p_elem.style.fontSize='inherit'; get(p_elem); }} function witch_h(elem){ if(elem.tagName=='H2'){ return 2; } else if(elem.tagName=='H3'){ return 3; } else return 0; } let d_content=iframe_doc.querySelectorAll('[data-entrydesign-content]'); for(let k=0; k<d_content.length; k++){ d_content[k].addEventListener('click', function(){ get(d_content[k]); }); } function get(elem){ let selection=iframe_doc.getSelection(); let range=iframe_doc.createRange(); range.selectNodeContents(elem); selection.removeAllRanges(); selection.addRange(range); } }}} // replace_tag()
「Rep Heading ⭐」最新版について
旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。
●「Rep Heading ⭐」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。