45日目 割烹芸人の開発5
ひたすらコードを書いていくだけの単純なお仕事です。
画像ブロックを作っていきます。
editor.jsのプラグインには画像ブロックもありますが、小説家になろうの活動報告で使えるようにはできていません(当たり前か)
活動報告で使えるようにカスタマイズしていく必要があります。
ということで作ります。
class SimpleImage{
static get enableLineBreaks() {
return true;
}
constructor({data, api, config}){
this.api = api;
this.config = config || {};
this.data = {
url: data.url || '',
position:data.position !== undefined ? data.position : 'left',
withBorder: data.withBorder !== undefined ? data.withBorder : false,
editURL: false
};
this.wrapper = undefined;
this.settings = [
{
name:'left',
icon:'左寄'
},
{
name:'center',
icon:'中央'
},
{
name:'right',
icon:'右寄'
},
{
name: 'withBorder',
icon:'枠線'
},
{
name: 'editURL',
icon:'URL',
}
]
}
render(){
this.wrapper = document.createElement('div');
this.wrapper.classList.add('image');
if(this.data && this.data.url){
this._createImage(this.data.url);
return this.wrapper;
}
this._resetImage()
return this.wrapper;
}
save(blockContent){
const input = blockContent.querySelector('img');
if (!input) {
return this.data;
}
return{
url:input.src,
withBorder:this.data['withBorder'],
potision:this.data.position
}
}
validate(saveData){
if(!saveData.url.trim()){
return false;
}
return true;
}
static get sanitize(){
return{
url:false,
withBorder:{},
potision:{},
linkURL:false
}
}
static get toolbox(){
return {
title:'画像の挿入(みてみんOnly)',
icon:'画像'
}
}
}
まずはクラス設定して、位置情報と枠線を追加できるようにします。
まずdataにpositionを追加します。rendersettingsようにsettingsに位置情報の選択ボタンを追加。またイメージURLの編集用のボタンも追加します。
renderSettings(){
const wrapper = document.createElement('div');
this.settings.forEach(tune =>{
let button = document.createElement('div');
button.classList.add(this.api.styles.settingsButton);
button.innerHTML = tune.icon;
wrapper.appendChild(button);
if(tune.name === 'withBorder'){
button.classList.toggle(this.api.styles.settingsButtonActive, this.data[tune.name]);
}
button.classList.toggle(this.api.styles.settingsButtonActive, tune.name === this.data.position);
button.addEventListener('click', ()=>{
if(tune.name === 'editURL'){
this._resetImage();
}else if(tune.name === 'withBorder'){
this._toggleTune(tune.name);
button.classList.toggle(this.api.styles.settingsButtonActive);
}else if(tune.name === 'linkURL'){
button.classList.toggle(this.api.styles.settingsButtonActive);
}else{
this._alingSet(tune.name);
button.classList.add(this.api.styles.settingsButtonActive);
wrapper.querySelectorAll(`.${this.api.styles.settingsButton}`).forEach(el => {
if(tune.name==='left' && (el.innerHTML === '中央' || el.innerHTML === '右寄') ){
el.classList.remove(this.api.styles.settingsButtonActive);
}else if(tune.name==='right' && (el.innerHTML === '中央' || el.innerHTML === '左寄') ){
el.classList.remove(this.api.styles.settingsButtonActive);
}else if(tune.name==='center' && (el.innerHTML === '右寄' || el.innerHTML === '左寄') ){
el.classList.remove(this.api.styles.settingsButtonActive);
}
});
}
});
});
return wrapper;
}
_createImage(url){
const image = document.createElement('img');
image.src = url;
this.wrapper.innerHTML='';
this.wrapper.appendChild(image);
this._acceptTuneView();
}
_resetImage(){
const input = document.createElement('input');
this.wrapper.innerHTML='';
this.wrapper.appendChild(input);
input.placeholder = 'みてみんのURLを貼り付けてください'
input.addEventListener('paste',(event)=>{
this._createImage(event.clipboardData.getData('text/plain'));
});
input.addEventListener('keydown', (event) => {
const [ENTER, A] = [13, 65];
switch (event.keyCode) {
case ENTER:
event.preventDefault();
event.stopPropagation();
this._createImage(input.value);
break;
}
});
}
_toggleTune(tune){
this.data[tune] = !this.data[tune];
this._acceptTuneView();
}
_acceptTuneView(){
this.wrapper.classList.toggle('withBorder', this.data['withBorder']);
}
_alingSet(tune){
this.wrapper.setAttribute("style", `text-align:${tune};`);
this.data.position=tune;
}
_resetImageと_alignsetを追加してボタンをおしたら画像を消したり、スタイルを変えてるようにしておきます。
ということで完成。




