WorkFlowyにチェックボックス機能を追加する(改良版1)

WorkFlowyに、チェックボックスの機能を追加する、スクリプト(ブックマークレット)です。
WorkFlowyにチェックボックス機能を追加するの改良版です。
今回の改良点
Bullet(行頭の●)のメニューやWorkFlowyのショートカットで完了・非完了を変更した時も、チェックボックスが変更されるようになりました。
使い方
スクリプト(またはブックマークレット)を実行し、トピックの行頭に[ ]または[x]1 を書くと、Bullet(行頭の●)とトピックの間にチェックボック(☐または☑)が表示されます。
既に[ ]または[x]が書かれている場合は、実行直後に、チェックボックが表示され、トピックも内容に合わせて完了・非完了になります。
もう一度、実行すると停止し、チェックボックスも消えます。
[ ][x]を書き換えると、内容に合わせてトピックの完了・非完了が変更されます。
また、チェックボック(☐☑)をクリックすることで、完了・非完了およびチェックボックスの記述を変更できます。
BulletのメニューやWorkFlowyのショートカット(⌘+rerutn)で完了・非完了を変更した場合も、チェックボックスと[ ][x]も変化します。
今後の改良予定
- チェックボックス(☐または☑)の挿入のOn/Offが指定できるようにする。
スクリプト
DeskFlowy、HandyFlowyで動きます。 ただ、HandyFlowyではチェックボックスは小さくて押しにくいです。特に僕の太い指では。。。
そのうち、チェックボックスのサイズなどのサイズを調整するかも。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var checkbox_tag = /^\s*\[([xX\- ])\]/; | |
function isComplete(t){ | |
return t.closest(".project").classList.contains("done"); | |
} | |
function chenge_CheckBox(t,f){ | |
undo_redo.startOperationBatch(); | |
var a=t.nextElementSibling; | |
var c=f?"x":" "; | |
a.innerText=a.innerText.replace(/^(\s*\[)[xX\- ](\])/,"$1"+c+"$2"); | |
a.contentEditable=true; | |
a.focus(); | |
undo_redo.finishOperationBatch(); | |
t.innerText=f?"\u2611":"\u2610"; | |
} | |
function onClick_CheckBox(){ | |
var r = this.nextElementSibling.textContent.match(checkbox_tag); | |
if (r){ | |
var p = $(this.closest(".project")); | |
var t = p.getName(); | |
var c = r[1].match(/[xX\-]/) | |
if ( c != null ){ | |
// on → off | |
chenge_CheckBox(this,false); | |
}else{ | |
// off → on | |
chenge_CheckBox(this,true); | |
} | |
p.completeIt(); | |
} | |
} | |
blur_CheckBox = window.blur_CheckBox!=undefined?window.blur_CheckBox:function(){ | |
var _this = this; | |
setTimeout(function(){ | |
var r = _this.textContent.match(checkbox_tag); | |
if (r){ | |
var c = r[1].match(/[xX\-]/) | |
if ((c != null ) != isComplete(_this)){ | |
var p = $(_this.closest(".project")); | |
CheckBox_CompleteFlag=true; | |
p.completeIt(c); | |
} | |
createCheckBox(_this); | |
}else{ | |
delete_CheckBox(_this); | |
} | |
},100); | |
} | |
function delete_CheckBox(t){ | |
if(t.parentNode.getElementsByClassName("CheckBox").length){ | |
var a = t.parentNode.getElementsByClassName("CheckBox"); | |
var l = a.length; | |
for(var i=0;i<l;i++){ | |
a[i].remove(); | |
} | |
} | |
} | |
function add_CheckBox(t,f){ | |
if (!t.parentNode.classList.contains("name")){ | |
// トピック以外はreturn | |
return; | |
} | |
delete_CheckBox(t); | |
var checkbox = document.createElement("span"); | |
if(f){ | |
checkbox.appendChild( document.createTextNode("\u2611") ); | |
}else{ | |
checkbox.appendChild( document.createTextNode("\u2610") ); | |
} | |
var p = $(t.closest(".project")); | |
if ((p.not(".done").length>0)===f){p.completeIt();} | |
checkbox.classList.add("CheckBox"); | |
checkbox.addEventListener('click', onClick_CheckBox, false); | |
t.parentNode.insertBefore(checkbox, t); | |
} | |
function createCheckBox(t){ | |
var text = t.textContent; | |
var r = text.match(checkbox_tag); | |
if (r){ | |
// チェックボックス有り | |
var c = r[1].match(/[xX\-]/)!=null; | |
add_CheckBox(t,c); | |
}else{ | |
// なし | |
delete_CheckBox(t); | |
} | |
} | |
function do_createCheckBox(){ | |
createCheckBox(this); | |
} | |
each_do_createCheckBox = window.each_do_createCheckBox!=undefined?window.each_do_createCheckBox:function(){ | |
$("div.name div.content").each(do_createCheckBox); | |
} | |
// 初期化処理(イベント等を設置する) | |
function init_CheckBox(){ | |
$("div.name div.content").live("blur",window.blur_CheckBox); | |
window.each_do_createCheckBox(); | |
$("#expandButton").live("click",window.each_do_createCheckBox); | |
// 再読み込み時に実行 | |
window.addEventListener('load', window.each_do_createCheckBox); | |
window.addEventListener('hashchange', window.each_do_createCheckBox); | |
// スタイルを設置 | |
if(document.getElementById("style_CheckBox")){ | |
document.getElementById("style_CheckBox").remove(); | |
}; | |
var s = document.createElement("style"); | |
s.id="style_CheckBox"; | |
s.innerHTML=".CheckBox{position:absolute;z-index:6;}.CheckBox:hover{cursor: pointer;}.name>.CheckBox{margin-top:5px;}.CheckBox+.content{left:1em;}"; | |
document.body.appendChild(s); | |
window.CheckBox_observer.observe(target, options); | |
isRunCheckBox = true; | |
} | |
// 終了処理(付けたイベントを外す) | |
function end_CheckBox(){ | |
$("div.name div.content").die("blur",window.blur_CheckBox); | |
$("#expandButton").die("click",window.each_do_createCheckBox); | |
// 再読み込み時に実行を停止 | |
window.removeEventListener('load', window.each_do_createCheckBox,false); | |
window.removeEventListener('hashchange', window.each_do_createCheckBox,false); | |
init_CheckBox = undefined; | |
// スタイルを削除 | |
if(document.getElementById("style_CheckBox")){ | |
document.getElementById("style_CheckBox").remove(); | |
}; | |
// チェックボックスを消す | |
$(".CheckBox").remove(); | |
window.CheckBox_observer.disconnect(); | |
isRunCheckBox = false; | |
} | |
var target = document.querySelector('.project'); | |
CheckBox_CompleteFlag = false; | |
CheckBox_observer = window.CheckBox_observer?window.CheckBox_observer:new MutationObserver(function(mutationRecords, _observer) { | |
if (CheckBox_CompleteFlag){ | |
setTimeout(function(){ | |
CheckBox_CompleteFlag=false; | |
},100); | |
return; | |
} | |
var t = mutationRecords[0].target; | |
var r = t.querySelectorAll(".name>.content")[0].textContent.match(checkbox_tag); | |
if (r!=null){ | |
if (t.classList.contains("done")){ | |
// on | |
chenge_CheckBox(t.getElementsByClassName("CheckBox")[0],true); | |
}else{ | |
// off | |
chenge_CheckBox(t.getElementsByClassName("CheckBox")[0],false); | |
} | |
} | |
console.log("B:",r,":",$(mutationRecords[0].target).getName().text()); | |
}); | |
var options = {subtree:true,attributes:true,attributeFilter:['class']}; | |
// トグル動作用 | |
isRunCheckBox = window.isRunCheckBox!=undefined?isRunCheckBox:false; | |
if (isRunCheckBox){ | |
end_CheckBox(); | |
}else{ | |
init_CheckBox(); | |
} |
HandyFlowy用
ブックマークレット
Chromeのみですが動作確認しています。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
javascript:(function(){function isComplete(t){return t.closest(".project").classList.contains("done")}function chenge_CheckBox(t,f){undo_redo.startOperationBatch();var a=t.nextElementSibling,c=f?"x":" ";a.innerText=a.innerText.replace(/^(\s*\[)[xX\- ](\])/,"$1"+c+"$2"),a.contentEditable=!0,a.focus(),undo_redo.finishOperationBatch(),t.innerText=f?"☑":"☐"}function onClick_CheckBox(){var r=this.nextElementSibling.textContent.match(checkbox_tag);if(r){var p=$(this.closest(".project"));p.getName();null!=r[1].match(/[xX\-]/)?chenge_CheckBox(this,!1):chenge_CheckBox(this,!0),p.completeIt()}}function delete_CheckBox(t){if(t.parentNode.getElementsByClassName("CheckBox").length)for(var a=t.parentNode.getElementsByClassName("CheckBox"),l=a.length,i=0;i<l;i++)a[i].remove()}function add_CheckBox(t,f){if(t.parentNode.classList.contains("name")){delete_CheckBox(t);var checkbox=document.createElement("span");f?checkbox.appendChild(document.createTextNode("☑")):checkbox.appendChild(document.createTextNode("☐"));var p=$(t.closest(".project"));p.not(".done").length>0===f&&p.completeIt(),checkbox.classList.add("CheckBox"),checkbox.addEventListener("click",onClick_CheckBox,!1),t.parentNode.insertBefore(checkbox,t)}}function createCheckBox(t){var r=t.textContent.match(checkbox_tag);r?add_CheckBox(t,null!=r[1].match(/[xX\-]/)):delete_CheckBox(t)}function do_createCheckBox(){createCheckBox(this)}function init_CheckBox(){$("div.name div.content").live("blur",window.blur_CheckBox),window.each_do_createCheckBox(),$("#expandButton").live("click",window.each_do_createCheckBox),window.addEventListener("load",window.each_do_createCheckBox),window.addEventListener("hashchange",window.each_do_createCheckBox),document.getElementById("style_CheckBox")&&document.getElementById("style_CheckBox").remove();var s=document.createElement("style");s.id="style_CheckBox",s.innerHTML=".CheckBox{position:absolute;z-index:6;}.CheckBox:hover{cursor: pointer;}.name>.CheckBox{margin-top:5px;}.CheckBox+.content{left:1em;}",document.body.appendChild(s),window.CheckBox_observer.observe(target,options),isRunCheckBox=!0}function end_CheckBox(){$("div.name div.content").die("blur",window.blur_CheckBox),$("#expandButton").die("click",window.each_do_createCheckBox),window.removeEventListener("load",window.each_do_createCheckBox,!1),window.removeEventListener("hashchange",window.each_do_createCheckBox,!1),init_CheckBox=void 0,document.getElementById("style_CheckBox")&&document.getElementById("style_CheckBox").remove(),$(".CheckBox").remove(),window.CheckBox_observer.disconnect(),isRunCheckBox=!1}var checkbox_tag=/^\s*\[([xX\- ])\]/;blur_CheckBox=void 0!=window.blur_CheckBox?window.blur_CheckBox:function(){var _this=this;setTimeout(function(){var r=_this.textContent.match(checkbox_tag);if(r){var c=r[1].match(/[xX\-]/);if(null!=c!=isComplete(_this)){var p=$(_this.closest(".project"));CheckBox_CompleteFlag=!0,p.completeIt(c)}createCheckBox(_this)}else delete_CheckBox(_this)},100)},each_do_createCheckBox=void 0!=window.each_do_createCheckBox?window.each_do_createCheckBox:function(){$("div.name div.content").each(do_createCheckBox)};var target=document.querySelector(".project");CheckBox_CompleteFlag=!1,CheckBox_observer=window.CheckBox_observer?window.CheckBox_observer:new MutationObserver(function(mutationRecords,_observer){if(CheckBox_CompleteFlag)setTimeout(function(){CheckBox_CompleteFlag=!1},100);else{var t=mutationRecords[0].target,r=t.querySelectorAll(".name>.content")[0].textContent.match(checkbox_tag);null!=r&&(t.classList.contains("done")?chenge_CheckBox(t.getElementsByClassName("CheckBox")[0],!0):chenge_CheckBox(t.getElementsByClassName("CheckBox")[0],!1)),console.log("B:",r,":",$(mutationRecords[0].target).getName().text())}});var options={subtree:!0,attributes:!0,attributeFilter:["class"]};isRunCheckBox=void 0!=window.isRunCheckBox&&isRunCheckBox,isRunCheckBox?end_CheckBox():init_CheckBox();})() |
[x]は[*][-]でもOKです。ただし、チェックボックスを変更した時は、[x]になります。 ↩︎