Markdown formwidget improvements (#5004)

* add readonly and disabled support to markdown editor

* add attributes support to markdown editor
This commit is contained in:
Klaas Poortinga 2020-03-29 17:37:03 +02:00 committed by GitHub
parent 8c0598cc4a
commit 2ad046f7ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 128 additions and 212 deletions

View File

@ -78,6 +78,7 @@ class ServiceProvider extends ModuleServiceProvider
$combiner->registerBundle('~/modules/backend/formwidgets/richeditor/assets/js/build-plugins.js'); $combiner->registerBundle('~/modules/backend/formwidgets/richeditor/assets/js/build-plugins.js');
$combiner->registerBundle('~/modules/backend/formwidgets/colorpicker/assets/less/colorpicker.less'); $combiner->registerBundle('~/modules/backend/formwidgets/colorpicker/assets/less/colorpicker.less');
$combiner->registerBundle('~/modules/backend/formwidgets/permissioneditor/assets/less/permissioneditor.less'); $combiner->registerBundle('~/modules/backend/formwidgets/permissioneditor/assets/less/permissioneditor.less');
$combiner->registerBundle('~/modules/backend/formwidgets/markdowneditor/assets/less/markdowneditor.less');
/* /*
* Rich Editor is protected by DRM * Rich Editor is protected by DRM

View File

@ -27,6 +27,16 @@ class MarkdownEditor extends FormWidgetBase
*/ */
public $safe = false; public $safe = false;
/**
* @var bool If true, the editor is set to read-only mode
*/
public $readOnly = false;
/**
* @var bool If true, the editor is set to read-only mode
*/
public $disabled = false;
// //
// Object properties // Object properties
// //
@ -44,6 +54,8 @@ class MarkdownEditor extends FormWidgetBase
$this->fillFromConfig([ $this->fillFromConfig([
'mode', 'mode',
'safe', 'safe',
'readOnly',
'disabled',
]); ]);
} }
@ -66,6 +78,8 @@ class MarkdownEditor extends FormWidgetBase
$this->vars['size'] = $this->formField->size; $this->vars['size'] = $this->formField->size;
$this->vars['name'] = $this->getFieldName(); $this->vars['name'] = $this->getFieldName();
$this->vars['value'] = $this->getLoadValue(); $this->vars['value'] = $this->getLoadValue();
$this->vars['readOnly'] = $this->readOnly;
$this->vars['disabled'] = $this->disabled;
$this->vars['useMediaManager'] = BackendAuth::getUser()->hasAccess('media.manage_media'); $this->vars['useMediaManager'] = BackendAuth::getUser()->hasAccess('media.manage_media');
} }

View File

