13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

スマホのブラウザでも使い易いエディタを作りました。

※ブラウザアプリ開発向けエディタです。
この記事では開発中に得た知見とか(私的備忘録的用途)を共有できればなと思います。
実はとある別のシステムに内蔵されているものなので
エディタ及びフロント以外のことも書いてるかもしれません。

ES6で書きたいしrequireもしたいしいろんなところで動いてほしい

Webpackとかを使う方法とかいろいろあるかと思います。
(もともとバックグラウンドはtypeScriptと
Webpackを使っていたプロジェクトではありました。)
先にES6(ナウいスッキリしたJavaScriptの書き方だと思っています)を
ES5(割といろんなところで動きそうなやつ)にすることだけ解決して
フロントでもrequireしたくなって対応してなので安直な対応になりました。

ES6 to ES5

yarn add babel-cli babel-preset-es2015 --dev
echo '{ "presets": ["es2015"] }' > .babelrc
babel dev.js -w -o app.js
// dev.js
const print = value => console.log(value);

↓ 多分こんな感じに

// app.js
function print(value){
  console.log(value);
}

-w ファイルの更新を監視するオプションです。
--compact=true 多分余計なスペースや改行を消したりするやつ
--source-maps ソースマップを出力するオプションでデバッグの際に便利です。

require

// print.js

module.exports = value => console.log(value); 
// dev.js

const print = require('./print');
print('Hello!');
yarn add watchify --dev
watchify dev.js -o app.js

ここまでしたらあとは

<script src="./app.js"></script>

読み込ませるだけ。
複数のファイルにコードを分割しても
ブラウザからのリクエスト回数を減らせたりといい感じです。

reveal.js – The HTML Presentation Framework https://revealjs.com/#/
にてscssやejsを使ったり
requireを使えるようにしようとしたときのものを流用できました。

とりあえずこれらは 
package.jsonscripts に登録しておくと便利だと思います。

https://ace.c9.io

ブラウザ上で動く非常に高機能なエディタです。
豊富な言語対応、コードのハイライトや補完、インデントの補助、undo・redo…etc
https://github.com/ajaxorg/ace/blob/master/LICENSE

<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ext-language_tools.js"></script>

<div id="editor" style="height: 100vh;"></div>

<script>
const editor = ace.edit('editor');
editor.setTheme('ace/theme/monokai');
editor.setFontSize(14);

editor.getSession().setMode('ace/mode/javascript');
// ace/mode/html or ace/mode/css

editor.getSession().setUseWrapMode(true);
editor.getSession().setTabSize(2);
editor.$blockScrolling = Infinity;
editor.setOptions({
  enableBasicAutocompletion: true,
  enableSnippets: true,
  enableLiveAutocompletion: true
});
</script>

image.png

内容更新イベント・内容取得・内容更新

editor.getSession().on('change', () => {
  if (editor.getValue() === 'ねこ') editor.getValue('にゃーん');
});

ねこ と書いたら多分 にゃーん となります。 😺

カーソル(セレクタ)変更イベント・カーソル位置取得

editor.selection.on('changeSelection', () => {
  console.log(editor.selection.getCursor());
  // {row: 0, column: 0}
});

カーソルの情報は例えば文章中に特定の文字を挿入する機能を実装したい場合に有効です。

const editorVal = editor.getValue();
let editorValLines = /\n/.test(editorVal) ? editorVal.split('\n') : [editorVal];
const targetLine = editorValLines[editor.selection.getCursor().row];
const beforeVal = targetLine.substr(0, editor.selection.getCursor().column);
const afterVal = targetLine.substr(editor.selection.getCursor().column, targetLine.length);
editorValLines[cursorInf.pos.row] = beforeVal + '挿入したい文字' + afterVal;
editor.setValue(editorValLines.join('\n'));

undo・redo

editor.undo();
editor.redo();

😊

jquery-linedtextarea

https://github.com/cotenoni/jquery-linedtextarea

指定したtextarea要素に行数を添えてくれるJQueryプラグインです。

https://github.com/cotenoni/jquery-linedtextarea/blob/master/jquery-linedtextarea-license.txt

暇つぶしにスマホでhttps://atcoder.jpの過去問題や
https://paiza.jpのスキルチェックの問題を提出する方々が
いらっしゃるかと思います。
ios__________.jpg
sample

とくにPaizaのスキルチェックのエディタは
Ace editorを使っている印象を受ける程高機能です。
しかしこれらをスマホブラウザで使ってみたところコピペ、
セレクトができない場合が多かったです。

そこでtextareaとAce editorで行き来できるように実装しました。
textareaの方には行数の表示くらいはするようにしました。

wget https://raw.githubusercontent.com/cotenoni/jquery-linedtextarea/master/jquery-linedtextarea.css
wget https://raw.githubusercontent.com/cotenoni/jquery-linedtextarea/master/jquery-linedtextarea.js
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<link rel="stylesheet" href="./jquery-linedtextarea.css">
<script src="./jquery-linedtextarea.js"></script>

<textarea style="height: 100vh;"></textarea>

<script>
$('textarea').linedtextarea({selectedLine: 1});
</script>

image.png

textareaでの内容更新イベント

内容が更新されたときに発火してほしい。

