「Fixed Format Palette ⭐」は定型範囲の入力ツールです
ページに配置する定型のデザインしたリンクカードや枠付きの案内などがある場合、新しい記事にそれらを再配置するには、過去記事を編集画面に開き、その定型の要素をコピーして、新しい記事にペーストする必要があります。 コピーする定型要素の種類によっては、HTML表示の画面でコピーし、新しい記事でHTML表示を開いてペーストしないと、上手くコピー出来ないものもあります。
見栄えの良いページや、行き届いた案内を設置したページを作るには、この様な定型の表示パーツを再利用すると効果的です。 しかし、いちいち過去のページから必要な表示パーツを探しコピーするのは手間です。 そこで、再利用する表示パーツをブラウザのローカルストレージに登録しておき、必要な時にいつでも取り出してペーストできるツール「Fixed Format Palette ⭐」を作りました。
しかし、実はこのツール、苦労した割にインターフェイスが悪く、これまではコピー登録もペーストも扱い難いものでした。 ネックはショートカットに「3キー」を使う仕様で、登録した内容が利用時にペーストしないと判らず、私自身が9個の登録Bankの内の2~3個しか使わないという状態でした。
そこで、問題のインターフェイスを最初から組み直し、スクロールホイールでBankの全てが一覧選択できる様にしました。 この更新で画期的に使い易くなりました。
新しい操作方法 / 登録した表示パーツのペースト
● ショートカット「Ctrl+F11」でペースト用のサブパネルが表示されます。
● マウスポインターをサブパネルに乗せてホイール操作をすると、Bank1~Bank9に登録されたパーツを順に参照できます。
下は、Bankを順に開き、ペーストする表示パーツを選んでいるところです。
● 必要な表示パーツを出して「Enter」キーで、編集画面のキャレット位置にそのパーツをペーストします。「Esc」でペーストを中止し、サブパネルが閉じます。
● ペーストは必ず「通常表示」の編集画面で行います。 また、編集画面内にキャレットが無いと、挿入する位置が定まらないので、ペースト動作をしません。
新しい操作方法 / 表示パーツの登録
● 登録する表示パーツ(特定の要素やページの範囲)を、通常表示の編集画面上のキャレット操作で反転選択します。
● 上はリンクカードの例ですが、カードの1行手前からカードを越えた次の1行までを選択しています。 登録時は、この様に選択範囲の前後に余裕を採ると確実です。
● ショートカット「Alt+F11」を押します。
サブパネルの上側に、選択した表示パーツが表示されます。 下側は登録するBankのこれまでの登録内容が表示されます。(ツールの最初の使用時は、下側が空です)
● ホイール操作で、登録するBankを選びます。
▶ 既に登録があるBankを選んだ場合
●「Enter」で、これまでの登録(下側の表示パーツ)は上書きされ、代わりに上側の新しい表示パーツが登録されます。
▶ 未登録の空いたBankを選んだ場合
●「Enter」で、この空Bankに表示パーツが登録されます。
Bankの登録内容の削除
● キャレットを編集画面内に置き、何も選択しない状態で「Alt+F11」を押します。
最初に表示されるBankは常に「Bank1」なので、削除したいBankをホイール操作で選択します。
● 削除する表示パーツがサブパネルに表示されたら「Enter」を押します。
選択したBankが空Bankになります。
新しい操作方法 / 表示パーツのHTML登録
「HTML登録」は Chrome/Edge でのみ可能な機能で、「HTML表示画面」で表示パーツを登録することができます。
この方法の利点は表示パーツの前後の余裕を省いて、きっちり表示パーツだけを登録できる事です。 この機能を扱う前提として、HTMLのコード上で、表示パーツの範囲を正確に判別して指定できる必要があります。
● 登録するパーツのHTMLコードを選択します。
●「Alt+F11」を押します。
サブパネルに選択した表示パーツが表示されます。
● 登録するBankをホイール操作で選択して「Enter」を押します。
選択したBankに表示パーツが登録されます。
登録データのファイル化
Bankに登録したデータは、ブラウザを終了しても消える事はありません。 しかしファイル化してバックアップするとより確実です。 また、9個のBankで足りない時は、ファイルにBank内容を書き出し、ファイル単位で管理すると無限に登録できます。
「登録」「ペースト」のサブパネルの隅に「File」ボタンがあります。
これを押すと、サブパネルが下の様なファイル専用のメニューになります。
●「登録データをファイルに保存」をクリックすると、PCのダウンロードフォルダーにファイル名が「FFP(n).json」といった形で、ファイルが保存されます。
この(n)の部分は自動連番で、ファイル化するごとに数が増えます。
●「登録データファイルを読込む」をクリックすると、PC内のファイルを読込めます。 前例のファイルなら、ダウンロードフォルダを開いて、目的の「FFP.json」ファイルを指定して開きます。
このツールが保存したファイルを指定すると、そのデータが各Bankに読込まれます。 この操作は同時に、それまでのBankの登録内容を上書きするので注意してください。
「Fixed Format Palette ⭐」ver. 5.0 を使用するには
このツールは Chrome・Edge / Firefox の各ブラウザ版「Tampermonkey」で動作します。「Tampermonkey」にページ末尾の掲載コードを登録する事で、このツールを利用することが出来ます。
この版から基本操作が変わりましたが、これまでの Bankのデータやバックアップファイルはそのまま使用できます。 ただし、「Tampermonkey」に登録した旧バージョンがある場合はそれを削除して、このバージョンを新たに登録してください。
❶「Tampermonkey」を導入します
使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。 以下のページに簡単な導入の説明があるので参照ください。
❷「Tampermonkey」にスクリプトを登録します
●「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
●「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 軽量シンプルなツール「PreBox Button 」を使うと
コード枠内を「Ctrl+左Click」➔「Copy code 」を「左Click」
の操作で、掲載コードのコピーが可能になります。
● 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 Fixed Format Palette ⭐ 〕 ver. 5.0
// ==UserScript==
// @name Fixed Format Palette ⭐
// @namespace http://tampermonkey.net/
// @version 5.0
// @description 編集枠に定型表示を自動記入するツール
// @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){
clearInterval(interval);
main(); }}
function main(){
let editor_iframe=document.querySelector('.cke_wysiwyg_frame');
let iframe_doc;
let iframe_html;
if(editor_iframe){
iframe_doc=editor_iframe.contentWindow.document;
iframe_html=iframe_doc.querySelector('html'); }
let format_data;
let bank;
let mode=-1; // 通常表示Write=0・Record=1 Html表示Record=2 Backup=3
let select_format;
let ua=0; // Chromeの場合のフラグ
let agent=window.navigator.userAgent.toLowerCase();
if(agent.indexOf('firefox') > -1){ ua=1; } // Firefoxの場合のフラグ
let read_json=localStorage.getItem('Format_Data'); // ローカルストレージ 保存名
format_data=JSON.parse(read_json);
if(format_data==null){
format_data=
[['0','FixedFormatPalette'],['1',''],['2',''],['3',''],['4',''],['5',''],['6',''],['7',''],['8',''],['9','']]; }
format_data[0][1]='FixedFormatPalette';
let write_json=JSON.stringify(format_data);
localStorage.setItem('Format_Data', write_json); // ローカルストレージ 保存
let target=document.getElementById('cke_1_contents'); // 監視 target
let monitor=new MutationObserver(catch_key);
monitor.observe(target, {childList: true}); // ショートカット待受け開始
catch_key();
function catch_key(){
if(document.querySelector('.l-gHeaderLeft__link a')){ // 起動を表示 📛
document.querySelector('.l-gHeaderLeft__link a')
.style.boxShadow='inset -14px 0 0 0 #79fbf6'; }
editor_iframe=document.querySelector('.cke_wysiwyg_frame');
if(editor_iframe){ // iframe がある「通常表示」の場合
mode=-1;
if(document.querySelector('.ffp_menu')){
document.querySelector('.ffp_menu').remove(); }
iframe_doc=editor_iframe.contentWindow.document;
iframe_doc.addEventListener("keydown", check_key);
function check_key(event){
if(event.ctrlKey && event.keyCode==122){ // 「Ctrl + F11」Bankから書出し
event.preventDefault();
mode=0;
setTimeout(()=>{
write_format(); }, 20); }
if(event.altKey && event.keyCode==122){ // 「Alt + F11」Bank登録
event.preventDefault();
mode=1;
setTimeout(()=>{
record_format(); }, 20); }
if(event.keyCode==122){ // ページ拡大の誤入力を抑止
event.preventDefault(); }
} // check_key()
} //「通常表示」の場合
else{ //「HTML表示」の場合
mode=-1;
if(document.querySelector('.ffp_menu')){
document.querySelector('.ffp_menu').remove(); }
document.addEventListener("keydown", check_key_h);
function check_key_h(event){
if(event.ctrlKey && event.keyCode==122){ // HTML表示で書込み操作をした場合
event.preventDefault();
document.querySelector('.CodeMirror textarea').blur();
setTimeout(()=>{
alert(
" ⛔ 定型ブロックの記入は通常編集枠で行ってください\n"+
" == Fixed Format Palette =="); }, 20); }
if(event.altKey && event.keyCode==122){ //「Alt+F11」Bank登録(HTMLで登録)
event.preventDefault();
if(ua==0){
mode=2; // HTMLでの登録処理
setTimeout(()=>{
record_format_h(); }, 20); }
else if(ua==1){ // FirefoxはHTML編集でブロック登録が出来ない
event.stopImmediatePropagation();
document.querySelector('.CodeMirror textarea').blur();
setTimeout(()=>{
alert(
" ⛔ 定型ブロックの登録は通常編集枠で行ってください\n"+
" == Fixed Format Palette =="); }, 20); }}
if(event.keyCode==122){ // ページ拡大の誤入力を抑止
event.preventDefault(); }
} // check_key_h
} //「HTML表示」の場合
} // catch_key
function write_format(){
disp_menu(0);
iframe_doc.addEventListener("keydown", menu_key1);
function menu_key1(event){
if(event.keyCode==27 && mode==0){ //「Esc」
event.preventDefault();
mode=-1;
menu0_end(); }
if(event.keyCode==13 && mode==0){ //「Enter」
event.preventDefault();
write_in(); // ペースト処理
setTimeout(()=>{
menu0_end(); }, 20); }}
function menu0_end(){
if(document.querySelector('.ffp_menu')){
document.querySelector('.ffp_menu').remove(); }}
function write_in(){
let selection=iframe_doc.getSelection();
let range;
if(selection && selection.rangeCount>0){
range=selection.getRangeAt(0); }
let ac_node=selection.anchorNode;
let insert_node_d=iframe_doc.createElement('div');
insert_node_d.innerHTML=format_data[bank][1];
if(ac_node && ac_node.parentNode){
// insert_node_d 生成の条件 親が div要素か BODYの場合
if(ac_node.parentNode.tagName=='DIV' ||
ac_node.parentNode.tagName=='BODY'){
ac_node.parentNode.insertBefore(insert_node_d, ac_node.nextSibling);
d_before_after(); }
// insert_node_d 生成の条件 ひとつ外の親が div要素か BODYの場合
else if(ac_node.parentNode.parentNode.tagName=='DIV' ||
ac_node.parentNode.parentNode.tagName=='BODY'){
ac_node.parentNode.parentNode.insertBefore(
insert_node_d, ac_node.parentNode.nextSibling);
d_before_after(); }
mode=4; }
function d_before_after(){
range.setEnd(insert_node_d, 0);
range.collapse(); }} // レンジを閉じる
} // write_format()
function record_format(){
let selection=iframe_doc.getSelection();
let range;
if(selection && selection.rangeCount>0){
range=selection.getRangeAt(0); }
select_format=document.createElement('div');
select_format.appendChild(range.cloneContents());
select_format=select_format.innerHTML;
disp_menu(1);
iframe_doc.addEventListener("keydown", menu_key0);
function menu_key0(event){
if(event.keyCode==27 && mode==1){ //「Esc」
event.preventDefault();
mode=-1;
menu1_end(); }
else if(event.keyCode==13 && mode==1){ //「Enter」
event.preventDefault();
format_data[bank][1]=select_format;
let write_json=JSON.stringify(format_data);
localStorage.setItem('Format_Data', write_json);
mode=4;
menu1_end(); }} // ローカルストレージ 保存
function menu1_end(){
selection.removeAllRanges(); // 反転を解除
editor_iframe.blur(); // 編集枠からカーソルを外し誤記入を防ぐ
if(document.querySelector('.ffp_menu')){
document.querySelector('.ffp_menu').remove(); }}
} // record_format()
function record_format_h(){
let result=new Promise( function(){
document.execCommand("copy"); })
navigator.clipboard.readText().then( function(clipText){
select_format=clipText; })
.then( function(){
disp_menu(1); })
.then( function(){
document.querySelector('.CodeMirror textarea').blur(); })
document.addEventListener("keydown", menu_key_h);
function menu_key_h(event){
if(event.keyCode==27 && mode==2){ //「Esc」
event.preventDefault();
mode=-1;
menu1_end(); }
if(event.keyCode==13 && mode==2){ //「Enter」
event.preventDefault();
mode=4;
format_data[bank][1]=select_format;
let write_json=JSON.stringify(format_data);
localStorage.setItem('Format_Data', write_json); // ローカルストレージ 保存
menu1_end(); }}
function menu1_end(){
if(document.querySelector('.ffp_menu')){
document.querySelector('.ffp_menu').remove(); }}
} // record_format_h(}
function disp_menu(type){
let css=
'.ffp_menu { position: absolute; top: 15px; right: 10px; z-index: 15; '+
'font-family: Meiryo; font-size: 16px; line-height: 1.6; width: 620px; '+
'padding: 8px 8px 18px; border: 1px solid #009688; border-radius: 4px; '+
'background: #fff; box-shadow: 20px 20px 60px 0 rgba(0, 0, 0, .2), '+
'inset 0 0 0 8px #eee; transform-origin: top; } '+
'.ffp_menu img { max-width: 99%; height: auto; } '+
'.ffp_title { padding: 3px 15px 1px; margin: 10px 0; background: #2196f3; '+
'color: #fff; font-size: 16px; } '+
'.ffp_bk { display: inline-block; padding: 0 6px; line-height: 24px; '+
'height: 22px; border: 1px solid #fff; border-radius: 3px; cursor: pointer; } '+
'.ffp_bk:hover { color: #2196f3; background: #fff; } '+
'.ffp_input { display: none; }';
let style_menu=document.createElement('style');
style_menu.setAttribute('id', "style_ffp_menu");
style_menu.textContent=css;
if(!document.querySelector('#style_ffp_menu')){
document.querySelector('.l-body').appendChild(style_menu); }
let menu=document.createElement('div');
menu.setAttribute('class', "ffp_menu");
if(!document.querySelector('.ffp_menu')){
document.querySelector('.l-body').appendChild(menu); }
if(type==1){
setTimeout(()=>{
let selection=iframe_doc.getSelection();
if(selection){
selection.removeAllRanges(); // 反転を解除しコピー元の削除を防ぐ
}}, 20 ); }
let out=0;
bank=1;
menu_change(1);
if(ua==0){
menu.onmousewheel=function(event){
let wd=event.wheelDelta/120;
out-=wd;
if(out>=0){
bank=out%9+1; }
else{
bank=(out+1)%9+9; }
menu_change(bank); }}
if(ua==1){
menu.addEventListener('DOMMouseScroll', function(event){
let wd=- event.detail/3;
out-=wd;
if(out>=0){
bank=out%9+1; }
else{
bank=(out+1)%9+9; }
menu_change(bank); }); }
function menu_change(bank){
let menu=document.querySelector('.ffp_menu');
let menu_str;
if(type==0){
menu_str=
'<div class="ffp_title">'+
'◁ Bank '+ bank +' ▷ の内容を貼り付けます '+
' 貼り付け:Enter 中止:Esc <span class="ffp_bk">File</span></div>'+
format_data[bank][1]; }
if(type==1){
menu_str='<div id="check">'+ select_format + '</div>'; // テスト
menu.innerHTML=menu_str;
let check=document.querySelector('#check');
if(check){
if(getComputedStyle(check, null).getPropertyValue("height")=='0px'){
select_format=''; // 非表示要素は無入力に変換する:登録の削除
menu_str=
'<div class="ffp_title" style="background: #000;">'+
'◁ Bank '+ bank +' ▷ の以下の内容を削除します'+
' 削除:Enter 中止:Esc</div>'+
format_data[bank][1]; }
else { // 登録データを更新する場合
menu_str=
'<div class="ffp_title">'+
'◁ Bank '+ bank +' ▷ に以下の内容を登録します'+
' 登録:Enter 中止:Esc '+
'<span class="ffp_bk">File</span></div>'+
'<div id="check">'+ select_format + '</div>'+
'<div class="ffp_title" style="background: #000;">'+
'◁ Bank '+ bank +' ▷ の以下の登録内容は削除されます</div>'+
format_data[bank][1]; }}}
menu.innerHTML=menu_str;
let ffp_bk=document.querySelector('.ffp_bk');
if(ffp_bk){
ffp_bk.onclick=function(){
ffp_backup(); }}} // menu_change()
} // disp_menu();
function ffp_backup(){
let menu=document.querySelector('.ffp_menu');
let menu_str;
menu_str=
'<div class="ffp_title"> '+
'<span class="ffp_button1 ffp_bk">登録データをファイルに保存</span> '+
'<span class="ffp_button2 ffp_bk">登録データファイルを読込む</span> '+
'<span class="ffp_button3 ffp_bk">✖</span>'+
'<input class="ffp_input" type="file"></div>';
menu.innerHTML=menu_str;
let button1=document.querySelector('.ffp_button1');
let button2=document.querySelector('.ffp_button2');
let ffp_input=document.querySelector('.ffp_input');
let button3=document.querySelector('.ffp_button3');
button1.onclick=function(){
let write_json=JSON.stringify(format_data); // 記録用配列 format_data を書出す
let blob=new Blob([write_json], {type: 'application/json'});
let a_elem=document.createElement('a');
a_elem.href=URL.createObjectURL(blob);
a_elem.download='FFP.json'; // 保存ファイル名
if(ua==1){
a_elem.target='_blank';
document.body.appendChild(a_elem); }
a_elem.click(event);
event.preventDefault();
if(ua==1){
document.body.removeChild(a_elem); }
URL.revokeObjectURL(a_elem.href); }
button2.onclick=function(){
ffp_input.click(); }
ffp_input.addEventListener("change", function(){
if(!(ffp_input.value)) return; // ファイルが選択されない場合
let file_list=ffp_input.files;
if(!file_list) return; // ファイルリストが選択されない場合
let file=file_list[0];
if(!file) return; // ファイルが無い場合
let file_reader=new FileReader();
file_reader.readAsText(file);
file_reader.onload=function(){
if(file_reader.result.slice(0, 15)=='[["0","FixedFor'){ // FFP.jsonの確認
let data_in=JSON.parse(file_reader.result);
format_data=data_in; // 記録用配列 format_data を上書き
let write_json=JSON.stringify(format_data);
localStorage.setItem('Format_Data', write_json); // ローカルストレージに保存
}};});
button3.onclick=function(){
if(document.querySelector('.ffp_menu')){
document.querySelector('.ffp_menu').remove(); }}
} // ffp_backup()
} // main()
「Fixed Format Palette」はブログ編集画面の表示パーツをコピー登録して、必要な時にペーストできるツールです。 9個のBankを選んで登録でき、ブログに表示できるものはほぼ全て登録が可能です。
▶ 登録・ペースト操作は「通常表示」の編集画面で
操作します( Chromeは「HTML登録」が可能 )
▶ 行数・サイズ・表示内容等に制限はありません
▶ 複雑なデザインを施したパーツの再利用に最適
ショートカット ➔ Bankへ登録: Alt + F11
ショートカット ➔ ペースト : Ctrl + F11
登録Bank・ペーストBank の選択はサブウインドウで指定します。
登録Bankの内容をファイルにバックアップ保存ができます。
「Fixed Format Palette」最新版について
旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。
●「Fixed Format Palette」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。