@ -1,203 +1,69 @@
.field-markdowneditor { .field-markdowneditor {width:100%;position:relative;border:1px solid #d1d6d9;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}
width: 100%; .field-markdowneditor textarea {opacity:0;filter:alpha(opacity=0)}
position: relative; .field-markdowneditor .editor-toolbar {border-top-right-radius:5px;border-top-left-radius:5px}
border: 1px solid #d1d6d9; .field-markdowneditor.editor-focus {border:1px solid #d1d6d9}
background: #fff; .field-markdowneditor.size-tiny .editor-write {min-height:50px}
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; .field-markdowneditor.size-tiny .editor-preview {height:50px}
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; .field-markdowneditor.size-tiny.stretch {min-height:90px}
-webkit-border-radius: 5px; .field-markdowneditor.size-small .editor-write {min-height:100px}
-moz-border-radius: 5px; .field-markdowneditor.size-small .editor-preview {height:100px}
border-radius: 5px; .field-markdowneditor.size-small.stretch {min-height:140px}
} .field-markdowneditor.size-large .editor-write {min-height:200px}
.field-markdowneditor textarea { .field-markdowneditor.size-large .editor-preview {height:200px}
opacity: 0; .field-markdowneditor.size-large.stretch {min-height:240px}
filter: alpha(opacity=0); .field-markdowneditor.size-huge .editor-write {min-height:250px}
} .field-markdowneditor.size-huge .editor-preview {height:250px}
.field-markdowneditor .editor-toolbar { .field-markdowneditor.size-huge.stretch {min-height:290px}
border-top-right-radius: 5px; .field-markdowneditor.size-giant .editor-write {min-height:350px}
border-top-left-radius: 5px; .field-markdowneditor.size-giant .editor-preview {height:350px}
} .field-markdowneditor.size-giant.stretch {min-height:390px}
.field-markdowneditor.editor-focus { .field-markdowneditor .editor-write {position:relative}
border: 1px solid #d1d6d9; .field-markdowneditor .editor-preview {padding:15px;overflow:auto}
} .field-markdowneditor .editor-preview-loader {display:block;width:20px;height:20px;position:absolute;right:10px;top:10px;margin-top:40px;background-image:url('../../../../../system/assets/ui/images/loader-transparent.svg');background-size:20px 20px;background-position:50% 50%;-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite}
.field-markdowneditor.size-tiny .editor-write { .field-markdowneditor.mode-tab .editor-preview {display:none}
min-height: 50px; .field-markdowneditor.mode-tab.is-preview .editor-write {display:none}
} .field-markdowneditor.mode-tab.is-preview .editor-preview {display:block}
.field-markdowneditor.size-tiny .editor-preview { .field-markdowneditor.mode-split {overflow:hidden}
height: 50px; .field-markdowneditor.mode-split .editor-preview {float:right;width:50%}
} .field-markdowneditor.mode-split .editor-write {float:left;width:50%}
.field-markdowneditor.size-tiny.stretch { .field-markdowneditor.mode-split .editor-write .editor-code {border-right:2px solid #808C8D}
min-height: 90px;
}
.field-markdowneditor.size-small .editor-write {
min-height: 100px;
}
.field-markdowneditor.size-small .editor-preview {
height: 100px;
}
.field-markdowneditor.size-small.stretch {
min-height: 140px;
}
.field-markdowneditor.size-large .editor-write {
min-height: 200px;
}
.field-markdowneditor.size-large .editor-preview {
height: 200px;
}
.field-markdowneditor.size-large.stretch {
min-height: 240px;
}
.field-markdowneditor.size-huge .editor-write {
min-height: 250px;
}
.field-markdowneditor.size-huge .editor-preview {
height: 250px;
}
.field-markdowneditor.size-huge.stretch {
min-height: 290px;
}
.field-markdowneditor.size-giant .editor-write {
min-height: 350px;
}
.field-markdowneditor.size-giant .editor-preview {
height: 350px;
}
.field-markdowneditor.size-giant.stretch {
min-height: 390px;
}
.field-markdowneditor .editor-write {
position: relative;
}
.field-markdowneditor .editor-preview {
padding: 15px;
overflow: auto;
}
.field-markdowneditor .editor-preview-loader {
display: block;
width: 20px;
height: 20px;
position: absolute;
right: 10px;
top: 10px;
margin-top: 40px;
background-image: url('../../../../../system/assets/ui/images/loader-transparent.svg');
background-size: 20px 20px;
background-position: 50% 50%;
-webkit-animation: spin 1s linear infinite;
animation: spin 1s linear infinite;
}
.field-markdowneditor.mode-tab .editor-preview {
display: none;
}
.field-markdowneditor.mode-tab.is-preview .editor-write {
display: none;
}
.field-markdowneditor.mode-tab.is-preview .editor-preview {
display: block;
}
.field-markdowneditor.mode-split {
overflow: hidden;
}
.field-markdowneditor.mode-split .editor-preview {
float: right;
width: 50%;
}
.field-markdowneditor.mode-split .editor-write {
float: left;
width: 50%;
}
.field-markdowneditor.mode-split .editor-write .editor-code {
border-right: 2px solid #808C8D;
}
.field-markdowneditor.stretch, .field-markdowneditor.stretch,
.field-markdowneditor.stretch .editor-toolbar { .field-markdowneditor.stretch .editor-toolbar {border-radius:0 !important}
border-radius: 0 !important; .field-markdowneditor.stretch .editor-toolbar {height:auto}
} .field-markdowneditor.stretch .editor-write {float:none;height:calc(100% - 40px);position:relative;min-height:0}
.field-markdowneditor.stretch .editor-toolbar { .field-markdowneditor.stretch .editor-preview {float:none;height:auto;position:absolute;left:0;right:0;top:0;bottom:0;margin-top:40px}
height: auto; .field-markdowneditor.stretch.mode-split .editor-preview {left:auto}
} .field-markdowneditor.stretch.mode-split .editor-write {right:auto}
.field-markdowneditor.stretch .editor-write { .field-markdowneditor.is-fullscreen {z-index:600;position:fixed !important;top:0;left:0;width:100%}
float: none;
height: calc(100% - 40px);
position: relative;
min-height: 0;
}
.field-markdowneditor.stretch .editor-preview {
float: none;
height: auto;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin-top: 40px;
}
.field-markdowneditor.stretch.mode-split .editor-preview {
left: auto;
}
.field-markdowneditor.stretch.mode-split .editor-write {
right: auto;
}
.field-markdowneditor.is-fullscreen {
z-index: 600;
position: fixed !important;
top: 0;
left: 0;
width: 100%;
}
.field-markdowneditor.is-fullscreen, .field-markdowneditor.is-fullscreen,
.field-markdowneditor.is-fullscreen .editor-toolbar { .field-markdowneditor.is-fullscreen .editor-toolbar {border-radius:0 !important;border:none}
border-radius: 0 !important; .field-markdowneditor.disabled .ace_scroller {cursor:not-allowed}
border: none; .field-markdowneditor.disabled .control-toolbar.editor-toolbar .toolbar-item .btn {cursor:not-allowed;color:#bdbdbd}
} .field-markdowneditor.disabled .control-toolbar.editor-toolbar .toolbar-item .btn:hover {background-color:transparent;color:#bdbdbd}
.field-markdowneditor .editor-preview { .field-markdowneditor.disabled .control-toolbar.editor-toolbar .toolbar-item .btn.oc-autumn-button {color:#bdbdbd !important}
color: #515c5d; .field-markdowneditor .editor-preview {color:#515c5d;font-family:"Helvetica",sans-serif;line-height:180%}
font-family: "Helvetica", sans-serif;
line-height: 180%;
}
.field-markdowneditor .editor-preview h1, .field-markdowneditor .editor-preview h1,
.field-markdowneditor .editor-preview h2, .field-markdowneditor .editor-preview h2,
.field-markdowneditor .editor-preview h3, .field-markdowneditor .editor-preview h3,
.field-markdowneditor .editor-preview h4, .field-markdowneditor .editor-preview h4,
.field-markdowneditor .editor-preview h5, .field-markdowneditor .editor-preview h5,
.field-markdowneditor .editor-preview h6 { .field-markdowneditor .editor-preview h6 {margin-top:20px;font-weight:bold}
margin-top: 20px;
font-weight: bold;
}
.field-markdowneditor .editor-preview h1:first-child, .field-markdowneditor .editor-preview h1:first-child,
.field-markdowneditor .editor-preview h2:first-child, .field-markdowneditor .editor-preview h2:first-child,
.field-markdowneditor .editor-preview h3:first-child, .field-markdowneditor .editor-preview h3:first-child,
.field-markdowneditor .editor-preview h4:first-child, .field-markdowneditor .editor-preview h4:first-child,
.field-markdowneditor .editor-preview h5:first-child, .field-markdowneditor .editor-preview h5:first-child,
.field-markdowneditor .editor-preview h6:first-child { .field-markdowneditor .editor-preview h6:first-child {margin-top:0}
margin-top: 0; .field-markdowneditor .editor-preview *:last-child {margin-bottom:0}
} .field-markdowneditor .editor-preview h1 {font-size:30px}
.field-markdowneditor .editor-preview *:last-child { .field-markdowneditor .editor-preview h2 {font-size:26px}
margin-bottom: 0; .field-markdowneditor .editor-preview h3 {font-size:24px}
} .field-markdowneditor .editor-preview h4 {font-size:22px}
.field-markdowneditor .editor-preview h1 { .field-markdowneditor .editor-preview h5 {font-size:20px}
font-size: 30px; .field-markdowneditor .editor-preview h6 {font-size:18px}
}
.field-markdowneditor .editor-preview h2 {
font-size: 26px;
}
.field-markdowneditor .editor-preview h3 {
font-size: 24px;
}
.field-markdowneditor .editor-preview h4 {
font-size: 22px;
}
.field-markdowneditor .editor-preview h5 {
font-size: 20px;
}
.field-markdowneditor .editor-preview h6 {
font-size: 18px;
}
.field-markdowneditor .editor-preview p, .field-markdowneditor .editor-preview p,
.field-markdowneditor .editor-preview ol, .field-markdowneditor .editor-preview ol,
.field-markdowneditor .editor-preview ul { .field-markdowneditor .editor-preview ul {font-size:14px}
font-size: 14px;
}
.field-markdowneditor .editor-preview h1, .field-markdowneditor .editor-preview h1,
.field-markdowneditor .editor-preview h2, .field-markdowneditor .editor-preview h2,
.field-markdowneditor .editor-preview h3, .field-markdowneditor .editor-preview h3,
@ -206,19 +72,6 @@
.field-markdowneditor .editor-preview h6, .field-markdowneditor .editor-preview h6,
.field-markdowneditor .editor-preview p, .field-markdowneditor .editor-preview p,
.field-markdowneditor .editor-preview ol, .field-markdowneditor .editor-preview ol,
.field-markdowneditor .editor-preview ul { .field-markdowneditor .editor-preview ul {margin-bottom:15px}
margin-bottom: 15px; .field-markdowneditor .editor-preview pre.prettyprint {border-width:0;padding:13px 16px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;line-height:130%}
} .field-markdowneditor .editor-preview img {display:block;max-width:100%;height:auto}
.field-markdowneditor .editor-preview pre.prettyprint {
border-width: 0;
padding: 13px 16px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
line-height: 130%;
}
.field-markdowneditor .editor-preview img {
display: block;
max-width: 100%;
height: auto;
}

View File

@ -91,6 +91,10 @@
// //
MarkdownEditor.prototype.onClickToolbarButton = function(ev) { MarkdownEditor.prototype.onClickToolbarButton = function(ev) {
if (this.options.disabled) {
return;
}
var $target = $(ev.target), var $target = $(ev.target),
$button = $target.is('a') ? $target : $target.closest('.btn'), $button = $target.is('a') ? $target : $target.closest('.btn'),
action = $button.data('button-action'), action = $button.data('button-action'),
@ -202,6 +206,10 @@
} }
MarkdownEditor.prototype.createToolbarDropdown = function(button, $el) { MarkdownEditor.prototype.createToolbarDropdown = function(button, $el) {
if (this.options.disabled) {
return;
}
var $dropdown = $('<ul class="dropdown-menu" />'), var $dropdown = $('<ul class="dropdown-menu" />'),
$childButton $childButton
@ -241,13 +249,18 @@
var $button = $('<button />').attr({ var $button = $('<button />').attr({
'type': "button", 'type': "button",
'class': 'btn', 'class': 'btn',
'title': $.oc.lang.get(button.label),
'data-control': "tooltip",
'data-placement': "bottom",
'data-container': "body",
'data-button-code': code
}) })
if (!this.options.disabled) {
$button.attr({
'title': $.oc.lang.get(button.label),
'data-control': "tooltip",
'data-placement': "bottom",
'data-container': "body",
'data-button-code': code
});
}
if (button.action) { if (button.action) {
$button.attr('data-button-action', button.action) $button.attr('data-button-action', button.action)
} }
@ -343,8 +356,15 @@
editor.renderer.setShowPrintMargin(false) editor.renderer.setShowPrintMargin(false)
editor.getSession().setUseWrapMode(true) editor.getSession().setUseWrapMode(true)
editor.setFontSize(14) editor.setFontSize(14)
editor.on('blur', this.proxy(this.onBlur))
editor.on('focus', this.proxy(this.onFocus)) if (this.options.disabled) {
editor.setReadOnly(true);
editor.setHighlightSelectedWord(false);
editor.renderer.$cursorLayer.element.style.display = 'none';
} else {
editor.on('blur', this.proxy(this.onBlur))
editor.on('focus', this.proxy(this.onFocus))
}
// Set the vendor path for Ace's require path // Set the vendor path for Ace's require path
ace.require('ace/config').set('basePath', this.options.vendorPath) ace.require('ace/config').set('basePath', this.options.vendorPath)
@ -679,7 +699,8 @@
refreshHandler: null, refreshHandler: null,
buttons: ['formatting', 'bold', 'italic', 'unorderedlist', 'orderedlist', 'link', 'horizontalrule'], buttons: ['formatting', 'bold', 'italic', 'unorderedlist', 'orderedlist', 'link', 'horizontalrule'],
viewMode: 'tab', viewMode: 'tab',
useMediaManager: false useMediaManager: false,
disabled: false
} }
// PLUGIN DEFINITION // PLUGIN DEFINITION

View File

@ -174,6 +174,31 @@
border: none; border: none;
} }
} }
//
// Disabled
//
&.disabled {
.ace_scroller {
cursor: not-allowed;
}
.control-toolbar.editor-toolbar {
.toolbar-item {
.btn {
cursor: not-allowed;
color: #bdbdbd;
&:hover {
background-color: transparent;
color: #bdbdbd;
}
}
.btn.oc-autumn-button {
color: #bdbdbd!important;
}
}
}
}
} }
// //

