add ckeditor support via onchange plugin
This commit is contained in:
parent
b1bd652fe9
commit
099d666fd2
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,3 +15,5 @@ spec/reports
|
|||||||
test/tmp
|
test/tmp
|
||||||
test/version_tmp
|
test/version_tmp
|
||||||
tmp
|
tmp
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
74
vendor/assets/javascripts/ckeditor/plugins/onchange/docs/install.html
vendored
Executable file
74
vendor/assets/javascripts/ckeditor/plugins/onchange/docs/install.html
vendored
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||||
|
"http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<title>OnChange event plugin</title>
|
||||||
|
<link href="styles.css" rel="stylesheet" type="text/css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>On Change event Plugin for CKEditor</h1>
|
||||||
|
|
||||||
|
<h2>Introduction</h2>
|
||||||
|
<p>This is a plugin that tries to fire a 'change' event whenever the content of a <a href="http://www.ckeditor.com">CKEditor</a> instance is changed.</p>
|
||||||
|
|
||||||
|
<h3 id="contact">Author:</h3>
|
||||||
|
<p><a href="mailto:amla70@gmail.com">Alfonso Martínez de Lizarrondo</a></p>
|
||||||
|
<h3>Sponsored by:</h3>
|
||||||
|
<p>Falcana</p>
|
||||||
|
<h3>Version history: </h3>
|
||||||
|
<ol>
|
||||||
|
<li>1.0: 21-January-2011. First version.</li>
|
||||||
|
<li>1.1: 3-September-2011. Fixed issues with the UndoManager events. Detect changes in Source mode.</li>
|
||||||
|
<li>1.2: 18-September-2011. Avoid too many events in CKEditor 3.6.2. Filter keyboard to skip control and movement keys.</li>
|
||||||
|
<li>1.3: 22-December-2011 Avoid firing the event after the editor has been destroyed.</li>
|
||||||
|
<li>1.4: 7-September-2012 Don't fire events if the editor is readonly, thanks to Ulrich Gabor. Included code to use Mutation Observers.</li>
|
||||||
|
<li>1.5: 20-October-2012 Detect Cut and Paste for IE in source mode thanks to Jacki.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2>Installation</h2>
|
||||||
|
<h3>1. Copying the files</h3>
|
||||||
|
<p>Extract the contents of the zip in you plugins directory, so it ends up like
|
||||||
|
this<br>
|
||||||
|
<!--<img src="installation.png" alt="Screenshot of installation" width="311" height="346" longdesc="#install">-->
|
||||||
|
</p>
|
||||||
|
<pre id="--install">
|
||||||
|
ckeditor\
|
||||||
|
...
|
||||||
|
images\
|
||||||
|
lang\
|
||||||
|
plugins\
|
||||||
|
...
|
||||||
|
onchange\
|
||||||
|
plugin.js
|
||||||
|
docs\
|
||||||
|
install.html
|
||||||
|
...
|
||||||
|
skins\
|
||||||
|
themes\
|
||||||
|
</pre>
|
||||||
|
<h3>2. Adding it to CKEditor</h3>
|
||||||
|
<p>Now add the plugin in your <em>config.js</em> or custom js configuration
|
||||||
|
file:
|
||||||
|
<code>config.extraPlugins='onchange'; </code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3>3. Configuration</h3>
|
||||||
|
<p>You can limit the minimum time between changes to avoid getting too many events fired:
|
||||||
|
<code>config.minimumChangeMilliseconds = 100; // 100 milliseconds (default value)
|
||||||
|
</code>.</p>
|
||||||
|
|
||||||
|
<h3>4. Use it</h3>
|
||||||
|
<p>Write your listener for the new 'change' event and perform whatever action you need there.
|
||||||
|
<code>editor.on( 'change', function(e) { console.log(e) });
|
||||||
|
</code>.</p>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<h2>Final notes</h2>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<h2>Disclaimers</h2>
|
||||||
|
<p>CKEditor is © CKSource.com</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
59
vendor/assets/javascripts/ckeditor/plugins/onchange/docs/styles.css
vendored
Executable file
59
vendor/assets/javascripts/ckeditor/plugins/onchange/docs/styles.css
vendored
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
text-align:center;
|
||||||
|
font-size:180%;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
border-bottom:2px solid #CCC;
|
||||||
|
margin:1em 0 0.4em 0;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
margin-bottom:0.4em;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin:0 0 1em 1em;
|
||||||
|
text-align:justify;
|
||||||
|
}
|
||||||
|
ol {
|
||||||
|
margin:0 0 1.2em 1em;
|
||||||
|
padding:0;
|
||||||
|
list-style-type:none;
|
||||||
|
}
|
||||||
|
ol li {
|
||||||
|
margin:0.2em 0;
|
||||||
|
}
|
||||||
|
pre, code {
|
||||||
|
font-size:100%;
|
||||||
|
font-family:"Courier New", Courier, mono;
|
||||||
|
background-color: #CCCCCC;
|
||||||
|
border:1px solid #999;
|
||||||
|
padding:0.2em 1em;
|
||||||
|
margin: 0.4em 0;
|
||||||
|
display:block;
|
||||||
|
white-space: pre;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
form {
|
||||||
|
margin:0 0 0 1em;
|
||||||
|
}
|
||||||
|
span.key {
|
||||||
|
color: #006600;
|
||||||
|
}
|
||||||
|
#install {
|
||||||
|
display:none
|
||||||
|
}
|
||||||
|
#languages ul {
|
||||||
|
display:inline;
|
||||||
|
list-style-type:none;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
#languages li {
|
||||||
|
display:inline;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
vertical-align:bottom;
|
||||||
|
}
|
148
vendor/assets/javascripts/ckeditor/plugins/onchange/plugin.js
vendored
Executable file
148
vendor/assets/javascripts/ckeditor/plugins/onchange/plugin.js
vendored
Executable file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* @file change event plugin for CKEditor
|
||||||
|
* Copyright (C) 2011 Alfonso Martinez de Lizarrondo
|
||||||
|
*
|
||||||
|
* == BEGIN LICENSE ==
|
||||||
|
*
|
||||||
|
* Licensed under the terms of any of the following licenses at your
|
||||||
|
* choice:
|
||||||
|
*
|
||||||
|
* - GNU General Public License Version 2 or later (the "GPL")
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*
|
||||||
|
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
*
|
||||||
|
* - Mozilla Public License Version 1.1 or later (the "MPL")
|
||||||
|
* http://www.mozilla.org/MPL/MPL-1.1.html
|
||||||
|
*
|
||||||
|
* == END LICENSE ==
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Keeps track of changes to the content and fires a "change" event
|
||||||
|
CKEDITOR.plugins.add( 'onchange',
|
||||||
|
{
|
||||||
|
init : function( editor )
|
||||||
|
{
|
||||||
|
// // Test:
|
||||||
|
// editor.on( 'change', function(e) { console.log( e ) });
|
||||||
|
|
||||||
|
var timer,
|
||||||
|
theMutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
|
||||||
|
observer;
|
||||||
|
// http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#mutation-observers
|
||||||
|
// http://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/
|
||||||
|
|
||||||
|
// Avoid firing the event too often
|
||||||
|
function somethingChanged()
|
||||||
|
{
|
||||||
|
// don't fire events if the editor is readOnly as they are false detections
|
||||||
|
if (editor.readOnly)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (timer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
timer = setTimeout( function() {
|
||||||
|
timer = 0;
|
||||||
|
editor.fire( 'change' );
|
||||||
|
}, editor.config.minimumChangeMilliseconds || 100);
|
||||||
|
}
|
||||||
|
// Kill the timer on editor destroy
|
||||||
|
editor.on( 'destroy', function() { if ( timer ) clearTimeout( timer ); timer = null; });
|
||||||
|
|
||||||
|
// in theory this block should be enabled only for browsers that don't support MutationObservers,
|
||||||
|
// but it doesn't seem to fire correctly in all the situations. Maybe in the future...
|
||||||
|
{
|
||||||
|
// Set several listeners to watch for changes to the content
|
||||||
|
editor.on( 'saveSnapshot', function( evt )
|
||||||
|
{
|
||||||
|
if ( !evt.data || !evt.data.contentOnly )
|
||||||
|
somethingChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
var undoCmd = editor.getCommand('undo');
|
||||||
|
undoCmd && undoCmd.on( 'afterUndo', somethingChanged);
|
||||||
|
var redoCmd = editor.getCommand('redo');
|
||||||
|
redoCmd && redoCmd.on( 'afterRedo', somethingChanged);
|
||||||
|
|
||||||
|
editor.on( 'afterCommandExec', function( event )
|
||||||
|
{
|
||||||
|
if ( event.data.name == 'source' )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( event.data.command.canUndo !== false )
|
||||||
|
somethingChanged();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( theMutationObserver )
|
||||||
|
{
|
||||||
|
observer = new theMutationObserver( function( mutations ) {
|
||||||
|
somethingChanged();
|
||||||
|
} );
|
||||||
|
|
||||||
|
// To check that we are using a cool browser.
|
||||||
|
if (window.console && window.console.log)
|
||||||
|
console.log("Detecting changes using MutationObservers");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Changes in WYSIWYG mode
|
||||||
|
editor.on( 'contentDom', function()
|
||||||
|
{
|
||||||
|
if ( observer )
|
||||||
|
{
|
||||||
|
// A notification is fired right now, but we don't want it so soon
|
||||||
|
setTimeout( function() {
|
||||||
|
observer.observe( editor.document.getBody().$, {
|
||||||
|
attributes: true,
|
||||||
|
childList: true,
|
||||||
|
characterData: true
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.document.on( 'keydown', function( event )
|
||||||
|
{
|
||||||
|
// Do not capture CTRL hotkeys.
|
||||||
|
if ( event.data.$.ctrlKey ||event.data.$.metaKey )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var keyCode = event.data.$.keyCode;
|
||||||
|
// Filter movement keys and related
|
||||||
|
if (keyCode==8 || keyCode == 13 || keyCode == 32 || ( keyCode >= 46 && keyCode <= 90) || ( keyCode >= 96 && keyCode <= 111) || ( keyCode >= 186 && keyCode <= 222) )
|
||||||
|
somethingChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Firefox OK
|
||||||
|
editor.document.on( 'drop', somethingChanged);
|
||||||
|
// IE OK
|
||||||
|
editor.document.getBody().on( 'drop', somethingChanged);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Detect changes in source mode
|
||||||
|
editor.on( 'mode', function( e )
|
||||||
|
{
|
||||||
|
if ( editor.mode != 'source' )
|
||||||
|
return;
|
||||||
|
|
||||||
|
editor.textarea.on( 'keydown', function( event )
|
||||||
|
{
|
||||||
|
// Do not capture CTRL hotkeys.
|
||||||
|
if ( !event.data.$.ctrlKey && !event.data.$.metaKey )
|
||||||
|
somethingChanged();
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.textarea.on( 'drop', somethingChanged);
|
||||||
|
editor.textarea.on( 'input', somethingChanged);
|
||||||
|
if (CKEDITOR.env.ie)
|
||||||
|
{
|
||||||
|
editor.textarea.on( 'cut', somethingChanged);
|
||||||
|
editor.textarea.on( 'paste', somethingChanged);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
} //Init
|
||||||
|
} );
|
19
vendor/assets/javascripts/sisyphus.js
vendored
19
vendor/assets/javascripts/sisyphus.js
vendored
@ -193,6 +193,23 @@
|
|||||||
self.bindSaveDataOnChange( field, prefix );
|
self.bindSaveDataOnChange( field, prefix );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
if ( typeof window.CKEDITOR !== 'undefined' ) {
|
||||||
|
CKEDITOR.on( 'instanceReady', function(ev) {
|
||||||
|
if ( $.inArray( ev.editor.element.$, fieldsToProtect ) ) {
|
||||||
|
ev.editor.on( 'change', function(eev) {
|
||||||
|
eev.editor.updateElement();
|
||||||
|
var element = eev.editor.element.$;
|
||||||
|
|
||||||
|
if ( typeof element.oninput === 'undefined' ) {
|
||||||
|
element.onpropertychange();
|
||||||
|
} else {
|
||||||
|
element.oninput();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
} );
|
} );
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -205,6 +222,7 @@
|
|||||||
*/
|
*/
|
||||||
saveAllData: function() {
|
saveAllData: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.targets.each( function() {
|
self.targets.each( function() {
|
||||||
var targetFormId = $( this ).attr( "id" );
|
var targetFormId = $( this ).attr( "id" );
|
||||||
var fieldsToProtect = $( this ).find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" ).not( ":file" );
|
var fieldsToProtect = $( this ).find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" ).not( ":file" );
|
||||||
@ -318,6 +336,7 @@
|
|||||||
*/
|
*/
|
||||||
bindSaveDataImmediately: function( field, prefix ) {
|
bindSaveDataImmediately: function( field, prefix ) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if ( typeof $.browser.msie === 'undefined' ) {
|
if ( typeof $.browser.msie === 'undefined' ) {
|
||||||
field.get(0).oninput = function() {
|
field.get(0).oninput = function() {
|
||||||
self.saveToBrowserStorage( prefix, field.val() );
|
self.saveToBrowserStorage( prefix, field.val() );
|
||||||
|
7
vendor/assets/javascripts/sisyphus/ckeditor.js
vendored
Normal file
7
vendor/assets/javascripts/sisyphus/ckeditor.js
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
//= require ckeditor/plugins/onchange/plugin.js
|
||||||
|
//= require_self
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
CKEDITOR.config.extraPlugins += ",onchange";
|
||||||
|
})(this);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user