$('textarea').change(() => {
  console.log('textareaのフォーカスが外れたときとかにしか発火しない。');
});

$('textarea').keyup(() => { // or keydown
  console.log('十字キーとかでも発火してしまう。 *ここではスマホで使うのが大前提だが');
});

$('textarea').on('input propertychange', () => {
  console.log('上手くいったもの');
});

textareaでのカーソル位置取得

$('textarea').eq(0).on('keyup click focus', () => {
  console.log($('textarea').eq(0).prop('selectionStart')); // 0
});

Ace editorと違い、rowやcolumnでの情報ではなく
$('textarea').eq(0).val() での文字列的に何文字目あたりに
カーソル(セレクタ)があるかというような数値の情報な印象を感じました。

スマホでのJQuery-UI

マウスでグリグリ動かせる draggable な要素を
作れたりする有名なJQueryプラグインです。
スマホではそのままでは使えないので以下を導入する必要があります。

<script src='https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js'></script>

スマホでも動くようになったけど draggable な要素上のボタンとかが押せない

脳筋的解決になりますが draggable な要素のスペースやポインタを作って
ボタンとかをのせた要素を position: absolute; な要素にさせて
先述の draggable な要素のスペースやポインタと
JavaScriptで重ねさせたり追尾させたりしてみました。

Auto Indent

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.10-beta1/beautify.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.10-beta1/beautify-css.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.8.10-beta1/beautify-html.min.js"></script>

<textarea id="html"></textarea>
<textarea id="css"></textarea>
<textarea id="js"></textarea>

<span id="auto">AUTO</span>

<script>
const beautifyOp = { indent_size: 2, space_in_empty_paren: true };

$('#auto').click(() => {
  $('#html').val(html_beautify($('#html').val(), beautifyOp));
  $('#css').val(css_beautify($('#css').val(), beautifyOp));
  $('#js').val(js_beautify($('#js').val(), beautifyOp));
});
</script>

思ったよりあっさり実装できてしまって感動もの。
https://github.com/beautify-web/js-beautify MIT😊

こんな左寄せコードも…
image.png

美しく✨
image.png

#成果物
image.png

実装済

  • 通常のtextareaで記述するモード ⬜
  • 行数表示つきのtextareaで記述するモード 🔢
  • AceEditorモード 🎨
  • 上記3つ全て表示 🚀
  • 上記3つの内容の連携
  • 上記3つの切り替え(表示・非表示)
  • 編集(表示)するファイルの切り替え
    • HTML CSS JavaScript から何れか1つ或いは全部
  • AutoIndent
  • undo
  • redo
  • よく使う記号などの挿入機能
    • ※スマホにてダブルクォーテーションなどが全角になったりする対策
  • ボタン一覧を好きな場所に設置可能

これから

  • コードのsave機能
  • アプリのプレビュー機能
  • アプリの公開ボタン

※バックグラウンドが絡むものたち

経緯

N高 🏫

私が在学中の学校法人角川ドワンゴ学園N高等学校は
通信制の高等学校ではあるものの
通学コースというものがあり、キャンパスもあり、オープンキャンパスもしています。
https://nnn.ed.jp/

オープンキャンパス 🌸

オープンキャンパスは月1度以上の頻度で行われ
たくさんの中学生と保護者の方々がお越し下さいます。(中には常連な方も)
プログラミングやプロジェクト学習の体験授業を行っています。

プログラミング体験授業 💻

プログラミングの体験授業ではN高生が作ったブラウザアプリを改造して
いわゆる自分色に変えていくという
40分前後しか時間が設けられてない割には濃い内容でした。
https://nnn.ed.jp/news/blog/archives/5283.html

新しい教材 📕

しかし最近は良くも悪くもScratchを採用したので
また別に新しい教材を作ろうと思いました。
自分自身のPCを持ってない方でもオープンキャンパス後でも利用できると
良いと思い…

  • 環境構築不要
  • ブラウザアプリを作れる(&作ったものを保護者や友人に触って貰える)
  • スマホのブラウザで 📱

上記3つのルール的なものの下いろいろ考えていたら
スマホのブラウザ上で動く使いやすいエディタが欲しいなと思いました。

(私自身の習得の機会も兼ねてネイティブアプリも考えたものの場合によっては
ペアレンタルコントロール等の制限があり、
保護者とコミュニケーションをするという
案外面倒な環境構築が必要になったりするかも😅)

最後に

プログラミングは楽しい上に美味しいので
いろんな方々に是非習得していってほしいなと思っています。
※とくにものづくりが好きな私みたいな方とかには🔧

既にプログラミング以外の得意なことを持っている方は尚更プログラミングと
合わせて使うことでより良いものになるかもしれません。(メディアアートとか)
あとコンテストや登壇会などのイベント、コミュニティも活発です。

とくにN高等学校での学校生活では、プログラミングをしている生徒や
現役のエンジニアの講師の方々が多くいて、彼らとプログラミングを教え会ったり
大会やイベントに参加したりできました。本当に良い思い出となりました。
私の留学先のキリロム工科大学(カンボジア🇰🇭 https://kit.edu.kh)でも
N高等学校で得たプログラミングなどのノウハウを活かせると嬉しく思います。

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?