Add basic preview mode

This commit is contained in:
Samuel Georges 2015-08-01 20:20:43 +10:00
parent c6409a8680
commit aef1964553
5 changed files with 143 additions and 30 deletions

View File

@ -1,5 +1,6 @@
<?php namespace Backend\FormWidgets;
use Markdown;
use Backend\Models\EditorPreferences;
use Backend\Classes\FormWidgetBase;
@ -63,4 +64,14 @@ class MarkdownEditor extends FormWidgetBase
$this->addJs('/modules/backend/formwidgets/codeeditor/assets/js/build-min.js', 'core');
}
public function onRefresh()
{
$value = post($this->formField->getName());
$previewHtml = Markdown::parse($value);
return [
'preview' => $previewHtml
];
}
}

View File

@ -5,8 +5,6 @@
background: #fff;
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.field-markdowneditor textarea {
@ -20,23 +18,40 @@
.field-markdowneditor.editor-focus {
border: 1px solid #808c8d;
}
.field-markdowneditor.size-tiny .editor-write {
min-height: 50px;
.field-markdowneditor.size-tiny .editor-write,
.field-markdowneditor.size-tiny .editor-preview {
height: 50px;
}
.field-markdowneditor.size-small .editor-write {
min-height: 100px;
.field-markdowneditor.size-small .editor-write,
.field-markdowneditor.size-small .editor-preview {
height: 100px;
}
.field-markdowneditor.size-large .editor-write {
min-height: 200px;
.field-markdowneditor.size-large .editor-write,
.field-markdowneditor.size-large .editor-preview {
height: 200px;
}
.field-markdowneditor.size-huge .editor-write {
min-height: 250px;
.field-markdowneditor.size-huge .editor-write,
.field-markdowneditor.size-huge .editor-preview {
height: 250px;
}
.field-markdowneditor.size-giant .editor-write {
min-height: 350px;
.field-markdowneditor.size-giant .editor-write,
.field-markdowneditor.size-giant .editor-preview {
height: 350px;
}
.field-markdowneditor .editor-write {
position: relative;
margin: 15px;
}
.field-markdowneditor .editor-preview {
padding: 15px;
}
.field-markdowneditor.mode-tab .editor-preview {
overflow: auto;
display: none;
}
.field-markdowneditor.mode-tab.is-preview .editor-write {
display: none;
}
.field-markdowneditor.mode-tab.is-preview .editor-preview {
display: block;
}

View File

@ -12,6 +12,8 @@
this.$code = null
this.editor = null
this.$form = null
this.$buttons = null
this.$fixedButtons = null
$.oc.foundation.controlUtils.markDisposable(element)
Base.call(this)
@ -31,11 +33,14 @@
this.$el.attr('id', 'element-' + Math.random().toString(36).substring(7))
}
this.$el.addClass('mode-' + this.options.viewMode)
this.$form = this.$el.closest('form')
this.createCodeContainer()
this.createToolbar()
this.$toolbar.on('click', '.btn, .md-dropdown-button', this.proxy(this.onClickButton))
this.$toolbar.on('click', '.btn, .md-dropdown-button', this.proxy(this.onClickToolbarButton))
this.$form.on('oc.beforeRequest', this.proxy(this.onBeforeRequest))
$('[data-control="tooltip"]', this.$toolbar).tooltip()
$('[data-toggle="dropdown"]', this.$toolbar).dropdown()
@ -43,7 +48,8 @@
MarkdownEditor.prototype.dispose = function() {
this.$el.off('dispose-control', this.proxy(this.dispose))
this.$toolbar.off('click', '.btn, .md-dropdown-button', this.proxy(this.onClickButton))
this.$toolbar.off('click', '.btn, .md-dropdown-button', this.proxy(this.onClickToolbarButton))
this.$form.off('oc.beforeRequest', this.proxy(this.onBeforeRequest))
this.$el.removeData('oc.markdownEditor')
@ -55,18 +61,31 @@
this.$code = null
this.editor = null
this.$form = null
this.$buttons = null
this.$fixedButtons = null
this.isSplitMode = false
this.isPreview = false
this.isFullscreen = false
this.options = null
BaseProto.dispose.call(this)
}
MarkdownEditor.prototype.onClickButton = function(ev) {
MarkdownEditor.prototype.onClickToolbarButton = function(ev) {
var $button = $(ev.target),
action = $button.data('button-action'),
template = $button.data('button-template')
this[action](template)
$button.blur()
if (template) {
this[action](template)
}
else {
this[action]()
}
}
MarkdownEditor.prototype.createToolbar = function() {
@ -114,6 +133,9 @@
$buttons.wrapInner('<div data-control="toolbar" />')
this.$toolbar.append($buttons)
this.$toolbar.append($fixedButtons)
this.$fixedButtons = $fixedButtons
this.$buttons = $buttons
}
MarkdownEditor.prototype.createToolbarDropdown = function(button, $el) {
@ -163,9 +185,9 @@
/*
* Initialize ACE editor
*/
var editor = this.editor = ace.edit(this.$code.attr('id')),
options = this.options,
$form = this.$el.closest('form');
var editor = this.editor = ace.edit(this.$code.attr('id'))
editor.getSession().setValue(this.$textarea.val())
editor.getSession().setMode({ path: 'ace/mode/markdown' })
editor.setHighlightActiveLine(false)
@ -177,6 +199,21 @@
editor.on('focus', this.proxy(this.onFocus))
}
MarkdownEditor.prototype.updatePreview = function() {
var self = this
this.$el.request(this.options.refreshHandler, {
success: function(data) {
this.success(data)
self.$preview.html(data.preview)
}
})
}
MarkdownEditor.prototype.onBeforeRequest = function() {
this.$textarea.val(this.editor.getSession().getValue())
}
MarkdownEditor.prototype.onResize = function() {
this.editor.resize()
}
@ -193,6 +230,19 @@
* Button actions
*/
MarkdownEditor.prototype.togglePreview = function() {
if (!this.isPreview) {
this.updatePreview()
}
else {
this.editor.focus()
}
this.$el.toggleClass('is-preview', !this.isPreview)
$('.btn', this.$buttons).prop('disabled', !this.isPreview)
this.isPreview = !this.isPreview
}
MarkdownEditor.prototype.insertLine = function(template) {
var editor = this.editor,
pos = this.editor.getCursorPosition()
@ -204,13 +254,14 @@
editor.navigateTo(editor.getSelectionRange().start.row, Number.MAX_VALUE)
}
editor.insert('\n'+template+'\n')
editor.insert(template)
editor.focus()
}
MarkdownEditor.DEFAULTS = {
buttons: ['formatting', 'bold', 'italic', 'unorderedlist', 'orderedlist', 'link', 'horizontalrule'],
viewMode: 'tab'
viewMode: 'tab',
refreshHandler: null
}
// PLUGIN DEFINITION
@ -337,18 +388,18 @@
label: 'markdowneditor.horizontalrule',
icon: 'horizontalrule',
action: 'insertLine',
template: '---'
template: '\n\n---\n'
},
fullscreen: {
label: 'markdowneditor.fullscreen',
icon: 'fullscreen',
action: 'fullscreen.toggle',
action: 'toggleFullscreen',
fixed: true
},
preview: {
label: 'markdowneditor.preview',
cssClass: 'oc-button oc-icon-eye',
action: 'preview.toggle',
action: 'togglePreview',
fixed: true
}
}

View File

@ -23,11 +23,21 @@
&.editor-focus { border: 1px solid @color-form-field-border-focus; }
&.size-tiny .editor-write { min-height: @size-tiny; }
&.size-small .editor-write { min-height: @size-small; }
&.size-large .editor-write { min-height: @size-large; }
&.size-huge .editor-write { min-height: @size-huge; }
&.size-giant .editor-write { min-height: @size-giant; }
&.size-tiny {
.editor-write, .editor-preview { height: @size-tiny; }
}
&.size-small {
.editor-write, .editor-preview { height: @size-small; }
}
&.size-large {
.editor-write, .editor-preview { height: @size-large; }
}
&.size-huge {
.editor-write, .editor-preview { height: @size-huge; }
}
&.size-giant {
.editor-write, .editor-preview { height: @size-giant; }
}
//
// Code
@ -43,5 +53,30 @@
//
.editor-preview {
padding: 15px;
}
//
// Mode: Tab
//
&.mode-tab {
.editor-preview {
overflow: auto;
display: none;
}
&.is-preview {
.editor-write { display: none; }
.editor-preview { display: block; }
}
}
//
// Mode: Split
//
&.mode-split {}
}

View File

@ -5,6 +5,7 @@
<div
id="<?= $this->getId() ?>"
class="field-markdowneditor size-<?= $size ?> <?= $stretch?'layout-relative':'' ?>"
data-refresh-handler="<?= $this->getEventHandler('onRefresh') ?>"
data-control="markdowneditor">
<div class="layout control-toolbar editor-toolbar"></div>