primo upload
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
CKEditor 4
|
||||
==========
|
||||
|
||||
Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
||||
http://ckeditor.com - See LICENSE.md for license information.
|
||||
|
||||
CKEditor is a text editor to be used inside web pages. It's not a replacement
|
||||
for desktop text editors like Word or OpenOffice, but a component to be used as
|
||||
part of web applications and websites.
|
||||
|
||||
## Documentation
|
||||
|
||||
The full editor documentation is available online at the following address:
|
||||
http://docs.ckeditor.com
|
||||
|
||||
## Installation
|
||||
|
||||
Installing CKEditor is an easy task. Just follow these simple steps:
|
||||
|
||||
1. **Download** the latest version from the CKEditor website:
|
||||
http://ckeditor.com. You should have already completed this step, but be
|
||||
sure you have the very latest version.
|
||||
2. **Extract** (decompress) the downloaded file into the root of your website.
|
||||
|
||||
**Note:** CKEditor is by default installed in the `ckeditor` folder. You can
|
||||
place the files in whichever you want though.
|
||||
|
||||
## Checking Your Installation
|
||||
|
||||
The editor comes with a few sample pages that can be used to verify that
|
||||
installation proceeded properly. Take a look at the `samples` directory.
|
||||
|
||||
To test your installation, just call the following page at your website:
|
||||
|
||||
http://<your site>/<CKEditor installation path>/samples/index.html
|
||||
|
||||
For example:
|
||||
|
||||
http://www.example.com/ckeditor/samples/index.html
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
(function(a){if("undefined"==typeof a)throw Error("jQuery should be loaded before CKEditor jQuery adapter.");if("undefined"==typeof CKEDITOR)throw Error("CKEditor should be loaded before CKEditor jQuery adapter.");CKEDITOR.config.jqueryOverrideVal="undefined"==typeof CKEDITOR.config.jqueryOverrideVal?!0:CKEDITOR.config.jqueryOverrideVal;a.extend(a.fn,{ckeditorGet:function(){var a=this.eq(0).data("ckeditorInstance");if(!a)throw"CKEditor is not initialized yet, use ckeditor() with a callback.";return a},
|
||||
ckeditor:function(g,d){if(!CKEDITOR.env.isCompatible)throw Error("The environment is incompatible.");if(!a.isFunction(g)){var m=d;d=g;g=m}var k=[];d=d||{};this.each(function(){var b=a(this),c=b.data("ckeditorInstance"),f=b.data("_ckeditorInstanceLock"),h=this,l=new a.Deferred;k.push(l.promise());if(c&&!f)g&&g.apply(c,[this]),l.resolve();else if(f)c.once("instanceReady",function(){setTimeout(function(){c.element?(c.element.$==h&&g&&g.apply(c,[h]),l.resolve()):setTimeout(arguments.callee,100)},0)},
|
||||
null,null,9999);else{if(d.autoUpdateElement||"undefined"==typeof d.autoUpdateElement&&CKEDITOR.config.autoUpdateElement)d.autoUpdateElementJquery=!0;d.autoUpdateElement=!1;b.data("_ckeditorInstanceLock",!0);c=a(this).is("textarea")?CKEDITOR.replace(h,d):CKEDITOR.inline(h,d);b.data("ckeditorInstance",c);c.on("instanceReady",function(d){var e=d.editor;setTimeout(function(){if(e.element){d.removeListener();e.on("dataReady",function(){b.trigger("dataReady.ckeditor",[e])});e.on("setData",function(a){b.trigger("setData.ckeditor",
|
||||
[e,a.data])});e.on("getData",function(a){b.trigger("getData.ckeditor",[e,a.data])},999);e.on("destroy",function(){b.trigger("destroy.ckeditor",[e])});e.on("save",function(){a(h.form).submit();return!1},null,null,20);if(e.config.autoUpdateElementJquery&&b.is("textarea")&&a(h.form).length){var c=function(){b.ckeditor(function(){e.updateElement()})};a(h.form).submit(c);a(h.form).bind("form-pre-serialize",c);b.bind("destroy.ckeditor",function(){a(h.form).unbind("submit",c);a(h.form).unbind("form-pre-serialize",
|
||||
c)})}e.on("destroy",function(){b.removeData("ckeditorInstance")});b.removeData("_ckeditorInstanceLock");b.trigger("instanceReady.ckeditor",[e]);g&&g.apply(e,[h]);l.resolve()}else setTimeout(arguments.callee,100)},0)},null,null,9999)}});var f=new a.Deferred;this.promise=f.promise();a.when.apply(this,k).then(function(){f.resolve()});this.editor=this.eq(0).data("ckeditorInstance");return this}});CKEDITOR.config.jqueryOverrideVal&&(a.fn.val=CKEDITOR.tools.override(a.fn.val,function(g){return function(d){if(arguments.length){var m=
|
||||
this,k=[],f=this.each(function(){var b=a(this),c=b.data("ckeditorInstance");if(b.is("textarea")&&c){var f=new a.Deferred;c.setData(d,function(){f.resolve()});k.push(f.promise());return!0}return g.call(b,d)});if(k.length){var b=new a.Deferred;a.when.apply(this,k).done(function(){b.resolveWith(m)});return b.promise()}return f}var f=a(this).eq(0),c=f.data("ckeditorInstance");return f.is("textarea")&&c?c.getData():g.call(f)}}))})(window.jQuery);
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
||||
* For licensing, see LICENSE.md or http://ckeditor.com/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* This file was added automatically by CKEditor builder.
|
||||
* You may re-use it at any time to build CKEditor again.
|
||||
*
|
||||
* If you would like to build CKEditor online again
|
||||
* (for example to upgrade), visit one the following links:
|
||||
*
|
||||
* (1) http://ckeditor.com/builder
|
||||
* Visit online builder to build CKEditor from scratch.
|
||||
*
|
||||
* (2) http://ckeditor.com/builder/8e53a61c5a403d4161d253fb0657d352
|
||||
* Visit online builder to build CKEditor, starting with the same setup as before.
|
||||
*
|
||||
* (3) http://ckeditor.com/builder/download/8e53a61c5a403d4161d253fb0657d352
|
||||
* Straight download link to the latest version of CKEditor (Optimized) with the same setup as before.
|
||||
*
|
||||
* NOTE:
|
||||
* This file is not used by CKEditor, you may remove it.
|
||||
* Changing this file will not change your CKEditor configuration.
|
||||
*/
|
||||
|
||||
var CKBUILDER_CONFIG = {
|
||||
skin: 'moono',
|
||||
preset: 'full',
|
||||
ignore: [
|
||||
'.DS_Store',
|
||||
'.bender',
|
||||
'.editorconfig',
|
||||
'.gitattributes',
|
||||
'.gitignore',
|
||||
'.idea',
|
||||
'.jscsrc',
|
||||
'.jshintignore',
|
||||
'.jshintrc',
|
||||
'.mailmap',
|
||||
'.travis.yml',
|
||||
'bender-err.log',
|
||||
'bender-out.log',
|
||||
'bender.ci.js',
|
||||
'bender.js',
|
||||
'dev',
|
||||
'gruntfile.js',
|
||||
'less',
|
||||
'node_modules',
|
||||
'package.json',
|
||||
'tests'
|
||||
],
|
||||
plugins : {
|
||||
'a11yhelp' : 1,
|
||||
'about' : 1,
|
||||
'basicstyles' : 1,
|
||||
'bidi' : 1,
|
||||
'blockquote' : 1,
|
||||
'clipboard' : 1,
|
||||
'colorbutton' : 1,
|
||||
'colordialog' : 1,
|
||||
'contextmenu' : 1,
|
||||
'copyformatting' : 1,
|
||||
'dialogadvtab' : 1,
|
||||
'div' : 1,
|
||||
'elementspath' : 1,
|
||||
'enterkey' : 1,
|
||||
'entities' : 1,
|
||||
'filebrowser' : 1,
|
||||
'find' : 1,
|
||||
'flash' : 1,
|
||||
'floatingspace' : 1,
|
||||
'font' : 1,
|
||||
'format' : 1,
|
||||
'forms' : 1,
|
||||
'horizontalrule' : 1,
|
||||
'htmlwriter' : 1,
|
||||
'iframe' : 1,
|
||||
'image' : 1,
|
||||
'indentblock' : 1,
|
||||
'indentlist' : 1,
|
||||
'justify' : 1,
|
||||
'language' : 1,
|
||||
'link' : 1,
|
||||
'list' : 1,
|
||||
'liststyle' : 1,
|
||||
'magicline' : 1,
|
||||
'maximize' : 1,
|
||||
'newpage' : 1,
|
||||
'pagebreak' : 1,
|
||||
'pastefromword' : 1,
|
||||
'pastetext' : 1,
|
||||
'preview' : 1,
|
||||
'print' : 1,
|
||||
'removeformat' : 1,
|
||||
'resize' : 1,
|
||||
'save' : 1,
|
||||
'scayt' : 1,
|
||||
'selectall' : 1,
|
||||
'showblocks' : 1,
|
||||
'showborders' : 1,
|
||||
'smiley' : 1,
|
||||
'sourcearea' : 1,
|
||||
'specialchar' : 1,
|
||||
'stylescombo' : 1,
|
||||
'tab' : 1,
|
||||
'table' : 1,
|
||||
'tableselection' : 1,
|
||||
'tabletools' : 1,
|
||||
'templates' : 1,
|
||||
'toolbar' : 1,
|
||||
'undo' : 1,
|
||||
'uploadimage' : 1,
|
||||
'wsc' : 1,
|
||||
'wysiwygarea' : 1
|
||||
},
|
||||
languages : {
|
||||
'en' : 1
|
||||
}
|
||||
};
|
||||
+1318
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
|
||||
* For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
|
||||
/*! \mainpage CKEditor - PHP server side intergation
|
||||
* \section intro_sec CKEditor
|
||||
* Visit <a href="http://ckeditor.com">CKEditor web site</a> to find more information about the editor.
|
||||
* \section install_sec Installation
|
||||
* \subsection step1 Include ckeditor.php in your PHP web site.
|
||||
* @code
|
||||
* <?php
|
||||
* include("ckeditor/ckeditor.php");
|
||||
* ?>
|
||||
* @endcode
|
||||
* \subsection step2 Create CKEditor class instance and use one of available methods to insert CKEditor.
|
||||
* @code
|
||||
* <?php
|
||||
* $CKEditor = new CKEditor();
|
||||
* echo $CKEditor->textarea("field1", "<p>Initial value.</p>");
|
||||
* ?>
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
if ( !function_exists('version_compare') || version_compare( phpversion(), '5', '<' ) )
|
||||
include_once( 'ckeditor_php4.php' ) ;
|
||||
else
|
||||
include_once( 'ckeditor_php5.php' ) ;
|
||||
@@ -0,0 +1,618 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
|
||||
* For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief CKEditor class that can be used to create editor
|
||||
* instances in PHP pages on server side.
|
||||
* @see http://ckeditor.com
|
||||
*
|
||||
* Sample usage:
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->editor("editor1", "<p>Initial value.</p>");
|
||||
* @endcode
|
||||
*/
|
||||
class CKEditor
|
||||
{
|
||||
/**
|
||||
* The version of %CKEditor.
|
||||
* \private
|
||||
*/
|
||||
var $version = '3.5';
|
||||
/**
|
||||
* A constant string unique for each release of %CKEditor.
|
||||
* \private
|
||||
*/
|
||||
var $_timestamp = 'ABLC4TW';
|
||||
|
||||
/**
|
||||
* URL to the %CKEditor installation directory (absolute or relative to document root).
|
||||
* If not set, CKEditor will try to guess it's path.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor->basePath = '/ckeditor/';
|
||||
* @endcode
|
||||
*/
|
||||
var $basePath;
|
||||
/**
|
||||
* An array that holds the global %CKEditor configuration.
|
||||
* For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor->config['height'] = 400;
|
||||
* // Use @@ at the beggining of a string to ouput it without surrounding quotes.
|
||||
* $CKEditor->config['width'] = '@@screen.width * 0.8';
|
||||
* @endcode
|
||||
*/
|
||||
var $config = array();
|
||||
/**
|
||||
* A boolean variable indicating whether CKEditor has been initialized.
|
||||
* Set it to true only if you have already included
|
||||
* <script> tag loading ckeditor.js in your website.
|
||||
*/
|
||||
var $initialized = false;
|
||||
/**
|
||||
* Boolean variable indicating whether created code should be printed out or returned by a function.
|
||||
*
|
||||
* Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function.
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->returnOutput = true;
|
||||
* $code = $CKEditor->editor("editor1", "<p>Initial value.</p>");
|
||||
* echo "<p>Editor 1:</p>";
|
||||
* echo $code;
|
||||
* @endcode
|
||||
*/
|
||||
var $returnOutput = false;
|
||||
/**
|
||||
* An array with textarea attributes.
|
||||
*
|
||||
* When %CKEditor is created with the editor() method, a HTML <textarea> element is created,
|
||||
* it will be displayed to anyone with JavaScript disabled or with incompatible browser.
|
||||
*/
|
||||
var $textareaAttributes = array( "rows" => 8, "cols" => 60 );
|
||||
/**
|
||||
* A string indicating the creation date of %CKEditor.
|
||||
* Do not change it unless you want to force browsers to not use previously cached version of %CKEditor.
|
||||
*/
|
||||
var $timestamp = "ABLC4TW";
|
||||
/**
|
||||
* An array that holds event listeners.
|
||||
* \private
|
||||
*/
|
||||
var $_events = array();
|
||||
/**
|
||||
* An array that holds global event listeners.
|
||||
* \private
|
||||
*/
|
||||
var $_globalEvents = array();
|
||||
|
||||
/**
|
||||
* Main Constructor.
|
||||
*
|
||||
* @param $basePath (string) URL to the %CKEditor installation directory (optional).
|
||||
*/
|
||||
function CKEditor($basePath = null) {
|
||||
if (!empty($basePath)) {
|
||||
$this->basePath = $basePath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a %CKEditor instance.
|
||||
* In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element.
|
||||
*
|
||||
* @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element).
|
||||
* @param $value (string) Initial value (optional).
|
||||
* @param $config (array) The specific configurations to apply to this editor instance (optional).
|
||||
* @param $events (array) Event listeners for this editor instance (optional).
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->editor("field1", "<p>Initial value.</p>");
|
||||
* @endcode
|
||||
*
|
||||
* Advanced example:
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $config = array();
|
||||
* $config['toolbar'] = array(
|
||||
* array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ),
|
||||
* array( 'Image', 'Link', 'Unlink', 'Anchor' )
|
||||
* );
|
||||
* $events['instanceReady'] = 'function (ev) {
|
||||
* alert("Loaded: " + ev.editor.name);
|
||||
* }';
|
||||
* $CKEditor->editor("field1", "<p>Initial value.</p>", $config, $events);
|
||||
* @endcode
|
||||
*/
|
||||
function editor($name, $value = "", $config = array(), $events = array())
|
||||
{
|
||||
$attr = "";
|
||||
|
||||
if (isset($config["skin"])) {
|
||||
if (!file_exists(dirname(__FILE__)."/skins/".$config["skin"])) {
|
||||
$dirs = scandir(dirname(__FILE__)."/skins/");
|
||||
for ($x=0; $x<sizeof($dirs); $x++) {
|
||||
if (is_dir(dirname(__FILE__)."/skins/" . $dirs[$x]) && $dirs[$x] != "." && $dirs[$x] != ".." ) {
|
||||
$config["skin"] = $dirs[$x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($this->textareaAttributes as $key => $val) {
|
||||
$attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"';
|
||||
}
|
||||
if (isset($config['props'])) {
|
||||
if (isset($config['props']['required']) && $config['props']['required']) {
|
||||
if (isset($config['props']['class'])) {
|
||||
$config['props']['class'] .= " cke_validated";
|
||||
} else {
|
||||
$config['props']['class'] = "cke_validated";
|
||||
}
|
||||
}
|
||||
foreach ($config['props'] as $key => $val) {
|
||||
$attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"';
|
||||
}
|
||||
}
|
||||
$out = "<textarea id=\"" . $name . "\" name=\"" . $name . "\"" . $attr . ">" . htmlspecialchars($value, ENT_COMPAT|ENT_IGNORE, "UTF-8") . "</textarea>\n";
|
||||
if (!$this->initialized) {
|
||||
$out .= $this->init();
|
||||
}
|
||||
|
||||
$_config = $this->configSettings($config, $events);
|
||||
|
||||
$js = $this->returnGlobalEvents();
|
||||
if (!empty($_config))
|
||||
$js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");";
|
||||
else
|
||||
$js .= "CKEDITOR.replace('".$name."');";
|
||||
|
||||
$out .= $this->script($js);
|
||||
|
||||
if (!$this->returnOutput) {
|
||||
print $out;
|
||||
$out = "";
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a <textarea> with a %CKEditor instance.
|
||||
*
|
||||
* @param $id (string) The id or name of textarea element.
|
||||
* @param $config (array) The specific configurations to apply to this editor instance (optional).
|
||||
* @param $events (array) Event listeners for this editor instance (optional).
|
||||
*
|
||||
* Example 1: adding %CKEditor to <textarea name="article"></textarea> element:
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->replace("article");
|
||||
* @endcode
|
||||
*/
|
||||
function replace($id, $config = array(), $events = array())
|
||||
{
|
||||
$out = "";
|
||||
if (!$this->initialized) {
|
||||
$out .= $this->init();
|
||||
}
|
||||
|
||||
$_config = $this->configSettings($config, $events);
|
||||
|
||||
$js = $this->returnGlobalEvents();
|
||||
if (!empty($_config)) {
|
||||
$js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");";
|
||||
}
|
||||
else {
|
||||
$js .= "CKEDITOR.replace('".$id."');";
|
||||
}
|
||||
$out .= $this->script($js);
|
||||
|
||||
if (!$this->returnOutput) {
|
||||
print $out;
|
||||
$out = "";
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all <textarea> elements available in the document with editor instances.
|
||||
*
|
||||
* @param $className (string) If set, replace all textareas with class className in the page.
|
||||
*
|
||||
* Example 1: replace all <textarea> elements in the page.
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->replaceAll();
|
||||
* @endcode
|
||||
*
|
||||
* Example 2: replace all <textarea class="myClassName"> elements in the page.
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->replaceAll( 'myClassName' );
|
||||
* @endcode
|
||||
*/
|
||||
function replaceAll($className = null)
|
||||
{
|
||||
$out = "";
|
||||
if (!$this->initialized) {
|
||||
$out .= $this->init();
|
||||
}
|
||||
|
||||
$_config = $this->configSettings();
|
||||
|
||||
$js = $this->returnGlobalEvents();
|
||||
if (empty($_config)) {
|
||||
if (empty($className)) {
|
||||
$js .= "CKEDITOR.replaceAll();";
|
||||
}
|
||||
else {
|
||||
$js .= "CKEDITOR.replaceAll('".$className."');";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$classDetection = "";
|
||||
$js .= "CKEDITOR.replaceAll( function(textarea, config) {\n";
|
||||
if (!empty($className)) {
|
||||
$js .= " var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n";
|
||||
$js .= " if (!classRegex.test(textarea.className))\n";
|
||||
$js .= " return false;\n";
|
||||
}
|
||||
$js .= " CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);";
|
||||
$js .= "} );";
|
||||
|
||||
}
|
||||
|
||||
$out .= $this->script($js);
|
||||
|
||||
if (!$this->returnOutput) {
|
||||
print $out;
|
||||
$out = "";
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds event listener.
|
||||
* Events are fired by %CKEditor in various situations.
|
||||
*
|
||||
* @param $event (string) Event name.
|
||||
* @param $javascriptCode (string) Javascript anonymous function or function name.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor->addEventHandler('instanceReady', 'function (ev) {
|
||||
* alert("Loaded: " + ev.editor.name);
|
||||
* }');
|
||||
* @endcode
|
||||
*/
|
||||
function addEventHandler($event, $javascriptCode)
|
||||
{
|
||||
if (!isset($this->_events[$event])) {
|
||||
$this->_events[$event] = array();
|
||||
}
|
||||
// Avoid duplicates.
|
||||
if (!in_array($javascriptCode, $this->_events[$event])) {
|
||||
$this->_events[$event][] = $javascriptCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear registered event handlers.
|
||||
* Note: this function will have no effect on already created editor instances.
|
||||
*
|
||||
* @param $event (string) Event name, if not set all event handlers will be removed (optional).
|
||||
*/
|
||||
function clearEventHandlers($event = null)
|
||||
{
|
||||
if (!empty($event)) {
|
||||
$this->_events[$event] = array();
|
||||
}
|
||||
else {
|
||||
$this->_events = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds global event listener.
|
||||
*
|
||||
* @param $event (string) Event name.
|
||||
* @param $javascriptCode (string) Javascript anonymous function or function name.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) {
|
||||
* alert("Loading dialog: " + ev.data.name);
|
||||
* }');
|
||||
* @endcode
|
||||
*/
|
||||
function addGlobalEventHandler($event, $javascriptCode)
|
||||
{
|
||||
if (!isset($this->_globalEvents[$event])) {
|
||||
$this->_globalEvents[$event] = array();
|
||||
}
|
||||
// Avoid duplicates.
|
||||
if (!in_array($javascriptCode, $this->_globalEvents[$event])) {
|
||||
$this->_globalEvents[$event][] = $javascriptCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear registered global event handlers.
|
||||
* Note: this function will have no effect if the event handler has been already printed/returned.
|
||||
*
|
||||
* @param $event (string) Event name, if not set all event handlers will be removed (optional).
|
||||
*/
|
||||
function clearGlobalEventHandlers($event = null)
|
||||
{
|
||||
if (!empty($event)) {
|
||||
$this->_globalEvents[$event] = array();
|
||||
}
|
||||
else {
|
||||
$this->_globalEvents = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints javascript code.
|
||||
* \private
|
||||
*
|
||||
* @param string $js
|
||||
*/
|
||||
function script($js)
|
||||
{
|
||||
$out = "<script type=\"text/javascript\">";
|
||||
$out .= "//<![CDATA[\n";
|
||||
$out .= $js;
|
||||
$out .= "\n//]]>";
|
||||
$out .= "</script>\n";
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration array (global and instance specific settings are merged into one array).
|
||||
* \private
|
||||
*
|
||||
* @param $config (array) The specific configurations to apply to editor instance.
|
||||
* @param $events (array) Event listeners for editor instance.
|
||||
*/
|
||||
function configSettings($config = array(), $events = array())
|
||||
{
|
||||
$_config = $this->config;
|
||||
$_events = $this->_events;
|
||||
|
||||
if (is_array($config) && !empty($config)) {
|
||||
$_config = array_merge($_config, $config);
|
||||
}
|
||||
|
||||
if (is_array($events) && !empty($events)) {
|
||||
foreach ($events as $eventName => $code) {
|
||||
if (!isset($_events[$eventName])) {
|
||||
$_events[$eventName] = array();
|
||||
}
|
||||
if (!in_array($code, $_events[$eventName])) {
|
||||
$_events[$eventName][] = $code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_events)) {
|
||||
foreach($_events as $eventName => $handlers) {
|
||||
if (empty($handlers)) {
|
||||
continue;
|
||||
}
|
||||
else if (count($handlers) == 1) {
|
||||
$_config['on'][$eventName] = '@@'.$handlers[0];
|
||||
}
|
||||
else {
|
||||
$_config['on'][$eventName] = '@@function (ev){';
|
||||
foreach ($handlers as $handler => $code) {
|
||||
$_config['on'][$eventName] .= '('.$code.')(ev);';
|
||||
}
|
||||
$_config['on'][$eventName] .= '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return global event handlers.
|
||||
* \private
|
||||
*/
|
||||
function returnGlobalEvents()
|
||||
{
|
||||
static $returnedEvents;
|
||||
$out = "";
|
||||
|
||||
if (!isset($returnedEvents)) {
|
||||
$returnedEvents = array();
|
||||
}
|
||||
|
||||
if (!empty($this->_globalEvents)) {
|
||||
foreach ($this->_globalEvents as $eventName => $handlers) {
|
||||
foreach ($handlers as $handler => $code) {
|
||||
if (!isset($returnedEvents[$eventName])) {
|
||||
$returnedEvents[$eventName] = array();
|
||||
}
|
||||
// Return only new events
|
||||
if (!in_array($code, $returnedEvents[$eventName])) {
|
||||
$out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);";
|
||||
$returnedEvents[$eventName][] = $code;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes CKEditor (executed only once).
|
||||
* \private
|
||||
*/
|
||||
function init()
|
||||
{
|
||||
static $initComplete;
|
||||
$out = "";
|
||||
|
||||
if (!empty($initComplete)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if ($this->initialized) {
|
||||
$initComplete = true;
|
||||
return "";
|
||||
}
|
||||
|
||||
$args = "";
|
||||
$ckeditorPath = $this->ckeditorPath();
|
||||
|
||||
if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") {
|
||||
$args = '?t=' . $this->timestamp;
|
||||
}
|
||||
|
||||
// Skip relative paths...
|
||||
if (strpos($ckeditorPath, '..') !== 0) {
|
||||
$out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';");
|
||||
}
|
||||
|
||||
$out .= "<script type=\"text/javascript\" src=\"" . $ckeditorPath . 'ckeditor.js' . $args . "\"></script>\n";
|
||||
|
||||
$extraCode = "";
|
||||
if ($this->timestamp != $this->_timestamp) {
|
||||
$extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';";
|
||||
}
|
||||
if ($extraCode) {
|
||||
$out .= $this->script($extraCode);
|
||||
}
|
||||
|
||||
$initComplete = $this->initialized = true;
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return path to ckeditor.js.
|
||||
* \private
|
||||
*/
|
||||
function ckeditorPath()
|
||||
{
|
||||
if (!empty($this->basePath)) {
|
||||
return $this->basePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute pathname of the currently executing script.
|
||||
* Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php,
|
||||
* $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user.
|
||||
*/
|
||||
if (isset($_SERVER['SCRIPT_FILENAME'])) {
|
||||
$realPath = dirname($_SERVER['SCRIPT_FILENAME']);
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* realpath — Returns canonicalized absolute pathname
|
||||
*/
|
||||
$realPath = realpath( './' ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* The filename of the currently executing script, relative to the document root.
|
||||
* For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar
|
||||
* would be /test.php/foo.bar.
|
||||
*/
|
||||
$selfPath = dirname($_SERVER['PHP_SELF']);
|
||||
$file = str_replace("\\", "/", __FILE__);
|
||||
|
||||
if (!$selfPath || !$realPath || !$file) {
|
||||
return "/ckeditor/";
|
||||
}
|
||||
|
||||
$documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath));
|
||||
$fileUrl = substr($file, strlen($documentRoot));
|
||||
$ckeditorUrl = str_replace("ckeditor_php5.php", "", $fileUrl);
|
||||
|
||||
return $ckeditorUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* This little function provides a basic JSON support.
|
||||
* http://php.net/manual/en/function.json-encode.php
|
||||
* \private
|
||||
*
|
||||
* @param mixed $val
|
||||
* @return string
|
||||
*/
|
||||
function jsEncode($val)
|
||||
{
|
||||
if (is_null($val)) {
|
||||
return 'null';
|
||||
}
|
||||
if ($val === false) {
|
||||
return 'false';
|
||||
}
|
||||
if ($val === true) {
|
||||
return 'true';
|
||||
}
|
||||
if (is_scalar($val))
|
||||
{
|
||||
if (is_float($val))
|
||||
{
|
||||
// Always use "." for floats.
|
||||
$val = str_replace(",", ".", strval($val));
|
||||
}
|
||||
|
||||
// Use @@ to not use quotes when outputting string value
|
||||
if (strpos($val, '@@') === 0) {
|
||||
return substr($val, 2);
|
||||
}
|
||||
else {
|
||||
// All scalars are converted to strings to avoid indeterminism.
|
||||
// PHP's "1" and 1 are equal for all PHP operators, but
|
||||
// JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend,
|
||||
// we should get the same result in the JS frontend (string).
|
||||
// Character replacements for JSON.
|
||||
static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'),
|
||||
array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
|
||||
|
||||
$val = str_replace($jsonReplaces[0], $jsonReplaces[1], $val);
|
||||
|
||||
return '"' . $val . '"';
|
||||
}
|
||||
}
|
||||
$isList = true;
|
||||
for ($i = 0, reset($val); $i < count($val); $i++, next($val))
|
||||
{
|
||||
if (key($val) !== $i)
|
||||
{
|
||||
$isList = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$result = array();
|
||||
if ($isList)
|
||||
{
|
||||
foreach ($val as $v) $result[] = $this->jsEncode($v);
|
||||
return '[ ' . join(', ', $result) . ' ]';
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($val as $k => $v) $result[] = $this->jsEncode($k).': '.$this->jsEncode($v);
|
||||
return '{ ' . join(', ', $result) . ' }';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,607 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
|
||||
* For licensing, see LICENSE.html or http://ckeditor.com/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief CKEditor class that can be used to create editor
|
||||
* instances in PHP pages on server side.
|
||||
* @see http://ckeditor.com
|
||||
*
|
||||
* Sample usage:
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->editor("editor1", "<p>Initial value.</p>");
|
||||
* @endcode
|
||||
*/
|
||||
class CKEditor
|
||||
{
|
||||
/**
|
||||
* The version of %CKEditor.
|
||||
*/
|
||||
const version = '3.5';
|
||||
/**
|
||||
* A constant string unique for each release of %CKEditor.
|
||||
*/
|
||||
const timestamp = 'ABLC4TW';
|
||||
|
||||
/**
|
||||
* URL to the %CKEditor installation directory (absolute or relative to document root).
|
||||
* If not set, CKEditor will try to guess it's path.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor->basePath = '/ckeditor/';
|
||||
* @endcode
|
||||
*/
|
||||
public $basePath;
|
||||
/**
|
||||
* An array that holds the global %CKEditor configuration.
|
||||
* For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor->config['height'] = 400;
|
||||
* // Use @@ at the beggining of a string to ouput it without surrounding quotes.
|
||||
* $CKEditor->config['width'] = '@@screen.width * 0.8';
|
||||
* @endcode
|
||||
*/
|
||||
public $config = array();
|
||||
/**
|
||||
* A boolean variable indicating whether CKEditor has been initialized.
|
||||
* Set it to true only if you have already included
|
||||
* <script> tag loading ckeditor.js in your website.
|
||||
*/
|
||||
public $initialized = false;
|
||||
/**
|
||||
* Boolean variable indicating whether created code should be printed out or returned by a function.
|
||||
*
|
||||
* Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function.
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->returnOutput = true;
|
||||
* $code = $CKEditor->editor("editor1", "<p>Initial value.</p>");
|
||||
* echo "<p>Editor 1:</p>";
|
||||
* echo $code;
|
||||
* @endcode
|
||||
*/
|
||||
public $returnOutput = false;
|
||||
/**
|
||||
* An array with textarea attributes.
|
||||
*
|
||||
* When %CKEditor is created with the editor() method, a HTML <textarea> element is created,
|
||||
* it will be displayed to anyone with JavaScript disabled or with incompatible browser.
|
||||
*/
|
||||
public $textareaAttributes = array( "rows" => 8, "cols" => 60 );
|
||||
/**
|
||||
* A string indicating the creation date of %CKEditor.
|
||||
* Do not change it unless you want to force browsers to not use previously cached version of %CKEditor.
|
||||
*/
|
||||
public $timestamp = "ABLC4TW";
|
||||
/**
|
||||
* An array that holds event listeners.
|
||||
*/
|
||||
private $events = array();
|
||||
/**
|
||||
* An array that holds global event listeners.
|
||||
*/
|
||||
private $globalEvents = array();
|
||||
|
||||
/**
|
||||
* Main Constructor.
|
||||
*
|
||||
* @param $basePath (string) URL to the %CKEditor installation directory (optional).
|
||||
*/
|
||||
function __construct($basePath = null) {
|
||||
if (!empty($basePath)) {
|
||||
$this->basePath = $basePath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a %CKEditor instance.
|
||||
* In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element.
|
||||
*
|
||||
* @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element).
|
||||
* @param $value (string) Initial value (optional).
|
||||
* @param $config (array) The specific configurations to apply to this editor instance (optional).
|
||||
* @param $events (array) Event listeners for this editor instance (optional).
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->editor("field1", "<p>Initial value.</p>");
|
||||
* @endcode
|
||||
*
|
||||
* Advanced example:
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $config = array();
|
||||
* $config['toolbar'] = array(
|
||||
* array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ),
|
||||
* array( 'Image', 'Link', 'Unlink', 'Anchor' )
|
||||
* );
|
||||
* $events['instanceReady'] = 'function (ev) {
|
||||
* alert("Loaded: " + ev.editor.name);
|
||||
* }';
|
||||
* $CKEditor->editor("field1", "<p>Initial value.</p>", $config, $events);
|
||||
* @endcode
|
||||
*/
|
||||
public function editor($name, $value = "", $config = array(), $events = array())
|
||||
{
|
||||
$attr = "";
|
||||
if (isset($config["skin"])) {
|
||||
if (!file_exists(dirname(__FILE__)."/skins/".$config["skin"])) {
|
||||
$dirs = scandir(dirname(__FILE__)."/skins/");
|
||||
for ($x=0; $x<sizeof($dirs); $x++) {
|
||||
if (is_dir(dirname(__FILE__)."/skins/" . $dirs[$x]) && $dirs[$x] != "." && $dirs[$x] != ".." ) {
|
||||
$config["skin"] = $dirs[$x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($this->textareaAttributes as $key => $val) {
|
||||
$attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"';
|
||||
}
|
||||
if (isset($config['props'])) {
|
||||
if (isset($config['props']['required']) && $config['props']['required']) {
|
||||
if (isset($config['props']['class'])) {
|
||||
$config['props']['class'] .= " cke_validated";
|
||||
} else {
|
||||
$config['props']['class'] = "cke_validated";
|
||||
}
|
||||
}
|
||||
foreach ($config['props'] as $key => $val) {
|
||||
$attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"';
|
||||
}
|
||||
}
|
||||
$out = "<textarea id=\"" . $name . "\" name=\"" . $name . "\"" . $attr . ">" . htmlspecialchars($value, ENT_COMPAT|ENT_IGNORE, "UTF-8") . "</textarea>\n";
|
||||
if (!$this->initialized) {
|
||||
$out .= $this->init();
|
||||
}
|
||||
|
||||
$_config = $this->configSettings($config, $events);
|
||||
|
||||
$js = $this->returnGlobalEvents();
|
||||
if (!empty($_config))
|
||||
$js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");";
|
||||
else
|
||||
$js .= "CKEDITOR.replace('".$name."');";
|
||||
|
||||
$out .= $this->script($js);
|
||||
|
||||
if (!$this->returnOutput) {
|
||||
print $out;
|
||||
$out = "";
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces a <textarea> with a %CKEditor instance.
|
||||
*
|
||||
* @param $id (string) The id or name of textarea element.
|
||||
* @param $config (array) The specific configurations to apply to this editor instance (optional).
|
||||
* @param $events (array) Event listeners for this editor instance (optional).
|
||||
*
|
||||
* Example 1: adding %CKEditor to <textarea name="article"></textarea> element:
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->replace("article");
|
||||
* @endcode
|
||||
*/
|
||||
public function replace($id, $config = array(), $events = array())
|
||||
{
|
||||
$out = "";
|
||||
if (!$this->initialized) {
|
||||
$out .= $this->init();
|
||||
}
|
||||
|
||||
$_config = $this->configSettings($config, $events);
|
||||
|
||||
$js = $this->returnGlobalEvents();
|
||||
if (!empty($_config)) {
|
||||
$js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");";
|
||||
}
|
||||
else {
|
||||
$js .= "CKEDITOR.replace('".$id."');";
|
||||
}
|
||||
$out .= $this->script($js);
|
||||
|
||||
if (!$this->returnOutput) {
|
||||
print $out;
|
||||
$out = "";
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all <textarea> elements available in the document with editor instances.
|
||||
*
|
||||
* @param $className (string) If set, replace all textareas with class className in the page.
|
||||
*
|
||||
* Example 1: replace all <textarea> elements in the page.
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->replaceAll();
|
||||
* @endcode
|
||||
*
|
||||
* Example 2: replace all <textarea class="myClassName"> elements in the page.
|
||||
* @code
|
||||
* $CKEditor = new CKEditor();
|
||||
* $CKEditor->replaceAll( 'myClassName' );
|
||||
* @endcode
|
||||
*/
|
||||
public function replaceAll($className = null)
|
||||
{
|
||||
$out = "";
|
||||
if (!$this->initialized) {
|
||||
$out .= $this->init();
|
||||
}
|
||||
|
||||
$_config = $this->configSettings();
|
||||
|
||||
$js = $this->returnGlobalEvents();
|
||||
if (empty($_config)) {
|
||||
if (empty($className)) {
|
||||
$js .= "CKEDITOR.replaceAll();";
|
||||
}
|
||||
else {
|
||||
$js .= "CKEDITOR.replaceAll('".$className."');";
|
||||
}
|
||||
}
|
||||
else {
|
||||
$classDetection = "";
|
||||
$js .= "CKEDITOR.replaceAll( function(textarea, config) {\n";
|
||||
if (!empty($className)) {
|
||||
$js .= " var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n";
|
||||
$js .= " if (!classRegex.test(textarea.className))\n";
|
||||
$js .= " return false;\n";
|
||||
}
|
||||
$js .= " CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);";
|
||||
$js .= "} );";
|
||||
|
||||
}
|
||||
|
||||
$out .= $this->script($js);
|
||||
|
||||
if (!$this->returnOutput) {
|
||||
print $out;
|
||||
$out = "";
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds event listener.
|
||||
* Events are fired by %CKEditor in various situations.
|
||||
*
|
||||
* @param $event (string) Event name.
|
||||
* @param $javascriptCode (string) Javascript anonymous function or function name.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor->addEventHandler('instanceReady', 'function (ev) {
|
||||
* alert("Loaded: " + ev.editor.name);
|
||||
* }');
|
||||
* @endcode
|
||||
*/
|
||||
public function addEventHandler($event, $javascriptCode)
|
||||
{
|
||||
if (!isset($this->events[$event])) {
|
||||
$this->events[$event] = array();
|
||||
}
|
||||
// Avoid duplicates.
|
||||
if (!in_array($javascriptCode, $this->events[$event])) {
|
||||
$this->events[$event][] = $javascriptCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear registered event handlers.
|
||||
* Note: this function will have no effect on already created editor instances.
|
||||
*
|
||||
* @param $event (string) Event name, if not set all event handlers will be removed (optional).
|
||||
*/
|
||||
public function clearEventHandlers($event = null)
|
||||
{
|
||||
if (!empty($event)) {
|
||||
$this->events[$event] = array();
|
||||
}
|
||||
else {
|
||||
$this->events = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds global event listener.
|
||||
*
|
||||
* @param $event (string) Event name.
|
||||
* @param $javascriptCode (string) Javascript anonymous function or function name.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) {
|
||||
* alert("Loading dialog: " + ev.data.name);
|
||||
* }');
|
||||
* @endcode
|
||||
*/
|
||||
public function addGlobalEventHandler($event, $javascriptCode)
|
||||
{
|
||||
if (!isset($this->globalEvents[$event])) {
|
||||
$this->globalEvents[$event] = array();
|
||||
}
|
||||
// Avoid duplicates.
|
||||
if (!in_array($javascriptCode, $this->globalEvents[$event])) {
|
||||
$this->globalEvents[$event][] = $javascriptCode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear registered global event handlers.
|
||||
* Note: this function will have no effect if the event handler has been already printed/returned.
|
||||
*
|
||||
* @param $event (string) Event name, if not set all event handlers will be removed (optional).
|
||||
*/
|
||||
public function clearGlobalEventHandlers($event = null)
|
||||
{
|
||||
if (!empty($event)) {
|
||||
$this->globalEvents[$event] = array();
|
||||
}
|
||||
else {
|
||||
$this->globalEvents = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints javascript code.
|
||||
*
|
||||
* @param string $js
|
||||
*/
|
||||
private function script($js)
|
||||
{
|
||||
$out = "<script type=\"text/javascript\">";
|
||||
$out .= "//<![CDATA[\n";
|
||||
$out .= $js;
|
||||
$out .= "\n//]]>";
|
||||
$out .= "</script>\n";
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration array (global and instance specific settings are merged into one array).
|
||||
*
|
||||
* @param $config (array) The specific configurations to apply to editor instance.
|
||||
* @param $events (array) Event listeners for editor instance.
|
||||
*/
|
||||
private function configSettings($config = array(), $events = array())
|
||||
{
|
||||
$_config = $this->config;
|
||||
$_events = $this->events;
|
||||
|
||||
if (is_array($config) && !empty($config)) {
|
||||
$_config = array_merge($_config, $config);
|
||||
}
|
||||
|
||||
if (is_array($events) && !empty($events)) {
|
||||
foreach ($events as $eventName => $code) {
|
||||
if (!isset($_events[$eventName])) {
|
||||
$_events[$eventName] = array();
|
||||
}
|
||||
if (!in_array($code, $_events[$eventName])) {
|
||||
$_events[$eventName][] = $code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($_events)) {
|
||||
foreach($_events as $eventName => $handlers) {
|
||||
if (empty($handlers)) {
|
||||
continue;
|
||||
}
|
||||
else if (count($handlers) == 1) {
|
||||
$_config['on'][$eventName] = '@@'.$handlers[0];
|
||||
}
|
||||
else {
|
||||
$_config['on'][$eventName] = '@@function (ev){';
|
||||
foreach ($handlers as $handler => $code) {
|
||||
$_config['on'][$eventName] .= '('.$code.')(ev);';
|
||||
}
|
||||
$_config['on'][$eventName] .= '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return global event handlers.
|
||||
*/
|
||||
private function returnGlobalEvents()
|
||||
{
|
||||
static $returnedEvents;
|
||||
$out = "";
|
||||
|
||||
if (!isset($returnedEvents)) {
|
||||
$returnedEvents = array();
|
||||
}
|
||||
|
||||
if (!empty($this->globalEvents)) {
|
||||
foreach ($this->globalEvents as $eventName => $handlers) {
|
||||
foreach ($handlers as $handler => $code) {
|
||||
if (!isset($returnedEvents[$eventName])) {
|
||||
$returnedEvents[$eventName] = array();
|
||||
}
|
||||
// Return only new events
|
||||
if (!in_array($code, $returnedEvents[$eventName])) {
|
||||
$out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);";
|
||||
$returnedEvents[$eventName][] = $code;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes CKEditor (executed only once).
|
||||
*/
|
||||
private function init()
|
||||
{
|
||||
static $initComplete;
|
||||
$out = "";
|
||||
|
||||
if (!empty($initComplete)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if ($this->initialized) {
|
||||
$initComplete = true;
|
||||
return "";
|
||||
}
|
||||
|
||||
$args = "";
|
||||
$ckeditorPath = $this->ckeditorPath();
|
||||
|
||||
if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") {
|
||||
$args = '?t=' . $this->timestamp;
|
||||
}
|
||||
|
||||
// Skip relative paths...
|
||||
if (strpos($ckeditorPath, '..') !== 0) {
|
||||
$out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';");
|
||||
}
|
||||
|
||||
$out .= "<script type=\"text/javascript\" src=\"" . $ckeditorPath . 'ckeditor.js' . $args . "\"></script>\n";
|
||||
|
||||
$extraCode = "";
|
||||
if ($this->timestamp != self::timestamp) {
|
||||
$extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';";
|
||||
}
|
||||
if ($extraCode) {
|
||||
$out .= $this->script($extraCode);
|
||||
}
|
||||
|
||||
$initComplete = $this->initialized = true;
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return path to ckeditor.js.
|
||||
*/
|
||||
private function ckeditorPath()
|
||||
{
|
||||
if (!empty($this->basePath)) {
|
||||
return $this->basePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* The absolute pathname of the currently executing script.
|
||||
* Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php,
|
||||
* $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user.
|
||||
*/
|
||||
if (isset($_SERVER['SCRIPT_FILENAME'])) {
|
||||
$realPath = dirname($_SERVER['SCRIPT_FILENAME']);
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* realpath — Returns canonicalized absolute pathname
|
||||
*/
|
||||
$realPath = realpath( './' ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* The filename of the currently executing script, relative to the document root.
|
||||
* For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar
|
||||
* would be /test.php/foo.bar.
|
||||
*/
|
||||
$selfPath = dirname($_SERVER['PHP_SELF']);
|
||||
$file = str_replace("\\", "/", __FILE__);
|
||||
|
||||
if (!$selfPath || !$realPath || !$file) {
|
||||
return "/ckeditor/";
|
||||
}
|
||||
|
||||
$documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath));
|
||||
$fileUrl = substr($file, strlen($documentRoot));
|
||||
$ckeditorUrl = str_replace("ckeditor_php5.php", "", $fileUrl);
|
||||
|
||||
return $ckeditorUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* This little function provides a basic JSON support.
|
||||
* http://php.net/manual/en/function.json-encode.php
|
||||
*
|
||||
* @param mixed $val
|
||||
* @return string
|
||||
*/
|
||||
private function jsEncode($val)
|
||||
{
|
||||
if (is_null($val)) {
|
||||
return 'null';
|
||||
}
|
||||
if ($val === false) {
|
||||
return 'false';
|
||||
}
|
||||
if ($val === true) {
|
||||
return 'true';
|
||||
}
|
||||
if (is_scalar($val))
|
||||
{
|
||||
if (is_float($val))
|
||||
{
|
||||
// Always use "." for floats.
|
||||
$val = str_replace(",", ".", strval($val));
|
||||
}
|
||||
|
||||
// Use @@ to not use quotes when outputting string value
|
||||
if (strpos($val, '@@') === 0) {
|
||||
return substr($val, 2);
|
||||
}
|
||||
else {
|
||||
// All scalars are converted to strings to avoid indeterminism.
|
||||
// PHP's "1" and 1 are equal for all PHP operators, but
|
||||
// JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend,
|
||||
// we should get the same result in the JS frontend (string).
|
||||
// Character replacements for JSON.
|
||||
static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'),
|
||||
array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
|
||||
|
||||
$val = str_replace($jsonReplaces[0], $jsonReplaces[1], $val);
|
||||
|
||||
return '"' . $val . '"';
|
||||
}
|
||||
}
|
||||
$isList = true;
|
||||
for ($i = 0, reset($val); $i < count($val); $i++, next($val))
|
||||
{
|
||||
if (key($val) !== $i)
|
||||
{
|
||||
$isList = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$result = array();
|
||||
if ($isList)
|
||||
{
|
||||
foreach ($val as $v) $result[] = $this->jsEncode($v);
|
||||
return '[ ' . join(', ', $result) . ' ]';
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($val as $k => $v) $result[] = $this->jsEncode($k).': '.$this->jsEncode($v);
|
||||
return '{ ' . join(', ', $result) . ' }';
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
||||
* For licensing, see https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
CKEDITOR.editorConfig = function( config ) {
|
||||
// Define changes to default configuration here. For example:
|
||||
// config.language = 'fr';
|
||||
// config.uiColor = '#AADC6E';
|
||||
config.enterMode = CKEDITOR.ENTER_BR;
|
||||
config.allowedContent = true;
|
||||
config.autoParagraph = false;
|
||||
};
|
||||
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
||||
For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
body
|
||||
{
|
||||
/* Font */
|
||||
font-family: sans-serif, Arial, Verdana, "Trebuchet MS";
|
||||
font-size: 12px;
|
||||
|
||||
/* Text color */
|
||||
color: #333;
|
||||
|
||||
/* Remove the background color to make it transparent */
|
||||
background-color: #fff;
|
||||
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
.cke_editable
|
||||
{
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
|
||||
/* Fix for missing scrollbars with RTL texts. (#10488) */
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
blockquote
|
||||
{
|
||||
font-style: italic;
|
||||
font-family: Georgia, Times, "Times New Roman", serif;
|
||||
padding: 2px 0;
|
||||
border-style: solid;
|
||||
border-color: #ccc;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.cke_contents_ltr blockquote
|
||||
{
|
||||
padding-left: 20px;
|
||||
padding-right: 8px;
|
||||
border-left-width: 5px;
|
||||
}
|
||||
|
||||
.cke_contents_rtl blockquote
|
||||
{
|
||||
padding-left: 8px;
|
||||
padding-right: 20px;
|
||||
border-right-width: 5px;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
color: #0782C1;
|
||||
}
|
||||
|
||||
ol,ul,dl
|
||||
{
|
||||
/* IE7: reset rtl list margin. (#7334) */
|
||||
*margin-right: 0px;
|
||||
/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6
|
||||
{
|
||||
font-weight: normal;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
hr
|
||||
{
|
||||
border: 0px;
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
img.right
|
||||
{
|
||||
border: 1px solid #ccc;
|
||||
float: right;
|
||||
margin-left: 15px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
img.left
|
||||
{
|
||||
border: 1px solid #ccc;
|
||||
float: left;
|
||||
margin-right: 15px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
pre
|
||||
{
|
||||
white-space: pre-wrap; /* CSS 2.1 */
|
||||
word-wrap: break-word; /* IE7 */
|
||||
-moz-tab-size: 4;
|
||||
tab-size: 4;
|
||||
}
|
||||
|
||||
.marker
|
||||
{
|
||||
background-color: Yellow;
|
||||
}
|
||||
|
||||
span[lang]
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
figure
|
||||
{
|
||||
text-align: center;
|
||||
outline: solid 1px #ccc;
|
||||
background: rgba(0,0,0,0.05);
|
||||
padding: 10px;
|
||||
margin: 10px 20px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
figure > figcaption
|
||||
{
|
||||
text-align: center;
|
||||
display: block; /* For IE8 */
|
||||
}
|
||||
|
||||
a > img {
|
||||
padding: 1px;
|
||||
margin: 1px;
|
||||
border: none;
|
||||
outline: 1px solid #0782C1;
|
||||
}
|
||||
|
||||
/* Widget Styles */
|
||||
.code-featured
|
||||
{
|
||||
border: 5px solid red;
|
||||
}
|
||||
|
||||
.math-featured
|
||||
{
|
||||
padding: 20px;
|
||||
box-shadow: 0 0 2px rgba(200, 0, 0, 1);
|
||||
background-color: rgba(255, 0, 0, 0.05);
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.image-clean
|
||||
{
|
||||
border: 0;
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.image-clean > figcaption
|
||||
{
|
||||
font-size: .9em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.image-grayscale
|
||||
{
|
||||
background-color: white;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.image-grayscale img, img.image-grayscale
|
||||
{
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.embed-240p
|
||||
{
|
||||
max-width: 426px;
|
||||
max-height: 240px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.embed-360p
|
||||
{
|
||||
max-width: 640px;
|
||||
max-height: 360px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.embed-480p
|
||||
{
|
||||
max-width: 854px;
|
||||
max-height: 480px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.embed-720p
|
||||
{
|
||||
max-width: 1280px;
|
||||
max-height: 720px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.embed-1080p
|
||||
{
|
||||
max-width: 1920px;
|
||||
max-height: 1080px;
|
||||
margin:0 auto;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
// This file contains style definitions that can be used by CKEditor plugins.
|
||||
//
|
||||
// The most common use for it is the "stylescombo" plugin which shows the Styles drop-down
|
||||
// list containing all styles in the editor toolbar. Other plugins, like
|
||||
// the "div" plugin, use a subset of the styles for their features.
|
||||
//
|
||||
// If you do not have plugins that depend on this file in your editor build, you can simply
|
||||
// ignore it. Otherwise it is strongly recommended to customize this file to match your
|
||||
// website requirements and design properly.
|
||||
//
|
||||
// For more information refer to: https://docs.ckeditor.com/ckeditor4/docs/#!/guide/dev_styles-section-style-rules
|
||||
|
||||
CKEDITOR.stylesSet.add( 'default', [
|
||||
/* Block styles */
|
||||
|
||||
// These styles are already available in the "Format" drop-down list ("format" plugin),
|
||||
// so they are not needed here by default. You may enable them to avoid
|
||||
// placing the "Format" combo in the toolbar, maintaining the same features.
|
||||
/*
|
||||
{ name: 'Paragraph', element: 'p' },
|
||||
{ name: 'Heading 1', element: 'h1' },
|
||||
{ name: 'Heading 2', element: 'h2' },
|
||||
{ name: 'Heading 3', element: 'h3' },
|
||||
{ name: 'Heading 4', element: 'h4' },
|
||||
{ name: 'Heading 5', element: 'h5' },
|
||||
{ name: 'Heading 6', element: 'h6' },
|
||||
{ name: 'Preformatted Text',element: 'pre' },
|
||||
{ name: 'Address', element: 'address' },
|
||||
*/
|
||||
|
||||
{ name: 'Italic Title', element: 'h2', styles: { 'font-style': 'italic' } },
|
||||
{ name: 'Subtitle', element: 'h3', styles: { 'color': '#aaa', 'font-style': 'italic' } },
|
||||
{
|
||||
name: 'Special Container',
|
||||
element: 'div',
|
||||
styles: {
|
||||
padding: '5px 10px',
|
||||
background: '#eee',
|
||||
border: '1px solid #ccc'
|
||||
}
|
||||
},
|
||||
|
||||
/* Inline styles */
|
||||
|
||||
// These are core styles available as toolbar buttons. You may opt enabling
|
||||
// some of them in the Styles drop-down list, removing them from the toolbar.
|
||||
// (This requires the "stylescombo" plugin.)
|
||||
/*
|
||||
{ name: 'Strong', element: 'strong', overrides: 'b' },
|
||||
{ name: 'Emphasis', element: 'em' , overrides: 'i' },
|
||||
{ name: 'Underline', element: 'u' },
|
||||
{ name: 'Strikethrough', element: 'strike' },
|
||||
{ name: 'Subscript', element: 'sub' },
|
||||
{ name: 'Superscript', element: 'sup' },
|
||||
*/
|
||||
|
||||
{ name: 'Marker', element: 'span', attributes: { 'class': 'marker' } },
|
||||
|
||||
{ name: 'Big', element: 'big' },
|
||||
{ name: 'Small', element: 'small' },
|
||||
{ name: 'Typewriter', element: 'tt' },
|
||||
|
||||
{ name: 'Computer Code', element: 'code' },
|
||||
{ name: 'Keyboard Phrase', element: 'kbd' },
|
||||
{ name: 'Sample Text', element: 'samp' },
|
||||
{ name: 'Variable', element: 'var' },
|
||||
|
||||
{ name: 'Deleted Text', element: 'del' },
|
||||
{ name: 'Inserted Text', element: 'ins' },
|
||||
|
||||
{ name: 'Cited Work', element: 'cite' },
|
||||
{ name: 'Inline Quotation', element: 'q' },
|
||||
|
||||
{ name: 'Language: RTL', element: 'span', attributes: { 'dir': 'rtl' } },
|
||||
{ name: 'Language: LTR', element: 'span', attributes: { 'dir': 'ltr' } },
|
||||
|
||||
/* Object styles */
|
||||
|
||||
{
|
||||
name: 'Styled Image (left)',
|
||||
element: 'img',
|
||||
attributes: { 'class': 'left' }
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Styled Image (right)',
|
||||
element: 'img',
|
||||
attributes: { 'class': 'right' }
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Compact Table',
|
||||
element: 'table',
|
||||
attributes: {
|
||||
cellpadding: '5',
|
||||
cellspacing: '0',
|
||||
border: '1',
|
||||
bordercolor: '#ccc'
|
||||
},
|
||||
styles: {
|
||||
'border-collapse': 'collapse'
|
||||
}
|
||||
},
|
||||
|
||||
{ name: 'Borderless Table', element: 'table', styles: { 'border-style': 'hidden', 'background-color': '#E6E6FA' } },
|
||||
{ name: 'Square Bulleted List', element: 'ul', styles: { 'list-style-type': 'square' } },
|
||||
|
||||
/* Widget styles */
|
||||
|
||||
{ name: 'Clean Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-clean' } },
|
||||
{ name: 'Grayscale Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-grayscale' } },
|
||||
|
||||
{ name: 'Featured Snippet', type: 'widget', widget: 'codeSnippet', attributes: { 'class': 'code-featured' } },
|
||||
|
||||
{ name: 'Featured Formula', type: 'widget', widget: 'mathjax', attributes: { 'class': 'math-featured' } },
|
||||
|
||||
{ name: '240p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-240p' }, group: 'size' },
|
||||
{ name: '360p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-360p' }, group: 'size' },
|
||||
{ name: '480p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-480p' }, group: 'size' },
|
||||
{ name: '720p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-720p' }, group: 'size' },
|
||||
{ name: '1080p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-1080p' }, group: 'size' },
|
||||
|
||||
// Adding space after the style name is an intended workaround. For now, there
|
||||
// is no option to create two styles with the same name for different widget types. See https://dev.ckeditor.com/ticket/16664.
|
||||
{ name: '240p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-240p' }, group: 'size' },
|
||||
{ name: '360p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-360p' }, group: 'size' },
|
||||
{ name: '480p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-480p' }, group: 'size' },
|
||||
{ name: '720p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-720p' }, group: 'size' },
|
||||
{ name: '1080p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-1080p' }, group: 'size' }
|
||||
|
||||
] );
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
4.92
|
||||
Reference in New Issue
Block a user