表示調整
閉じる
挿絵表示切替ボタン
▼配色
▼行間
▼文字サイズ
▼メニューバー
×閉じる

ブックマークに追加しました

設定
0/400
設定を保存しました
エラーが発生しました
※文字以内
ブックマークを解除しました。

エラーが発生しました。

エラーの原因がわからない場合はヘルプセンターをご確認ください。

ブックマーク機能を使うにはログインしてください。
とある割烹芸人の開発日誌 ~100日以内に割烹エディターをリリースする割烹芸人~  作者: とある割烹芸人まーくつーせかんど
α版への道
19/48

48日目 割烹芸人の開発8

こー

次はデフォルトの段落を改良していきます。


デフォルトの段落も色々と機能が足りてないのでカスタマイズします。


class Paragraph2 {


 static get enableLineBreaks(){

return true;

}

static get DEFAULT_PLACEHOLDER() {

return '';

}


constructor({data, config, api}) {

this.api = api;


this._CSS = {

block: this.api.styles.block,

wrapper: 'ce-paragraph'

};


this.onKeyUp = this.onKeyUp.bind(this);

this.onKeyDOWN = this.onKeyDOWN.bind(this);


this._placeholder = config.placeholder ? config.placeholder : Paragraph.DEFAULT_PLACEHOLDER;

this._data = {};


this._element = this.drawView();

this._setform=false;


this.data = {

text: data.text || '',

position:data.position !== undefined ? data.position : 'left',

size: data.size !== undefined ? data.size : '1',

withBorder: data.withBorder !== undefined ? data.withBorder : false,

color: data.color !== undefined ? data.color : '#000',

backcolor: data.backcolor !== undefined ? data.backcolor : '#fff'

};


this._changePosition(this.data.position);

if(this.data.withBorder){

this._element.classList.toggle('withBorder');

}


this.settings = [

{

name:'left',

icon:'左寄'

},

{

name:'center',

icon:'中央'

},

{

name:'right',

icon:'右寄'

},

{

name: 'withBorder',

icon:'枠線'

},

{

name: 'detail',

icon:'詳細'

}

]

}


onKeyUp(e) {

if (e.code !== 'Backspace' && e.code !== 'Delete') {

return;

}


const textblock = this._element.querySelector('[contenteditable]');


const {textContent} = textblock;


if (textContent === '') {

textblock.innerHTML = '';

}


}


onKeyDOWN(e){

if( e.key === 'Enter' && !e.shiftKey ){

/*

const textblock = this._element.querySelector('[contenteditable]');


let sel = document.getSelection();


const pos = sel.anchorOffset;


const str = textblock.innerHTML ;


textblock.innerHTML=str.slice(0, pos) + '

' + str.slice(pos);


console.log(textblock.innerHTML);

textblock.dispatchEvent( new KeyboardEvent( "keydown", { keyCode: 13 }));

*/


e.stopPropagation();

e.preventDefault();


let selection = window.getSelection(),

range = selection.getRangeAt(0),

newline = document.createTextNode('\r\n');


let del = document.createElement('br');


del.appendChild(range.extractContents());

//range.insertNode(del);


range.deleteContents();

//range.insertNode(newline);

range.insertNode(del);

//range.setStartAfter(newline);

//range.setEndAfter(newline);

range.setStartAfter(del);

range.setEndAfter(del);

range.collapse(false);

selection.removeAllRanges();

selection.addRange(range);



}

}




drawView() {

let containr = document.createElement('DIV');

let textblock = document.createElement('DIV');

let setform = document.createElement('form');


containr.classList.add(this._CSS.wrapper, this._CSS.block);


textblock.contentEditable = true;

textblock.classList.add('p-textblock');


document.execCommand('defaultParagraphSeparator', false, 'div');


textblock.addEventListener('keyup', this.onKeyUp);

textblock.addEventListener('keydown', this.onKeyDOWN);



containr.appendChild(textblock);

containr.appendChild(setform);


return containr;

}


render() {

return this._element;

}


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

}else if(tune.name === 'left' || tune.name === 'center' || tune.name === 'right'){

button.classList.toggle(this.api.styles.settingsButtonActive, tune.name === this.data.position);

}else{

if(this._setform){

button.classList.toggle(this.api.styles.settingsButtonActive);

}

}


button.addEventListener('click', ()=>{

if(tune.name === 'detail'){

button.classList.toggle(this.api.styles.settingsButtonActive);

if(button.classList.contains(this.api.styles.settingsButtonActive)){

this._showColorPicker();

this._setform=true;

}else{

this._hideColorPicker();

this._setform=false;

}


}else if(tune.name === 'withBorder'){


button.classList.toggle(this.api.styles.settingsButtonActive);

this._changewithborder(tune);

}else{


wrapper.querySelectorAll(`.${this.api.styles.settingsButton}`).forEach(el => {

if((el.innerHTML === '左寄' || el.innerHTML === '中央' || el.innerHTML === '右寄') ){

el.classList.remove(this.api.styles.settingsButtonActive);

}

});

button.classList.add(this.api.styles.settingsButtonActive);

this._changePosition(tune.name);

}

});

});


