generated at
ScrapExec
(2021/3/20)

クリックでコードブロックを実行可能にするUserScript
▶ をクリックすると実行
別ページに飛んだときリセット
/miyamonz/ScrapJupyter を参考にした
コードをいきなり eval するので注意!

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();