類義語を表示
https://gyazo.com/8e939e3aae965db49fa4af96d42677c4
候補を選ぶとクリップボードにコピーされる
code:script.js
scrapbox.PopupMenu.addButton({
title: "Synonym",
onClick: async (text) => {
if (!window.getSynonyms) {
alert('Please install "getSynonyms" to TamperMonkey');
return;
}
const response = await window.getSynonyms(text)
.then(req => req.response);
const synonyms = response.synonyms
const suggestion=new suggestWindow();
const cursor = document.getElementById('text-input');
suggestion.updateItems(
createGuiList(synonyms, suggestion));
suggestion.reDraw(cursor);
suggestion.open()
suggestion.reDraw(cursor);
window.addEventListener('click', () => { //関係ないとこクリックしても閉じる様に
suggestion.close()
})
}
})
code:script.js
export class suggestWindow{
constructor() {
this.box = document.createElement('div');
this.box.setAttribute('id', 'external-suggestion');
this.box.classList.add('form-group');
this.box.style.position = 'absolute';
this.container = document.createElement('div');
this.container.classList.add('dropdown');
this.box.appendChild(this.container);
this.items = document.createElement('ul');
this.items.classList.add('dropdown-menu');
this.items.style.whiteSpace='nowrap'; // 文字列を折り返さない
this.container.appendChild(this.items);
this.editor = document.getElementById('editor');
this.editor.appendChild(this.box);
}
// 入力補完window を開く
open() {
// 入力候補がなければ開かない
if (this.getItems().length == 0) return;
this.container.classList.add('open');
console.log(this.getItems())
}
// 入力補完window を閉じる
close(cursor = null) {
//console.log('close the window.');
this.container.classList.remove('open');
this.items.textContent='';
if(!cursor) cursor = document.getElementById('text-input');
cursor.focus();
}
// 入力補完window の開閉判定
isOpen() {
return this.container.classList.contains('open');
}
// 入力候補に表示するアイテムを更新する
updateItems(items) {
const newList = document.createElement('ul');
newList.classList.add('dropdown-menu');
newList.style.whiteSpace='nowrap';
for(const item of items) {
let listItem = document.createElement('li');
listItem.classList.add('dropdown-item');
listItem.appendChild(item);
newList.appendChild(listItem)
}
this.items.replaceWith(newList);
this.items = newList; // これを書かないと置き換えが完了しない
}
getItems() {
return this.items.children;
}
// 入力補完windowの位置を更新する
reDraw(cursor) {
this.box.style.top = ${parseInt(cursor.style.top) + parseInt(cursor.style.height) + 3}px;
this.box.style.left = ${parseInt(cursor.style.left)}px;
}
// 現在focusがあたっている入力候補を返す
getFocusedItem() {
return this.items.querySelector(':focus');
}
hasFocus(){
return this.getFocusedItem() != null;
}
// 補完候補の先頭にfocusを当てる
selectFirstItem() {
this.items.firstElementChild.firstElementChild.focus();
//console.log('the first item is focused.');
}
// 最初の補完候補にfocusがあたっているかどうか
hasFirstItemFocus() {
//console.log(selectedItem: ${this.getFocusedItem()});
return this.getFocusedItem()
== this.items.firstElementChild.firstElementChild;
}
// 次の補完候補に移動する
selectNextItem(cursor) {
// focusが当たっている要素を取得
const selectedItem = this.items.querySelector(':focus');
if(!selectedItem) {
this.selectFirstItem();
return;
}
if(selectedItem == this.items.lastElementChild) {
this.selectFirstItem();
return;
}
//selectedItem.nextElementSibling.firstElementChild.focus();
}
// 前の補完候補に移動する
selectPreviousItem(cursor) {
// focusが当たっている要素を取得
const selectedItem = this.items.querySelector(':focus');
if(!selectedItem) {
this.close();
return;
}
//selectedItem.previousElementSibling.firstElementChild.focus();
}
// 現在の選択候補の文字列を取得する
getCurrentItemString() {
const selectedItem = this.items.querySelector(':focus');
if(!selectedItem) {
return undefined;
}
return selectedItem.textContent;
}
}
code:script.js
function createGuiList(suggestTitles, suggestion) {
return suggestTitles
.map(title => {
const a = document.createElement('a');
a.setAttribute('tabindex', '0');
a.setAttribute('role', 'menuitem');
const div = document.createElement('div');
div.textContent = title;
a.appendChild(div);
a.onclick = () => {
copyTextToClipboard(title);
suggestion.close();
document.execCommand("paste");
}
return a;
});
}
code:script.js
function copyTextToClipboard(textVal){
// テキストエリアを用意する
var copyFrom = document.createElement("textarea");
// テキストエリアへ値をセット
copyFrom.textContent = textVal;
// bodyタグの要素を取得
var bodyElm = document.getElementsByTagName("body")0; // 子要素にテキストエリアを配置
bodyElm.appendChild(copyFrom);
// テキストエリアの値を選択
copyFrom.select();
// コピーコマンド発行
var retVal = document.execCommand('copy');
// 追加テキストエリアを削除
bodyElm.removeChild(copyFrom);
// 処理結果を返却
return retVal;
}