Commit 19f67ab8 by tady

wysiwyg editor

parent 3f0451f8
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
......@@ -16,6 +16,7 @@
// require turbolinks
//= require ./lib/jquery.ui.widget
//= require_tree ./lib
//= require_tree ./modules
//= require_tree .
_.mixin(_.string.exports());
......
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# TODO:
# mod-mdEditorがページ内に複数あった場合の処理
$.fn.extend
mod_mdEditor: (options) ->
settings =
# preview api url
end_point: ''
settings = $.extend settings, options
return @each ()->
$root = $(@)
# Automaticaly change textarea height.
$root.find('.mod-mdEditor-body').autosize();
# disable tab key
$root.find('.mod-mdEditor-body').on 'keydown', (e) ->
$this = $(@)
keyCode = e.keyCode || e.which
# tab key
if keyCode is 9
e.preventDefault()
start = $this.get(0).selectionStart
end = $this.get(0).selectionEnd
# set textarea value to: text before caret + tab + text after caret
$this.val($this.val().substring(0, start) +
'\t' +
$this.val().substring(end))
# put caret at right position again
$this.get(0).selectionStart =
$this.get(0).selectionEnd = start + 1
# enter key
else if keyCode is 13
val = $this.val()
start = $this.get(0).selectionStart
bl = val.lastIndexOf("\n", start-1)
line = val.substring(bl, start)
lm = line.match(/^\s+/)
ns = if lm? then lm[0].length - 1 else 0
nv = val.substring(0, start) + "\n"
_(ns).times ->
nv += "\t"
$this.val(nv + val.substring(start))
$this.get(0).selectionStart =
$this.get(0).selectionEnd = start + ns + 1
e.preventDefault()
# タグを選択可能に
$root.find('.mod-mdEditor-tags').select2 {
tags: window.RV.AllTags
}
# Previewを生成
generatePreview = ->
$.post(settings.end_point, {
'text': $root.find('.mod-mdEditor-body').val()
'authenticity_token': $("meta[name='csrf-token']").attr('content')
})
.done (data) ->
$root.find('.mod-mdEditor-preview').html(data)
# TODO
prettyPrint()
$('.mod-mdEditor-body').on('keyup mouseup change', generatePreview)
generatePreview()
# TODO:
# mod-mdEditorがページ内に複数あった場合の処理
$.fn.extend
mod_mdEditor: (options) ->
settings =
# preview api url
end_point: ''
settings = $.extend settings, options
return @each ()->
$root = $(@)
$textarea = $root.find('.mod-mdEditor-textarea')
# textareのサイズ調整
$textarea.autosize();
# textareaのtabキー制御,indent維持
$textarea.on 'keydown', (e) ->
$this = $(@)
keyCode = e.keyCode || e.which
# tab key
if keyCode is 9
e.preventDefault()
start = $this.get(0).selectionStart
end = $this.get(0).selectionEnd
# set textarea value to: text before caret + tab + text after caret
$this.val($this.val().substring(0, start) +
'\t' +
$this.val().substring(end))
# put caret at right position again
$this.get(0).selectionStart =
$this.get(0).selectionEnd = start + 1
# enter key
else if keyCode is 13
e.preventDefault()
val = $this.val()
start = $this.get(0).selectionStart
bl = val.lastIndexOf("\n", start-1)
line = val.substring(bl, start)
lm = line.match(/^\s+/)
ns = if lm? then lm[0].length - 1 else 0
nv = val.substring(0, start) + "\n"
_(ns).times ->
nv += "\t"
$this.val(nv + val.substring(start))
$this.get(0).selectionStart =
$this.get(0).selectionEnd = start + ns + 1
# タグを選択可能に
$root.find('.mod-mdEditor-tags').select2 {
tags: window.RV.AllTags
}
# Previewを生成
generatePreview = ->
$.post(settings.end_point, {
'text': $textarea.val()
'authenticity_token': $("meta[name='csrf-token']").attr('content')
})
.done (data) ->
$root.find('.mod-mdEditor-preview').html(data)
# TODO
prettyPrint()
$textarea.on('keyup mouseup change', generatePreview)
generatePreview()
# textの行数をcount
count_line_number = (text) ->
matches = text.match(/\n/g)
if matches? then matches.length + 1 else 1
replace_regexp_meta = (str) ->
b = str.replace(/([\.\^\$\[\]\*\+\?\|\(\)])/g, "\\$1")
console.log str + ' -> ' + b
b
# 行の先頭に文字を挿入
md_head_insert_string = (insert_str) ->
textarea_text = $textarea.val()
console.log 'insert_str: ' + insert_str
sel_start_pos = $textarea.get(0).selectionStart
console.log 'sel_start_pos: ' + sel_start_pos
# sel_end_pos = $textarea.get(0).selectionEnd
# console.log 'sel_end_pos: ' + sel_end_pos
# # textの全行数
# line_num = count_line_number(textarea_text)
# console.log('line_num: ' + line_num)
# # 現在行の行数
# current_line_num = count_line_number(textarea_text.substr(0, sel_start_pos))
# console.log('current_line_num: ' + current_line_num)
# 現在行の最初の文字の位置
current_line_head_pos = textarea_text.lastIndexOf("\n", sel_start_pos - 1) + 1
console.log('current_line_head_pos: ' + current_line_head_pos)
# 現在行のカーソル位置
current_pos_in_line = sel_start_pos - current_line_head_pos
console.log('current_pos_in_line: ' + current_pos_in_line)
# すでに挿入済みの場合は取り除く
insert_str_re = new RegExp('^' + replace_regexp_meta(insert_str), "g") # TODO ?
if textarea_text.substring(current_line_head_pos).match(insert_str_re)
$textarea.val([
textarea_text.substring(0, current_line_head_pos),
textarea_text.substring(current_line_head_pos).replace(insert_str_re, '')
].join(''))
else
$textarea.val([
textarea_text.substring(0, current_line_head_pos),
insert_str,
textarea_text.substring(current_line_head_pos)
].join(''))
# 選択文字を囲う
md_wrap_string = (wrap_str) ->
textarea_text = $textarea.val()
console.log 'wrap_str: ' + wrap_str
sel_start_pos = $textarea.get(0).selectionStart
console.log 'sel_start_pos: ' + sel_start_pos
sel_end_pos = $textarea.get(0).selectionEnd
console.log 'sel_end_pos: ' + sel_end_pos
# 文字が選択されていなければplaceholderを挿入
if sel_start_pos == sel_end_pos
placeholder_str = '<ここに文字>'
$textarea.val([
textarea_text.substring(0, sel_start_pos),
placeholder_str,
textarea_text.substring(sel_end_pos)
].join(''))
$textarea.get(0).selectionEnd = sel_end_pos + 2 + 2 * wrap_str.length + placeholder_str.length
console.log '$textarea.get(0).selectionEnd: ' + $textarea.get(0).selectionEnd
# execute self.
md_wrap_string(wrap_str)
return
console.log '$textarea.get(0).selectionStart: ' + $textarea.get(0).selectionStart
console.log '$textarea.get(0).selectionEnd: ' + $textarea.get(0).selectionEnd
# すでに挿入済みの場合は取り除く
wrap_str_re = new RegExp('^ ' + replace_regexp_meta(wrap_str))
console.log wrap_str_re
wrap_str_re_end = new RegExp(replace_regexp_meta(wrap_str) + ' $')
if textarea_text.substring(sel_start_pos, sel_end_pos).match(wrap_str_re)
console.log textarea_text.substring(sel_start_pos, sel_end_pos).replace(wrap_str_re, '')
console.log textarea_text.substring(0, sel_start_pos)
console.log textarea_text.substring(sel_end_pos)
$textarea.val([
textarea_text.substring(0, sel_start_pos),
textarea_text.substring(sel_start_pos, sel_end_pos).
replace(wrap_str_re, '').
replace(wrap_str_re_end, ''),
textarea_text.substring(sel_end_pos)
].join(''))
else
$textarea.val([
textarea_text.substring(0, sel_start_pos),
' ',
wrap_str,
textarea_text.substring(sel_start_pos, sel_end_pos),
wrap_str,
' ',
textarea_text.substring(sel_end_pos)
].join(''))
# カーソルの終了位置を移動
$textarea.get(0).selectionEnd = sel_end_pos + 2 + 2 * wrap_str.length
$textarea.get(0).selectionStart = sel_start_pos
console.log '$textarea.get(0).selectionStart: ' + $textarea.get(0).selectionStart
console.log '$textarea.get(0).selectionEnd: ' + $textarea.get(0).selectionEnd
# WYSIWYG
$root.find('.mod-mdEditor-btn-h1').on 'click', (e) ->
e.preventDefault()
md_head_insert_string('# ')
generatePreview()
$root.find('.mod-mdEditor-btn-h2').on 'click', (e) ->
e.preventDefault()
md_head_insert_string('## ')
generatePreview()
$root.find('.mod-mdEditor-btn-h3').on 'click', (e) ->
e.preventDefault()
md_head_insert_string('### ')
generatePreview()
$root.find('.mod-mdEditor-btn-ol').on 'click', (e) ->
e.preventDefault()
md_head_insert_string('1. ')
generatePreview()
$root.find('.mod-mdEditor-btn-ul').on 'click', (e) ->
e.preventDefault()
md_head_insert_string('- ')
generatePreview()
$root.find('.mod-mdEditor-btn-bold').on 'click', (e) ->
e.preventDefault()
md_wrap_string('**')
generatePreview()
$root.find('.mod-mdEditor-btn-italic').on 'click', (e) ->
e.preventDefault()
md_wrap_string('_')
generatePreview()
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
// Place all the styles related to the apis controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
// Place all the styles related to the flow controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
......@@ -13,7 +13,7 @@
// }
// }
.mod-mdEditor-body {
.mod-mdEditor-textarea {
width: 100%;
min-height: 400px;
font-size: 9pt;
......
// Place all the styles related to the posts controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
// Place all the styles related to the search controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
// Place all the styles related to the stock controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
// Place all the styles related to the tags controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
......@@ -8,6 +8,7 @@ html lang="ja"
link href="//netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap-theme.min.css" rel="stylesheet" /
link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/1.6.4/fullcalendar.css" rel="stylesheet" /
link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/1.6.4/fullcalendar.print.css" rel="stylesheet" /
link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"
= stylesheet_link_tag "application", media: "all"
= render_style
= csrf_meta_tags
......
......@@ -8,6 +8,7 @@
ul
- @post.errors.full_messages.each do |msg|
li= msg
.row
.col-xs-10
.field
......@@ -19,18 +20,36 @@
= f.submit class: 'btn btn-primary js-disable-confirm-unload', id: 'save_button'
.row
.col-xs-8
.col-xs-12
.field
.input-group
span.input-group-addon= f.label :tags
= hidden_field :post, :tags, class: 'mod-mdEditor-tags', style: 'width:300px', value: @post.tags.map{ |_tag| _tag.name }.join(',')
.col-xs-4
.row
.col-xs-12
.btn-toolbar role="toolbar"
.btn-group.btn-group-xs
button.btn.btn-default.mod-mdEditor-btn-h1 type="button" H1
button.btn.btn-default.mod-mdEditor-btn-h2 type="button" H2
button.btn.btn-default.mod-mdEditor-btn-h3 type="button" H3
.btn-group.btn-group-xs
button.btn.btn-default.mod-mdEditor-btn-bold type="button"
i.fa.fa-bold
button.btn.btn-default.mod-mdEditor-btn-italic type="button"
i.fa.fa-italic
button.btn.btn-default.mod-mdEditor-btn-ol type="button"
i.fa.fa-list-ol
button.btn.btn-default.mod-mdEditor-btn-ul type="button"
i.fa.fa-list-ul
/ button.btn.btn-default.mod-mdEditor-btn-link type="button"
/ i.fa.fa-link
br/
.row
.col-xs-6.col-md-6
.field
= f.text_area :body, class: 'mod-mdEditor-body'
= f.text_area :body, class: 'mod-mdEditor-textarea'
.col-xs-12.col-sm-6.col-md-6
.box-text
.text-box.body.viewer.github.mod-mdEditor-preview
......@@ -38,11 +57,11 @@
input#fileupload data-url="/apis/file_receiver" multiple="" name="files[]" style="display:none" type="file" /
- content_for :footer_js do
javascript:
$.setConfirmUnload();
// $.setConfirmUnload();
$('#post-form').mod_mdEditor({end_point: '/apis/markdown_preview'});
$.mod_fileuploader({
$input: $('#fileupload'),
$textarea: $('.mod-mdEditor-body')
$textarea: $('.mod-mdEditor-textarea')
});
......@@ -24,7 +24,7 @@ a.list-group-item.post-list.mod-hover-hidden data-post-id=post.id href=post_path
span.mod-hover-hidden-item
| 読了時間
| &nbsp;#{post.read_time}&nbsp;&nbsp;
span.glyphicon.glyphicon-edit
span.glyphicon.glyphicon-comment
span.mod-hover-hidden-item
| コメント
| &nbsp;#{post.comments.count}&nbsp;&nbsp;
......
......@@ -22,7 +22,7 @@
.col-xs-6.col-md-6
.field
/! <haml:loud> f.label :body </haml:loud><br
= f.text_area :body, class: 'mod-mdEditor-body'
= f.text_area :body, class: 'mod-mdEditor-textarea'
/! /span
.col-xs-12.col-sm-6.col-md-6
.box-text
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment