scrapbox-reference-maker
使い方
bookmarkletを押すとdialogが出てくる
こういうの
https://gyazo.com/765462a4bdc05d6bfbe8d5e2dc79ee4b
タイトル・URL
変更する必要があればいじる
説明文
textarea
一言メモを残すように促す
project
scrapを作成する先のproject
defaultはtakker
confirmを押すと作成される
2021-02-03 18:38:00 選択範囲を引用として取り込むようにした
code:bookmarklet.js
Native JS版
code:script2.js
javascript: (() => {
const dialogId = 'scrapbox-reference-maker';
const dialogHTML = `<dialog id="${dialogId}">
<form method="dialog">
<p>
<label>Title:
<input name="title" type="text" ></input>
</label>
</p>
<p>
<label>Project:
<input name="project" type="text" ></input>
</label>
</p>
<p>
<label>Description:
<textarea name="description"></textarea>
</label>
</p>
<menu>
<button value="cancel">Cancel</button>
<button value="default">Confirm</button>
</menu>
</form></dialog>`;
document.getElementById(dialogId)?.remove();
document.body.insertAdjacentHTML('beforeend',dialogHTML);
// 選択範囲を取得する
const quote = window.getSelection().toString().trim()
.split(/\n\r?|\r?\n|\r|\f/g) // 改行区切りで配列化
.filter(line => line !== '') // 空行は削除
.map(line => >${line}); // 引用記号
// utilities
const ng = text => text.trim().replace(/[\\\n]/g, ' '); const e = text => encodeURIComponent(text);
const zero = n => String(n).padStart(2, '0');
const today = (d => [${d.getFullYear()}-${zero(d.getMonth()+1)}-${zero(d.getDate())}] ${zero(d.getHours())}:${zero(d.getMinutes())}:${zero(d.getSeconds())})(new Date());
const dialog = document.getElementById(dialogId);
dialog.querySelector('inputname="title"').value = ng(document.title).trim(); dialog.addEventListener('close', () => {
if (dialog.returnValue !== 'default') return;
const elements = dialog.firstElementChild.elements;
const title = elements'title'.value; const description = dialog.querySelector('textarea').value;
// scrap pageを作成する
const lines = [
[${window.location.href} ${title}],
...quote,
description,
'',
Added on ${today},
];
window.open(https://scrapbox.io/${project}/${e(ng(title))}?body=${e(lines.join('\n'))});
});
dialog.showModal();
})();
/icons/hr.icon
↓うまく動かないので放置
↓のanswerのcodeに沿えば直るかもしれないが、流石に面倒になってきたので止めた
また独自にeventを生やす方法もよくわからなかった
cf.
本当にweb componentで作りたいときは、Slim.jsを使ったほうが良さそう。 code:script.js
javascript: (() => {
const dialogId = 'scrapbox-reference-maker';
const dialogHTML = `
<form method="dialog">
<label>Title:
<input id="title" type="text" ></input>
</label>
<label>Project:
<input id="project" type="text" ></input>
</label>
<label>Description:
<textarea id="description"></textarea>
</label>
<menu>
<button value="cancel">Cancel</button>
<button value="default">Confirm</button>
</menu>
</form>`;
customElements.define(dialogId,
class extends HTMLDialogElement {
constructor() {
super();
// dialogのDOMを作成
const shadowRoot = this.attachShadow({mode: 'open'});
const fragment = document.createDocumentFragment();
fragment.innerHTML = dialogHTML;
// 要素を取得
this.titleForm = fragment.querySelector('#title');
this.projectForm = fragment.querySelector('#project');
this.descriptionForm = fragment.querySelector('#description');
// 属性から初期値を設定する
const title = this.getAttribute('title');
const project = this.getAttribute('project');
const url = this.getAttribute('url');
const onConfirm = this.getAttribute('onConfirm');
this.titleForm.textContent = title;
this.projectForm.textContent = project;
// confirmを押されたらscrapのdataを返す
this.addEventListener('close', () =>{
if (this.returnValue === "cancel") return;
onConfirm({
title: this.titleForm.textContent,
url: url,
project: this.projectForm.textContent,
description: this.descriptionForm.textContent});
});
shadowRoot.appendChild(fragment);
this.rendered = false;
}
static get observedAttributes() {
}
attributeChangedCallback(attrName, oldVal, newVal) {
if (oldVal !== newVal) {
console.log('attributeChangedCallback', newVal);
this.root.querySelector('.name').textContent = newVal;
}
}
},{extends: 'dialog'});
// utilities
const ng = text => text.trim().replace(/[\\\n]/g, ' '); const e = text => encodeURIComponent(text);
const zero = n => String(n).padStart(2, '0');
const today = (d => ${d.getFullYear()}-${zero(d.getMonth()+1)}-${zero(d.getDate())} ${zero(d.getHours())}:${zero(d.getMinutes())}:${zero(d.getSeconds())})(new Date());
document.body.insertAdjacentHTML('beforeend', `
<dialog is="${dialogId}"
id="${dialogId}"
title="${ng(document.title).trim()}"
project="takker"
url="${window.location.href}"></dialog>
`);
let result = {};
const dialog = document.getElementById(dialogId);
dialog.setAttribute('onConfirm', ({title,url,project,description})=>{
// scrap pageを作成する
const lines = [
[${url} ${title}],
'',
description,
'',
Added on [${today}],
];
window.open(https://scrapbox.io/${project}/${e(ng(title))}?body=${e(lines.join('\n'))});
});
dialog.showModal();
})();