ScrapExec
(2021/3/20)
クリックでコードブロックを実行可能にするUserScript
▶ をクリックすると実行
別ページに飛んだときリセット
コードをいきなりevalするので注意!
code:script.js
function observeUrlChange(handler) {
let lastUrl = location.href;
const titleObserver = new MutationObserver((records, observer) => {
for (const record of records) {
if (lastUrl !== location.href) {
const newUrl = location.href;
const oldUrl = lastUrl;
lastUrl = location.href;
handler(newUrl, oldUrl, observer);
}
}
});
const title = document.querySelector('head title');
titleObserver.observe(title, {childList: true});
}
const targetProject = scrapbox.Project.name;
observeUrlChange((newUrl, oldUrl, observer) => {
setExecButtons();
if (scrapbox.Project.name !== targetProject) {
observer.disconnect();
}
});
async function setExecButtons(){
$('.execButton').remove()
for(let line of scrapbox.Page.lines){
const m = line.text.match(/^\s*code:(.*\.js)/);
if(m){
const res = await fetch(/api/code/${scrapbox.Project.name}/${scrapbox.Page.title}/${m[1]});
const code = await res.text();
const {left, top} = $([id=L${line.id}]).position();
$('<div>').css("position","absolute")
.addClass('execButton')
.append("▶")
.css({left: left - 25,top, 'z-index': 900})
.attr('code',code)
.on('click',function() {
// P5.jsが動くようにする
(async function (){
(0,eval)(await (await fetch("/files/6055b46e625aa9001ccde19c.js")).text())
})();
(1,eval)($(this).attr('code')); // グローバル環境で式を評価
})
.on('mousedown',function(){ // クリックしたとき色を変える
$(this).css('color','yellow')
})
.on('mouseup',function(){
$(this).css('color','black')
})
.appendTo($('.lines'))
}
}
}
setExecButtons();