return wrapper;

}


merge(data) {

let newData = {

text : this.data.text + data.text

};


this.data = newData;

}


_changePosition(tune){

this.data.position=tune;

this._element.classList.remove('center');

this._element.classList.remove('right');

this._element.classList.remove('left');


this._element.classList.add(tune);

}


_changewithborder(tune){

this._element.classList.toggle('withBorder');

this.data.withBorder = !this.data.withBorder;

}


validate(savedData) {

if (savedData.text.trim() === '') {

return false;

}


return true;

}


save(toolsContent) {

return {

text: toolsContent.innerHTML,

position:this.data.position,

size:this.data.size,

color:this.data.color,

backcolor:this.data.backcolor

};

}


onPaste(event) {

const data = {

text: event.detail.data.innerHTML

};


this.data = data;

}


static get conversionConfig() {

return {

export: 'text', // to convert Paragraph to other block, use 'text' property of saved data

import: 'text' // to covert other block's exported string to Paragraph, fill 'text' property of tool data

};

}


static get sanitize() {

return {

text: {

br: true,

}

};

}


_showColorPicker(){

const setbox = this._element.querySelector('form');


const textcolor = document.createElement('input');

const backcolor = document.createElement('input');

const sizeblock = document.createElement('input');


textcolor.type = 'color';

textcolor.value = this.data.color;


backcolor.type = 'color';

backcolor.value = this.data.backcolor;


sizeblock.type = 'number';

sizeblock.step = '0.1';

sizeblock.min= "0.1" ;

sizeblock.max= "10";

sizeblock.value = this.data.size;


setbox.insertAdjacentHTML('beforeend', '文字色:');

setbox.appendChild(textcolor);

setbox.insertAdjacentHTML('beforeend', '

背景色:');

setbox.appendChild(backcolor);

setbox.insertAdjacentHTML('beforeend', '

サイズ:');

setbox.appendChild(sizeblock);


textcolor.onchange = () => {

const textblock = this._element.querySelector('[contenteditable]');


this.data.color = textcolor.value;

textblock.style.color=this.data.color;

};


backcolor.onchange = () => {

const textblock = this._element.querySelector('[contenteditable]');


this.data.backcolor = backcolor.value;

textblock.style.background=this.data.backcolor;

};


sizeblock.addEventListener('change', (event) => {

const textblock = this._element.querySelector('[contenteditable]');


this.data.size = sizeblock.value;

textblock.style.fontSize = this.data.size+'em';

});


sizeblock.addEventListener('keydown', (event) => {

if( event.key === 'Enter'){

const textblock = this._element.querySelector('[contenteditable]');


this.data.size = sizeblock.value;

textblock.style.fontSize = this.data.size+'em';

event.preventDefault();

}

});


}


_hideColorPicker(){

const setbox = this._element.querySelector('form');


setbox.innerHTML='';

}


get data() {


const textblock = this._element.querySelector('[contenteditable]');

let text = textblock.innerHTML;


this._data.text = text;


return this._data;

}


set data(data) {

this._data = data || {};


const textblock = this._element.querySelector('[contenteditable]');

textblock.innerHTML = this._data.text || '';

}


static get pasteConfig() {

return {

tags: [ 'P' ]

};

}


static get toolbox() {

return {

icon: '文字',

title: '段落の挿入'

};

}


}


挿絵(By みてみん)



主に頑張ったのは、エンターキーでbrタグを入れるようにしたところ。どこのエディターもそうなんですけど、contenteditableにするとエンターキーでデフォルトのだとdivブロックが挿入されます。


それをbrに変えてます。


で、あとは位置、背景、文字色、サイズかな。


こんな感じで最低限彩れるようになりました。


挿絵(By みてみん)

挿絵(By みてみん)

横向きってむつかしいですね。

評価をするにはログインしてください。
ブックマークに追加
ブックマーク機能を使うにはログインしてください。
― 新着の感想 ―
このエピソードに感想はまだ書かれていません。
感想一覧
+注意+

特に記載なき場合、掲載されている作品はすべてフィクションであり実在の人物・団体等とは一切関係ありません。
特に記載なき場合、掲載されている作品の著作権は作者にあります(一部作品除く)。
作者以外の方による作品の引用を超える無断転載は禁止しており、行った場合、著作権法の違反となります。

この作品はリンクフリーです。ご自由にリンク(紹介)してください。
この作品はスマートフォン対応です。スマートフォンかパソコンかを自動で判別し、適切なページを表示します。

↑ページトップへ