View File

@ -3,12 +3,14 @@
<?php else: ?> <?php else: ?>
<div <div
id="<?= $this->getId() ?>" id="<?= $this->getId() ?>"
class="field-markdowneditor size-<?= $size ?> <?= $stretch?'layout-relative stretch':'' ?>" class="field-markdowneditor size-<?= $size ?> <?= $stretch?'layout-relative stretch':'' ?> <?php if ($readOnly || $disabled): ?>disabled<?php endif; ?>"
data-control="markdowneditor" data-control="markdowneditor"
data-refresh-handler="<?= $this->getEventHandler('onRefresh') ?>" data-refresh-handler="<?= $this->getEventHandler('onRefresh') ?>"
data-view-mode="<?= $mode ?>" data-view-mode="<?= $mode ?>"
<?php if ($useMediaManager): ?>data-use-media-manager="true"<?php endif ?> <?php if ($useMediaManager): ?>data-use-media-manager="true"<?php endif ?>
data-vendor-path="<?= Url::asset('/modules/backend/formwidgets/codeeditor/assets/vendor/ace') ?>"> data-vendor-path="<?= Url::asset('/modules/backend/formwidgets/codeeditor/assets/vendor/ace') ?>"
<?php if ($readOnly || $disabled): ?>data-disabled="true"<?php endif; ?>
<?= $this->formField->getAttributes() ?>>
<div class="control-toolbar editor-toolbar"></div> <div class="control-toolbar editor-toolbar"></div>