Rich editor should use a data locker so fullscreen does not pull textarea out of the form element. Add cleanup plugin.

This commit is contained in:
Sam Georges 2014-09-18 18:21:40 +10:00
parent e7e518adf8
commit 3007cc6e0a
6 changed files with 77 additions and 228 deletions

View File

@ -50,6 +50,7 @@ class RichEditor extends FormWidgetBase
public function loadAssets()
{
// Plugins
$this->addJs('js/plugin.cleanup.js', 'core');
$this->addJs('js/plugin.fullscreen.js', 'core');
// Redactor

View File

@ -1,14 +1,14 @@
html {
margin: 0;
padding: 0;
margin: 0;
padding: 0;
}
body {
margin: 0;
padding: 10px;
font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
color: #333;
margin: 0;
padding: 10px;
font-family: Arial, Helvetica, Verdana, Tahoma, sans-serif;
color: #333;
}
/*
code,
pre {
font-family: Menlo, Monaco, monospace, sans-serif;
@ -205,198 +205,3 @@ body.redactor_editor_wym {
.redactor_editor_wym ol li ul {
border: none !important;
}
*/
figure {
position: relative;
}
figcaption {
text-align: center;
line-height: 1.428571429;
font-size: 14px;
}
figure[data-type=table] {
clear: both;
}
figure[data-type=video] {
position: relative;
margin-bottom: 1.428571429;
text-align: center;
clear: both;
}
figure[data-type=video] p {
margin: 0;
}
figure[data-type=video].wy-figure-full:before {
position: relative;
padding-bottom: 51%;
width: 100%;
height: 0;
content: "";
display: block;
}
figure[data-type=video].wy-figure-full iframe {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
figure[data-type=image] {
position: relative;
margin-bottom: 1.428571429;
}
figure[data-type=image] .wy-figure-controls {
top: 0px;
}
figure[data-type=image] img {
width: 100%;
}
figure[data-type=image].wy-figure-large {
width: 100%;
clear: both;
}
figure[data-type=image].wy-figure-medium {
width: 50%;
}
figure[data-type=image].wy-figure-small {
width: 33%;
}
figure[data-type=quote] {
margin-bottom: 1.428571429;
margin-left: 1.428571429;
font-style: italic;
position: relative;
border-left: solid 5px #333333;
padding-left: 1.428571429;
}
figure[data-type=quote] figcaption {
font-weight: bold;
text-align: left;
}
figure[data-type=quote] .wy-figure-controls {
margin-left: -5px;
}
figure[data-type=quote].wy-figure-medium {
font-size: 20px;
}
figure[data-type=quote].wy-figure-large {
font-size: 24px;
}
figure[data-type=quote].wy-figure-right {
width: 33%;
}
figure[data-type=quote].wy-figure-left {
width: 33%;
border-left: none;
border-right: solid 5px #333333;
padding-left: 0;
padding-right: 1.428571429;
margin-left: 0;
margin-right: 1.428571429;
}
figure[data-type=quote].wy-figure-left .wy-figure-controls {
margin-left: 0;
margin-right: -5px;
}
figure[data-type=quote] cite {
display: block;
text-align: left;
font-weight: bold;
}
figure[data-type=quote] cite:before {
content: "\2014\00a0";
}
figure[data-type=quote] cite:empty:before {
opacity: 0.4;
content: "\2014 Type to add citation (optional)";
}
figure:hover .wy-figure-controls {
display: block;
}
.wy-figure-controls {
background: #555555;
padding: 0.35714285725;
position: absolute;
display: none;
min-width: 100%;
white-space: nowrap;
left: 0;
height: 37px;
top: -37px;
margin: 0 auto;
font-family: 'Open Sans', Arial, sans-serif;
border-bottom: solid 3px #3c3c3c;
line-height: 1.428571429;
font-style: normal;
z-index: 5;
text-align: center;
}
.wy-figure-controls span {
display: inline-block;
border: none;
background: none;
color: #fff;
vertical-align: top;
font-size: 14px;
width: 24px;
height: 24px;
line-height: 24px;
text-align: center;
cursor: pointer;
}
.wy-figure-controls span:hover {
background: rgba(255, 255, 255, 0.3);
color: #fff;
}
.wy-figure-controls span.on {
background: #fff;
color: #555555;
}
.wy-figure-controls span.wy-figure-controls-divider {
width: 1px;
background: #6f6f6f;
padding: 0;
margin: 0 2px;
cursor: normal;
}
.wy-figure-controls span.wy-figure-controls-small {
font-size: 50%;
}
.wy-figure-controls span.wy-figure-controls-medium {
font-size: 75%;
}
.wy-figure-controls span.wy-figure-controls-delete {
margin-left: 1.428571429;
}
.wy-figure-controls span.wy-figure-controls-delete:hover {
background: #ff0000;
}
.wy-figure-controls span.wy-figure-controls-table {
width: auto;
padding-left: 0.35714285725;
text-align: left;
}
.wy-figure-right {
float: right;
margin-left: 1.428571429;
}
.wy-figure-right .wy-figure-controls {
right: 0;
}
.wy-figure-left {
float: left;
margin-right: 1.428571429;
}
@media (max-width: 769px) {
figure[data-type=image] {
width: 100% !important;
float: none !important;
margin-left: 0;
margin-right: 0;
}
figure[data-type=video] iframe {
width: 100% !important;
height: auto !important;
}
}

View File

@ -0,0 +1,35 @@
(function ($) {
'use strict';
window.RedactorPlugins = window.RedactorPlugins || {};
var Cleanup = function (redactor) {
this.redactor = redactor
this.init()
}
Cleanup.prototype = {
init: function () {
this.removeEmptyParagraphs()
},
/*
* Removes empty P tags
*/
removeEmptyParagraphs: function () {
this.redactor.$editor
.find('p')
.filter(function() { return !$.trim($(this).text()) })
.remove()
}
}
window.RedactorPlugins.cleanup = {
init: function () {
this.cleanup = new Cleanup(this)
}
}
}(jQuery));

View File

@ -106,9 +106,9 @@
if (this.opts.toolbarExternal) {
this.$box.css('top', this.boxcss.top)
this.$toolbar.css({
'width': this.toolcss.width,
'top': this.toolcss.top,
'position': this.toolcss.position
width: this.toolcss.width,
top: this.toolcss.top,
position: this.toolcss.position
})
}
@ -160,9 +160,9 @@
if (this.opts.toolbarExternal) {
this.$toolbar.css({
'top': '0px',
'position': 'absolute',
'width': '100%'
top: '0px',
position: 'absolute',
width: '100%'
})
this.$box.css('top', toolbarHeight + 'px')

View File

@ -16,10 +16,11 @@
// ============================
var RichEditor = function(element, options) {
this.options = options
this.$el = $(element)
this.$textarea = this.$el.find('>textarea:first')
this.$form = this.$el.closest('form')
this.options = options
this.$el = $(element)
this.$textarea = this.$el.find('>textarea:first')
this.$form = this.$el.closest('form')
this.$dataLocker = null
this.init();
}
@ -32,6 +33,16 @@
RichEditor.prototype.init = function (){
var self = this;
/*
* Sync all changes to a data locker, since fullscreen mode
* will pull the textarea outside of the form element.
*/
if (this.options.dataLocker) {
this.$dataLocker = $(this.options.dataLocker)
this.$textarea.val(this.$dataLocker.val())
}
/*
* Textarea must have an identifier
*/
@ -52,6 +63,9 @@
self.sanityCheckContent(this.$editor)
// this.$editor.trigger('mutate')
self.$form.trigger('change')
if (self.$dataLocker)
self.$dataLocker.val(this.$editor.html())
}
}
@ -60,15 +74,14 @@
}
// redactorOptions.plugins = ['cleanup', 'fullscreen', 'figure', 'table', 'quote']
redactorOptions.plugins = ['fullscreen']
redactorOptions.plugins = ['cleanup', 'fullscreen']
this.$textarea.redactor(redactorOptions)
}
RichEditor.prototype.build = function() {
var $editors = $('iframe, textarea', this.$el),
$toolbar = $('.redactor_toolbar', this.$el),
$html = $('html')
var $editors = $('textarea', this.$el),
$toolbar = $('.redactor_toolbar', this.$el)
if (!$editors.length)
return
@ -76,17 +89,6 @@
if (this.$el.hasClass('stretch')) {
$editors.css('padding-top', $toolbar.height())
}
/*
* Replicate hotkeys to parent container
*/
$editors.contents().find('html').on('keydown', function(event){
$html.triggerHandler(event)
})
$editors.contents().find('html').on('keyup', function(event){
$html.triggerHandler(event)
})
}
RichEditor.prototype.sanityCheckContent = function($editor) {

View File

@ -5,7 +5,13 @@
id="<?= $this->getId() ?>"
class="field-richeditor size-<?= $size ?> <?= $stretch?'layout-relative stretch':'' ?>"
<?php if ($fullPage): ?>data-fullpage="true"<?php endif ?>
data-data-locker="#<?= $this->getId('dataLocker') ?>"
data-control="richeditor">
<textarea name="<?= $name ?>" id="<?= $this->getId('textarea') ?>"><?= e($value) ?></textarea>
<textarea id="<?= $this->getId('textarea') ?>"></textarea>
</div>
<!-- Data locker -->
<div style="display: none">
<textarea name="<?= $name ?>" id="<?= $this->getId('dataLocker') ?>"><?= e($value) ?></textarea>
</div>
<?php endif ?>