update
This commit is contained in:
2339
Admin/plugins/ckeditor/CHANGES.md
Normal file
2339
Admin/plugins/ckeditor/CHANGES.md
Normal file
File diff suppressed because it is too large
Load Diff
1670
Admin/plugins/ckeditor/LICENSE.md
Normal file
1670
Admin/plugins/ckeditor/LICENSE.md
Normal file
File diff suppressed because it is too large
Load Diff
39
Admin/plugins/ckeditor/README.md
Normal file
39
Admin/plugins/ckeditor/README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
CKEditor 4
|
||||
==========
|
||||
|
||||
Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
https://ckeditor.com - See https://ckeditor.com/legal/ckeditor-oss-license for license information.
|
||||
|
||||
CKEditor 4 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:
|
||||
https://ckeditor.com/docs/
|
||||
|
||||
## Installation
|
||||
|
||||
Installing CKEditor is an easy task. Just follow these simple steps:
|
||||
|
||||
1. **Download** the latest version from the CKEditor website:
|
||||
https://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
Admin/plugins/ckeditor/SECURITY.md
Normal file
10
Admin/plugins/ckeditor/SECURITY.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Reporting a security issues
|
||||
|
||||
If you believe you have found a security issue in the CKEditor 4 software, please contact us immediately.
|
||||
|
||||
When reporting a potential security problem, please bear this in mind:
|
||||
|
||||
* Make sure to provide as many details as possible about the vulnerability.
|
||||
* Please do not disclose publicly any security issues until we fix them and publish security releases.
|
||||
|
||||
Contact the security team at security@cksource.com. As soon as we receive the security report, we will work promptly to confirm the issue and then to provide a security fix.
|
||||
379
Admin/plugins/ckeditor/adapters/jquery.js
vendored
Normal file
379
Admin/plugins/ckeditor/adapters/jquery.js
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR_Adapters.jQuery jQuery Adapter}.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class CKEDITOR_Adapters.jQuery
|
||||
* @singleton
|
||||
*
|
||||
* The jQuery Adapter allows for easy use of basic CKEditor functions and access to the internal API.
|
||||
* To find more information about the jQuery Adapter, go to the {@glink guide/dev_jquery jQuery Adapter section}
|
||||
* of the Developer's Guide or see the "Create Editors with jQuery" sample.
|
||||
*
|
||||
* @aside guide dev_jquery
|
||||
*/
|
||||
|
||||
( function( $ ) {
|
||||
if ( typeof $ == 'undefined' ) {
|
||||
throw new Error( 'jQuery should be loaded before CKEditor jQuery adapter.' );
|
||||
}
|
||||
|
||||
if ( typeof CKEDITOR == 'undefined' ) {
|
||||
throw new Error( 'CKEditor should be loaded before CKEditor jQuery adapter.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows CKEditor to override `jQuery.fn.val()`. When set to `true`, the `val()` function
|
||||
* used on textarea elements replaced with CKEditor uses the CKEditor API.
|
||||
*
|
||||
* This configuration option is global and is executed during the loading of the jQuery Adapter.
|
||||
* It cannot be customized across editor instances.
|
||||
*
|
||||
* Read more in the {@glink guide/dev_jquery documentation}.
|
||||
*
|
||||
* <script>
|
||||
* CKEDITOR.config.jqueryOverrideVal = true;
|
||||
* </script>
|
||||
*
|
||||
* <!-- Important: The jQuery Adapter is loaded *after* setting jqueryOverrideVal. -->
|
||||
* <script src="/ckeditor/adapters/jquery.js"></script>
|
||||
*
|
||||
* <script>
|
||||
* $( 'textarea' ).ckeditor();
|
||||
* // ...
|
||||
* $( 'textarea' ).val( 'New content' );
|
||||
* </script>
|
||||
*
|
||||
* @cfg {Boolean} [jqueryOverrideVal=true]
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
CKEDITOR.config.jqueryOverrideVal =
|
||||
typeof CKEDITOR.config.jqueryOverrideVal == 'undefined' ? true : CKEDITOR.config.jqueryOverrideVal;
|
||||
|
||||
// jQuery object methods.
|
||||
$.extend( $.fn, {
|
||||
/**
|
||||
* Returns an existing CKEditor instance for the first matched element.
|
||||
* Allows to easily use the internal API. Does not return a jQuery object.
|
||||
*
|
||||
* Raises an exception if the editor does not exist or is not ready yet.
|
||||
*
|
||||
* @returns CKEDITOR.editor
|
||||
* @deprecated Use {@link #editor editor property} instead.
|
||||
*/
|
||||
ckeditorGet: function() {
|
||||
var instance = this.eq( 0 ).data( 'ckeditorInstance' );
|
||||
|
||||
if ( !instance )
|
||||
throw 'CKEditor is not initialized yet, use ckeditor() with a callback.';
|
||||
|
||||
return instance;
|
||||
},
|
||||
|
||||
/**
|
||||
* A jQuery function which triggers the creation of CKEditor with `<textarea>` and
|
||||
* {@link CKEDITOR.dtd#$editable editable} elements.
|
||||
* Every `<textarea>` element will be converted to a classic (`iframe`-based) editor,
|
||||
* while any other supported element will be converted to an inline editor.
|
||||
* This method binds the callback to the `instanceReady` event of all instances.
|
||||
* If the editor has already been created, the callback is fired straightaway.
|
||||
* You can also create multiple editors at once by using `$( '.className' ).ckeditor();`.
|
||||
*
|
||||
* **Note**: jQuery chaining and mixed parameter order is allowed.
|
||||
*
|
||||
* @param {Function} callback
|
||||
* Function to be run on the editor instance. Callback takes the source element as a parameter.
|
||||
*
|
||||
* $( 'textarea' ).ckeditor( function( textarea ) {
|
||||
* // Callback function code.
|
||||
* } );
|
||||
*
|
||||
* @param {Object} config
|
||||
* Configuration options for new instance(s) if not already created.
|
||||
*
|
||||
* $( 'textarea' ).ckeditor( {
|
||||
* uiColor: '#9AB8F3'
|
||||
* } );
|
||||
*
|
||||
* @returns jQuery.fn
|
||||
*/
|
||||
ckeditor: function( callback, config ) {
|
||||
if ( !CKEDITOR.env.isCompatible )
|
||||
throw new Error( 'The environment is incompatible.' );
|
||||
|
||||
// Reverse the order of arguments if the first one isn't a function.
|
||||
if ( typeof callback !== 'function' ) {
|
||||
var tmp = config;
|
||||
config = callback;
|
||||
callback = tmp;
|
||||
}
|
||||
|
||||
// An array of instanceReady callback promises.
|
||||
var promises = [];
|
||||
|
||||
config = config || {};
|
||||
|
||||
// Iterate over the collection.
|
||||
this.each( function() {
|
||||
var $element = $( this ),
|
||||
editor = $element.data( 'ckeditorInstance' ),
|
||||
instanceLock = $element.data( '_ckeditorInstanceLock' ),
|
||||
element = this,
|
||||
dfd = new $.Deferred();
|
||||
|
||||
promises.push( dfd.promise() );
|
||||
|
||||
if ( editor && !instanceLock ) {
|
||||
if ( callback )
|
||||
callback.apply( editor, [ this ] );
|
||||
|
||||
dfd.resolve();
|
||||
} else if ( !instanceLock ) {
|
||||
// CREATE NEW INSTANCE
|
||||
|
||||
// Handle config.autoUpdateElement inside this plugin if desired.
|
||||
if ( config.autoUpdateElement || ( typeof config.autoUpdateElement == 'undefined' && CKEDITOR.config.autoUpdateElement ) ) {
|
||||
config.autoUpdateElementJquery = true;
|
||||
}
|
||||
|
||||
// Always disable config.autoUpdateElement.
|
||||
config.autoUpdateElement = false;
|
||||
$element.data( '_ckeditorInstanceLock', true );
|
||||
|
||||
// Set instance reference in element's data.
|
||||
if ( $( this ).is( 'textarea' ) )
|
||||
editor = CKEDITOR.replace( element, config );
|
||||
else
|
||||
editor = CKEDITOR.inline( element, config );
|
||||
|
||||
$element.data( 'ckeditorInstance', editor );
|
||||
|
||||
// Register callback.
|
||||
editor.on( 'instanceReady', function( evt ) {
|
||||
var editor = evt.editor;
|
||||
|
||||
setTimeout( function waitForEditor() {
|
||||
// Delay bit more if editor is still not ready.
|
||||
if ( !editor.element ) {
|
||||
setTimeout( waitForEditor, 100 );
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove this listener. Triggered when new instance is ready.
|
||||
evt.removeListener();
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-dataReady dataReady event} as a jQuery event.
|
||||
*
|
||||
* @event dataReady
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
*/
|
||||
editor.on( 'dataReady', function() {
|
||||
$element.trigger( 'dataReady.ckeditor', [ editor ] );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-setData setData event} as a jQuery event.
|
||||
*
|
||||
* @event setData
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
* @param data
|
||||
* @param {String} data.dataValue The data that will be used.
|
||||
*/
|
||||
editor.on( 'setData', function( evt ) {
|
||||
$element.trigger( 'setData.ckeditor', [ editor, evt.data ] );
|
||||
} );
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-getData getData event} as a jQuery event.
|
||||
*
|
||||
* @event getData
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
* @param data
|
||||
* @param {String} data.dataValue The data that will be returned.
|
||||
*/
|
||||
editor.on( 'getData', function( evt ) {
|
||||
$element.trigger( 'getData.ckeditor', [ editor, evt.data ] );
|
||||
}, 999 );
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-destroy destroy event} as a jQuery event.
|
||||
*
|
||||
* @event destroy
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
*/
|
||||
editor.on( 'destroy', function() {
|
||||
$element.trigger( 'destroy.ckeditor', [ editor ] );
|
||||
} );
|
||||
|
||||
// Overwrite save button to call jQuery submit instead of javascript submit.
|
||||
// Otherwise jQuery.forms does not work properly
|
||||
editor.on( 'save', function() {
|
||||
$( element.form ).trigger('submit');
|
||||
return false;
|
||||
}, null, null, 20 );
|
||||
|
||||
// Integrate with form submit.
|
||||
if ( editor.config.autoUpdateElementJquery && $element.is( 'textarea' ) && $( element.form ).length ) {
|
||||
var onSubmit = function() {
|
||||
$element.ckeditor( function() {
|
||||
editor.updateElement();
|
||||
} );
|
||||
};
|
||||
|
||||
// Bind to submit event.
|
||||
$( element.form ).on( 'submit', onSubmit );
|
||||
|
||||
// Bind to form-pre-serialize from jQuery Forms plugin.
|
||||
$( element.form ).on( 'form-pre-serialize', onSubmit );
|
||||
|
||||
// Unbind when editor destroyed.
|
||||
$element.on( 'destroy.ckeditor', function() {
|
||||
$( element.form ).off( 'submit', onSubmit );
|
||||
$( element.form ).off( 'form-pre-serialize', onSubmit );
|
||||
} );
|
||||
}
|
||||
|
||||
// Garbage collect on destroy.
|
||||
editor.on( 'destroy', function() {
|
||||
$element.removeData( 'ckeditorInstance' );
|
||||
} );
|
||||
|
||||
// Remove lock.
|
||||
$element.removeData( '_ckeditorInstanceLock' );
|
||||
|
||||
/**
|
||||
* Forwards the CKEditor {@link CKEDITOR.editor#event-instanceReady instanceReady event} as a jQuery event.
|
||||
*
|
||||
* @event instanceReady
|
||||
* @param {CKEDITOR.editor} editor Editor instance.
|
||||
*/
|
||||
$element.trigger( 'instanceReady.ckeditor', [ editor ] );
|
||||
|
||||
// Run given (first) code.
|
||||
if ( callback )
|
||||
callback.apply( editor, [ element ] );
|
||||
|
||||
dfd.resolve();
|
||||
}, 0 );
|
||||
}, null, null, 9999 );
|
||||
} else {
|
||||
// Editor is already during creation process, bind our code to the event.
|
||||
editor.once( 'instanceReady', function() {
|
||||
setTimeout( function waitForEditor() {
|
||||
// Delay bit more if editor is still not ready.
|
||||
if ( !editor.element ) {
|
||||
setTimeout( waitForEditor, 100 );
|
||||
return;
|
||||
}
|
||||
|
||||
// Run given code.
|
||||
if ( editor.element.$ == element && callback )
|
||||
callback.apply( editor, [ element ] );
|
||||
|
||||
dfd.resolve();
|
||||
}, 0 );
|
||||
}, null, null, 9999 );
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* The [jQuery Promise object](http://api.jquery.com/promise/) that handles the asynchronous constructor.
|
||||
* This promise will be resolved after **all** of the constructors.
|
||||
*
|
||||
* @property {Function} promise
|
||||
*/
|
||||
var dfd = new $.Deferred();
|
||||
|
||||
this.promise = dfd.promise();
|
||||
|
||||
$.when.apply( this, promises ).then( function() {
|
||||
dfd.resolve();
|
||||
} );
|
||||
|
||||
/**
|
||||
* Existing CKEditor instance. Allows to easily use the internal API.
|
||||
*
|
||||
* **Note**: This is not a jQuery object.
|
||||
*
|
||||
* var editor = $( 'textarea' ).ckeditor().editor;
|
||||
*
|
||||
* @property {CKEDITOR.editor} editor
|
||||
*/
|
||||
this.editor = this.eq( 0 ).data( 'ckeditorInstance' );
|
||||
|
||||
return this;
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* Overwritten jQuery `val()` method for `<textarea>` elements that have bound CKEditor instances.
|
||||
* This method gets or sets editor content by using the {@link CKEDITOR.editor#method-getData editor.getData()}
|
||||
* or {@link CKEDITOR.editor#method-setData editor.setData()} methods. To handle
|
||||
* the {@link CKEDITOR.editor#method-setData editor.setData()} callback (as `setData` is asynchronous),
|
||||
* `val( 'some data' )` will return a [jQuery Promise object](http://api.jquery.com/promise/).
|
||||
*
|
||||
* @method val
|
||||
* @returns String|Number|Array|jQuery.fn|function(jQuery Promise)
|
||||
*/
|
||||
if ( CKEDITOR.config.jqueryOverrideVal ) {
|
||||
$.fn.val = CKEDITOR.tools.override( $.fn.val, function( oldValMethod ) {
|
||||
return function( value ) {
|
||||
// Setter, i.e. .val( "some data" );
|
||||
if ( arguments.length ) {
|
||||
var _this = this,
|
||||
promises = [], //use promise to handle setData callback
|
||||
|
||||
result = this.each( function() {
|
||||
var $elem = $( this ),
|
||||
editor = $elem.data( 'ckeditorInstance' );
|
||||
|
||||
// Handle .val for CKEditor.
|
||||
if ( $elem.is( 'textarea' ) && editor ) {
|
||||
var dfd = new $.Deferred();
|
||||
|
||||
editor.setData( value, function() {
|
||||
dfd.resolve();
|
||||
} );
|
||||
|
||||
promises.push( dfd.promise() );
|
||||
return true;
|
||||
// Call default .val function for rest of elements
|
||||
} else {
|
||||
return oldValMethod.call( $elem, value );
|
||||
}
|
||||
} );
|
||||
|
||||
// If there is no promise return default result (jQuery object of chaining).
|
||||
if ( !promises.length )
|
||||
return result;
|
||||
// Create one promise which will be resolved when all of promises will be done.
|
||||
else {
|
||||
var dfd = new $.Deferred();
|
||||
|
||||
$.when.apply( this, promises ).done( function() {
|
||||
dfd.resolveWith( _this );
|
||||
} );
|
||||
|
||||
return dfd.promise();
|
||||
}
|
||||
}
|
||||
// Getter .val();
|
||||
else {
|
||||
var $elem = $( this ).eq( 0 ),
|
||||
editor = $elem.data( 'ckeditorInstance' );
|
||||
|
||||
if ( $elem.is( 'textarea' ) && editor )
|
||||
return editor.getData();
|
||||
else
|
||||
return oldValMethod.call( $elem );
|
||||
}
|
||||
};
|
||||
} );
|
||||
}
|
||||
} )( window.jQuery );
|
||||
16
Admin/plugins/ckeditor/bender-runner.config.json
Normal file
16
Admin/plugins/ckeditor/bender-runner.config.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"bender": {
|
||||
"port": 9001
|
||||
},
|
||||
"server": {
|
||||
"port": 9002
|
||||
},
|
||||
"paths": {
|
||||
"ckeditor4": "../ckeditor4/",
|
||||
"runner": "./src/runner.html"
|
||||
},
|
||||
"browsers": {
|
||||
"linux": [ "chrome", "firefox" ],
|
||||
"macos": [ "safari" ]
|
||||
}
|
||||
}
|
||||
126
Admin/plugins/ckeditor/build-config.js
Normal file
126
Admin/plugins/ckeditor/build-config.js
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-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) https://ckeditor.com/cke4/builder
|
||||
* Visit online builder to build CKEditor from scratch.
|
||||
*
|
||||
* (2) https://ckeditor.com/cke4/builder/6efec1cd51a3e9e0748902688573526a
|
||||
* Visit online builder to build CKEditor, starting with the same setup as before.
|
||||
*
|
||||
* (3) https://ckeditor.com/cke4/builder/download/6efec1cd51a3e9e0748902688573526a
|
||||
* 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: 'office2013',
|
||||
preset: 'full',
|
||||
ignore: [
|
||||
'.DS_Store',
|
||||
'.bender',
|
||||
'.editorconfig',
|
||||
'.gitattributes',
|
||||
'.gitignore',
|
||||
'.idea',
|
||||
'.jscsrc',
|
||||
'.jshintignore',
|
||||
'.jshintrc',
|
||||
'.mailmap',
|
||||
'.npm',
|
||||
'.nvmrc',
|
||||
'.travis.yml',
|
||||
'bender-err.log',
|
||||
'bender-out.log',
|
||||
'bender.ci.js',
|
||||
'bender.js',
|
||||
'dev',
|
||||
'gruntfile.js',
|
||||
'less',
|
||||
'node_modules',
|
||||
'package-lock.json',
|
||||
'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,
|
||||
'editorplaceholder' : 1,
|
||||
'elementspath' : 1,
|
||||
'enterkey' : 1,
|
||||
'entities' : 1,
|
||||
'exportpdf' : 1,
|
||||
'filebrowser' : 1,
|
||||
'find' : 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,
|
||||
'pastefromgdocs' : 1,
|
||||
'pastefromlibreoffice' : 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,
|
||||
'wysiwygarea' : 1
|
||||
},
|
||||
languages : {
|
||||
'en' : 1,
|
||||
'pl' : 1
|
||||
}
|
||||
};
|
||||
47
Admin/plugins/ckeditor/ckeditor.js
vendored
Normal file
47
Admin/plugins/ckeditor/ckeditor.js
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
// Compressed version of core/ckeditor_base.js. See original for instructions.
|
||||
/* jshint ignore:start */
|
||||
/* jscs:disable */
|
||||
// replace_start
|
||||
window.CKEDITOR||(window.CKEDITOR=function(){var o,d=/(^|.*[\\\/])ckeditor\.js(?:\?.*|;.*)?$/i,e={timestamp:"",version:"%VERSION%",revision:"%REV%",rnd:Math.floor(900*Math.random())+100,_:{pending:[],basePathSrcPattern:d},status:"unloaded",basePath:function(){var t=window.CKEDITOR_BASEPATH||"";if(!t)for(var e=document.getElementsByTagName("script"),n=0;n<e.length;n++){var a=e[n].src.match(d);if(a){t=a[1];break}}if(-1==t.indexOf(":/")&&"//"!=t.slice(0,2)&&(t=0===t.indexOf("/")?location.href.match(/^.*?:\/\/[^\/]*/)[0]+t:location.href.match(/^[^\?]*\/(?:)/)[0]+t),!t)throw'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return t}(),getUrl:function(t){return-1==t.indexOf(":/")&&0!==t.indexOf("/")&&(t=this.basePath+t),t=this.appendTimestamp(t)},appendTimestamp:function(t){if(!this.timestamp||"/"===t.charAt(t.length-1)||/[&?]t=/.test(t))return t;var e=0<=t.indexOf("?")?"&":"?";return t+e+"t="+this.timestamp},domReady:(o=[],function(t){if(o.push(t),"complete"===document.readyState&&setTimeout(i,1),1==o.length)if(document.addEventListener)document.addEventListener("DOMContentLoaded",i,!1),window.addEventListener("load",i,!1);else if(document.attachEvent){document.attachEvent("onreadystatechange",i),window.attachEvent("onload",i);var e=!1;try{e=!window.frameElement}catch(n){}document.documentElement.doScroll&&e&&!function a(){try{document.documentElement.doScroll("left")}catch(n){return void setTimeout(a,1)}i()}()}})};function i(){try{document.addEventListener?(document.removeEventListener("DOMContentLoaded",i,!1),window.removeEventListener("load",i,!1),n()):document.attachEvent&&"complete"===document.readyState&&(document.detachEvent("onreadystatechange",i),window.detachEvent("onload",i),n())}catch(t){}}function n(){for(var t;t=o.shift();)t()}var a,r=window.CKEDITOR_GETURL;return r&&(a=e.getUrl,e.getUrl=function(t){return r.call(e,t)||a.call(e,t)}),e}());
|
||||
// replace_end
|
||||
/* jscs:enable */
|
||||
/* jshint ignore:end */
|
||||
|
||||
if ( CKEDITOR.loader )
|
||||
CKEDITOR.loader.load( 'ckeditor' );
|
||||
else {
|
||||
// Set the script name to be loaded by the loader.
|
||||
CKEDITOR._autoLoad = 'ckeditor';
|
||||
|
||||
// Include the loader script.
|
||||
if ( document.body && ( !document.readyState || document.readyState == 'complete' ) ) {
|
||||
var script = document.createElement( 'script' );
|
||||
script.type = 'text/javascript';
|
||||
script.src = CKEDITOR.getUrl( 'core/loader.js' );
|
||||
document.body.appendChild( script );
|
||||
} else {
|
||||
document.write( '<script type="text/javascript" src="' + CKEDITOR.getUrl( 'core/loader.js' ) + '"></script>' );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The skin to load for all created instances, it may be the name of the skin
|
||||
* folder inside the editor installation path, or the name and the path separated
|
||||
* by a comma.
|
||||
*
|
||||
* **Note:** This is a global configuration that applies to all instances.
|
||||
*
|
||||
* CKEDITOR.skinName = 'moono';
|
||||
*
|
||||
* CKEDITOR.skinName = 'myskin,/customstuff/myskin/';
|
||||
*
|
||||
* @cfg {String} [skinName='moono-lisa']
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.skinName = 'moono-lisa';
|
||||
45
Admin/plugins/ckeditor/config.js
Normal file
45
Admin/plugins/ckeditor/config.js
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
CKEDITOR.editorConfig = function( config ) {
|
||||
|
||||
// %REMOVE_START%
|
||||
// The configuration options below are needed when running CKEditor from source files.
|
||||
config.plugins = 'dialogui,dialog,about,a11yhelp,dialogadvtab,basicstyles,bidi,blockquote,notification,button,toolbar,clipboard,panelbutton,panel,floatpanel,colorbutton,colordialog,xml,ajax,templates,menu,contextmenu,copyformatting,div,editorplaceholder,resize,elementspath,enterkey,entities,exportpdf,popup,filetools,filebrowser,find,floatingspace,listblock,richcombo,font,fakeobjects,forms,format,horizontalrule,htmlwriter,iframe,wysiwygarea,image,indent,indentblock,indentlist,smiley,justify,menubutton,language,link,list,liststyle,magicline,maximize,newpage,pagebreak,pastetext,pastetools,pastefromgdocs,pastefromlibreoffice,pastefromword,preview,print,removeformat,save,selectall,showblocks,showborders,sourcearea,specialchar,scayt,stylescombo,tab,table,tabletools,tableselection,undo,lineutils,widgetselection,widget,notificationaggregator,uploadwidget,uploadimage';
|
||||
config.skin = 'office2013';
|
||||
// %REMOVE_END%
|
||||
|
||||
// Define changes to default configuration here. For example:
|
||||
// config.language = 'fr';
|
||||
config.uiColor = '#AADC6E';
|
||||
config.iframe_attributes = [
|
||||
{sandbox: 'allow-scripts allow-same-origin'},
|
||||
{allow: 'autoplay'}
|
||||
];
|
||||
|
||||
config.toolbarGroups = [
|
||||
{ name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
|
||||
{ name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },
|
||||
{ name: 'forms', groups: [ 'forms' ] },
|
||||
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
|
||||
{ name: 'styles', groups: [ 'styles' ] },
|
||||
{ name: 'paragraph', groups: [ 'list', 'indent', 'blocks', 'align', 'bidi', 'paragraph' ] },
|
||||
'/',
|
||||
{ name: 'links', groups: [ 'links' ] },
|
||||
{ name: 'insert', groups: [ 'insert' ] },
|
||||
{ name: 'colors', groups: [ 'colors' ] },
|
||||
{ name: 'tools', groups: [ 'tools' ] },
|
||||
{ name: 'others', groups: [ 'others' ] },
|
||||
{ name: 'about', groups: [ 'about' ] },
|
||||
{ name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
|
||||
'/'
|
||||
];
|
||||
|
||||
config.removeButtons = 'NewPage,ExportPdf,Preview,Print,Save,Templates,PasteFromWord,Find,SelectAll,Scayt,Replace,Form,Checkbox,Radio,TextField,Textarea,Select,Button,ImageButton,HiddenField,Language,Smiley,Styles';
|
||||
|
||||
//config.extraPlugins = 'pastecode';
|
||||
//config.removePlugins = 'link';
|
||||
//config.extraPlugins = 'adv_link';
|
||||
};
|
||||
208
Admin/plugins/ckeditor/contents.css
Normal file
208
Admin/plugins/ckeditor/contents.css
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
body
|
||||
{
|
||||
/* Font */
|
||||
/* Emoji fonts are added to visualise them nicely in Internet Explorer. */
|
||||
font-family: sans-serif, Arial, Verdana, "Trebuchet MS", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
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 different 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;
|
||||
}
|
||||
69
Admin/plugins/ckeditor/core/_bootstrap.js
Normal file
69
Admin/plugins/ckeditor/core/_bootstrap.js
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview API initialization code.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
// Check whether high contrast is active by creating a colored border.
|
||||
var hcDetect = CKEDITOR.dom.element.createFromHtml( '<div style="width:0;height:0;position:absolute;left:-10000px;' +
|
||||
'border:1px solid;border-color:red blue"></div>', CKEDITOR.document );
|
||||
|
||||
hcDetect.appendTo( CKEDITOR.document.getHead() );
|
||||
|
||||
// Update CKEDITOR.env.
|
||||
// Catch exception needed sometimes for FF. (https://dev.ckeditor.com/ticket/4230)
|
||||
try {
|
||||
var top = hcDetect.getComputedStyle( 'border-top-color' ),
|
||||
right = hcDetect.getComputedStyle( 'border-right-color' );
|
||||
|
||||
// We need to check if getComputedStyle returned any value, because on FF
|
||||
// it returnes empty string if CKEditor is loaded in hidden iframe. (https://dev.ckeditor.com/ticket/11121)
|
||||
CKEDITOR.env.hc = !!( top && top == right );
|
||||
} catch ( e ) {
|
||||
CKEDITOR.env.hc = false;
|
||||
}
|
||||
|
||||
hcDetect.remove();
|
||||
|
||||
if ( CKEDITOR.env.hc )
|
||||
CKEDITOR.env.cssClass += ' cke_hc';
|
||||
|
||||
// Initially hide UI spaces when relevant skins are loading, later restored by skin css.
|
||||
CKEDITOR.document.appendStyleText( '.cke{visibility:hidden;}' );
|
||||
|
||||
// Mark the editor as fully loaded.
|
||||
CKEDITOR.status = 'loaded';
|
||||
CKEDITOR.fireOnce( 'loaded' );
|
||||
|
||||
// Process all instances created by the "basic" implementation.
|
||||
var pending = CKEDITOR._.pending;
|
||||
if ( pending ) {
|
||||
delete CKEDITOR._.pending;
|
||||
|
||||
for ( var i = 0; i < pending.length; i++ ) {
|
||||
CKEDITOR.editor.prototype.constructor.apply( pending[ i ][ 0 ], pending[ i ][ 1 ] );
|
||||
CKEDITOR.add( pending[ i ][ 0 ] );
|
||||
}
|
||||
}
|
||||
} )();
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running on a High Contrast environment.
|
||||
*
|
||||
* if ( CKEDITOR.env.hc )
|
||||
* alert( 'You\'re running on High Contrast mode. The editor interface will get adapted to provide you a better experience.' );
|
||||
*
|
||||
* @property {Boolean} hc
|
||||
* @member CKEDITOR.env
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when a CKEDITOR core object is fully loaded and ready for interaction.
|
||||
*
|
||||
* @event loaded
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
209
Admin/plugins/ckeditor/core/ckeditor.js
vendored
Normal file
209
Admin/plugins/ckeditor/core/ckeditor.js
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Contains the third and last part of the {@link CKEDITOR} object
|
||||
* definition.
|
||||
*/
|
||||
|
||||
/** @class CKEDITOR */
|
||||
|
||||
// Remove the CKEDITOR.loadFullCore reference defined on ckeditor_basic.
|
||||
delete CKEDITOR.loadFullCore;
|
||||
|
||||
/**
|
||||
* Stores references to all editor instances created. The name of the properties
|
||||
* in this object correspond to instance names, and their values contain the
|
||||
* {@link CKEDITOR.editor} object representing them.
|
||||
*
|
||||
* alert( CKEDITOR.instances.editor1.name ); // 'editor1'
|
||||
*
|
||||
* @property {Object}
|
||||
*/
|
||||
CKEDITOR.instances = {};
|
||||
|
||||
/**
|
||||
* The document of the window storing the CKEDITOR object.
|
||||
*
|
||||
* alert( CKEDITOR.document.getBody().getName() ); // 'body'
|
||||
*
|
||||
* @property {CKEDITOR.dom.document}
|
||||
*/
|
||||
CKEDITOR.document = new CKEDITOR.dom.document( document );
|
||||
|
||||
/**
|
||||
* Adds an editor instance to the global {@link CKEDITOR} object. This function
|
||||
* is available for internal use mainly.
|
||||
*
|
||||
* @param {CKEDITOR.editor} editor The editor instance to be added.
|
||||
*/
|
||||
CKEDITOR.add = function( editor ) {
|
||||
CKEDITOR.instances[ editor.name ] = editor;
|
||||
|
||||
editor.on( 'focus', function() {
|
||||
if ( CKEDITOR.currentInstance != editor ) {
|
||||
CKEDITOR.currentInstance = editor;
|
||||
CKEDITOR.fire( 'currentInstance' );
|
||||
}
|
||||
} );
|
||||
|
||||
editor.on( 'blur', removeInstance );
|
||||
|
||||
// Remove currentInstance if it's destroyed (#589).
|
||||
editor.on( 'destroy', removeInstance );
|
||||
|
||||
CKEDITOR.fire( 'instance', null, editor );
|
||||
|
||||
function removeInstance() {
|
||||
if ( CKEDITOR.currentInstance == editor ) {
|
||||
CKEDITOR.currentInstance = null;
|
||||
CKEDITOR.fire( 'currentInstance' );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes an editor instance from the global {@link CKEDITOR} object. This function
|
||||
* is available for internal use only. External code must use {@link CKEDITOR.editor#method-destroy}.
|
||||
*
|
||||
* @private
|
||||
* @param {CKEDITOR.editor} editor The editor instance to be removed.
|
||||
*/
|
||||
CKEDITOR.remove = function( editor ) {
|
||||
delete CKEDITOR.instances[ editor.name ];
|
||||
};
|
||||
|
||||
( function() {
|
||||
var tpls = {};
|
||||
|
||||
/**
|
||||
* Adds a named {@link CKEDITOR.template} instance to be reused among all editors.
|
||||
* This will return the existing one if a template with same name is already
|
||||
* defined. Additionally, it fires the "template" event to allow template source customization.
|
||||
*
|
||||
* @param {String} name The name which identifies a UI template.
|
||||
* @param {String} source The source string for constructing this template.
|
||||
* @returns {CKEDITOR.template} The created template instance.
|
||||
*/
|
||||
CKEDITOR.addTemplate = function( name, source ) {
|
||||
var tpl = tpls[ name ];
|
||||
if ( tpl )
|
||||
return tpl;
|
||||
|
||||
// Make it possible to customize the template through event.
|
||||
var params = { name: name, source: source };
|
||||
CKEDITOR.fire( 'template', params );
|
||||
|
||||
return ( tpls[ name ] = new CKEDITOR.template( params.source ) );
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves a defined template created with {@link CKEDITOR#addTemplate}.
|
||||
*
|
||||
* @param {String} name The template name.
|
||||
*/
|
||||
CKEDITOR.getTemplate = function( name ) {
|
||||
return tpls[ name ];
|
||||
};
|
||||
} )();
|
||||
|
||||
( function() {
|
||||
var styles = [];
|
||||
|
||||
/**
|
||||
* Adds CSS rules to be appended to the editor document.
|
||||
* This method is mostly used by plugins to add custom styles to the editor
|
||||
* document. For basic content styling the `contents.css` file should be
|
||||
* used instead.
|
||||
*
|
||||
* **Note:** This function should be called before the creation of editor instances.
|
||||
*
|
||||
* // Add styles for all headings inside editable contents.
|
||||
* CKEDITOR.addCss( '.cke_editable h1,.cke_editable h2,.cke_editable h3 { border-bottom: 1px dotted red }' );
|
||||
*
|
||||
* @param {String} css The style rules to be appended.
|
||||
* @see CKEDITOR.config#contentsCss
|
||||
*/
|
||||
CKEDITOR.addCss = function( css ) {
|
||||
styles.push( css );
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a string with all CSS rules passed to the {@link CKEDITOR#addCss} method.
|
||||
*
|
||||
* @returns {String} A string containing CSS rules.
|
||||
*/
|
||||
CKEDITOR.getCss = function() {
|
||||
return styles.join( '\n' );
|
||||
};
|
||||
} )();
|
||||
|
||||
// Perform global clean up to free as much memory as possible
|
||||
// when there are no instances left
|
||||
CKEDITOR.on( 'instanceDestroyed', function() {
|
||||
if ( CKEDITOR.tools.isEmpty( this.instances ) )
|
||||
CKEDITOR.fire( 'reset' );
|
||||
} );
|
||||
|
||||
// Load the bootstrap script.
|
||||
CKEDITOR.loader.load( '_bootstrap' ); // %REMOVE_LINE%
|
||||
|
||||
// Tri-state constants.
|
||||
/**
|
||||
* Used to indicate the ON or ACTIVE state.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
*/
|
||||
CKEDITOR.TRISTATE_ON = 1;
|
||||
|
||||
/**
|
||||
* Used to indicate the OFF or INACTIVE state.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
*/
|
||||
CKEDITOR.TRISTATE_OFF = 2;
|
||||
|
||||
/**
|
||||
* Used to indicate the DISABLED state.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0]
|
||||
*/
|
||||
CKEDITOR.TRISTATE_DISABLED = 0;
|
||||
|
||||
/**
|
||||
* The editor which is currently active (has user focus).
|
||||
*
|
||||
* function showCurrentEditorName() {
|
||||
* if ( CKEDITOR.currentInstance )
|
||||
* alert( CKEDITOR.currentInstance.name );
|
||||
* else
|
||||
* alert( 'Please focus an editor first.' );
|
||||
* }
|
||||
*
|
||||
* @property {CKEDITOR.editor} currentInstance
|
||||
* @see CKEDITOR#event-currentInstance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the CKEDITOR.currentInstance object reference changes. This may
|
||||
* happen when setting the focus on different editor instances in the page.
|
||||
*
|
||||
* var editor; // A variable to store a reference to the current editor.
|
||||
* CKEDITOR.on( 'currentInstance', function() {
|
||||
* editor = CKEDITOR.currentInstance;
|
||||
* } );
|
||||
*
|
||||
* @event currentInstance
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the last instance has been destroyed. This event is used to perform
|
||||
* global memory cleanup.
|
||||
*
|
||||
* @event reset
|
||||
*/
|
||||
340
Admin/plugins/ckeditor/core/ckeditor_base.js
Normal file
340
Admin/plugins/ckeditor/core/ckeditor_base.js
Normal file
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Contains the first and essential part of the {@link CKEDITOR}
|
||||
* object definition.
|
||||
*/
|
||||
|
||||
// #### Compressed Code
|
||||
// Compressed code in ckeditor.js must be be updated on changes in the script.
|
||||
// Simply run `grunt ckeditor-base-replace` after changing this file.
|
||||
|
||||
// #### Raw code
|
||||
// ATTENTION: read the above "Compressed Code" notes when changing this code.
|
||||
|
||||
if ( !window.CKEDITOR ) {
|
||||
/**
|
||||
* This is the API entry point. The entire CKEditor code runs under this object.
|
||||
* @class CKEDITOR
|
||||
* @mixins CKEDITOR.event
|
||||
* @singleton
|
||||
*/
|
||||
window.CKEDITOR = ( function() {
|
||||
var basePathSrcPattern = /(^|.*[\\\/])ckeditor\.js(?:\?.*|;.*)?$/i;
|
||||
|
||||
var CKEDITOR = {
|
||||
|
||||
/**
|
||||
* A constant string unique for each release of CKEditor. Its value
|
||||
* is used, by default, to build the URL for all resources loaded
|
||||
* by the editor code, guaranteeing clean cache results when
|
||||
* upgrading.
|
||||
*
|
||||
* alert( CKEDITOR.timestamp ); // e.g. '87dm'
|
||||
*/
|
||||
timestamp: '', // %REMOVE_LINE%
|
||||
/* // %REMOVE_LINE%
|
||||
// The production implementation contains a fixed timestamp, unique
|
||||
// for each release and generated by the releaser.
|
||||
// (Base 36 value of each component of YYMMDDHH - 4 chars total - e.g. 87bm == 08071122)
|
||||
timestamp: '%TIMESTAMP%',
|
||||
// %REMOVE_LINE% */
|
||||
|
||||
/**
|
||||
* Contains the CKEditor version number.
|
||||
*
|
||||
* alert( CKEDITOR.version ); // e.g. 'CKEditor 3.4.1'
|
||||
*/
|
||||
version: '%VERSION%',
|
||||
|
||||
/**
|
||||
* Contains the CKEditor revision number.
|
||||
* The revision number is incremented automatically, following each
|
||||
* modification to the CKEditor source code.
|
||||
*
|
||||
* alert( CKEDITOR.revision ); // e.g. '3975'
|
||||
*/
|
||||
revision: '%REV%',
|
||||
|
||||
/**
|
||||
* A 3-digit random integer, valid for the entire life of the CKEDITOR object.
|
||||
*
|
||||
* alert( CKEDITOR.rnd ); // e.g. 319
|
||||
*
|
||||
* Generated integer is not cryptographically secure. It has been deprecated to
|
||||
* prevent using it in a security-sensitive context by accident.
|
||||
* Use `window.crypto.getRandomValues()` native browser method instead.
|
||||
*
|
||||
* @deprecated 4.18.0
|
||||
* @property {Number}
|
||||
*/
|
||||
rnd: Math.floor( Math.random() * ( 999 /*Max*/ - 100 /*Min*/ + 1 ) ) + 100 /*Min*/,
|
||||
|
||||
/**
|
||||
* Private object used to hold core stuff. It should not be used outside of
|
||||
* the API code as properties defined here may change at any time
|
||||
* without notice.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_: {
|
||||
pending: [],
|
||||
basePathSrcPattern: basePathSrcPattern
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates the API loading status. The following statuses are available:
|
||||
*
|
||||
* * **unloaded**: the API is not yet loaded.
|
||||
* * **basic_loaded**: the basic API features are available.
|
||||
* * **basic_ready**: the basic API is ready to load the full core code.
|
||||
* * **loaded**: the API can be fully used.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* if ( CKEDITOR.status == 'loaded' ) {
|
||||
* // The API can now be fully used.
|
||||
* doSomething();
|
||||
* } else {
|
||||
* // Wait for the full core to be loaded and fire its loading.
|
||||
* CKEDITOR.on( 'load', doSomething );
|
||||
* CKEDITOR.loadFullCore && CKEDITOR.loadFullCore();
|
||||
* }
|
||||
*/
|
||||
status: 'unloaded',
|
||||
|
||||
/**
|
||||
* The full URL for the CKEditor installation directory.
|
||||
* It is possible to manually provide the base path by setting a
|
||||
* global variable named `CKEDITOR_BASEPATH`. This global variable
|
||||
* must be set **before** the editor script loading.
|
||||
*
|
||||
* alert( CKEDITOR.basePath ); // e.g. 'http://www.example.com/ckeditor/'
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
basePath: ( function() {
|
||||
// Find out the editor directory path, based on its <script> tag.
|
||||
var path = window.CKEDITOR_BASEPATH || '';
|
||||
|
||||
if ( !path ) {
|
||||
var scripts = document.getElementsByTagName( 'script' );
|
||||
|
||||
for ( var i = 0; i < scripts.length; i++ ) {
|
||||
var match = scripts[ i ].src.match( basePathSrcPattern );
|
||||
|
||||
if ( match ) {
|
||||
path = match[ 1 ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In IE (only) the script.src string is the raw value entered in the
|
||||
// HTML source. Other browsers return the full resolved URL instead.
|
||||
if ( path.indexOf( ':/' ) == -1 && path.slice( 0, 2 ) != '//' ) {
|
||||
// Absolute path.
|
||||
if ( path.indexOf( '/' ) === 0 )
|
||||
path = location.href.match( /^.*?:\/\/[^\/]*/ )[ 0 ] + path;
|
||||
// Relative path.
|
||||
else
|
||||
path = location.href.match( /^[^\?]*\/(?:)/ )[ 0 ] + path;
|
||||
}
|
||||
|
||||
if ( !path )
|
||||
throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';
|
||||
|
||||
return path;
|
||||
} )(),
|
||||
|
||||
/**
|
||||
* Gets the full URL for CKEditor resources. By default, URLs
|
||||
* returned by this function contain a querystring parameter ("t")
|
||||
* set to the {@link CKEDITOR#timestamp} value.
|
||||
*
|
||||
* It is possible to provide a custom implementation of this
|
||||
* function by setting a global variable named `CKEDITOR_GETURL`.
|
||||
* This global variable must be set **before** the editor script
|
||||
* loading. If the custom implementation returns nothing (`==null`), the
|
||||
* default implementation is used.
|
||||
*
|
||||
* // e.g. 'http://www.example.com/ckeditor/skins/default/editor.css?t=87dm'
|
||||
* alert( CKEDITOR.getUrl( 'skins/default/editor.css' ) );
|
||||
*
|
||||
* // e.g. 'http://www.example.com/skins/default/editor.css?t=87dm'
|
||||
* alert( CKEDITOR.getUrl( '/skins/default/editor.css' ) );
|
||||
*
|
||||
* // e.g. 'http://www.somesite.com/skins/default/editor.css?t=87dm'
|
||||
* alert( CKEDITOR.getUrl( 'http://www.somesite.com/skins/default/editor.css' ) );
|
||||
*
|
||||
* @param {String} resource The resource whose full URL we want to get.
|
||||
* It may be a full, absolute, or relative URL.
|
||||
* @returns {String} The full URL.
|
||||
*/
|
||||
getUrl: function( resource ) {
|
||||
// If this is not a full or absolute path.
|
||||
if ( resource.indexOf( ':/' ) == -1 && resource.indexOf( '/' ) !== 0 )
|
||||
resource = this.basePath + resource;
|
||||
|
||||
resource = this.appendTimestamp( resource );
|
||||
|
||||
return resource;
|
||||
},
|
||||
|
||||
/**
|
||||
* Appends {@link CKEDITOR#timestamp} to the provided URL as querystring parameter ("t").
|
||||
*
|
||||
* Leaves the URL unchanged if it is a directory URL or it already contains querystring parameter.
|
||||
*
|
||||
* @since 4.17.2
|
||||
* @param {String} resource The resource URL to which the timestamp should be appended.
|
||||
* @returns {String} The resource URL with cache key appended whenever possible.
|
||||
*/
|
||||
appendTimestamp: function( resource ) {
|
||||
if ( !this.timestamp ||
|
||||
resource.charAt( resource.length - 1 ) === '/' ||
|
||||
( /[&?]t=/ ).test( resource )
|
||||
) {
|
||||
return resource;
|
||||
}
|
||||
|
||||
var concatenateSign = resource.indexOf( '?' ) >= 0 ? '&' : '?';
|
||||
return resource + concatenateSign + 't=' + this.timestamp;
|
||||
},
|
||||
|
||||
/**
|
||||
* Specify a function to execute when the DOM is fully loaded.
|
||||
*
|
||||
* If called after the DOM has been initialized, the function passed in will
|
||||
* be executed immediately.
|
||||
*
|
||||
* @method
|
||||
* @todo
|
||||
*/
|
||||
domReady: ( function() {
|
||||
// Based on the original jQuery code (available under the MIT license, see LICENSE.md).
|
||||
|
||||
var callbacks = [];
|
||||
|
||||
function onReady() {
|
||||
try {
|
||||
// Cleanup functions for the document ready method
|
||||
if ( document.addEventListener ) {
|
||||
document.removeEventListener( 'DOMContentLoaded', onReady, false );
|
||||
window.removeEventListener( 'load', onReady, false );
|
||||
executeCallbacks();
|
||||
}
|
||||
// Make sure body exists, at least, in case IE gets a little overzealous.
|
||||
else if ( document.attachEvent && document.readyState === 'complete' ) {
|
||||
document.detachEvent( 'onreadystatechange', onReady );
|
||||
window.detachEvent( 'onload', onReady );
|
||||
executeCallbacks();
|
||||
}
|
||||
} catch ( er ) {}
|
||||
}
|
||||
|
||||
function executeCallbacks() {
|
||||
var i;
|
||||
while ( ( i = callbacks.shift() ) )
|
||||
i();
|
||||
}
|
||||
|
||||
return function( fn ) {
|
||||
callbacks.push( fn );
|
||||
|
||||
// Catch cases where this is called after the
|
||||
// browser event has already occurred.
|
||||
if ( document.readyState === 'complete' )
|
||||
// Handle it asynchronously to allow scripts the opportunity to delay ready
|
||||
setTimeout( onReady, 1 );
|
||||
|
||||
// Run below once on demand only.
|
||||
if ( callbacks.length != 1 )
|
||||
return;
|
||||
|
||||
// For IE>8, Firefox, Opera and Webkit.
|
||||
if ( document.addEventListener ) {
|
||||
// Use the handy event callback
|
||||
document.addEventListener( 'DOMContentLoaded', onReady, false );
|
||||
|
||||
// A fallback to window.onload, that will always work
|
||||
window.addEventListener( 'load', onReady, false );
|
||||
|
||||
}
|
||||
// If old IE event model is used
|
||||
else if ( document.attachEvent ) {
|
||||
// ensure firing before onload,
|
||||
// maybe late but safe also for iframes
|
||||
document.attachEvent( 'onreadystatechange', onReady );
|
||||
|
||||
// A fallback to window.onload, that will always work
|
||||
window.attachEvent( 'onload', onReady );
|
||||
|
||||
// If IE and not a frame
|
||||
// continually check to see if the document is ready
|
||||
// use the trick by Diego Perini
|
||||
// http://javascript.nwbox.com/IEContentLoaded/
|
||||
var toplevel = false;
|
||||
|
||||
try {
|
||||
toplevel = !window.frameElement;
|
||||
} catch ( e ) {}
|
||||
|
||||
if ( document.documentElement.doScroll && toplevel ) {
|
||||
scrollCheck();
|
||||
}
|
||||
}
|
||||
|
||||
function scrollCheck() {
|
||||
try {
|
||||
document.documentElement.doScroll( 'left' );
|
||||
} catch ( e ) {
|
||||
setTimeout( scrollCheck, 1 );
|
||||
return;
|
||||
}
|
||||
onReady();
|
||||
}
|
||||
};
|
||||
|
||||
} )()
|
||||
};
|
||||
|
||||
// Make it possible to override the "url" function with a custom
|
||||
// implementation pointing to a global named CKEDITOR_GETURL.
|
||||
var newGetUrl = window.CKEDITOR_GETURL;
|
||||
if ( newGetUrl ) {
|
||||
var originalGetUrl = CKEDITOR.getUrl;
|
||||
CKEDITOR.getUrl = function( resource ) {
|
||||
return newGetUrl.call( CKEDITOR, resource ) || originalGetUrl.call( CKEDITOR, resource );
|
||||
};
|
||||
}
|
||||
|
||||
return CKEDITOR;
|
||||
} )();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function called upon loading a custom configuration file that can
|
||||
* modify the editor instance configuration ({@link CKEDITOR.editor#config}).
|
||||
* It is usually defined inside the custom configuration files that can
|
||||
* include developer defined settings.
|
||||
*
|
||||
* // This is supposed to be placed in the config.js file.
|
||||
* CKEDITOR.editorConfig = function( config ) {
|
||||
* // Define changes to default configuration here. For example:
|
||||
* config.language = 'fr';
|
||||
* config.uiColor = '#AADC6E';
|
||||
* };
|
||||
*
|
||||
* @method editorConfig
|
||||
* @param {CKEDITOR.config} config A configuration object containing the
|
||||
* settings defined for a {@link CKEDITOR.editor} instance up to this
|
||||
* function call. Note that not all settings may still be available. See
|
||||
* [Configuration Loading Order](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_configuration.html)
|
||||
* for details.
|
||||
*/
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR )
|
||||
94
Admin/plugins/ckeditor/core/ckeditor_basic.js
Normal file
94
Admin/plugins/ckeditor/core/ckeditor_basic.js
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Contains the second part of the {@link CKEDITOR} object
|
||||
* definition, which defines the basic editor features to be available in
|
||||
* the root ckeditor_basic.js file.
|
||||
*/
|
||||
|
||||
if ( CKEDITOR.status == 'unloaded' ) {
|
||||
( function() {
|
||||
CKEDITOR.event.implementOn( CKEDITOR );
|
||||
|
||||
/**
|
||||
* Forces the full CKEditor core code, in the case only the basic code has been
|
||||
* loaded (`ckeditor_basic.js`). This method self-destroys (becomes undefined) in
|
||||
* the first call or as soon as the full code is available.
|
||||
*
|
||||
* // Check if the full core code has been loaded and load it.
|
||||
* if ( CKEDITOR.loadFullCore )
|
||||
* CKEDITOR.loadFullCore();
|
||||
*
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.loadFullCore = function() {
|
||||
// If the basic code is not ready, just mark it to be loaded.
|
||||
if ( CKEDITOR.status != 'basic_ready' ) {
|
||||
CKEDITOR.loadFullCore._load = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Destroy this function.
|
||||
delete CKEDITOR.loadFullCore;
|
||||
|
||||
// Append the script to the head.
|
||||
var script = document.createElement( 'script' );
|
||||
script.type = 'text/javascript';
|
||||
script.src = CKEDITOR.basePath + 'ckeditor.js';
|
||||
script.src = CKEDITOR.basePath + 'ckeditor_source.js'; // %REMOVE_LINE%
|
||||
|
||||
document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
|
||||
};
|
||||
|
||||
/**
|
||||
* The time to wait (in seconds) to load the full editor code after the
|
||||
* page load, if the "ckeditor_basic" file is used. If set to zero, the
|
||||
* editor is loaded on demand, as soon as an instance is created.
|
||||
*
|
||||
* This value must be set on the page before the page load completion.
|
||||
*
|
||||
* // Loads the full source after five seconds.
|
||||
* CKEDITOR.loadFullCoreTimeout = 5;
|
||||
*
|
||||
* @property
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.loadFullCoreTimeout = 0;
|
||||
|
||||
// Documented at ckeditor.js.
|
||||
CKEDITOR.add = function( editor ) {
|
||||
// For now, just put the editor in the pending list. It will be
|
||||
// processed as soon as the full code gets loaded.
|
||||
var pending = this._.pending || ( this._.pending = [] );
|
||||
pending.push( editor );
|
||||
};
|
||||
|
||||
( function() {
|
||||
var onload = function() {
|
||||
var loadFullCore = CKEDITOR.loadFullCore,
|
||||
loadFullCoreTimeout = CKEDITOR.loadFullCoreTimeout;
|
||||
|
||||
if ( !loadFullCore )
|
||||
return;
|
||||
|
||||
CKEDITOR.status = 'basic_ready';
|
||||
|
||||
if ( loadFullCore && loadFullCore._load )
|
||||
loadFullCore();
|
||||
else if ( loadFullCoreTimeout ) {
|
||||
setTimeout( function() {
|
||||
if ( CKEDITOR.loadFullCore )
|
||||
CKEDITOR.loadFullCore();
|
||||
}, loadFullCoreTimeout * 1000 );
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.domReady( onload );
|
||||
} )();
|
||||
|
||||
CKEDITOR.status = 'basic_loaded';
|
||||
} )();
|
||||
}
|
||||
197
Admin/plugins/ckeditor/core/ckeditor_version-check.js
Normal file
197
Admin/plugins/ckeditor/core/ckeditor_version-check.js
Normal file
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/* global console */
|
||||
|
||||
( function() {
|
||||
var apiUrl = 'https://cke4.ckeditor.com/ckeditor4-secure-version/versions.json',
|
||||
upgradeLink = 'https://ckeditor.com/ckeditor-4-support/',
|
||||
versionRegex = /^4\.(\d+)\.(\d+)(-lts)?(?: \(?.+?\)?)?$/,
|
||||
isDrupal = 'Drupal' in window,
|
||||
consoleErrorDisplayed = false,
|
||||
versionInfo = {
|
||||
current: parseVersion( CKEDITOR.version )
|
||||
};
|
||||
|
||||
if ( isDrupal || !versionInfo.current ) {
|
||||
return;
|
||||
}
|
||||
|
||||
CKEDITOR.config.versionCheck = versionInfo.current.isLts ? false : true;
|
||||
|
||||
CKEDITOR.on( 'instanceReady', function( evt ) {
|
||||
var editor = evt.editor;
|
||||
|
||||
if ( !editor.config.versionCheck ) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor.on( 'dialogShow', function( evt ) {
|
||||
var dialog = evt.data;
|
||||
|
||||
if ( dialog._.name !== 'about' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
performVersionCheck( function() {
|
||||
addInfoToAboutDialog( editor, dialog );
|
||||
} );
|
||||
} );
|
||||
|
||||
performVersionCheck( function() {
|
||||
notifyAboutInsecureVersion( editor );
|
||||
} );
|
||||
} );
|
||||
|
||||
function performVersionCheck( callback ) {
|
||||
if ( versionInfo.secure && versionInfo.latest ) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
try {
|
||||
var request = new XMLHttpRequest(),
|
||||
requestUrl = apiUrl + '?v=' + encodeURIComponent( versionInfo.current.original );
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
if ( request.readyState === 4 && request.status === 200 ) {
|
||||
var response = JSON.parse( request.responseText );
|
||||
|
||||
versionInfo.latest = parseVersion( response.latestVersion );
|
||||
versionInfo.secure = parseVersion( response.secureVersion );
|
||||
versionInfo.isLatest = isLatestVersion();
|
||||
versionInfo.isSecure = isSecureVersion();
|
||||
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
request.open( 'GET', requestUrl );
|
||||
request.responseType = 'text';
|
||||
request.send();
|
||||
} catch ( e ) {
|
||||
}
|
||||
}
|
||||
|
||||
function notifyAboutInsecureVersion( editor ) {
|
||||
if ( versionInfo.isSecure ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var notificationMessage = editor.lang.versionCheck.notificationMessage.replace( '%current', versionInfo.current.original ).
|
||||
replace( '%latest', versionInfo.latest.original ).
|
||||
replace( /%link/g, upgradeLink ),
|
||||
isNotificationAvailable = 'notification' in editor.plugins;
|
||||
|
||||
showConsoleError( editor );
|
||||
|
||||
if ( isNotificationAvailable ) {
|
||||
editor.showNotification( notificationMessage, 'warning' );
|
||||
}
|
||||
}
|
||||
|
||||
function showConsoleError( editor ) {
|
||||
if ( !window.console || !window.console.error ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( consoleErrorDisplayed ) {
|
||||
return;
|
||||
}
|
||||
|
||||
consoleErrorDisplayed = true;
|
||||
|
||||
var consoleMessage = editor.lang.versionCheck.consoleMessage.replace( '%current', versionInfo.current.original ).
|
||||
replace( '%latest', versionInfo.latest.original ).
|
||||
replace( /%link/g, upgradeLink );
|
||||
|
||||
console.error( consoleMessage );
|
||||
}
|
||||
|
||||
function addInfoToAboutDialog( editor, dialog ) {
|
||||
var container = dialog.getElement().findOne( '.cke_about_version-check' ),
|
||||
message = getAboutMessage( editor );
|
||||
|
||||
container.setHtml( '' );
|
||||
|
||||
if ( editor.config.versionCheck ) {
|
||||
container.setStyle( 'color', versionInfo.isSecure ? '' : '#C83939' );
|
||||
container.setHtml( message );
|
||||
}
|
||||
}
|
||||
|
||||
function getAboutMessage( editor ) {
|
||||
var lang = editor.lang.versionCheck,
|
||||
msg = '';
|
||||
|
||||
if ( !versionInfo.isLatest ) {
|
||||
msg = lang.aboutDialogUpgradeMessage;
|
||||
}
|
||||
|
||||
if ( !versionInfo.isSecure ) {
|
||||
msg = lang.aboutDialogInsecureMessage;
|
||||
}
|
||||
|
||||
return msg.replace( '%current', versionInfo.current.original ).
|
||||
replace( '%latest', versionInfo.latest.original ).
|
||||
replace( /%link/g, upgradeLink );
|
||||
}
|
||||
|
||||
function isLatestVersion() {
|
||||
return versionInfo.current.minor === versionInfo.latest.minor &&
|
||||
versionInfo.current.patch === versionInfo.latest.patch;
|
||||
}
|
||||
|
||||
function isSecureVersion() {
|
||||
if ( versionInfo.current.minor > versionInfo.secure.minor ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( versionInfo.current.minor === versionInfo.secure.minor &&
|
||||
versionInfo.current.patch >= versionInfo.secure.patch ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function parseVersion( version ) {
|
||||
var parts = version.match( versionRegex );
|
||||
|
||||
if ( !parts ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
original: version,
|
||||
major: 4,
|
||||
minor: Number( parts[ 1 ] ),
|
||||
patch: Number( parts[ 2 ] ),
|
||||
isLts: !!parts[ 3 ]
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The version check feature adds a notification system to the editor that informs
|
||||
* users if the editor version is secure. It is highly recommended to stay up to
|
||||
* date with the editor version to ensure that the editor is secure and provides
|
||||
* the best editing experience to users.
|
||||
*
|
||||
* If the current version is below the latest published secure version,
|
||||
* a user will be prompted about the available update. This feature is integrated
|
||||
* with the [Notification](https://ckeditor.com/cke4/addon/notification) plugin,
|
||||
* the [About](https://ckeditor.com/cke4/addon/about) dialog,
|
||||
* and developer console logs.
|
||||
*
|
||||
* You can manually disable this feature by setting the option to `false`,
|
||||
* but we strongly recommend upgrading the editor instead.
|
||||
*
|
||||
* - For CKEditor 4.22.* and below, this option is enabled by default.
|
||||
* - For CKEditor 4 LTS (4.23.0 and above), this option is disabled by default.
|
||||
*
|
||||
* @cfg {Boolean} [versionCheck]
|
||||
* @since 4.22.0
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
} )();
|
||||
275
Admin/plugins/ckeditor/core/command.js
Normal file
275
Admin/plugins/ckeditor/core/command.js
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a command that can be executed on an editor instance.
|
||||
*
|
||||
* var command = new CKEDITOR.command( editor, {
|
||||
* exec: function( editor ) {
|
||||
* alert( editor.document.getBody().getHtml() );
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.commandDefinition
|
||||
* @mixins CKEDITOR.event
|
||||
* @constructor Creates a command class instance.
|
||||
* @param {CKEDITOR.editor} editor The editor instance this command will be
|
||||
* related to.
|
||||
* @param {CKEDITOR.commandDefinition} commandDefinition The command
|
||||
* definition.
|
||||
*/
|
||||
CKEDITOR.command = function( editor, commandDefinition ) {
|
||||
/**
|
||||
* Lists UI items that are associated to this command. This list can be
|
||||
* used to interact with the UI on command execution (by the execution code
|
||||
* itself, for example).
|
||||
*
|
||||
* alert( 'Number of UI items associated to this command: ' + command.uiItems.length );
|
||||
*/
|
||||
this.uiItems = [];
|
||||
|
||||
/**
|
||||
* Executes the command.
|
||||
*
|
||||
* command.exec(); // The command gets executed.
|
||||
*
|
||||
* **Note:** You should use the {@link CKEDITOR.editor#execCommand} method instead of calling
|
||||
* `command.exec()` directly.
|
||||
*
|
||||
* @param {Object} [data] Any data to pass to the command. Depends on the
|
||||
* command implementation and requirements.
|
||||
* @returns {Boolean} A boolean indicating that the command has been successfully executed.
|
||||
*/
|
||||
this.exec = function( data ) {
|
||||
if ( this.state == CKEDITOR.TRISTATE_DISABLED || !this.checkAllowed() )
|
||||
return false;
|
||||
|
||||
if ( this.editorFocus ) // Give editor focus if necessary (https://dev.ckeditor.com/ticket/4355).
|
||||
editor.focus();
|
||||
|
||||
if ( this.fire( 'exec' ) === false )
|
||||
return true;
|
||||
|
||||
return ( commandDefinition.exec.call( this, editor, data ) !== false );
|
||||
};
|
||||
|
||||
/**
|
||||
* Explicitly update the status of the command, by firing the {@link CKEDITOR.command#event-refresh} event,
|
||||
* as well as invoke the {@link CKEDITOR.commandDefinition#refresh} method if defined, this method
|
||||
* is to allow different parts of the editor code to contribute in command status resolution.
|
||||
*
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
* @param {CKEDITOR.dom.elementPath} path
|
||||
*/
|
||||
this.refresh = function( editor, path ) {
|
||||
// Do nothing is we're on read-only and this command doesn't support it.
|
||||
// We don't need to disabled the command explicitely here, because this
|
||||
// is already done by the "readOnly" event listener.
|
||||
if ( !this.readOnly && editor.readOnly )
|
||||
return true;
|
||||
|
||||
// Disable commands that are not allowed in the current selection path context.
|
||||
if ( this.context && !path.isContextFor( this.context ) ) {
|
||||
this.disable();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Disable commands that are not allowed by the active filter.
|
||||
if ( !this.checkAllowed( true ) ) {
|
||||
this.disable();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make the "enabled" state a default for commands enabled from start.
|
||||
if ( !this.startDisabled )
|
||||
this.enable();
|
||||
|
||||
// Disable commands which shouldn't be enabled in this mode.
|
||||
if ( this.modes && !this.modes[ editor.mode ] )
|
||||
this.disable();
|
||||
|
||||
if ( this.fire( 'refresh', { editor: editor, path: path } ) === false )
|
||||
return true;
|
||||
|
||||
return ( commandDefinition.refresh && commandDefinition.refresh.apply( this, arguments ) !== false );
|
||||
};
|
||||
|
||||
var allowed;
|
||||
|
||||
/**
|
||||
* Checks whether this command is allowed by the active allowed
|
||||
* content filter ({@link CKEDITOR.editor#activeFilter}). This means
|
||||
* that if command implements {@link CKEDITOR.feature} interface it will be tested
|
||||
* by the {@link CKEDITOR.filter#checkFeature} method.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {Boolean} [noCache] Skip cache for example due to active filter change. Since CKEditor 4.2.0.
|
||||
* @returns {Boolean} Whether this command is allowed.
|
||||
*/
|
||||
this.checkAllowed = function( noCache ) {
|
||||
if ( !noCache && typeof allowed == 'boolean' )
|
||||
return allowed;
|
||||
|
||||
return allowed = editor.activeFilter.checkFeature( this );
|
||||
};
|
||||
|
||||
CKEDITOR.tools.extend( this, commandDefinition, {
|
||||
/**
|
||||
* The editor modes within which the command can be executed. The
|
||||
* execution will have no action if the current mode is not listed
|
||||
* in this property.
|
||||
*
|
||||
* // Enable the command in both WYSIWYG and Source modes.
|
||||
* command.modes = { wysiwyg:1,source:1 };
|
||||
*
|
||||
* // Enable the command in Source mode only.
|
||||
* command.modes = { source:1 };
|
||||
*
|
||||
* @see CKEDITOR.editor#mode
|
||||
*/
|
||||
modes: { wysiwyg: 1 },
|
||||
|
||||
/**
|
||||
* Indicates that the editor will get the focus before executing
|
||||
* the command.
|
||||
*
|
||||
* // Do not force the editor to have focus when executing the command.
|
||||
* command.editorFocus = false;
|
||||
*
|
||||
* @property {Boolean} [=true]
|
||||
*/
|
||||
editorFocus: 1,
|
||||
|
||||
/**
|
||||
* Indicates that this command is sensible to the selection context.
|
||||
* If `true`, the {@link CKEDITOR.command#method-refresh} method will be
|
||||
* called for this command on the {@link CKEDITOR.editor#event-selectionChange} event.
|
||||
*
|
||||
* @property {Boolean} [=false]
|
||||
*/
|
||||
contextSensitive: !!commandDefinition.context,
|
||||
|
||||
/**
|
||||
* Indicates the editor state. Possible values are:
|
||||
*
|
||||
* * {@link CKEDITOR#TRISTATE_DISABLED}: the command is
|
||||
* disabled. It's execution will have no effect. Same as {@link #disable}.
|
||||
* * {@link CKEDITOR#TRISTATE_ON}: the command is enabled
|
||||
* and currently active in the editor (for context sensitive commands, for example).
|
||||
* * {@link CKEDITOR#TRISTATE_OFF}: the command is enabled
|
||||
* and currently inactive in the editor (for context sensitive commands, for example).
|
||||
*
|
||||
* Do not set this property directly, using the {@link #setState} method instead.
|
||||
*
|
||||
* if ( command.state == CKEDITOR.TRISTATE_DISABLED )
|
||||
* alert( 'This command is disabled' );
|
||||
*
|
||||
* @property {Number} [=CKEDITOR.TRISTATE_DISABLED]
|
||||
*/
|
||||
state: CKEDITOR.TRISTATE_DISABLED
|
||||
} );
|
||||
|
||||
// Call the CKEDITOR.event constructor to initialize this instance.
|
||||
CKEDITOR.event.call( this );
|
||||
};
|
||||
|
||||
CKEDITOR.command.prototype = {
|
||||
/**
|
||||
* Enables the command for execution. The command state (see
|
||||
* {@link CKEDITOR.command#property-state}) available before disabling it is restored.
|
||||
*
|
||||
* command.enable();
|
||||
* command.exec(); // Execute the command.
|
||||
*/
|
||||
enable: function() {
|
||||
if ( this.state == CKEDITOR.TRISTATE_DISABLED && this.checkAllowed() )
|
||||
this.setState( ( !this.preserveState || ( typeof this.previousState == 'undefined' ) ) ? CKEDITOR.TRISTATE_OFF : this.previousState );
|
||||
},
|
||||
|
||||
/**
|
||||
* Disables the command for execution. The command state (see
|
||||
* {@link CKEDITOR.command#property-state}) will be set to {@link CKEDITOR#TRISTATE_DISABLED}.
|
||||
*
|
||||
* command.disable();
|
||||
* command.exec(); // "false" - Nothing happens.
|
||||
*/
|
||||
disable: function() {
|
||||
this.setState( CKEDITOR.TRISTATE_DISABLED );
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the command state.
|
||||
*
|
||||
* command.setState( CKEDITOR.TRISTATE_ON );
|
||||
* command.exec(); // Execute the command.
|
||||
* command.setState( CKEDITOR.TRISTATE_DISABLED );
|
||||
* command.exec(); // 'false' - Nothing happens.
|
||||
* command.setState( CKEDITOR.TRISTATE_OFF );
|
||||
* command.exec(); // Execute the command.
|
||||
*
|
||||
* @param {Number} newState The new state. See {@link #property-state}.
|
||||
* @returns {Boolean} Returns `true` if the command state changed.
|
||||
*/
|
||||
setState: function( newState ) {
|
||||
// Do nothing if there is no state change.
|
||||
if ( this.state == newState )
|
||||
return false;
|
||||
|
||||
if ( newState != CKEDITOR.TRISTATE_DISABLED && !this.checkAllowed() )
|
||||
return false;
|
||||
|
||||
this.previousState = this.state;
|
||||
|
||||
// Set the new state.
|
||||
this.state = newState;
|
||||
|
||||
// Fire the "state" event, so other parts of the code can react to the
|
||||
// change.
|
||||
this.fire( 'state' );
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggles the on/off (active/inactive) state of the command. This is
|
||||
* mainly used internally by context sensitive commands.
|
||||
*
|
||||
* command.toggleState();
|
||||
*/
|
||||
toggleState: function() {
|
||||
if ( this.state == CKEDITOR.TRISTATE_OFF )
|
||||
this.setState( CKEDITOR.TRISTATE_ON );
|
||||
else if ( this.state == CKEDITOR.TRISTATE_ON )
|
||||
this.setState( CKEDITOR.TRISTATE_OFF );
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.event.implementOn( CKEDITOR.command.prototype );
|
||||
|
||||
/**
|
||||
* Indicates the previous command state.
|
||||
*
|
||||
* alert( command.previousState );
|
||||
*
|
||||
* @property {Number} previousState
|
||||
* @see #state
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the command state changes.
|
||||
*
|
||||
* command.on( 'state', function() {
|
||||
* // Alerts the new state.
|
||||
* alert( this.state );
|
||||
* } );
|
||||
*
|
||||
* @event state
|
||||
*/
|
||||
|
||||
/**
|
||||
* @event refresh
|
||||
* @todo
|
||||
*/
|
||||
162
Admin/plugins/ckeditor/core/commanddefinition.js
Normal file
162
Admin/plugins/ckeditor/core/commanddefinition.js
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.commandDefinition} class
|
||||
* which contains the defintion of a command. This file is for
|
||||
* documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Virtual class that illustrates the features of command objects to be
|
||||
* passed to the {@link CKEDITOR.editor#addCommand} function.
|
||||
*
|
||||
* @class CKEDITOR.commandDefinition
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* The function to be fired when the commend is executed.
|
||||
*
|
||||
* editorInstance.addCommand( 'sample', {
|
||||
* exec: function( editor ) {
|
||||
* alert( 'Executing a command for the editor name "' + editor.name + '"!' );
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* @method exec
|
||||
* @param {CKEDITOR.editor} editor The editor within which to run the command.
|
||||
* @param {Object} [data] Additional data to be used to execute the command.
|
||||
* @returns {Boolean} Whether the command has been successfully executed.
|
||||
* Defaults to `true` if nothing is returned.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the command needs to be hooked into the redo/undo system.
|
||||
*
|
||||
* editorInstance.addCommand( 'alertName', {
|
||||
* exec: function( editor ) {
|
||||
* alert( editor.name );
|
||||
* },
|
||||
* canUndo: false // No support for undo/redo.
|
||||
* } );
|
||||
*
|
||||
* @property {Boolean} [canUndo=true]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the command is asynchronous, which means that the
|
||||
* {@link CKEDITOR.editor#event-afterCommandExec} event will be fired by the
|
||||
* command itself manually, and that the return value of this command is not to
|
||||
* be returned by the {@link #exec} function.
|
||||
*
|
||||
* editorInstance.addCommand( 'loadoptions', {
|
||||
* exec: function( editor ) {
|
||||
* var cmd = this;
|
||||
* // Asynchronous operation below.
|
||||
* CKEDITOR.ajax.loadXml( 'data.xml', function() {
|
||||
* editor.fire( 'afterCommandExec', {
|
||||
* name: 'loadoptions',
|
||||
* command: cmd
|
||||
* } );
|
||||
* } );
|
||||
* },
|
||||
* async: true // The command needs some time to complete after the exec function returns.
|
||||
* } );
|
||||
*
|
||||
* @property {Boolean} [async=false]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the command should give focus to the editor before execution.
|
||||
*
|
||||
* editorInstance.addCommand( 'maximize', {
|
||||
* exec: function( editor ) {
|
||||
* // ...
|
||||
* },
|
||||
* editorFocus: false // The command does not require focusing the editing document.
|
||||
* } );
|
||||
*
|
||||
* See also {@link CKEDITOR.command#editorFocus}.
|
||||
*
|
||||
* @property {Boolean} [editorFocus=true]
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Whether the command state should be set to {@link CKEDITOR#TRISTATE_DISABLED} on startup.
|
||||
*
|
||||
* editorInstance.addCommand( 'unlink', {
|
||||
* exec: function( editor ) {
|
||||
* // ...
|
||||
* },
|
||||
* startDisabled: true // The command is unavailable until the selection is inside a link.
|
||||
* } );
|
||||
*
|
||||
* @property {Boolean} [startDisabled=false]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that this command is sensitive to the selection context.
|
||||
* If `true`, the {@link CKEDITOR.command#method-refresh} method will be
|
||||
* called for this command on selection changes, with a single parameter
|
||||
* representing the current elements path.
|
||||
*
|
||||
* @property {Boolean} [contextSensitive=true]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defined by the command definition, a function to determine the command state. It will be invoked
|
||||
* when the editor has its `states` or `selection` changed.
|
||||
*
|
||||
* **Note:** The function provided must be calling {@link CKEDITOR.command#setState} in all circumstances
|
||||
* if it is intended to update the command state.
|
||||
*
|
||||
* @method refresh
|
||||
* @param {CKEDITOR.editor} editor
|
||||
* @param {CKEDITOR.dom.elementPath} path
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sets the element name used to reflect the command state on selection changes.
|
||||
* If the selection is in a place where the element is not allowed, the command
|
||||
* will be disabled.
|
||||
* Setting this property overrides {@link #contextSensitive} to `true`.
|
||||
*
|
||||
* @property {Boolean} [context=true]
|
||||
*/
|
||||
|
||||
/**
|
||||
* The editor modes within which the command can be executed. The execution
|
||||
* will have no action if the current mode is not listed in this property.
|
||||
*
|
||||
* editorInstance.addCommand( 'link', {
|
||||
* exec: function( editor ) {
|
||||
* // ...
|
||||
* },
|
||||
* modes: { wysiwyg:1 } // The command is available in wysiwyg mode only.
|
||||
* } );
|
||||
*
|
||||
* See also {@link CKEDITOR.command#modes}.
|
||||
*
|
||||
* @property {Object} [modes={ wysiwyg:1 }]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Whether the command should be enabled in the {@link CKEDITOR.editor#setReadOnly read-only mode}.
|
||||
*
|
||||
* @since 4.0.0
|
||||
* @property {Boolean} [readOnly=false]
|
||||
*/
|
||||
|
||||
/**
|
||||
* A property that should be set when a command has no keystroke assigned by {@link CKEDITOR.editor#setKeystroke}, but
|
||||
* the keystroke is still supported. For example: `cut`, `copy` and `paste` commands are handled that way.
|
||||
* This property is used when displaying keystroke information in tooltips and context menus. It is used by
|
||||
* {@link CKEDITOR.editor#getCommandKeystroke}.
|
||||
*
|
||||
* @since 4.6.0
|
||||
* @property {Number} fakeKeystroke
|
||||
*/
|
||||
453
Admin/plugins/ckeditor/core/config.js
Normal file
453
Admin/plugins/ckeditor/core/config.js
Normal file
@@ -0,0 +1,453 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.config} object that stores the
|
||||
* default configuration settings.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used in conjunction with the {@link CKEDITOR.config#enterMode}
|
||||
* and {@link CKEDITOR.config#shiftEnterMode} configuration
|
||||
* settings to make the editor produce `<p>` tags when
|
||||
* using the <kbd>Enter</kbd> key.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.ENTER_P = 1;
|
||||
|
||||
/**
|
||||
* Used in conjunction with the {@link CKEDITOR.config#enterMode}
|
||||
* and {@link CKEDITOR.config#shiftEnterMode} configuration
|
||||
* settings to make the editor produce `<br>` tags when
|
||||
* using the <kbd>Enter</kbd> key.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.ENTER_BR = 2;
|
||||
|
||||
/**
|
||||
* Used in conjunction with the {@link CKEDITOR.config#enterMode}
|
||||
* and {@link CKEDITOR.config#shiftEnterMode} configuration
|
||||
* settings to make the editor produce `<div>` tags when
|
||||
* using the <kbd>Enter</kbd> key.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=3]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.ENTER_DIV = 3;
|
||||
|
||||
/**
|
||||
* Stores default configuration settings. Changes to this object are
|
||||
* reflected in all editor instances, if not specified otherwise for a particular
|
||||
* instance.
|
||||
*
|
||||
* Read more about setting CKEditor configuration in the
|
||||
* {@glink guide/dev_configuration documentation}.
|
||||
*
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.config = {
|
||||
/**
|
||||
* The URL path to the custom configuration file to be loaded. If not
|
||||
* overwritten with inline configuration, it defaults to the `config.js`
|
||||
* file present in the root of the CKEditor installation directory.
|
||||
*
|
||||
* CKEditor will recursively load custom configuration files defined inside
|
||||
* other custom configuration files.
|
||||
*
|
||||
* Read more about setting CKEditor configuration in the
|
||||
* {@glink guide/dev_configuration documentation}.
|
||||
*
|
||||
* // Load a specific configuration file.
|
||||
* CKEDITOR.replace( 'myfield', { customConfig: '/myconfig.js' } );
|
||||
*
|
||||
* // Do not load any custom configuration file.
|
||||
* CKEDITOR.replace( 'myfield', { customConfig: '' } );
|
||||
*
|
||||
* @cfg {String} [="<CKEditor folder>/config.js"]
|
||||
*/
|
||||
customConfig: 'config.js',
|
||||
|
||||
/**
|
||||
* Whether the element replaced by the editor (usually a `<textarea>`)
|
||||
* is to be updated automatically when posting the form containing the editor.
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
autoUpdateElement: true,
|
||||
|
||||
/**
|
||||
* The user interface language localization to use. If left empty, the editor
|
||||
* will automatically be localized to the user language. If the user language is not supported,
|
||||
* the language specified in the {@link CKEDITOR.config#defaultLanguage}
|
||||
* configuration setting is used.
|
||||
*
|
||||
* Read more in the {@glink features/uilanguage documentation} and see the
|
||||
* {@glink examples/uilanguages example}.
|
||||
*
|
||||
* // Load the German interface.
|
||||
* config.language = 'de';
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
language: '',
|
||||
|
||||
/**
|
||||
* The language to be used if the {@link CKEDITOR.config#language}
|
||||
* setting is left empty and it is not possible to localize the editor to the user language.
|
||||
*
|
||||
* Read more in the {@glink features/uilanguage documentation} and see the
|
||||
* {@glink examples/uilanguages example}.
|
||||
*
|
||||
* config.defaultLanguage = 'it';
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
defaultLanguage: 'en',
|
||||
|
||||
/**
|
||||
* The writing direction of the language which is used to create editor content.
|
||||
* Allowed values are:
|
||||
*
|
||||
* * `''` (an empty string) – Indicates that content direction will be the same as either
|
||||
* the editor UI direction or the page element direction depending on the editor type:
|
||||
* * {@glink guide/dev_framed Classic editor} – The same as the user interface language direction.
|
||||
* * {@glink guide/dev_inline Inline editor}– The same as the editable element text direction.
|
||||
* * `'ltr'` – Indicates a Left-To-Right text direction (like in English).
|
||||
* * `'rtl'` – Indicates a Right-To-Left text direction (like in Arabic).
|
||||
*
|
||||
* See the {@glink examples/language example}.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* config.contentsLangDirection = 'rtl';
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
contentsLangDirection: '',
|
||||
|
||||
/**
|
||||
* Sets the behavior of the <kbd>Enter</kbd> key. It also determines other behavior
|
||||
* rules of the editor, like whether the `<br>` element is to be used
|
||||
* as a paragraph separator when indenting text.
|
||||
* The allowed values are the following constants that cause the behavior outlined below:
|
||||
*
|
||||
* * {@link CKEDITOR#ENTER_P} (1) – New `<p>` paragraphs are created.
|
||||
* * {@link CKEDITOR#ENTER_BR} (2) – Lines are broken with `<br>` elements.
|
||||
* * {@link CKEDITOR#ENTER_DIV} (3) – New `<div>` blocks are created.
|
||||
*
|
||||
* **Note**: It is recommended to use the {@link CKEDITOR#ENTER_P} setting because of
|
||||
* its semantic value and correctness. The editor is optimized for this setting.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* // Not recommended.
|
||||
* config.enterMode = CKEDITOR.ENTER_BR;
|
||||
*
|
||||
* @cfg {Number} [=CKEDITOR.ENTER_P]
|
||||
*/
|
||||
enterMode: CKEDITOR.ENTER_P,
|
||||
|
||||
/**
|
||||
* Forces the use of {@link CKEDITOR.config#enterMode} as line break regardless
|
||||
* of the context. If, for example, {@link CKEDITOR.config#enterMode} is set
|
||||
* to {@link CKEDITOR#ENTER_P}, pressing the <kbd>Enter</kbd> key inside a
|
||||
* `<div>` element will create a new paragraph with a `<p>`
|
||||
* instead of a `<div>`.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* // Not recommended.
|
||||
* config.forceEnterMode = true;
|
||||
*
|
||||
* @since 3.2.1
|
||||
* @cfg
|
||||
*/
|
||||
forceEnterMode: false,
|
||||
|
||||
/**
|
||||
* Similarly to the {@link CKEDITOR.config#enterMode} setting, it defines the behavior
|
||||
* of the <kbd>Shift+Enter</kbd> key combination.
|
||||
*
|
||||
* The allowed values are the following constants that cause the behavior outlined below:
|
||||
*
|
||||
* * {@link CKEDITOR#ENTER_P} (1) – New `<p>` paragraphs are created.
|
||||
* * {@link CKEDITOR#ENTER_BR} (2) – Lines are broken with `<br>` elements.
|
||||
* * {@link CKEDITOR#ENTER_DIV} (3) – New `<div>` blocks are created.
|
||||
*
|
||||
* Read more in the {@glink features/enterkey documentation} and see the
|
||||
* {@glink examples/enterkey example}.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* config.shiftEnterMode = CKEDITOR.ENTER_P;
|
||||
*
|
||||
* @cfg {Number} [=CKEDITOR.ENTER_BR]
|
||||
*/
|
||||
shiftEnterMode: CKEDITOR.ENTER_BR,
|
||||
|
||||
/**
|
||||
* Sets the `DOCTYPE` to be used when loading the editor content as HTML.
|
||||
*
|
||||
* // Set the DOCTYPE to the HTML 4 (Quirks) mode.
|
||||
* config.docType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
docType: '<!DOCTYPE html>',
|
||||
|
||||
/**
|
||||
* Sets the `id` attribute to be used on the `body` element
|
||||
* of the editing area. This can be useful when you intend to reuse the original CSS
|
||||
* file you are using on your live website and want to assign the editor the same ID
|
||||
* as the section that will include the contents. In this way ID-specific CSS rules will
|
||||
* be enabled.
|
||||
*
|
||||
* config.bodyId = 'contents_id';
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @cfg
|
||||
*/
|
||||
bodyId: '',
|
||||
|
||||
/**
|
||||
* Sets the `class` attribute to be used on the `body` element
|
||||
* of the editing area. This can be useful when you intend to reuse the original CSS
|
||||
* file you are using on your live website and want to assign the editor the same class
|
||||
* as the section that will include the contents. In this way class-specific CSS rules will
|
||||
* be enabled.
|
||||
*
|
||||
* config.bodyClass = 'contents';
|
||||
*
|
||||
* **Note:** The editor needs to load stylesheets containing contents styles. You can either
|
||||
* copy them to the `contents.css` file that the editor loads by default or set the {@link #contentsCss}
|
||||
* option.
|
||||
*
|
||||
* **Note:** This setting only applies to {@glink guide/dev_framed classic editor} (the one that uses `iframe`).
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @cfg
|
||||
*/
|
||||
bodyClass: '',
|
||||
|
||||
/**
|
||||
* Indicates whether the content to be edited is being input as a full HTML page.
|
||||
* A full page includes the `<html>`, `<head>`, and `<body>` elements.
|
||||
* The final output will also reflect this setting, including the
|
||||
* `<body>` content only if this setting is disabled.
|
||||
*
|
||||
* Read more in the {@glink features/fullpage documentation} and see the
|
||||
* {@glink examples/fullpage example}.
|
||||
*
|
||||
* config.fullPage = true;
|
||||
*
|
||||
* @since 3.1.0
|
||||
* @cfg
|
||||
*/
|
||||
fullPage: false,
|
||||
|
||||
/**
|
||||
* The height of the editing area that includes the editor content. This configuration
|
||||
* option accepts an integer (to denote a value in pixels) or any CSS-defined length unit
|
||||
* except percent (`%`) values which are not supported.
|
||||
*
|
||||
* **Note:** This configuration option is ignored by {@glink guide/dev_inline inline editor}.
|
||||
*
|
||||
* Read more in the {@glink features/size documentation} and see the
|
||||
* {@glink examples/size example}.
|
||||
*
|
||||
* config.height = 500; // 500 pixels.
|
||||
* config.height = '25em'; // CSS length.
|
||||
* config.height = '300px'; // CSS length.
|
||||
*
|
||||
* @cfg {Number/String}
|
||||
*/
|
||||
height: 200,
|
||||
|
||||
/**
|
||||
* The CSS file(s) to be used to apply style to editor content. It should
|
||||
* reflect the CSS used in the target pages where the content is to be
|
||||
* displayed.
|
||||
*
|
||||
* **Note:** This configuration value is used only in {@glink guide/dev_framed `<iframe>`-based editor }
|
||||
* and ignored by {@glink guide/dev_inline inline editor}
|
||||
* as it uses the styles that come directly from the page that CKEditor is
|
||||
* rendered on. It is also ignored in the {@link #fullPage full page mode} in
|
||||
* which the developer has full control over the page HTML code.
|
||||
*
|
||||
* Read more in the {@glink features/styles documentation} and see the
|
||||
* {@glink examples/styles example}.
|
||||
*
|
||||
* config.contentsCss = '/css/mysitestyles.css';
|
||||
* config.contentsCss = [ '/css/mysitestyles.css', '/css/anotherfile.css' ];
|
||||
*
|
||||
* @cfg {String/Array} [contentsCss=CKEDITOR.getUrl( 'contents.css' )]
|
||||
*/
|
||||
contentsCss: CKEDITOR.getUrl( 'contents.css' ),
|
||||
|
||||
/**
|
||||
* Comma-separated list of plugins to be used in an editor instance. Note that
|
||||
* the actual plugins that are to be loaded could still be affected by two other settings:
|
||||
* {@link CKEDITOR.config#extraPlugins} and {@link CKEDITOR.config#removePlugins}.
|
||||
*
|
||||
* @cfg {String/String[]} [="<default list of plugins>"]
|
||||
*/
|
||||
plugins: '', // %REMOVE_LINE%
|
||||
|
||||
/**
|
||||
* A list of additional plugins to be loaded. This setting makes it easier
|
||||
* to add new plugins without having to touch the {@link CKEDITOR.config#plugins} setting.
|
||||
*
|
||||
* **Note:** The most recommended way to
|
||||
* [add CKEditor plugins](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_plugins.html) is through
|
||||
* [CKEditor Builder](https://ckeditor.com/cke4/builder). Read more in the
|
||||
* {@glink guide/dev_plugins documentation}.
|
||||
*
|
||||
* config.extraPlugins = 'myplugin,anotherplugin';
|
||||
*
|
||||
* @cfg {String/String[]}
|
||||
*/
|
||||
extraPlugins: '',
|
||||
|
||||
/**
|
||||
* A list of plugins that must not be loaded. This setting makes it possible
|
||||
* to avoid loading some plugins defined in the {@link CKEDITOR.config#plugins}
|
||||
* setting without having to touch it.
|
||||
*
|
||||
* **Note:** A plugin required by another plugin cannot be removed and will cause
|
||||
* an error to be thrown. So for example if `contextmenu` is required by `tabletools`,
|
||||
* it can only be removed if `tabletools` is not loaded.
|
||||
*
|
||||
* config.removePlugins = 'elementspath,save,font';
|
||||
*
|
||||
* @cfg {String/String[]}
|
||||
*/
|
||||
removePlugins: '',
|
||||
|
||||
/**
|
||||
* A list of regular expressions to be executed on input HTML,
|
||||
* indicating HTML source code that when matched, must **not** be available in the WYSIWYG
|
||||
* mode for editing.
|
||||
*
|
||||
* config.protectedSource.push( /<\?[\s\S]*?\?>/g ); // PHP code
|
||||
* config.protectedSource.push( /<%[\s\S]*?%>/g ); // ASP code
|
||||
* config.protectedSource.push( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi ); // ASP.NET code
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
protectedSource: [],
|
||||
|
||||
/**
|
||||
* The editor `tabindex` value.
|
||||
*
|
||||
* Read more in the {@glink features/tabindex documentation} and see the
|
||||
* {@glink examples/tabindex example}.
|
||||
*
|
||||
* config.tabIndex = 1;
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
tabIndex: 0,
|
||||
|
||||
/**
|
||||
* Indicates that some of the editor features, like alignment and text
|
||||
* direction, should use the "computed value" of the feature to indicate its
|
||||
* on/off state instead of using the "real value".
|
||||
*
|
||||
* If enabled in a Left-To-Right written document, the "Left Justify"
|
||||
* alignment button will be shown as active, even if the alignment style is not
|
||||
* explicitly applied to the current paragraph in the editor.
|
||||
*
|
||||
* config.useComputedState = false;
|
||||
*
|
||||
* @since 3.4.0
|
||||
* @cfg {Boolean} [useComputedState=true]
|
||||
*/
|
||||
useComputedState: true,
|
||||
|
||||
/**
|
||||
* The editor UI outer width. This configuration option accepts an integer
|
||||
* (to denote a value in pixels) or any CSS-defined length unit.
|
||||
*
|
||||
* Unlike the {@link CKEDITOR.config#height} setting, this
|
||||
* one will set the outer width of the entire editor UI, not for the
|
||||
* editing area only.
|
||||
*
|
||||
* **Note:** This configuration option is ignored by {@glink guide/dev_inline inline editor}.
|
||||
*
|
||||
* Read more in the {@glink features/size documentation} and see the
|
||||
* {@glink examples/size example}.
|
||||
*
|
||||
* config.width = 850; // 850 pixels wide.
|
||||
* config.width = '75%'; // CSS unit.
|
||||
*
|
||||
* @cfg {String/Number}
|
||||
*/
|
||||
width: '',
|
||||
|
||||
/**
|
||||
* The base Z-index for floating dialog windows and popups.
|
||||
*
|
||||
* config.baseFloatZIndex = 2000;
|
||||
*
|
||||
* @cfg
|
||||
*/
|
||||
baseFloatZIndex: 10000,
|
||||
|
||||
/**
|
||||
* The keystrokes that are blocked by default as the browser implementation
|
||||
* is buggy. These default keystrokes are handled by the editor.
|
||||
*
|
||||
* // Default setting.
|
||||
* config.blockedKeystrokes = [
|
||||
* CKEDITOR.CTRL + 66, // Ctrl+B
|
||||
* CKEDITOR.CTRL + 73, // Ctrl+I
|
||||
* CKEDITOR.CTRL + 85 // Ctrl+U
|
||||
* ];
|
||||
*
|
||||
* @cfg {Array} [blockedKeystrokes=see example]
|
||||
*/
|
||||
blockedKeystrokes: [
|
||||
CKEDITOR.CTRL + 66, // Ctrl+B
|
||||
CKEDITOR.CTRL + 73, // Ctrl+I
|
||||
CKEDITOR.CTRL + 85 // Ctrl+U
|
||||
]
|
||||
};
|
||||
|
||||
/**
|
||||
* The base user interface color to be used by the editor. Not all skins are
|
||||
* {@glink guide/skin_sdk_chameleon compatible with this setting}.
|
||||
*
|
||||
* Read more in the {@glink features/uicolor documentation} and see the
|
||||
* {@glink examples/uicolor example}.
|
||||
*
|
||||
* // Using a color code.
|
||||
* config.uiColor = '#AADC6E';
|
||||
*
|
||||
* // Using an HTML color name.
|
||||
* config.uiColor = 'Gold';
|
||||
*
|
||||
* @cfg {String} uiColor
|
||||
*/
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.config )
|
||||
204
Admin/plugins/ckeditor/core/creators/inline.js
Normal file
204
Admin/plugins/ckeditor/core/creators/inline.js
Normal file
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/** @class CKEDITOR */
|
||||
|
||||
/**
|
||||
* Turns a DOM element with the `contenteditable` attribute set to `true` into a
|
||||
* CKEditor instance. Check {@link CKEDITOR.dtd#$editable} for a list of
|
||||
* allowed element names.
|
||||
*
|
||||
* **Note:** If the DOM element for which inline editing is being enabled does not have
|
||||
* the `contenteditable` attribute set to `true` or the {@link CKEDITOR.config#readOnly `config.readOnly`}
|
||||
* configuration option is set to `true`, the editor will start in read-only mode.
|
||||
*
|
||||
* <div contenteditable="true" id="content">...</div>
|
||||
* ...
|
||||
* CKEDITOR.inline( 'content' );
|
||||
*
|
||||
* It is also possible to create an inline editor from the `<textarea>` element.
|
||||
* If you do so, an additional `<div>` element with editable content will be created
|
||||
* directly after the `<textarea>` element and the `<textarea>` element will be hidden.
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
*
|
||||
* Since 4.19 if the editor has been configured to use the {@glink features/delayed_creation Delayed Editor Creation}
|
||||
* feature and the editor has not been initialized yet, this function will return a handle allowing
|
||||
* to cancel the interval set by the {@link CKEDITOR.config#delayIfDetached} and
|
||||
* {@link CKEDITOR.config#delayIfDetached_interval} options.
|
||||
*
|
||||
* ```javascript
|
||||
* var cancelInterval = CKEDITOR.inline( 'editor', {
|
||||
* delayIfDetached: true,
|
||||
* delayIfDetached_interval: 50 // Default value, you can skip that option.
|
||||
* } );
|
||||
*
|
||||
* cancelInterval(); // Cancel editor initialization if needed.
|
||||
* ```
|
||||
*
|
||||
* It is recommended to use this function to prevent potential memory leaks. Use it if you know
|
||||
* that the editor host element will never be attached to the DOM. As an example, execute cancel handle
|
||||
* in your component cleanup logic (e.g. `onDestroy` lifecycle methods in popular frontend frameworks).
|
||||
*
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*
|
||||
* @param {Object/String} element The DOM element or its ID.
|
||||
* @param {Object} [instanceConfig] The specific configurations to apply to this editor instance.
|
||||
* See {@link CKEDITOR.config}.
|
||||
* @returns {CKEDITOR.editor/Function/null} The editor instance or a cancellation function.
|
||||
* If {@glink features/delayed_creation Delayed Editor Creation} feature has not been set and
|
||||
* element is missing in DOM, this function will return `null`.
|
||||
*/
|
||||
CKEDITOR.inline = function( element, instanceConfig ) {
|
||||
element = CKEDITOR.editor._getEditorElement( element );
|
||||
|
||||
if ( !element ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// (#4461)
|
||||
if ( CKEDITOR.editor.shouldDelayEditorCreation( element, instanceConfig ) ) {
|
||||
return CKEDITOR.editor.initializeDelayedEditorCreation( element, instanceConfig, 'inline' );
|
||||
}
|
||||
|
||||
var textarea = element.is( 'textarea' ) ? element : null,
|
||||
editorData = textarea ? textarea.getValue() : element.getHtml(),
|
||||
editor = new CKEDITOR.editor( instanceConfig, element, CKEDITOR.ELEMENT_MODE_INLINE );
|
||||
|
||||
if ( textarea ) {
|
||||
editor.setData( editorData, null, true );
|
||||
|
||||
//Change element from textarea to div
|
||||
element = CKEDITOR.dom.element.createFromHtml(
|
||||
'<div contenteditable="' + !!editor.readOnly + '" class="cke_textarea_inline">' +
|
||||
textarea.getValue() +
|
||||
'</div>',
|
||||
CKEDITOR.document );
|
||||
|
||||
element.insertAfter( textarea );
|
||||
textarea.hide();
|
||||
|
||||
// Attaching the concrete form.
|
||||
if ( textarea.$.form )
|
||||
editor._attachToForm();
|
||||
} else {
|
||||
// If editor element does not have contenteditable attribute, but config.readOnly
|
||||
// is explicitly set to false, set the contentEditable property to true (#3866).
|
||||
if ( instanceConfig && typeof instanceConfig.readOnly !== 'undefined' && !instanceConfig.readOnly ) {
|
||||
element.setAttribute( 'contenteditable', 'true' );
|
||||
}
|
||||
|
||||
// Initial editor data is simply loaded from the page element content to make
|
||||
// data retrieval possible immediately after the editor creation.
|
||||
editor.setData( editorData, null, true );
|
||||
}
|
||||
|
||||
// Once the editor is loaded, start the UI.
|
||||
editor.on( 'loaded', function() {
|
||||
editor.fire( 'uiReady' );
|
||||
|
||||
// Enable editing on the element.
|
||||
editor.editable( element );
|
||||
|
||||
// Editable itself is the outermost element.
|
||||
editor.container = element;
|
||||
editor.ui.contentsElement = element;
|
||||
|
||||
// Load and process editor data.
|
||||
editor.setData( editor.getData( 1 ) );
|
||||
|
||||
// Clean on startup.
|
||||
editor.resetDirty();
|
||||
|
||||
editor.fire( 'contentDom' );
|
||||
|
||||
// Inline editing defaults to "wysiwyg" mode, so plugins don't
|
||||
// need to make special handling for this "mode-less" environment.
|
||||
editor.mode = 'wysiwyg';
|
||||
editor.fire( 'mode' );
|
||||
|
||||
// The editor is completely loaded for interaction.
|
||||
editor.status = 'ready';
|
||||
editor.fireOnce( 'instanceReady' );
|
||||
CKEDITOR.fire( 'instanceReady', null, editor );
|
||||
|
||||
// give priority to plugins that relay on editor#loaded for bootstrapping.
|
||||
}, null, null, 10000 );
|
||||
|
||||
// Handle editor destroying.
|
||||
editor.on( 'destroy', function() {
|
||||
var container = editor.container;
|
||||
// Remove container from DOM if inline-textarea editor.
|
||||
// Show <textarea> back again.
|
||||
// Editor can be destroyed before container is created (#3115).
|
||||
if ( textarea && container ) {
|
||||
container.clearCustomData();
|
||||
container.remove();
|
||||
}
|
||||
|
||||
if ( textarea ) {
|
||||
textarea.show();
|
||||
}
|
||||
|
||||
editor.element.clearCustomData();
|
||||
|
||||
delete editor.element;
|
||||
} );
|
||||
|
||||
return editor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calls the {@link CKEDITOR#inline `CKEDITOR.inline()`} method for all page elements with the `contenteditable` attribute set to
|
||||
* `true` that are allowed in the {@link CKEDITOR.dtd#$editable} object.
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*/
|
||||
CKEDITOR.inlineAll = function() {
|
||||
var el,
|
||||
data;
|
||||
|
||||
for ( var name in CKEDITOR.dtd.$editable ) {
|
||||
var elements = CKEDITOR.document.getElementsByTag( name );
|
||||
|
||||
for ( var i = 0, len = elements.count(); i < len; i++ ) {
|
||||
el = elements.getItem( i );
|
||||
|
||||
// Check whether an element is editable and if an editor attached is not to it already (#4293).
|
||||
if ( el.getAttribute( 'contenteditable' ) == 'true' && !el.getEditor() ) {
|
||||
// Fire the "inline" event, making it possible to customize
|
||||
// the instance settings and eventually cancel the creation.
|
||||
|
||||
data = {
|
||||
element: el,
|
||||
config: {}
|
||||
};
|
||||
|
||||
if ( CKEDITOR.fire( 'inline', data ) !== false ) {
|
||||
CKEDITOR.inline( el, data.config );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.domReady( function() {
|
||||
!CKEDITOR.disableAutoInline && CKEDITOR.inlineAll();
|
||||
} );
|
||||
|
||||
} )();
|
||||
|
||||
/**
|
||||
* Disables creating the inline editor automatically for elements with
|
||||
* the `contenteditable` attribute set to `true`.
|
||||
*
|
||||
* CKEDITOR.disableAutoInline = true;
|
||||
*
|
||||
* @cfg {Boolean} [disableAutoInline=false]
|
||||
*/
|
||||
630
Admin/plugins/ckeditor/core/creators/themedui.js
Normal file
630
Admin/plugins/ckeditor/core/creators/themedui.js
Normal file
@@ -0,0 +1,630 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/** @class CKEDITOR */
|
||||
|
||||
/**
|
||||
* The class name used to identify `<textarea>` elements to be replaced
|
||||
* by CKEditor instances. Set it to empty/`null` to disable this feature.
|
||||
*
|
||||
* CKEDITOR.replaceClass = 'rich_editor';
|
||||
*
|
||||
* @cfg {String} [replaceClass='ckeditor']
|
||||
*/
|
||||
CKEDITOR.replaceClass = 'ckeditor';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Replaces a `<textarea>` or a DOM element (`<div>`) with a CKEditor
|
||||
* instance. For textareas, the initial value in the editor will be the
|
||||
* textarea value. For DOM elements, their `innerHTML` will be used
|
||||
* instead. It is recommended to use `<textarea>` and `<div>` elements only.
|
||||
*
|
||||
* <textarea id="myfield" name="myfield"></textarea>
|
||||
* ...
|
||||
* CKEDITOR.replace( 'myfield' );
|
||||
*
|
||||
* var textarea = document.body.appendChild( document.createElement( 'textarea' ) );
|
||||
* CKEDITOR.replace( textarea );
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
*
|
||||
* Since 4.19 if the editor has been configured to use the {@glink features/delayed_creation Delayed Editor Creation}
|
||||
* feature and the editor has not been initialized yet, this function will return a handle allowing
|
||||
* to cancel the interval set by the {@link CKEDITOR.config#delayIfDetached} and
|
||||
* {@link CKEDITOR.config#delayIfDetached_interval} options.
|
||||
*
|
||||
* ```javascript
|
||||
* var cancelInterval = CKEDITOR.replace( 'editor', {
|
||||
* delayIfDetached: true,
|
||||
* delayIfDetached_interval: 50 // Default value, you can skip that option.
|
||||
* } );
|
||||
*
|
||||
* cancelInterval(); // Cancel editor initialization if needed.
|
||||
* ```
|
||||
*
|
||||
* It is recommended to use this function to prevent potential memory leaks. Use it if you know
|
||||
* that the editor host element will never be attached to the DOM. As an example, execute cancel handle
|
||||
* in your component cleanup logic (e.g. `onDestroy` lifecycle methods in popular frontend frameworks).
|
||||
*
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*
|
||||
* @param {Object/String} element The DOM element (textarea), its ID, or name.
|
||||
* @param {Object} [config] The specific configuration to apply to this
|
||||
* editor instance. Configuration set here will override the global CKEditor settings
|
||||
* (see {@link CKEDITOR.config}).
|
||||
* @returns {CKEDITOR.editor/Function/null} The editor instance or a cancellation function.
|
||||
* If {@glink features/delayed_creation Delayed Editor Creation} feature has not been set and
|
||||
* element is missing in DOM, this function will return `null`.
|
||||
*/
|
||||
CKEDITOR.replace = function( element, config ) {
|
||||
return createInstance( element, config, null, CKEDITOR.ELEMENT_MODE_REPLACE );
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new editor instance at the end of a specific DOM element.
|
||||
*
|
||||
* <!DOCTYPE html>
|
||||
* <html>
|
||||
* <head>
|
||||
* <meta charset="utf-8">
|
||||
* <title>CKEditor</title>
|
||||
* <!-- Make sure the path to CKEditor is correct. -->
|
||||
* <script src="/ckeditor/ckeditor.js"></script>
|
||||
* </head>
|
||||
* <body>
|
||||
* <div id="editorSpace"></div>
|
||||
* <script>
|
||||
* CKEDITOR.appendTo( 'editorSpace' );
|
||||
* </script>
|
||||
* </body>
|
||||
* </html>
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
*
|
||||
* Since 4.19 if the editor has been configured to use the {@glink features/delayed_creation Delayed Editor Creation}
|
||||
* feature and the editor has not been initialized yet, this function will return a handle allowing
|
||||
* to cancel the interval set by the {@link CKEDITOR.config#delayIfDetached} and
|
||||
* {@link CKEDITOR.config#delayIfDetached_interval} options.
|
||||
*
|
||||
* ```javascript
|
||||
* var cancelInterval = CKEDITOR.appendTo( 'editorSpace', {
|
||||
* delayIfDetached: true,
|
||||
* delayIfDetached_interval: 50 // Default value, you can skip that option.
|
||||
* } );
|
||||
*
|
||||
* cancelInterval(); // Cancel editor initialization if needed.
|
||||
* ```
|
||||
*
|
||||
* It is recommended to use this function to prevent potential memory leaks. Use it if you know
|
||||
* that the editor host element will never be attached to the DOM. As an example, execute cancel handle
|
||||
* in your component cleanup logic (e.g. `onDestroy` lifecycle methods in popular frontend frameworks).
|
||||
*
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*
|
||||
* @param {Object/String} element The DOM element, its ID, or name.
|
||||
* @param {Object} [config] The specific configuration to apply to this
|
||||
* editor instance. Configuration set here will override the global CKEditor settings
|
||||
* (see {@link CKEDITOR.config}).
|
||||
* @param {String} [data] Since 3.3. Initial value for the instance.
|
||||
* @returns {CKEDITOR.editor/Function/null} The editor instance or a cancelation function.
|
||||
* If {@glink features/delayed_creation Delayed Editor Creation} feature has not been set and
|
||||
* element is missing in DOM, this function will return `null`.
|
||||
*/
|
||||
CKEDITOR.appendTo = function( element, config, data ) {
|
||||
return createInstance( element, config, data, CKEDITOR.ELEMENT_MODE_APPENDTO );
|
||||
};
|
||||
|
||||
/**
|
||||
* Replaces all `<textarea>` elements available in the document with
|
||||
* editor instances.
|
||||
*
|
||||
* // Replace all <textarea> elements in the page.
|
||||
* CKEDITOR.replaceAll();
|
||||
*
|
||||
* // Replace all <textarea class="myClassName"> elements in the page.
|
||||
* CKEDITOR.replaceAll( 'myClassName' );
|
||||
*
|
||||
* // Selectively replace <textarea> elements, based on a custom evaluation function.
|
||||
* CKEDITOR.replaceAll( function( textarea, config ) {
|
||||
* // A function that needs to be evaluated for the <textarea>
|
||||
* // to be replaced. It must explicitly return "false" to ignore a
|
||||
* // specific <textarea>.
|
||||
* // You can also customize the editor instance by having the function
|
||||
* // modify the "config" parameter.
|
||||
* } );
|
||||
*
|
||||
* // Full page example where three <textarea> elements are replaced.
|
||||
* <!DOCTYPE html>
|
||||
* <html>
|
||||
* <head>
|
||||
* <meta charset="utf-8">
|
||||
* <title>CKEditor</title>
|
||||
* <!-- Make sure the path to CKEditor is correct. -->
|
||||
* <script src="/ckeditor/ckeditor.js"></script>
|
||||
* </head>
|
||||
* <body>
|
||||
* <textarea name="editor1"></textarea>
|
||||
* <textarea name="editor2"></textarea>
|
||||
* <textarea name="editor3"></textarea>
|
||||
* <script>
|
||||
* // Replace all three <textarea> elements above with CKEditor instances.
|
||||
* CKEDITOR.replaceAll();
|
||||
* </script>
|
||||
* </body>
|
||||
* </html>
|
||||
*
|
||||
* Since 4.17 this function also supports the {@glink features/delayed_creation Delayed Editor Creation} feature
|
||||
* allowing to postpone the editor initialization.
|
||||
* Read more about this feature in the {@glink features/delayed_creation documentation}.
|
||||
*
|
||||
* @param {String} [className] The `<textarea>` class name.
|
||||
* @param {Function} [evaluator] An evaluation function that must return `true` for a `<textarea>`
|
||||
* to be replaced with the editor. If the function returns `false`, the `<textarea>` element
|
||||
* will not be replaced.
|
||||
*/
|
||||
CKEDITOR.replaceAll = function() {
|
||||
var textareas = document.getElementsByTagName( 'textarea' );
|
||||
|
||||
for ( var i = 0; i < textareas.length; i++ ) {
|
||||
var config = null,
|
||||
textarea = textareas[ i ];
|
||||
|
||||
// The "name" and/or "id" attribute must exist.
|
||||
if ( !textarea.name && !textarea.id )
|
||||
continue;
|
||||
|
||||
if ( typeof arguments[ 0 ] == 'string' ) {
|
||||
// The textarea class name could be passed as the function
|
||||
// parameter.
|
||||
|
||||
var classRegex = new RegExp( '(?:^|\\s)' + arguments[ 0 ] + '(?:$|\\s)' );
|
||||
|
||||
if ( !classRegex.test( textarea.className ) )
|
||||
continue;
|
||||
} else if ( typeof arguments[ 0 ] == 'function' ) {
|
||||
// An evaluation function could be passed as the function parameter.
|
||||
// It must explicitly return "false" to ignore a specific <textarea>.
|
||||
config = {};
|
||||
if ( arguments[ 0 ]( textarea, config ) === false )
|
||||
continue;
|
||||
}
|
||||
|
||||
this.replace( textarea, config );
|
||||
}
|
||||
};
|
||||
|
||||
/** @class CKEDITOR.editor */
|
||||
|
||||
/**
|
||||
* Registers an editing mode. This function is to be used mainly by plugins.
|
||||
*
|
||||
* @param {String} mode The mode name.
|
||||
* @param {Function} exec The function that performs the actual mode change.
|
||||
*/
|
||||
CKEDITOR.editor.prototype.addMode = function( mode, exec ) {
|
||||
( this._.modes || ( this._.modes = {} ) )[ mode ] = exec;
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes the editing mode of this editor instance.
|
||||
*
|
||||
* **Note:** The mode switch could be asynchronous depending on the mode provider.
|
||||
* Use the `callback` to hook subsequent code.
|
||||
*
|
||||
* // Switch to "source" view.
|
||||
* CKEDITOR.instances.editor1.setMode( 'source' );
|
||||
* // Switch to "wysiwyg" view and be notified on completion.
|
||||
* CKEDITOR.instances.editor1.setMode( 'wysiwyg', function() { alert( 'wysiwyg mode loaded!' ); } );
|
||||
*
|
||||
* @param {String} [newMode] If not specified, the {@link CKEDITOR.config#startupMode} will be used.
|
||||
* @param {Function} [callback] Optional callback function which is invoked once the mode switch has succeeded.
|
||||
*/
|
||||
CKEDITOR.editor.prototype.setMode = function( newMode, callback ) {
|
||||
var editor = this;
|
||||
|
||||
var modes = this._.modes;
|
||||
|
||||
// Mode loading quickly fails.
|
||||
if ( newMode == editor.mode || !modes || !modes[ newMode ] )
|
||||
return;
|
||||
|
||||
editor.fire( 'beforeSetMode', newMode );
|
||||
|
||||
if ( editor.mode ) {
|
||||
var isDirty = editor.checkDirty(),
|
||||
previousModeData = editor._.previousModeData,
|
||||
currentData,
|
||||
unlockSnapshot = 0;
|
||||
|
||||
editor.fire( 'beforeModeUnload' );
|
||||
|
||||
// Detach the current editable. While detaching editable will set
|
||||
// cached editor's data (with internal setData call). We use this
|
||||
// data below to avoid two getData() calls in a row.
|
||||
editor.editable( 0 );
|
||||
|
||||
editor._.previousMode = editor.mode;
|
||||
// Get cached data, which was set while detaching editable.
|
||||
editor._.previousModeData = currentData = editor.getData( 1 );
|
||||
|
||||
// If data has not been modified in the mode which we are currently leaving,
|
||||
// avoid making snapshot right after initializing new mode.
|
||||
// https://dev.ckeditor.com/ticket/5217#comment:20
|
||||
// Tested by:
|
||||
// 'test switch mode with unrecoreded, inner HTML specific content (boguses)'
|
||||
// 'test switch mode with unrecoreded, inner HTML specific content (boguses) plus changes in source mode'
|
||||
if ( editor.mode == 'source' && previousModeData == currentData ) {
|
||||
// We need to make sure that unlockSnapshot will update the last snapshot
|
||||
// (will not create new one) if lockSnapshot is not called on outdated snapshots stack.
|
||||
// Additionally, forceUpdate prevents from making content image now, which is useless
|
||||
// (because it equals editor data not inner HTML).
|
||||
editor.fire( 'lockSnapshot', { forceUpdate: true } );
|
||||
unlockSnapshot = 1;
|
||||
}
|
||||
|
||||
// Clear up the mode space.
|
||||
editor.ui.space( 'contents' ).setHtml( '' );
|
||||
|
||||
editor.mode = '';
|
||||
} else {
|
||||
editor._.previousModeData = editor.getData( 1 );
|
||||
}
|
||||
|
||||
// Fire the mode handler.
|
||||
this._.modes[ newMode ]( function() {
|
||||
// Set the current mode.
|
||||
editor.mode = newMode;
|
||||
|
||||
if ( isDirty !== undefined )
|
||||
!isDirty && editor.resetDirty();
|
||||
|
||||
if ( unlockSnapshot )
|
||||
editor.fire( 'unlockSnapshot' );
|
||||
// Since snapshot made on dataReady (which normally catches changes done by setData)
|
||||
// won't work because editor.mode was not set yet (it's set in this function), we need
|
||||
// to make special snapshot for changes done in source mode here.
|
||||
else if ( newMode == 'wysiwyg' )
|
||||
editor.fire( 'saveSnapshot' );
|
||||
|
||||
// Delay to avoid race conditions (setMode inside setMode).
|
||||
setTimeout( function() {
|
||||
if ( editor.isDestroyed() || editor.isDetached() ) {
|
||||
return;
|
||||
}
|
||||
editor.fire( 'mode' );
|
||||
callback && callback.call( editor );
|
||||
}, 0 );
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Resizes the editor interface.
|
||||
*
|
||||
* **Note:** Since 4.14.1 this method accepts numeric or absolute CSS length units.
|
||||
*
|
||||
* ```javascript
|
||||
* editor.resize( 900, 300 );
|
||||
*
|
||||
* editor.resize( '5in', 450, true );
|
||||
* ```
|
||||
*
|
||||
* @param {Number/String} width The new width. It can be an integer denoting a value
|
||||
* in pixels or a CSS size value with unit. When null is passed, the value will not be set.
|
||||
* @param {Number/String} height The new height. It can be an integer denoting a value
|
||||
* in pixels or a CSS size value with unit.
|
||||
* @param {Boolean} [isContentHeight] Indicates that the provided height is to
|
||||
* be applied to the editor content area, and not to the entire editor
|
||||
* interface. Defaults to `false`.
|
||||
* @param {Boolean} [resizeInner] Indicates that it is the inner interface
|
||||
* element that must be resized, not the outer element. The default theme
|
||||
* defines the editor interface inside a pair of `<span>` elements
|
||||
* (`<span><span>...</span></span>`). By default the first,
|
||||
* outer `<span>` element receives the sizes. If this parameter is set to
|
||||
* `true`, the second, inner `<span>` is resized instead.
|
||||
*/
|
||||
CKEDITOR.editor.prototype.resize = function( width, height, isContentHeight, resizeInner ) {
|
||||
var container = this.container,
|
||||
contents = this.ui.space( 'contents' ),
|
||||
contentsFrame = CKEDITOR.env.webkit && this.document && this.document.getWindow().$.frameElement,
|
||||
outer;
|
||||
|
||||
if ( resizeInner ) {
|
||||
outer = this.container.getFirst( function( node ) {
|
||||
return node.type == CKEDITOR.NODE_ELEMENT && node.hasClass( 'cke_inner' );
|
||||
} );
|
||||
} else {
|
||||
outer = container;
|
||||
}
|
||||
|
||||
if ( width || width === 0 ) {
|
||||
width = convertCssUnitToPx( width );
|
||||
}
|
||||
|
||||
// Set as border box width. (https://dev.ckeditor.com/ticket/5353)
|
||||
outer.setSize( 'width', width, true );
|
||||
|
||||
// WebKit needs to refresh the iframe size to avoid rendering issues. (1/2) (https://dev.ckeditor.com/ticket/8348)
|
||||
contentsFrame && ( contentsFrame.style.width = '1%' );
|
||||
|
||||
height = convertCssUnitToPx( height );
|
||||
|
||||
// Get the height delta between the outer table and the content area.
|
||||
var contentsOuterDelta = ( outer.$.offsetHeight || 0 ) - ( contents.$.clientHeight || 0 ),
|
||||
|
||||
// If we're setting the content area's height, then we don't need the delta.
|
||||
resultContentsHeight = Math.max( height - ( isContentHeight ? 0 : contentsOuterDelta ), 0 ),
|
||||
resultOuterHeight = ( isContentHeight ? height + contentsOuterDelta : height );
|
||||
|
||||
contents.setStyle( 'height', CKEDITOR.tools.cssLength( resultContentsHeight ) );
|
||||
|
||||
// WebKit needs to refresh the iframe size to avoid rendering issues. (2/2) (https://dev.ckeditor.com/ticket/8348)
|
||||
contentsFrame && ( contentsFrame.style.width = '100%' );
|
||||
|
||||
// Emit a resize event.
|
||||
this.fire( 'resize', {
|
||||
outerHeight: resultOuterHeight,
|
||||
contentsHeight: resultContentsHeight,
|
||||
// Sometimes width is not provided.
|
||||
outerWidth: width || outer.getSize( 'width' )
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the element that can be used to check the editor size. This method
|
||||
* is mainly used by the [Editor Resize](https://ckeditor.com/cke4/addon/resize) plugin, which adds
|
||||
* a UI handle that can be used to resize the editor.
|
||||
*
|
||||
* @param {Boolean} forContents Whether to return the "contents" part of the theme instead of the container.
|
||||
* @returns {CKEDITOR.dom.element} The resizable element.
|
||||
*/
|
||||
CKEDITOR.editor.prototype.getResizable = function( forContents ) {
|
||||
return forContents ? this.ui.space( 'contents' ) : this.container;
|
||||
};
|
||||
|
||||
function convertCssUnitToPx( unit ) {
|
||||
return CKEDITOR.tools.convertToPx( CKEDITOR.tools.cssLength( unit ) );
|
||||
}
|
||||
|
||||
function createInstance( element, config, data, mode ) {
|
||||
element = CKEDITOR.editor._getEditorElement( element );
|
||||
|
||||
if ( !element ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// (#4461)
|
||||
if ( CKEDITOR.editor.shouldDelayEditorCreation( element, config ) ) {
|
||||
return CKEDITOR.editor.initializeDelayedEditorCreation( element, config, 'replace' );
|
||||
}
|
||||
|
||||
// Create the editor instance.
|
||||
var editor = new CKEDITOR.editor( config, element, mode );
|
||||
|
||||
if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
|
||||
// Do not replace the textarea right now, just hide it. The effective
|
||||
// replacement will be done later in the editor creation lifecycle.
|
||||
element.setStyle( 'visibility', 'hidden' );
|
||||
|
||||
// https://dev.ckeditor.com/ticket/8031 Remember if textarea was required and remove the attribute.
|
||||
editor._.required = element.hasAttribute( 'required' );
|
||||
element.removeAttribute( 'required' );
|
||||
}
|
||||
|
||||
data && editor.setData( data, null, true );
|
||||
|
||||
// Once the editor is loaded, start the UI.
|
||||
editor.on( 'loaded', function() {
|
||||
if ( editor.isDestroyed() || editor.isDetached() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadTheme( editor );
|
||||
|
||||
if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE && editor.config.autoUpdateElement && element.$.form )
|
||||
editor._attachToForm();
|
||||
|
||||
editor.setMode( editor.config.startupMode, function() {
|
||||
// Clean on startup.
|
||||
editor.resetDirty();
|
||||
|
||||
// Editor is completely loaded for interaction.
|
||||
editor.status = 'ready';
|
||||
editor.fireOnce( 'instanceReady' );
|
||||
CKEDITOR.fire( 'instanceReady', null, editor );
|
||||
} );
|
||||
} );
|
||||
|
||||
editor.on( 'destroy', destroy );
|
||||
return editor;
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
var editor = this,
|
||||
container = editor.container,
|
||||
element = editor.element;
|
||||
|
||||
if ( container ) {
|
||||
container.clearCustomData();
|
||||
container.remove();
|
||||
}
|
||||
|
||||
if ( element ) {
|
||||
element.clearCustomData();
|
||||
if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
|
||||
element.show();
|
||||
if ( editor._.required )
|
||||
element.setAttribute( 'required', 'required' );
|
||||
}
|
||||
delete editor.element;
|
||||
}
|
||||
}
|
||||
|
||||
function loadTheme( editor ) {
|
||||
var name = editor.name,
|
||||
element = editor.element,
|
||||
elementMode = editor.elementMode;
|
||||
|
||||
// Get the HTML for the predefined spaces.
|
||||
var topHtml = editor.fire( 'uiSpace', { space: 'top', html: '' } ).html;
|
||||
var bottomHtml = editor.fire( 'uiSpace', { space: 'bottom', html: '' } ).html;
|
||||
|
||||
var themedTpl = new CKEDITOR.template(
|
||||
'<{outerEl}' +
|
||||
' id="cke_{name}"' +
|
||||
' class="{id} cke cke_reset cke_chrome cke_editor_{name} cke_{langDir} ' + CKEDITOR.env.cssClass + '" ' +
|
||||
' dir="{langDir}"' +
|
||||
' lang="{langCode}"' +
|
||||
' role="application"' +
|
||||
( editor.applicationTitle ? ' aria-labelledby="cke_{name}_arialbl"' : '' ) +
|
||||
'>' +
|
||||
( editor.applicationTitle ? '<span id="cke_{name}_arialbl" class="cke_voice_label">{voiceLabel}</span>' : '' ) +
|
||||
'<{outerEl} class="cke_inner cke_reset" role="presentation">' +
|
||||
'{topHtml}' +
|
||||
'<{outerEl} id="{contentId}" class="cke_contents cke_reset" role="presentation"></{outerEl}>' +
|
||||
'{bottomHtml}' +
|
||||
'</{outerEl}>' +
|
||||
'</{outerEl}>' );
|
||||
|
||||
var container = CKEDITOR.dom.element.createFromHtml( themedTpl.output( {
|
||||
id: editor.id,
|
||||
name: name,
|
||||
langDir: editor.lang.dir,
|
||||
langCode: editor.langCode,
|
||||
voiceLabel: editor.applicationTitle,
|
||||
topHtml: topHtml ? '<span id="' + editor.ui.spaceId( 'top' ) + '" class="cke_top cke_reset_all" role="presentation" style="height:auto">' + topHtml + '</span>' : '',
|
||||
contentId: editor.ui.spaceId( 'contents' ),
|
||||
bottomHtml: bottomHtml ? '<span id="' + editor.ui.spaceId( 'bottom' ) + '" class="cke_bottom cke_reset_all" role="presentation">' + bottomHtml + '</span>' : '',
|
||||
outerEl: CKEDITOR.env.ie ? 'span' : 'div' // https://dev.ckeditor.com/ticket/9571
|
||||
} ) );
|
||||
|
||||
if ( elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
|
||||
element.hide();
|
||||
container.insertAfter( element );
|
||||
} else {
|
||||
element.append( container );
|
||||
}
|
||||
|
||||
editor.container = container;
|
||||
editor.ui.contentsElement = editor.ui.space( 'contents' );
|
||||
|
||||
// Make top and bottom spaces unelectable, but not content space,
|
||||
// otherwise the editable area would be affected.
|
||||
topHtml && editor.ui.space( 'top' ).unselectable();
|
||||
bottomHtml && editor.ui.space( 'bottom' ).unselectable();
|
||||
|
||||
var width = editor.config.width, height = editor.config.height;
|
||||
if ( width )
|
||||
container.setStyle( 'width', CKEDITOR.tools.cssLength( width ) );
|
||||
|
||||
// The editor height is applied to the contents space.
|
||||
if ( height )
|
||||
editor.ui.space( 'contents' ).setStyle( 'height', CKEDITOR.tools.cssLength( height ) );
|
||||
|
||||
// Disable browser context menu for editor's chrome.
|
||||
container.disableContextMenu();
|
||||
|
||||
// Redirect the focus into editor for webkit. (https://dev.ckeditor.com/ticket/5713)
|
||||
CKEDITOR.env.webkit && container.on( 'focus', function() {
|
||||
editor.focus();
|
||||
} );
|
||||
|
||||
editor.fireOnce( 'uiReady' );
|
||||
}
|
||||
|
||||
// Replace all textareas with the default class name.
|
||||
CKEDITOR.domReady( function() {
|
||||
CKEDITOR.replaceClass && CKEDITOR.replaceAll( CKEDITOR.replaceClass );
|
||||
} );
|
||||
} )();
|
||||
|
||||
/**
|
||||
* The current editing mode. An editing mode basically provides
|
||||
* different ways of editing or viewing the editor content.
|
||||
*
|
||||
* alert( CKEDITOR.instances.editor1.mode ); // (e.g.) 'wysiwyg'
|
||||
*
|
||||
* @readonly
|
||||
* @property {String} mode
|
||||
*/
|
||||
|
||||
/**
|
||||
* The mode to load at the editor startup. It depends on the plugins
|
||||
* loaded. By default, the `wysiwyg` and `source` modes are available.
|
||||
*
|
||||
* config.startupMode = 'source';
|
||||
*
|
||||
* @cfg {String} [startupMode='wysiwyg']
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
CKEDITOR.config.startupMode = 'wysiwyg';
|
||||
|
||||
/**
|
||||
* Fired after the editor instance is resized through
|
||||
* the {@link CKEDITOR.editor#method-resize CKEDITOR.resize} method.
|
||||
*
|
||||
* @event resize
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
* @param {Object} data Available since CKEditor 4.5.0.
|
||||
* @param {Number} data.outerHeight The height of the entire area that the editor covers.
|
||||
* @param {Number} data.contentsHeight Editable area height in pixels.
|
||||
* @param {Number} data.outerWidth The width of the entire area that the editor covers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired before changing the editing mode. See also
|
||||
* {@link #beforeSetMode} and {@link #event-mode}.
|
||||
*
|
||||
* @event beforeModeUnload
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired before the editor mode is set. See also
|
||||
* {@link #event-mode} and {@link #beforeModeUnload}.
|
||||
*
|
||||
* @since 3.5.3
|
||||
* @event beforeSetMode
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
* @param {String} data The name of the mode which is about to be set.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired after setting the editing mode. See also {@link #beforeSetMode} and {@link #beforeModeUnload}
|
||||
*
|
||||
* @event mode
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the editor (replacing a `<textarea>` which has a `required` attribute) is empty during form submission.
|
||||
*
|
||||
* This event replaces native required fields validation that the browsers cannot
|
||||
* perform when CKEditor replaces `<textarea>` elements.
|
||||
*
|
||||
* You can cancel this event to prevent the page from submitting data.
|
||||
*
|
||||
* editor.on( 'required', function( evt ) {
|
||||
* alert( 'Article content is required.' );
|
||||
* evt.cancel();
|
||||
* } );
|
||||
*
|
||||
* @event required
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the UI space is created. This event allows to modify the top bar or the bottom bar with additional HTML.
|
||||
*
|
||||
* For example, it is used in the [Editor Resize](https://ckeditor.com/cke4/addon/resize) plugin
|
||||
* to add the HTML element used to resize the editor.
|
||||
*
|
||||
* @event uiSpace
|
||||
* @param {Object} data
|
||||
* @param {String} data.space The name of the {@link CKEDITOR.ui#space space} for which the event is fired.
|
||||
* @param {String} data.html HTML string which will be included in the given space.
|
||||
*/
|
||||
70
Admin/plugins/ckeditor/core/dataprocessor.js
Normal file
70
Admin/plugins/ckeditor/core/dataprocessor.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.dataProcessor} class, which
|
||||
* defines the basic structure of data processor objects to be
|
||||
* set to {@link CKEDITOR.editor.dataProcessor}.
|
||||
*/
|
||||
|
||||
/**
|
||||
* If defined, points to the data processor which is responsible for translating
|
||||
* and transforming the editor data on input and output.
|
||||
* Generally it will point to an instance of {@link CKEDITOR.htmlDataProcessor},
|
||||
* which handles HTML data. The editor may also handle other data formats by
|
||||
* using different data processors provided by specific plugins.
|
||||
*
|
||||
* @property {CKEDITOR.dataProcessor} dataProcessor
|
||||
* @member CKEDITOR.editor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a data processor which is responsible for translating and
|
||||
* transforming the editor data on input and output.
|
||||
*
|
||||
* This class is here for documentation purposes only and is not really part of
|
||||
* the API. It serves as the base ("interface") for data processor implementations.
|
||||
*
|
||||
* @class CKEDITOR.dataProcessor
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* Transforms input data into HTML to be loaded into the editor.
|
||||
* While the editor is able to handle non-HTML data (like BBCode), it can only
|
||||
* handle HTML data at runtime. The role of the data processor is to transform
|
||||
* the input data into HTML through this function.
|
||||
*
|
||||
* // Tranforming BBCode data, with a custom BBCode data processor available.
|
||||
* var data = 'This is [b]an example[/b].';
|
||||
* var html = editor.dataProcessor.toHtml( data ); // '<p>This is <b>an example</b>.</p>'
|
||||
*
|
||||
* @method toHtml
|
||||
* @param {String} data The input data to be transformed.
|
||||
* @param {String} [fixForBody] The tag name to be used if the data must be
|
||||
* fixed because it is supposed to be loaded direcly into the `<body>`
|
||||
* tag. This is generally not used by non-HTML data processors.
|
||||
* @todo fixForBody type - compare to htmlDataProcessor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Transforms HTML into data to be output by the editor, in the format
|
||||
* expected by the data processor.
|
||||
*
|
||||
* While the editor is able to handle non-HTML data (like BBCode), it can only
|
||||
* handle HTML data at runtime. The role of the data processor is to transform
|
||||
* the HTML data contained by the editor into a specific data format through
|
||||
* this function.
|
||||
*
|
||||
* // Tranforming into BBCode data, with a custom BBCode data processor available.
|
||||
* var html = '<p>This is <b>an example</b>.</p>';
|
||||
* var data = editor.dataProcessor.toDataFormat( html ); // 'This is [b]an example[/b].'
|
||||
*
|
||||
* @method toDataFormat
|
||||
* @param {String} html The HTML to be transformed.
|
||||
* @param {String} fixForBody The tag name to be used if the output data is
|
||||
* coming from the `<body>` element and may be eventually fixed for it. This is
|
||||
* generally not used by non-HTML data processors.
|
||||
*/
|
||||
13
Admin/plugins/ckeditor/core/dom.js
Normal file
13
Admin/plugins/ckeditor/core/dom.js
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom} object, which contains DOM
|
||||
* manipulation objects and function.
|
||||
*/
|
||||
|
||||
CKEDITOR.dom = {};
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.dom )
|
||||
53
Admin/plugins/ckeditor/core/dom/comment.js
Normal file
53
Admin/plugins/ckeditor/core/dom/comment.js
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.comment} class, which represents
|
||||
* a DOM comment node.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM comment node.
|
||||
*
|
||||
* var nativeNode = document.createComment( 'Example' );
|
||||
* var comment = new CKEDITOR.dom.comment( nativeNode );
|
||||
*
|
||||
* var comment = new CKEDITOR.dom.comment( 'Example' );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.node
|
||||
* @constructor Creates a comment class instance.
|
||||
* @param {Object/String} comment A native DOM comment node or a string containing
|
||||
* the text to use to create a new comment node.
|
||||
* @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
|
||||
* the node in case of new node creation. Defaults to the current document.
|
||||
*/
|
||||
CKEDITOR.dom.comment = function( comment, ownerDocument ) {
|
||||
if ( typeof comment == 'string' )
|
||||
comment = ( ownerDocument ? ownerDocument.$ : document ).createComment( comment );
|
||||
|
||||
CKEDITOR.dom.domObject.call( this, comment );
|
||||
};
|
||||
|
||||
CKEDITOR.dom.comment.prototype = new CKEDITOR.dom.node();
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.comment.prototype, {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_COMMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_COMMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_COMMENT,
|
||||
|
||||
/**
|
||||
* Gets the outer HTML of this comment.
|
||||
*
|
||||
* @returns {String} The HTML `<!-- comment value -->`.
|
||||
*/
|
||||
getOuterHtml: function() {
|
||||
return '<!--' + this.$.nodeValue + '-->';
|
||||
}
|
||||
} );
|
||||
328
Admin/plugins/ckeditor/core/dom/document.js
Normal file
328
Admin/plugins/ckeditor/core/dom/document.js
Normal file
@@ -0,0 +1,328 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.document} class which
|
||||
* represents a DOM document.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM document.
|
||||
*
|
||||
* var document = new CKEDITOR.dom.document( document );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.domObject
|
||||
* @constructor Creates a document class instance.
|
||||
* @param {Object} domDocument A native DOM document.
|
||||
*/
|
||||
CKEDITOR.dom.document = function( domDocument ) {
|
||||
CKEDITOR.dom.domObject.call( this, domDocument );
|
||||
};
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.dom.document )
|
||||
|
||||
CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject();
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype, {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_DOCUMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_DOCUMENT,
|
||||
|
||||
/**
|
||||
* Appends a CSS file to the document.
|
||||
*
|
||||
* CKEDITOR.document.appendStyleSheet( '/mystyles.css' );
|
||||
*
|
||||
* @param {String} cssFileUrl The CSS file URL.
|
||||
*/
|
||||
appendStyleSheet: function( cssFileUrl ) {
|
||||
cssFileUrl = CKEDITOR.appendTimestamp( cssFileUrl );
|
||||
|
||||
if ( this.$.createStyleSheet )
|
||||
this.$.createStyleSheet( cssFileUrl );
|
||||
else {
|
||||
var link = new CKEDITOR.dom.element( 'link' );
|
||||
link.setAttributes( {
|
||||
rel: 'stylesheet',
|
||||
type: 'text/css',
|
||||
href: cssFileUrl
|
||||
} );
|
||||
|
||||
this.getHead().append( link );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a CSS stylesheet and inserts it into the document.
|
||||
*
|
||||
* @param cssStyleText {String} CSS style text.
|
||||
* @returns {Object} The created DOM native stylesheet object.
|
||||
*/
|
||||
appendStyleText: function( cssStyleText ) {
|
||||
if ( this.$.createStyleSheet ) {
|
||||
var styleSheet = this.$.createStyleSheet( '' );
|
||||
styleSheet.cssText = cssStyleText;
|
||||
} else {
|
||||
var style = new CKEDITOR.dom.element( 'style', this );
|
||||
style.append( new CKEDITOR.dom.text( cssStyleText, this ) );
|
||||
this.getHead().append( style );
|
||||
}
|
||||
|
||||
return styleSheet || style.$.sheet;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a {@link CKEDITOR.dom.element} instance in this document.
|
||||
*
|
||||
* @param {String} name The name of the element.
|
||||
* @param {Object} [attributesAndStyles]
|
||||
* @param {Object} [attributesAndStyles.attributes] Attributes that will be set.
|
||||
* @param {Object} [attributesAndStyles.styles] Styles that will be set.
|
||||
* @returns {CKEDITOR.dom.element}
|
||||
*/
|
||||
createElement: function( name, attribsAndStyles ) {
|
||||
var element = new CKEDITOR.dom.element( name, this );
|
||||
|
||||
if ( attribsAndStyles ) {
|
||||
if ( attribsAndStyles.attributes )
|
||||
element.setAttributes( attribsAndStyles.attributes );
|
||||
|
||||
if ( attribsAndStyles.styles )
|
||||
element.setStyles( attribsAndStyles.styles );
|
||||
}
|
||||
|
||||
return element;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a {@link CKEDITOR.dom.text} instance in this document.
|
||||
*
|
||||
* @param {String} text Value of the text node.
|
||||
* @returns {CKEDITOR.dom.element}
|
||||
*/
|
||||
createText: function( text ) {
|
||||
return new CKEDITOR.dom.text( text, this );
|
||||
},
|
||||
|
||||
/**
|
||||
* Moves the selection focus to this document's window.
|
||||
*/
|
||||
focus: function() {
|
||||
this.getWindow().focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the element that is currently designated as the active element in the document.
|
||||
*
|
||||
* **Note:** Only one element can be active at a time in a document.
|
||||
* An active element does not necessarily have focus,
|
||||
* but an element with focus is always the active element in a document.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} Active element or `null` if an IE8-9 bug is encountered.
|
||||
* See [#10030](https://dev.ckeditor.com/ticket/10030).
|
||||
*/
|
||||
getActive: function() {
|
||||
var $active;
|
||||
try {
|
||||
$active = this.$.activeElement;
|
||||
} catch ( e ) {
|
||||
return null;
|
||||
}
|
||||
return new CKEDITOR.dom.element( $active );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets an element based on its ID.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'myElement' );
|
||||
* alert( element.getId() ); // 'myElement'
|
||||
*
|
||||
* @param {String} elementId The element ID.
|
||||
* @returns {CKEDITOR.dom.element} The element instance, or `null` if not found.
|
||||
*/
|
||||
getById: function( elementId ) {
|
||||
var $ = this.$.getElementById( elementId );
|
||||
return $ ? new CKEDITOR.dom.element( $ ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a node based on its address. See {@link CKEDITOR.dom.node#getAddress}.
|
||||
*
|
||||
* @param {Array} address
|
||||
* @param {Boolean} [normalized=false]
|
||||
*/
|
||||
getByAddress: function( address, normalized ) {
|
||||
var $ = this.$.documentElement;
|
||||
|
||||
for ( var i = 0; $ && i < address.length; i++ ) {
|
||||
var target = address[ i ];
|
||||
|
||||
if ( !normalized ) {
|
||||
$ = $.childNodes[ target ];
|
||||
continue;
|
||||
}
|
||||
|
||||
var currentIndex = -1;
|
||||
|
||||
for ( var j = 0; j < $.childNodes.length; j++ ) {
|
||||
var candidate = $.childNodes[ j ];
|
||||
|
||||
if ( normalized === true && candidate.nodeType == 3 && candidate.previousSibling && candidate.previousSibling.nodeType == 3 )
|
||||
continue;
|
||||
|
||||
currentIndex++;
|
||||
|
||||
if ( currentIndex == target ) {
|
||||
$ = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ ? new CKEDITOR.dom.node( $ ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets elements list based on a given tag name.
|
||||
*
|
||||
* @param {String} tagName The element tag name.
|
||||
* @returns {CKEDITOR.dom.nodeList} The nodes list.
|
||||
*/
|
||||
getElementsByTag: function( tagName, namespace ) {
|
||||
if ( !( CKEDITOR.env.ie && ( document.documentMode <= 8 ) ) && namespace )
|
||||
tagName = namespace + ':' + tagName;
|
||||
return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the `<head>` element for this document.
|
||||
*
|
||||
* var element = CKEDITOR.document.getHead();
|
||||
* alert( element.getName() ); // 'head'
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} The `<head>` element.
|
||||
*/
|
||||
getHead: function() {
|
||||
var head = this.$.getElementsByTagName( 'head' )[ 0 ];
|
||||
if ( !head )
|
||||
head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true );
|
||||
else
|
||||
head = new CKEDITOR.dom.element( head );
|
||||
|
||||
return head;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the `<body>` element for this document.
|
||||
*
|
||||
* var element = CKEDITOR.document.getBody();
|
||||
* alert( element.getName() ); // 'body'
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} The `<body>` element.
|
||||
*/
|
||||
getBody: function() {
|
||||
return new CKEDITOR.dom.element( this.$.body );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the DOM document element for this document.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} The DOM document element.
|
||||
*/
|
||||
getDocumentElement: function() {
|
||||
return new CKEDITOR.dom.element( this.$.documentElement );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the window object that stores this document.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.window} The window object.
|
||||
*/
|
||||
getWindow: function() {
|
||||
return new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView );
|
||||
},
|
||||
|
||||
/**
|
||||
* Defines the document content through `document.write`. Note that the
|
||||
* previous document content will be lost (cleaned).
|
||||
*
|
||||
* document.write(
|
||||
* '<html>' +
|
||||
* '<head><title>Sample Document</title></head>' +
|
||||
* '<body>Document content created by code.</body>' +
|
||||
* '</html>'
|
||||
* );
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @param {String} html The HTML defining the document content.
|
||||
*/
|
||||
write: function( html ) {
|
||||
// Don't leave any history log in IE. (https://dev.ckeditor.com/ticket/5657)
|
||||
this.$.open( 'text/html', 'replace' );
|
||||
|
||||
// Support for custom document.domain in IE.
|
||||
//
|
||||
// The script must be appended because if placed before the
|
||||
// doctype, IE will go into quirks mode and mess with
|
||||
// the editable, e.g. by changing its default height.
|
||||
if ( CKEDITOR.env.ie )
|
||||
html = html.replace( /(?:^\s*<!DOCTYPE[^>]*?>)|^/i, '$&\n<script data-cke-temp="1">(' + CKEDITOR.tools.fixDomain + ')();</script>' );
|
||||
|
||||
this.$.write( html );
|
||||
this.$.close();
|
||||
},
|
||||
|
||||
/**
|
||||
* Wrapper for `querySelectorAll`. Returns a list of elements within this document that match
|
||||
* the specified `selector`.
|
||||
*
|
||||
* **Note:** The returned list is not a live collection (like the result of native `querySelectorAll`).
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} selector A valid [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors).
|
||||
* @returns {CKEDITOR.dom.nodeList}
|
||||
*/
|
||||
find: function( selector ) {
|
||||
return new CKEDITOR.dom.nodeList( this.$.querySelectorAll( selector ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Wrapper for `querySelector`. Returns the first element within this document that matches
|
||||
* the specified `selector`.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} selector A valid [CSS selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors).
|
||||
* @returns {CKEDITOR.dom.element}
|
||||
*/
|
||||
findOne: function( selector ) {
|
||||
var el = this.$.querySelector( selector );
|
||||
|
||||
return el ? new CKEDITOR.dom.element( el ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Internet Explorer 8 only method. It returns a document fragment which has all HTML5 elements enabled.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @private
|
||||
* @returns DocumentFragment
|
||||
*/
|
||||
_getHtml5ShivFrag: function() {
|
||||
var $frag = this.getCustomData( 'html5ShivFrag' );
|
||||
|
||||
if ( !$frag ) {
|
||||
$frag = this.$.createDocumentFragment();
|
||||
CKEDITOR.tools.enableHtml5Elements( $frag, true );
|
||||
this.setCustomData( 'html5ShivFrag', $frag );
|
||||
}
|
||||
|
||||
return $frag;
|
||||
}
|
||||
} );
|
||||
194
Admin/plugins/ckeditor/core/dom/documentfragment.js
Normal file
194
Admin/plugins/ckeditor/core/dom/documentfragment.js
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* DocumentFragment is a "lightweight" or "minimal" Document object. It is
|
||||
* commonly used to extract a portion of the document's tree or to create a new
|
||||
* fragment of the document. Various operations may take document fragment objects
|
||||
* as arguments and result in all the child nodes of the document fragment being
|
||||
* moved to the child list of this node.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a document fragment class instance.
|
||||
* @param {CKEDITOR.dom.document/DocumentFragment} [nodeOrDoc=CKEDITOR.document]
|
||||
*/
|
||||
CKEDITOR.dom.documentFragment = function( nodeOrDoc ) {
|
||||
nodeOrDoc = nodeOrDoc || CKEDITOR.document;
|
||||
|
||||
if ( nodeOrDoc.type == CKEDITOR.NODE_DOCUMENT )
|
||||
this.$ = nodeOrDoc.$.createDocumentFragment();
|
||||
else
|
||||
this.$ = nodeOrDoc;
|
||||
};
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.documentFragment.prototype, CKEDITOR.dom.element.prototype, {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_DOCUMENT_FRAGMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_DOCUMENT_FRAGMENT,
|
||||
|
||||
/**
|
||||
* Inserts the document fragment content after the specified node.
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} node
|
||||
*/
|
||||
insertAfterNode: function( node ) {
|
||||
node = node.$;
|
||||
node.parentNode.insertBefore( this.$, node.nextSibling );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the HTML of this document fragment's children.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @returns {String} The HTML of this document fragment's children.
|
||||
*/
|
||||
getHtml: function() {
|
||||
var container = new CKEDITOR.dom.element( 'div' );
|
||||
|
||||
this.clone( 1, 1 ).appendTo( container );
|
||||
|
||||
return container.getHtml().replace( /\s*data-cke-expando=".*?"/g, '' );
|
||||
}
|
||||
}, true, {
|
||||
'append': 1, 'appendBogus': 1, 'clone': 1, 'getFirst': 1, 'getHtml': 1, 'getLast': 1, 'getParent': 1, 'getNext': 1, 'getPrevious': 1,
|
||||
'appendTo': 1, 'moveChildren': 1, 'insertBefore': 1, 'insertAfterNode': 1, 'replace': 1, 'trim': 1, 'type': 1,
|
||||
'ltrim': 1, 'rtrim': 1, 'getDocument': 1, 'getChildCount': 1, 'getChild': 1, 'getChildren': 1
|
||||
} );
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.documentFragment.prototype, CKEDITOR.dom.document.prototype, true, {
|
||||
'find': 1, 'findOne': 1
|
||||
} );
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method append
|
||||
* @inheritdoc CKEDITOR.dom.element#append
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method appendBogus
|
||||
* @inheritdoc CKEDITOR.dom.element#appendBogus
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method clone
|
||||
* @inheritdoc CKEDITOR.dom.element#clone
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getFirst
|
||||
* @inheritdoc CKEDITOR.dom.element#getFirst
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getLast
|
||||
* @inheritdoc CKEDITOR.dom.element#getLast
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getParent
|
||||
* @inheritdoc CKEDITOR.dom.element#getParent
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getNext
|
||||
* @inheritdoc CKEDITOR.dom.element#getNext
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getPrevious
|
||||
* @inheritdoc CKEDITOR.dom.element#getPrevious
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method appendTo
|
||||
* @inheritdoc CKEDITOR.dom.element#appendTo
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method moveChildren
|
||||
* @inheritdoc CKEDITOR.dom.element#moveChildren
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method insertBefore
|
||||
* @inheritdoc CKEDITOR.dom.element#insertBefore
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method replace
|
||||
* @inheritdoc CKEDITOR.dom.element#replace
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method trim
|
||||
* @inheritdoc CKEDITOR.dom.element#trim
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method ltrim
|
||||
* @inheritdoc CKEDITOR.dom.element#ltrim
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method rtrim
|
||||
* @inheritdoc CKEDITOR.dom.element#rtrim
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getDocument
|
||||
* @inheritdoc CKEDITOR.dom.element#getDocument
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getChildCount
|
||||
* @inheritdoc CKEDITOR.dom.element#getChildCount
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getChild
|
||||
* @inheritdoc CKEDITOR.dom.element#getChild
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method getChildren
|
||||
* @inheritdoc CKEDITOR.dom.element#getChildren
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method find
|
||||
* @since 4.12.0
|
||||
* @inheritdoc CKEDITOR.dom.document#find
|
||||
*/
|
||||
|
||||
/**
|
||||
* @member CKEDITOR.dom.documentFragment
|
||||
* @method findOne
|
||||
* @since 4.12.0
|
||||
* @inheritdoc CKEDITOR.dom.document#findOne
|
||||
*/
|
||||
275
Admin/plugins/ckeditor/core/dom/domobject.js
Normal file
275
Admin/plugins/ckeditor/core/dom/domobject.js
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.editor} class, which is the base
|
||||
* for other classes representing DOM objects.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM object. This class is not intended to be used directly. It
|
||||
* serves as the base class for other classes representing specific DOM
|
||||
* objects.
|
||||
*
|
||||
* @class
|
||||
* @mixins CKEDITOR.event
|
||||
* @constructor Creates a domObject class instance.
|
||||
* @param {Object} nativeDomObject A native DOM object.
|
||||
*/
|
||||
CKEDITOR.dom.domObject = function( nativeDomObject ) {
|
||||
if ( nativeDomObject ) {
|
||||
/**
|
||||
* The native DOM object represented by this class instance.
|
||||
*
|
||||
* var element = new CKEDITOR.dom.element( 'span' );
|
||||
* alert( element.$.nodeType ); // '1'
|
||||
*
|
||||
* @readonly
|
||||
* @property {Object}
|
||||
*/
|
||||
this.$ = nativeDomObject;
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.dom.domObject.prototype = ( function() {
|
||||
// Do not define other local variables here. We want to keep the native
|
||||
// listener closures as clean as possible.
|
||||
|
||||
var getNativeListener = function( domObject, eventName ) {
|
||||
return function( domEvent ) {
|
||||
// In FF, when reloading the page with the editor focused, it may
|
||||
// throw an error because the CKEDITOR global is not anymore
|
||||
// available. So, we check it here first. (https://dev.ckeditor.com/ticket/2923)
|
||||
if ( typeof CKEDITOR != 'undefined' )
|
||||
domObject.fire( eventName, new CKEDITOR.dom.event( domEvent ) );
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
* Gets the private `_` object which is bound to the native
|
||||
* DOM object using {@link #getCustomData}.
|
||||
*
|
||||
* var elementA = new CKEDITOR.dom.element( nativeElement );
|
||||
* elementA.getPrivate().value = 1;
|
||||
* ...
|
||||
* var elementB = new CKEDITOR.dom.element( nativeElement );
|
||||
* elementB.getPrivate().value; // 1
|
||||
*
|
||||
* @returns {Object} The private object.
|
||||
*/
|
||||
getPrivate: function() {
|
||||
var priv;
|
||||
|
||||
// Get the main private object from the custom data. Create it if not defined.
|
||||
if ( !( priv = this.getCustomData( '_' ) ) )
|
||||
this.setCustomData( '_', ( priv = {} ) );
|
||||
|
||||
return priv;
|
||||
},
|
||||
|
||||
// Docs inherited from event.
|
||||
on: function( eventName ) {
|
||||
// We customize the "on" function here. The basic idea is that we'll have
|
||||
// only one listener for a native event, which will then call all listeners
|
||||
// set to the event.
|
||||
|
||||
// Get the listeners holder object.
|
||||
var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
|
||||
|
||||
if ( !nativeListeners ) {
|
||||
nativeListeners = {};
|
||||
this.setCustomData( '_cke_nativeListeners', nativeListeners );
|
||||
}
|
||||
|
||||
// Check if we have a listener for that event.
|
||||
if ( !nativeListeners[ eventName ] ) {
|
||||
var listener = nativeListeners[ eventName ] = getNativeListener( this, eventName );
|
||||
|
||||
if ( this.$.addEventListener )
|
||||
this.$.addEventListener( eventName, listener, !!CKEDITOR.event.useCapture );
|
||||
else if ( this.$.attachEvent )
|
||||
this.$.attachEvent( 'on' + eventName, listener );
|
||||
}
|
||||
|
||||
// Call the original implementation.
|
||||
return CKEDITOR.event.prototype.on.apply( this, arguments );
|
||||
},
|
||||
|
||||
// Docs inherited from event.
|
||||
removeListener: function( eventName ) {
|
||||
// Call the original implementation.
|
||||
CKEDITOR.event.prototype.removeListener.apply( this, arguments );
|
||||
|
||||
// If we don't have listeners for this event, clean the DOM up.
|
||||
if ( !this.hasListeners( eventName ) ) {
|
||||
var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
|
||||
var listener = nativeListeners && nativeListeners[ eventName ];
|
||||
if ( listener ) {
|
||||
if ( this.$.removeEventListener )
|
||||
this.$.removeEventListener( eventName, listener, false );
|
||||
else if ( this.$.detachEvent )
|
||||
this.$.detachEvent( 'on' + eventName, listener );
|
||||
|
||||
delete nativeListeners[ eventName ];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes any listener set on this object.
|
||||
*
|
||||
* To avoid memory leaks we must assure that there are no
|
||||
* references left after the object is no longer needed.
|
||||
*/
|
||||
removeAllListeners: function() {
|
||||
try {
|
||||
var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
|
||||
for ( var eventName in nativeListeners ) {
|
||||
var listener = nativeListeners[ eventName ];
|
||||
if ( this.$.detachEvent ) {
|
||||
this.$.detachEvent( 'on' + eventName, listener );
|
||||
} else if ( this.$.removeEventListener ) {
|
||||
this.$.removeEventListener( eventName, listener, false );
|
||||
}
|
||||
|
||||
delete nativeListeners[ eventName ];
|
||||
}
|
||||
// Catch Edge `Permission denied` error which occurs randomly. Since the error is quite
|
||||
// random, catching allows to continue the code execution and cleanup (#3419).
|
||||
} catch ( error ) {
|
||||
if ( !CKEDITOR.env.edge || error.number !== -2146828218 ) {
|
||||
throw( error );
|
||||
}
|
||||
}
|
||||
|
||||
// Remove events from events object so fire() method will not call
|
||||
// listeners (https://dev.ckeditor.com/ticket/11400).
|
||||
CKEDITOR.event.prototype.removeAllListeners.call( this );
|
||||
}
|
||||
};
|
||||
} )();
|
||||
|
||||
( function( domObjectProto ) {
|
||||
var customData = {};
|
||||
|
||||
CKEDITOR.on( 'reset', function() {
|
||||
customData = {};
|
||||
} );
|
||||
|
||||
/**
|
||||
* Determines whether the specified object is equal to the current object.
|
||||
*
|
||||
* var doc = new CKEDITOR.dom.document( document );
|
||||
* alert( doc.equals( CKEDITOR.document ) ); // true
|
||||
* alert( doc == CKEDITOR.document ); // false
|
||||
*
|
||||
* @param {Object} object The object to compare with the current object.
|
||||
* @returns {Boolean} `true` if the object is equal.
|
||||
*/
|
||||
domObjectProto.equals = function( object ) {
|
||||
// Try/Catch to avoid IE permission error when object is from different document.
|
||||
try {
|
||||
return ( object && object.$ === this.$ );
|
||||
} catch ( er ) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets a data slot value for this object. These values are shared by all
|
||||
* instances pointing to that same DOM object.
|
||||
*
|
||||
* **Note:** The created data slot is only guaranteed to be available on this unique DOM node,
|
||||
* thus any wish to continue access to it from other element clones (either created by
|
||||
* clone node or from `innerHtml`) will fail. For such usage please use
|
||||
* {@link CKEDITOR.dom.element#setAttribute} instead.
|
||||
*
|
||||
* **Note**: This method does not work on text nodes prior to Internet Explorer 9.
|
||||
*
|
||||
* var element = new CKEDITOR.dom.element( 'span' );
|
||||
* element.setCustomData( 'hasCustomData', true );
|
||||
*
|
||||
* @param {String} key A key used to identify the data slot.
|
||||
* @param {Object} value The value to set to the data slot.
|
||||
* @returns {CKEDITOR.dom.domObject} This DOM object instance.
|
||||
* @chainable
|
||||
*/
|
||||
domObjectProto.setCustomData = function( key, value ) {
|
||||
var expandoNumber = this.getUniqueId(),
|
||||
dataSlot = customData[ expandoNumber ] || ( customData[ expandoNumber ] = {} );
|
||||
|
||||
dataSlot[ key ] = value;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the value set to a data slot in this object.
|
||||
*
|
||||
* var element = new CKEDITOR.dom.element( 'span' );
|
||||
* alert( element.getCustomData( 'hasCustomData' ) ); // e.g. 'true'
|
||||
* alert( element.getCustomData( 'nonExistingKey' ) ); // null
|
||||
*
|
||||
* @param {String} key The key used to identify the data slot.
|
||||
* @returns {Object} This value set to the data slot.
|
||||
*/
|
||||
domObjectProto.getCustomData = function( key ) {
|
||||
var expandoNumber = this.$[ 'data-cke-expando' ],
|
||||
dataSlot = expandoNumber && customData[ expandoNumber ];
|
||||
|
||||
return ( dataSlot && key in dataSlot ) ? dataSlot[ key ] : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes the value in the data slot under the given `key`.
|
||||
*
|
||||
* @param {String} key
|
||||
* @returns {Object} Removed value or `null` if not found.
|
||||
*/
|
||||
domObjectProto.removeCustomData = function( key ) {
|
||||
var expandoNumber = this.$[ 'data-cke-expando' ],
|
||||
dataSlot = expandoNumber && customData[ expandoNumber ],
|
||||
retval, hadKey;
|
||||
|
||||
if ( dataSlot ) {
|
||||
retval = dataSlot[ key ];
|
||||
hadKey = key in dataSlot;
|
||||
delete dataSlot[ key ];
|
||||
}
|
||||
|
||||
return hadKey ? retval : null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes any data stored in this object.
|
||||
* To avoid memory leaks we must assure that there are no
|
||||
* references left after the object is no longer needed.
|
||||
*/
|
||||
domObjectProto.clearCustomData = function() {
|
||||
// Clear all event listeners
|
||||
this.removeAllListeners();
|
||||
|
||||
var expandoNumber = this.getUniqueId();
|
||||
expandoNumber && delete customData[ expandoNumber ];
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets an ID that can be used to identify this DOM object in
|
||||
* the running session.
|
||||
*
|
||||
* **Note**: This method does not work on text nodes prior to Internet Explorer 9.
|
||||
*
|
||||
* @returns {Number} A unique ID.
|
||||
*/
|
||||
domObjectProto.getUniqueId = function() {
|
||||
return this.$[ 'data-cke-expando' ] || ( this.$[ 'data-cke-expando' ] = CKEDITOR.tools.getNextNumber() );
|
||||
};
|
||||
|
||||
// Implement CKEDITOR.event.
|
||||
CKEDITOR.event.implementOn( domObjectProto );
|
||||
|
||||
} )( CKEDITOR.dom.domObject.prototype );
|
||||
2272
Admin/plugins/ckeditor/core/dom/element.js
Normal file
2272
Admin/plugins/ckeditor/core/dom/element.js
Normal file
File diff suppressed because it is too large
Load Diff
265
Admin/plugins/ckeditor/core/dom/elementpath.js
Normal file
265
Admin/plugins/ckeditor/core/dom/elementpath.js
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
|
||||
var pathBlockLimitElements = {},
|
||||
pathBlockElements = {},
|
||||
tag;
|
||||
|
||||
// Elements that are considered the "Block limit" in an element path.
|
||||
for ( tag in CKEDITOR.dtd.$blockLimit ) {
|
||||
// Exclude from list roots.
|
||||
if ( !( tag in CKEDITOR.dtd.$list ) )
|
||||
pathBlockLimitElements[ tag ] = 1;
|
||||
}
|
||||
|
||||
// Elements that are considered the "End level Block" in an element path.
|
||||
for ( tag in CKEDITOR.dtd.$block ) {
|
||||
// Exclude block limits, and empty block element, e.g. hr.
|
||||
if ( !( tag in CKEDITOR.dtd.$blockLimit || tag in CKEDITOR.dtd.$empty ) )
|
||||
pathBlockElements[ tag ] = 1;
|
||||
}
|
||||
|
||||
// Check if an element contains any block element.
|
||||
function checkHasBlock( element ) {
|
||||
var childNodes = element.getChildren();
|
||||
|
||||
for ( var i = 0, count = childNodes.count(); i < count; i++ ) {
|
||||
var child = childNodes.getItem( i );
|
||||
|
||||
if ( child.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$block[ child.getName() ] )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the list of nodes walked from the start node up to the editable element of the editor.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates an element path class instance.
|
||||
* @param {CKEDITOR.dom.element} startNode From which the path should start.
|
||||
* @param {CKEDITOR.dom.element} root To which element the path should stop, defaults to the `body` element.
|
||||
*/
|
||||
CKEDITOR.dom.elementPath = function( startNode, root ) {
|
||||
var block = null,
|
||||
blockLimit = null,
|
||||
elements = [],
|
||||
e = startNode,
|
||||
elementName;
|
||||
|
||||
// Backward compact.
|
||||
root = root || startNode.getDocument().getBody();
|
||||
|
||||
// Assign root value if startNode is null (#424)(https://dev.ckeditor.com/ticket/17028).
|
||||
if ( !e ) {
|
||||
e = root;
|
||||
}
|
||||
|
||||
do {
|
||||
if ( e.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
elements.push( e );
|
||||
|
||||
if ( !this.lastElement ) {
|
||||
this.lastElement = e;
|
||||
|
||||
// If an object or non-editable element is fully selected at the end of the element path,
|
||||
// it must not become the block limit.
|
||||
if ( e.is( CKEDITOR.dtd.$object ) || e.getAttribute( 'contenteditable' ) == 'false' )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( e.equals( root ) )
|
||||
break;
|
||||
|
||||
if ( !blockLimit ) {
|
||||
elementName = e.getName();
|
||||
|
||||
// First editable element becomes a block limit, because it cannot be split.
|
||||
if ( e.getAttribute( 'contenteditable' ) == 'true' )
|
||||
blockLimit = e;
|
||||
// "Else" because element cannot be both - block and block levelimit.
|
||||
else if ( !block && pathBlockElements[ elementName ] )
|
||||
block = e;
|
||||
|
||||
if ( pathBlockLimitElements[ elementName ] ) {
|
||||
// End level DIV is considered as the block, if no block is available. (https://dev.ckeditor.com/ticket/525)
|
||||
// But it must NOT be the root element (checked above).
|
||||
if ( !block && elementName == 'div' && !checkHasBlock( e ) )
|
||||
block = e;
|
||||
else
|
||||
blockLimit = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while ( ( e = e.getParent() ) );
|
||||
|
||||
// Block limit defaults to root.
|
||||
if ( !blockLimit )
|
||||
blockLimit = root;
|
||||
|
||||
/**
|
||||
* First non-empty block element which:
|
||||
*
|
||||
* * is not a {@link CKEDITOR.dtd#$blockLimit},
|
||||
* * or is a `div` which does not contain block elements and is not a `root`.
|
||||
*
|
||||
* This means a first, splittable block in elements path.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element}
|
||||
*/
|
||||
this.block = block;
|
||||
|
||||
/**
|
||||
* See the {@link CKEDITOR.dtd#$blockLimit} description.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element}
|
||||
*/
|
||||
this.blockLimit = blockLimit;
|
||||
|
||||
/**
|
||||
* The root of the elements path - `root` argument passed to class constructor or a `body` element.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element}
|
||||
*/
|
||||
this.root = root;
|
||||
|
||||
/**
|
||||
* An array of elements (from `startNode` to `root`) in the path.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element[]}
|
||||
*/
|
||||
this.elements = elements;
|
||||
|
||||
/**
|
||||
* The last element of the elements path - `startNode` or its parent.
|
||||
*
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element} lastElement
|
||||
*/
|
||||
};
|
||||
|
||||
} )();
|
||||
|
||||
CKEDITOR.dom.elementPath.prototype = {
|
||||
/**
|
||||
* Compares this element path with another one.
|
||||
*
|
||||
* @param {CKEDITOR.dom.elementPath} otherPath The elementPath object to be
|
||||
* compared with this one.
|
||||
* @returns {Boolean} `true` if the paths are equal, containing the same
|
||||
* number of elements and the same elements in the same order.
|
||||
*/
|
||||
compare: function( otherPath ) {
|
||||
var thisElements = this.elements;
|
||||
var otherElements = otherPath && otherPath.elements;
|
||||
|
||||
if ( !otherElements || thisElements.length != otherElements.length )
|
||||
return false;
|
||||
|
||||
for ( var i = 0; i < thisElements.length; i++ ) {
|
||||
if ( !thisElements[ i ].equals( otherElements[ i ] ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Search the path elements that meets the specified criteria.
|
||||
*
|
||||
* @param {String/Array/Function/Object/CKEDITOR.dom.element} query The criteria that can be
|
||||
* either a tag name, list (array and object) of tag names, element or an node evaluator function.
|
||||
* @param {Boolean} [excludeRoot] Not taking path root element into consideration.
|
||||
* @param {Boolean} [fromTop] Search start from the topmost element instead of bottom.
|
||||
* @returns {CKEDITOR.dom.element} The first matched dom element or `null`.
|
||||
*/
|
||||
contains: function( query, excludeRoot, fromTop ) {
|
||||
var i = 0,
|
||||
evaluator;
|
||||
|
||||
if ( typeof query == 'string' )
|
||||
evaluator = function( node ) {
|
||||
return node.getName() == query;
|
||||
};
|
||||
if ( query instanceof CKEDITOR.dom.element )
|
||||
evaluator = function( node ) {
|
||||
return node.equals( query );
|
||||
};
|
||||
else if ( CKEDITOR.tools.isArray( query ) )
|
||||
evaluator = function( node ) {
|
||||
return CKEDITOR.tools.indexOf( query, node.getName() ) > -1;
|
||||
};
|
||||
else if ( typeof query == 'function' )
|
||||
evaluator = query;
|
||||
else if ( typeof query == 'object' )
|
||||
evaluator = function( node ) {
|
||||
return node.getName() in query;
|
||||
};
|
||||
|
||||
var elements = this.elements,
|
||||
length = elements.length;
|
||||
|
||||
if ( excludeRoot ) {
|
||||
if ( !fromTop ) {
|
||||
length -= 1;
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fromTop ) {
|
||||
elements = Array.prototype.slice.call( elements, 0 );
|
||||
elements.reverse();
|
||||
}
|
||||
|
||||
for ( ; i < length; i++ ) {
|
||||
if ( evaluator( elements[ i ] ) )
|
||||
return elements[ i ];
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether the elements path is the proper context for the specified
|
||||
* tag name in the DTD.
|
||||
*
|
||||
* @param {String} tag The tag name.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isContextFor: function( tag ) {
|
||||
var holder;
|
||||
|
||||
// Check for block context.
|
||||
if ( tag in CKEDITOR.dtd.$block ) {
|
||||
// Indeterminate elements which are not subjected to be splitted or surrounded must be checked first.
|
||||
var inter = this.contains( CKEDITOR.dtd.$intermediate );
|
||||
holder = inter || ( this.root.equals( this.block ) && this.block ) || this.blockLimit;
|
||||
return !!holder.getDtd()[ tag ];
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the text direction for this elements path.
|
||||
*
|
||||
* @returns {'ltr'/'rtl'}
|
||||
*/
|
||||
direction: function() {
|
||||
var directionNode = this.block || this.blockLimit || this.root;
|
||||
return directionNode.getDirection( 1 );
|
||||
}
|
||||
};
|
||||
238
Admin/plugins/ckeditor/core/dom/event.js
Normal file
238
Admin/plugins/ckeditor/core/dom/event.js
Normal file
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.event} class, which
|
||||
* represents the a native DOM event object.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a native DOM event object.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates an event class instance.
|
||||
* @param {Object} domEvent A native DOM event object.
|
||||
*/
|
||||
CKEDITOR.dom.event = function( domEvent ) {
|
||||
/**
|
||||
* The native DOM event object represented by this class instance.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
this.$ = domEvent;
|
||||
};
|
||||
|
||||
CKEDITOR.dom.event.prototype = {
|
||||
/**
|
||||
* Gets the key code associated to the event.
|
||||
*
|
||||
* alert( event.getKey() ); // '65' if 'a' has been pressed
|
||||
*
|
||||
* @returns {Number} The key code.
|
||||
*/
|
||||
getKey: function() {
|
||||
return this.$.keyCode || this.$.which;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a number represeting the combination of the keys pressed during the
|
||||
* event. It is the sum with the current key code and the {@link CKEDITOR#CTRL},
|
||||
* {@link CKEDITOR#SHIFT} and {@link CKEDITOR#ALT} constants.
|
||||
*
|
||||
* alert( event.getKeystroke() == 65 ); // 'a' key
|
||||
* alert( event.getKeystroke() == CKEDITOR.CTRL + 65 ); // CTRL + 'a' key
|
||||
* alert( event.getKeystroke() == CKEDITOR.CTRL + CKEDITOR.SHIFT + 65 ); // CTRL + SHIFT + 'a' key
|
||||
*
|
||||
* @returns {Number} The number representing the keys combination.
|
||||
*/
|
||||
getKeystroke: function() {
|
||||
var keystroke = this.getKey();
|
||||
|
||||
if ( this.$.ctrlKey || this.$.metaKey )
|
||||
keystroke += CKEDITOR.CTRL;
|
||||
|
||||
if ( this.$.shiftKey )
|
||||
keystroke += CKEDITOR.SHIFT;
|
||||
|
||||
if ( this.$.altKey )
|
||||
keystroke += CKEDITOR.ALT;
|
||||
|
||||
return keystroke;
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevents the original behavior of the event to happen. It can optionally
|
||||
* stop propagating the event in the event chain.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'myElement' );
|
||||
* element.on( 'click', function( ev ) {
|
||||
* // The DOM event object is passed by the 'data' property.
|
||||
* var domEvent = ev.data;
|
||||
* // Prevent the click to chave any effect in the element.
|
||||
* domEvent.preventDefault();
|
||||
* } );
|
||||
*
|
||||
* @param {Boolean} [stopPropagation=false] Stop propagating this event in the
|
||||
* event chain.
|
||||
*/
|
||||
preventDefault: function( stopPropagation ) {
|
||||
var $ = this.$;
|
||||
if ( $.preventDefault )
|
||||
$.preventDefault();
|
||||
else
|
||||
$.returnValue = false;
|
||||
|
||||
if ( stopPropagation )
|
||||
this.stopPropagation();
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops this event propagation in the event chain.
|
||||
*/
|
||||
stopPropagation: function() {
|
||||
var $ = this.$;
|
||||
if ( $.stopPropagation )
|
||||
$.stopPropagation();
|
||||
else
|
||||
$.cancelBubble = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the DOM node where the event was targeted to.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'myElement' );
|
||||
* element.on( 'click', function( ev ) {
|
||||
* // The DOM event object is passed by the 'data' property.
|
||||
* var domEvent = ev.data;
|
||||
* // Add a CSS class to the event target.
|
||||
* domEvent.getTarget().addClass( 'clicked' );
|
||||
* } );
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The target DOM node.
|
||||
*/
|
||||
getTarget: function() {
|
||||
var rawNode = this.$.target || this.$.srcElement;
|
||||
return rawNode ? new CKEDITOR.dom.node( rawNode ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an integer value that indicates the current processing phase of an event.
|
||||
* For browsers that doesn't support event phase, {@link CKEDITOR#EVENT_PHASE_AT_TARGET} is always returned.
|
||||
*
|
||||
* @returns {Number} One of {@link CKEDITOR#EVENT_PHASE_CAPTURING},
|
||||
* {@link CKEDITOR#EVENT_PHASE_AT_TARGET}, or {@link CKEDITOR#EVENT_PHASE_BUBBLING}.
|
||||
*/
|
||||
getPhase: function() {
|
||||
return this.$.eventPhase || 2;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the coordinates of the mouse pointer relative to the top-left
|
||||
* corner of the document, in mouse related event.
|
||||
*
|
||||
* element.on( 'mousemouse', function( ev ) {
|
||||
* var pageOffset = ev.data.getPageOffset();
|
||||
* alert( pageOffset.x ); // page offset X
|
||||
* alert( pageOffset.y ); // page offset Y
|
||||
* } );
|
||||
*
|
||||
* @returns {Object} The object contains the position.
|
||||
* @returns {Number} return.x
|
||||
* @returns {Number} return.y
|
||||
*/
|
||||
getPageOffset: function() {
|
||||
var doc = this.getTarget().getDocument().$;
|
||||
var pageX = this.$.pageX || this.$.clientX + ( doc.documentElement.scrollLeft || doc.body.scrollLeft );
|
||||
var pageY = this.$.pageY || this.$.clientY + ( doc.documentElement.scrollTop || doc.body.scrollTop );
|
||||
return { x: pageX, y: pageY };
|
||||
}
|
||||
};
|
||||
|
||||
// For the followind constants, we need to go over the Unicode boundaries
|
||||
// (0x10FFFF) to avoid collision.
|
||||
|
||||
/**
|
||||
* CTRL key (0x110000).
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0x110000]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.CTRL = 0x110000;
|
||||
|
||||
/**
|
||||
* SHIFT key (0x220000).
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0x220000]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.SHIFT = 0x220000;
|
||||
|
||||
/**
|
||||
* ALT key (0x440000).
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0x440000]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.ALT = 0x440000;
|
||||
|
||||
/**
|
||||
* Capturing phase.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.EVENT_PHASE_CAPTURING = 1;
|
||||
|
||||
/**
|
||||
* Event at target.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.EVENT_PHASE_AT_TARGET = 2;
|
||||
|
||||
/**
|
||||
* Bubbling phase.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=3]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.EVENT_PHASE_BUBBLING = 3;
|
||||
|
||||
/**
|
||||
* Integration with browser's "Go back" and "Go forward" buttons using Native History API.
|
||||
*
|
||||
* @since 4.17.0
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.HISTORY_NATIVE = 1;
|
||||
|
||||
/**
|
||||
* Integration with browser's "Go back" and "Go forward" buttons using hash-based navigation.
|
||||
*
|
||||
* @since 4.17.0
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.HISTORY_HASH = 2;
|
||||
|
||||
/**
|
||||
* Switch off integration with browser's "Go back" and "Go forward" buttons.
|
||||
*
|
||||
* @since 4.17.0
|
||||
* @readonly
|
||||
* @property {Number} [=0]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.HISTORY_OFF = 0;
|
||||
565
Admin/plugins/ckeditor/core/dom/iterator.js
Normal file
565
Admin/plugins/ckeditor/core/dom/iterator.js
Normal file
@@ -0,0 +1,565 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* File overview: DOM iterator which iterates over list items, lines and paragraphs.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Represents the iterator class. It can be used to iterate
|
||||
* over all elements (or even text nodes in case of {@link #enlargeBr} set to `false`)
|
||||
* which establish "paragraph-like" spaces within the passed range.
|
||||
*
|
||||
* // <h1>[foo</h1><p>bar]</p>
|
||||
* var iterator = range.createIterator();
|
||||
* iterator.getNextParagraph(); // h1 element
|
||||
* iterator.getNextParagraph(); // p element
|
||||
*
|
||||
* // <ul><li>[foo</li><li>bar]</li>
|
||||
* // With enforceRealBlocks set to false the iterator will return two list item elements.
|
||||
* // With enforceRealBlocks set to true the iterator will return two paragraphs and the DOM will be changed to:
|
||||
* // <ul><li><p>foo</p></li><li><p>bar</p></li>
|
||||
*
|
||||
* @class CKEDITOR.dom.iterator
|
||||
* @constructor Creates an iterator class instance.
|
||||
* @param {CKEDITOR.dom.range} range
|
||||
*/
|
||||
function iterator( range ) {
|
||||
if ( arguments.length < 1 )
|
||||
return;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.range}
|
||||
*/
|
||||
this.range = range;
|
||||
|
||||
/**
|
||||
* @property {Boolean} [forceBrBreak=false]
|
||||
*/
|
||||
this.forceBrBreak = 0;
|
||||
|
||||
// (https://dev.ckeditor.com/ticket/3730).
|
||||
/**
|
||||
* Whether to include `<br>` elements in the enlarged range. Should be
|
||||
* set to `false` when using the iterator in the {@link CKEDITOR#ENTER_BR} mode.
|
||||
*
|
||||
* @property {Boolean} [enlargeBr=true]
|
||||
*/
|
||||
this.enlargeBr = 1;
|
||||
|
||||
/**
|
||||
* Whether the iterator should create a transformable block
|
||||
* if the current one contains text and cannot be transformed.
|
||||
* For example new blocks will be established in elements like
|
||||
* `<li>` or `<td>`.
|
||||
*
|
||||
* @property {Boolean} [enforceRealBlocks=false]
|
||||
*/
|
||||
this.enforceRealBlocks = 0;
|
||||
|
||||
this._ || ( this._ = {} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Default iterator's filter. It is set only for nested iterators.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @readonly
|
||||
* @property {CKEDITOR.filter} filter
|
||||
*/
|
||||
|
||||
/**
|
||||
* Iterator's active filter. It is set by the {@link #getNextParagraph} method
|
||||
* when it enters a nested editable.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @readonly
|
||||
* @property {CKEDITOR.filter} activeFilter
|
||||
*/
|
||||
|
||||
var beginWhitespaceRegex = /^[\r\n\t ]+$/,
|
||||
// Ignore bookmark nodes.(https://dev.ckeditor.com/ticket/3783)
|
||||
bookmarkGuard = CKEDITOR.dom.walker.bookmark( false, true ),
|
||||
whitespacesGuard = CKEDITOR.dom.walker.whitespaces( true ),
|
||||
skipGuard = function( node ) {
|
||||
return bookmarkGuard( node ) && whitespacesGuard( node );
|
||||
},
|
||||
listItemNames = { dd: 1, dt: 1, li: 1 };
|
||||
|
||||
iterator.prototype = {
|
||||
/**
|
||||
* Returns the next paragraph-like element or `null` if the end of a range is reached.
|
||||
*
|
||||
* @param {String} [blockTag='p'] Name of a block element which will be established by
|
||||
* the iterator in block-less elements (see {@link #enforceRealBlocks}).
|
||||
*/
|
||||
getNextParagraph: function( blockTag ) {
|
||||
// The block element to be returned.
|
||||
var block;
|
||||
|
||||
// The range object used to identify the paragraph contents.
|
||||
var range;
|
||||
|
||||
// Indicats that the current element in the loop is the last one.
|
||||
var isLast;
|
||||
|
||||
// Instructs to cleanup remaining BRs.
|
||||
var removePreviousBr, removeLastBr;
|
||||
|
||||
blockTag = blockTag || 'p';
|
||||
|
||||
// We're iterating over nested editable.
|
||||
if ( this._.nestedEditable ) {
|
||||
// Get next block from nested iterator and returns it if was found.
|
||||
block = this._.nestedEditable.iterator.getNextParagraph( blockTag );
|
||||
if ( block ) {
|
||||
// Inherit activeFilter from the nested iterator.
|
||||
this.activeFilter = this._.nestedEditable.iterator.activeFilter;
|
||||
return block;
|
||||
}
|
||||
|
||||
// No block in nested iterator means that we reached the end of the nested editable.
|
||||
// Reset the active filter to the default filter (or undefined if this iterator didn't have it).
|
||||
this.activeFilter = this.filter;
|
||||
|
||||
// Try to find next nested editable or get back to parent (this) iterator.
|
||||
if ( startNestedEditableIterator( this, blockTag, this._.nestedEditable.container, this._.nestedEditable.remaining ) ) {
|
||||
// Inherit activeFilter from the nested iterator.
|
||||
this.activeFilter = this._.nestedEditable.iterator.activeFilter;
|
||||
return this._.nestedEditable.iterator.getNextParagraph( blockTag );
|
||||
} else {
|
||||
this._.nestedEditable = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Block-less range should be checked first.
|
||||
if ( !this.range.root.getDtd()[ blockTag ] )
|
||||
return null;
|
||||
|
||||
// This is the first iteration. Let's initialize it.
|
||||
if ( !this._.started )
|
||||
range = startIterator.call( this );
|
||||
|
||||
var currentNode = this._.nextNode,
|
||||
lastNode = this._.lastNode;
|
||||
|
||||
this._.nextNode = null;
|
||||
while ( currentNode ) {
|
||||
// closeRange indicates that a paragraph boundary has been found,
|
||||
// so the range can be closed.
|
||||
var closeRange = 0,
|
||||
parentPre = currentNode.hasAscendant( 'pre' );
|
||||
|
||||
// includeNode indicates that the current node is good to be part
|
||||
// of the range. By default, any non-element node is ok for it.
|
||||
var includeNode = ( currentNode.type != CKEDITOR.NODE_ELEMENT ),
|
||||
continueFromSibling = 0;
|
||||
|
||||
// If it is an element node, let's check if it can be part of the range.
|
||||
if ( !includeNode ) {
|
||||
var nodeName = currentNode.getName();
|
||||
|
||||
// Non-editable block was found - return it and move to processing
|
||||
// its nested editables if they exist.
|
||||
if ( CKEDITOR.dtd.$block[ nodeName ] && currentNode.getAttribute( 'contenteditable' ) == 'false' ) {
|
||||
block = currentNode;
|
||||
|
||||
// Setup iterator for first of nested editables.
|
||||
// If there's no editable, then algorithm will move to next element after current block.
|
||||
startNestedEditableIterator( this, blockTag, block );
|
||||
|
||||
// Gets us straight to the end of getParagraph() because block variable is set.
|
||||
break;
|
||||
} else if ( currentNode.isBlockBoundary( this.forceBrBreak && !parentPre && { br: 1 } ) ) {
|
||||
// <br> boundaries must be part of the range. It will
|
||||
// happen only if ForceBrBreak.
|
||||
if ( nodeName == 'br' )
|
||||
includeNode = 1;
|
||||
else if ( !range && !currentNode.getChildCount() && nodeName != 'hr' ) {
|
||||
// If we have found an empty block, and haven't started
|
||||
// the range yet, it means we must return this block.
|
||||
block = currentNode;
|
||||
isLast = currentNode.equals( lastNode );
|
||||
break;
|
||||
}
|
||||
|
||||
// The range must finish right before the boundary,
|
||||
// including possibly skipped empty spaces. (https://dev.ckeditor.com/ticket/1603)
|
||||
if ( range ) {
|
||||
range.setEndAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
|
||||
|
||||
// The found boundary must be set as the next one at this
|
||||
// point. (https://dev.ckeditor.com/ticket/1717)
|
||||
if ( nodeName != 'br' ) {
|
||||
this._.nextNode = currentNode;
|
||||
}
|
||||
}
|
||||
|
||||
closeRange = 1;
|
||||
} else {
|
||||
// If we have child nodes, let's check them.
|
||||
if ( currentNode.getFirst() ) {
|
||||
// If we don't have a range yet, let's start it.
|
||||
if ( !range ) {
|
||||
range = this.range.clone();
|
||||
range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
|
||||
}
|
||||
|
||||
currentNode = currentNode.getFirst();
|
||||
continue;
|
||||
}
|
||||
includeNode = 1;
|
||||
}
|
||||
} else if ( currentNode.type == CKEDITOR.NODE_TEXT ) {
|
||||
// Ignore normal whitespaces (i.e. not including or
|
||||
// other unicode whitespaces) before/after a block node.
|
||||
if ( beginWhitespaceRegex.test( currentNode.getText() ) )
|
||||
includeNode = 0;
|
||||
}
|
||||
|
||||
// The current node is good to be part of the range and we are
|
||||
// starting a new range, initialize it first.
|
||||
if ( includeNode && !range ) {
|
||||
range = this.range.clone();
|
||||
range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
|
||||
}
|
||||
|
||||
// The last node has been found.
|
||||
isLast = ( ( !closeRange || includeNode ) && currentNode.equals( lastNode ) );
|
||||
|
||||
// If we are in an element boundary, let's check if it is time
|
||||
// to close the range, otherwise we include the parent within it.
|
||||
if ( range && !closeRange ) {
|
||||
while ( !currentNode.getNext( skipGuard ) && !isLast ) {
|
||||
var parentNode = currentNode.getParent();
|
||||
|
||||
if ( parentNode.isBlockBoundary( this.forceBrBreak && !parentPre && { br: 1 } ) ) {
|
||||
closeRange = 1;
|
||||
includeNode = 0;
|
||||
isLast = isLast || ( parentNode.equals( lastNode ) );
|
||||
// Make sure range includes bookmarks at the end of the block. (https://dev.ckeditor.com/ticket/7359)
|
||||
range.setEndAt( parentNode, CKEDITOR.POSITION_BEFORE_END );
|
||||
break;
|
||||
}
|
||||
|
||||
currentNode = parentNode;
|
||||
includeNode = 1;
|
||||
isLast = ( currentNode.equals( lastNode ) );
|
||||
continueFromSibling = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now finally include the node.
|
||||
if ( includeNode )
|
||||
range.setEndAt( currentNode, CKEDITOR.POSITION_AFTER_END );
|
||||
|
||||
currentNode = this._getNextSourceNode( currentNode, continueFromSibling, lastNode );
|
||||
isLast = !currentNode;
|
||||
|
||||
// We have found a block boundary. Let's close the range and move out of the
|
||||
// loop.
|
||||
if ( isLast || ( closeRange && range ) )
|
||||
break;
|
||||
}
|
||||
|
||||
// Now, based on the processed range, look for (or create) the block to be returned.
|
||||
if ( !block ) {
|
||||
// If no range has been found, this is the end.
|
||||
if ( !range ) {
|
||||
this._.docEndMarker && this._.docEndMarker.remove();
|
||||
this._.nextNode = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
var startPath = new CKEDITOR.dom.elementPath( range.startContainer, range.root );
|
||||
var startBlockLimit = startPath.blockLimit,
|
||||
checkLimits = { div: 1, th: 1, td: 1 };
|
||||
block = startPath.block;
|
||||
|
||||
if ( !block && startBlockLimit && !this.enforceRealBlocks && checkLimits[ startBlockLimit.getName() ] &&
|
||||
range.checkStartOfBlock() && range.checkEndOfBlock() && !startBlockLimit.equals( range.root ) ) {
|
||||
block = startBlockLimit;
|
||||
} else if ( !block || ( this.enforceRealBlocks && block.is( listItemNames ) ) ) {
|
||||
// Create the fixed block.
|
||||
block = this.range.document.createElement( blockTag );
|
||||
|
||||
// Move the contents of the temporary range to the fixed block.
|
||||
range.extractContents().appendTo( block );
|
||||
block.trim();
|
||||
|
||||
// Insert the fixed block into the DOM.
|
||||
range.insertNode( block );
|
||||
|
||||
removePreviousBr = removeLastBr = true;
|
||||
} else if ( block.getName() != 'li' ) {
|
||||
// If the range doesn't includes the entire contents of the
|
||||
// block, we must split it, isolating the range in a dedicated
|
||||
// block.
|
||||
if ( !range.checkStartOfBlock() || !range.checkEndOfBlock() ) {
|
||||
// The resulting block will be a clone of the current one.
|
||||
block = block.clone( false );
|
||||
|
||||
// Extract the range contents, moving it to the new block.
|
||||
range.extractContents().appendTo( block );
|
||||
block.trim();
|
||||
|
||||
// Split the block. At this point, the range will be in the
|
||||
// right position for our intents.
|
||||
var splitInfo = range.splitBlock();
|
||||
|
||||
removePreviousBr = !splitInfo.wasStartOfBlock;
|
||||
removeLastBr = !splitInfo.wasEndOfBlock;
|
||||
|
||||
// Insert the new block into the DOM.
|
||||
range.insertNode( block );
|
||||
}
|
||||
} else if ( !isLast ) {
|
||||
// LIs are returned as is, with all their children (due to the
|
||||
// nested lists). But, the next node is the node right after
|
||||
// the current range, which could be an <li> child (nested
|
||||
// lists) or the next sibling <li>.
|
||||
|
||||
this._.nextNode = ( block.equals( lastNode ) ? null : this._getNextSourceNode( range.getBoundaryNodes().endNode, 1, lastNode ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( removePreviousBr ) {
|
||||
var previousSibling = block.getPrevious();
|
||||
if ( previousSibling && previousSibling.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( previousSibling.getName() == 'br' )
|
||||
previousSibling.remove();
|
||||
else if ( previousSibling.getLast() && previousSibling.getLast().$.nodeName.toLowerCase() == 'br' )
|
||||
previousSibling.getLast().remove();
|
||||
}
|
||||
}
|
||||
|
||||
if ( removeLastBr ) {
|
||||
var lastChild = block.getLast();
|
||||
if ( lastChild && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.getName() == 'br' ) {
|
||||
// Remove br filler on browser which do not need it.
|
||||
if ( !CKEDITOR.env.needsBrFiller || lastChild.getPrevious( bookmarkGuard ) || lastChild.getNext( bookmarkGuard ) )
|
||||
lastChild.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Get a reference for the next element. This is important because the
|
||||
// above block can be removed or changed, so we can rely on it for the
|
||||
// next interation.
|
||||
if ( !this._.nextNode ) {
|
||||
this._.nextNode = ( isLast || block.equals( lastNode ) || !lastNode ) ? null : this._getNextSourceNode( block, 1, lastNode );
|
||||
}
|
||||
|
||||
return block;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the next element to check or `null` when the `lastNode` or the
|
||||
* {@link #range}'s {@link CKEDITOR.dom.range#root root} is reached. Bookmarks are skipped.
|
||||
*
|
||||
* @since 4.4.6
|
||||
* @private
|
||||
* @param {CKEDITOR.dom.node} node
|
||||
* @param {Boolean} startFromSibling
|
||||
* @param {CKEDITOR.dom.node} lastNode
|
||||
* @returns {CKEDITOR.dom.node}
|
||||
*/
|
||||
_getNextSourceNode: function( node, startFromSibling, lastNode ) {
|
||||
var rootNode = this.range.root,
|
||||
next;
|
||||
|
||||
// Here we are checking in guard function whether current element
|
||||
// reach lastNode(default behaviour) and root node to prevent against
|
||||
// getting out of editor instance root DOM object.
|
||||
// https://dev.ckeditor.com/ticket/12484
|
||||
function guardFunction( node ) {
|
||||
return !( node.equals( lastNode ) || node.equals( rootNode ) );
|
||||
}
|
||||
|
||||
next = node.getNextSourceNode( startFromSibling, null, guardFunction );
|
||||
while ( !bookmarkGuard( next ) ) {
|
||||
next = next.getNextSourceNode( startFromSibling, null, guardFunction );
|
||||
}
|
||||
return next;
|
||||
}
|
||||
};
|
||||
|
||||
// @context CKEDITOR.dom.iterator
|
||||
// @returns Collapsed range which will be reused when during furter processing.
|
||||
function startIterator() {
|
||||
var range = this.range.clone(),
|
||||
// Indicate at least one of the range boundaries is inside a preformat block.
|
||||
touchPre,
|
||||
|
||||
// (https://dev.ckeditor.com/ticket/12178)
|
||||
// Remember if following situation takes place:
|
||||
// * startAtInnerBoundary: <p>foo[</p>...
|
||||
// * endAtInnerBoundary: ...<p>]bar</p>
|
||||
// Because information about line break will be lost when shrinking range.
|
||||
// Note that we test only if path block exist, because we must properly shrink
|
||||
// range containing table and/or table cells.
|
||||
// Note: When range is collapsed there's no way it can be shrinked.
|
||||
// By checking if range is collapsed we also prevent https://dev.ckeditor.com/ticket/12308.
|
||||
startPath = range.startPath(),
|
||||
endPath = range.endPath(),
|
||||
startAtInnerBoundary = !range.collapsed && rangeAtInnerBlockBoundary( range, startPath.block ),
|
||||
endAtInnerBoundary = !range.collapsed && rangeAtInnerBlockBoundary( range, endPath.block, 1 );
|
||||
|
||||
// Shrink the range to exclude harmful "noises" (https://dev.ckeditor.com/ticket/4087, https://dev.ckeditor.com/ticket/4450, https://dev.ckeditor.com/ticket/5435).
|
||||
range.shrink( CKEDITOR.SHRINK_ELEMENT, true );
|
||||
|
||||
if ( startAtInnerBoundary )
|
||||
range.setStartAt( startPath.block, CKEDITOR.POSITION_BEFORE_END );
|
||||
if ( endAtInnerBoundary )
|
||||
range.setEndAt( endPath.block, CKEDITOR.POSITION_AFTER_START );
|
||||
|
||||
touchPre = range.endContainer.hasAscendant( 'pre', true ) || range.startContainer.hasAscendant( 'pre', true );
|
||||
|
||||
range.enlarge( this.forceBrBreak && !touchPre || !this.enlargeBr ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
|
||||
|
||||
if ( !range.collapsed ) {
|
||||
var walker = new CKEDITOR.dom.walker( range.clone() ),
|
||||
ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );
|
||||
// Avoid anchor inside bookmark inner text.
|
||||
walker.evaluator = ignoreBookmarkTextEvaluator;
|
||||
this._.nextNode = walker.next();
|
||||
// TODO: It's better to have walker.reset() used here.
|
||||
walker = new CKEDITOR.dom.walker( range.clone() );
|
||||
walker.evaluator = ignoreBookmarkTextEvaluator;
|
||||
var lastNode = walker.previous();
|
||||
this._.lastNode = lastNode.getNextSourceNode( true, null, range.root );
|
||||
|
||||
// We may have an empty text node at the end of block due to [3770].
|
||||
// If that node is the lastNode, it would cause our logic to leak to the
|
||||
// next block.(https://dev.ckeditor.com/ticket/3887)
|
||||
if ( this._.lastNode && this._.lastNode.type == CKEDITOR.NODE_TEXT && !CKEDITOR.tools.trim( this._.lastNode.getText() ) && this._.lastNode.getParent().isBlockBoundary() ) {
|
||||
var testRange = this.range.clone();
|
||||
testRange.moveToPosition( this._.lastNode, CKEDITOR.POSITION_AFTER_END );
|
||||
if ( testRange.checkEndOfBlock() ) {
|
||||
var path = new CKEDITOR.dom.elementPath( testRange.endContainer, testRange.root ),
|
||||
lastBlock = path.block || path.blockLimit;
|
||||
this._.lastNode = lastBlock.getNextSourceNode( true );
|
||||
}
|
||||
}
|
||||
|
||||
// The end of document or range.root was reached, so we need a marker node inside.
|
||||
if ( !this._.lastNode || !range.root.contains( this._.lastNode ) ) {
|
||||
this._.lastNode = this._.docEndMarker = range.document.createText( '' );
|
||||
this._.lastNode.insertAfter( lastNode );
|
||||
}
|
||||
|
||||
// Let's reuse this variable.
|
||||
range = null;
|
||||
}
|
||||
|
||||
this._.started = 1;
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
// Does a nested editables lookup inside editablesContainer.
|
||||
// If remainingEditables is set will lookup inside this array.
|
||||
// @param {CKEDITOR.dom.element} editablesContainer
|
||||
// @param {CKEDITOR.dom.element[]} [remainingEditables]
|
||||
function getNestedEditableIn( editablesContainer, remainingEditables ) {
|
||||
if ( remainingEditables == null )
|
||||
remainingEditables = findNestedEditables( editablesContainer );
|
||||
|
||||
var editable;
|
||||
|
||||
while ( ( editable = remainingEditables.shift() ) ) {
|
||||
if ( isIterableEditable( editable ) )
|
||||
return { element: editable, remaining: remainingEditables };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Checkes whether we can iterate over this editable.
|
||||
function isIterableEditable( editable ) {
|
||||
// Reject blockless editables.
|
||||
return editable.getDtd().p;
|
||||
}
|
||||
|
||||
// Finds nested editables within container. Does not return
|
||||
// editables nested in another editable (twice).
|
||||
function findNestedEditables( container ) {
|
||||
var editables = [];
|
||||
|
||||
container.forEach( function( element ) {
|
||||
if ( element.getAttribute( 'contenteditable' ) == 'true' ) {
|
||||
editables.push( element );
|
||||
return false; // Skip children.
|
||||
}
|
||||
}, CKEDITOR.NODE_ELEMENT, true );
|
||||
|
||||
return editables;
|
||||
}
|
||||
|
||||
// Looks for a first nested editable after previousEditable (if passed) and creates
|
||||
// nested iterator for it.
|
||||
function startNestedEditableIterator( parentIterator, blockTag, editablesContainer, remainingEditables ) {
|
||||
var editable = getNestedEditableIn( editablesContainer, remainingEditables );
|
||||
|
||||
if ( !editable )
|
||||
return 0;
|
||||
|
||||
var filter = CKEDITOR.filter.instances[ editable.element.data( 'cke-filter' ) ];
|
||||
|
||||
// If current editable has a filter and this filter does not allow for block tag,
|
||||
// search for next nested editable in remaining ones.
|
||||
if ( filter && !filter.check( blockTag ) )
|
||||
return startNestedEditableIterator( parentIterator, blockTag, editablesContainer, editable.remaining );
|
||||
|
||||
var range = new CKEDITOR.dom.range( editable.element );
|
||||
range.selectNodeContents( editable.element );
|
||||
|
||||
var iterator = range.createIterator();
|
||||
// This setting actually does not change anything in this case,
|
||||
// because entire range contents is selected, so there're no <br>s to be included.
|
||||
// But it seems right to copy it too.
|
||||
iterator.enlargeBr = parentIterator.enlargeBr;
|
||||
// Inherit configuration from parent iterator.
|
||||
iterator.enforceRealBlocks = parentIterator.enforceRealBlocks;
|
||||
// Set the activeFilter (which can be overriden when this iteator will start nested iterator)
|
||||
// and the default filter, which will make it possible to reset to
|
||||
// current iterator's activeFilter after leaving nested editable.
|
||||
iterator.activeFilter = iterator.filter = filter;
|
||||
|
||||
parentIterator._.nestedEditable = {
|
||||
element: editable.element,
|
||||
container: editablesContainer,
|
||||
remaining: editable.remaining,
|
||||
iterator: iterator
|
||||
};
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Checks whether range starts or ends at inner block boundary.
|
||||
// See usage comments to learn more.
|
||||
function rangeAtInnerBlockBoundary( range, block, checkEnd ) {
|
||||
if ( !block )
|
||||
return false;
|
||||
|
||||
var testRange = range.clone();
|
||||
testRange.collapse( !checkEnd );
|
||||
return testRange.checkBoundaryOfElement( block, checkEnd ? CKEDITOR.START : CKEDITOR.END );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link CKEDITOR.dom.iterator} instance for this range.
|
||||
*
|
||||
* @member CKEDITOR.dom.range
|
||||
* @returns {CKEDITOR.dom.iterator}
|
||||
*/
|
||||
CKEDITOR.dom.range.prototype.createIterator = function() {
|
||||
return new iterator( this );
|
||||
};
|
||||
} )();
|
||||
898
Admin/plugins/ckeditor/core/dom/node.js
Normal file
898
Admin/plugins/ckeditor/core/dom/node.js
Normal file
@@ -0,0 +1,898 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.node} class which is the base
|
||||
* class for classes that represent DOM nodes.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for classes representing DOM nodes. This constructor may return
|
||||
* an instance of a class that inherits from this class, like
|
||||
* {@link CKEDITOR.dom.element} or {@link CKEDITOR.dom.text}.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.domObject
|
||||
* @constructor Creates a node class instance.
|
||||
* @param {Object} domNode A native DOM node.
|
||||
* @see CKEDITOR.dom.element
|
||||
* @see CKEDITOR.dom.text
|
||||
*/
|
||||
CKEDITOR.dom.node = function( domNode ) {
|
||||
if ( domNode ) {
|
||||
var type =
|
||||
domNode.nodeType == CKEDITOR.NODE_DOCUMENT ? 'document' :
|
||||
domNode.nodeType == CKEDITOR.NODE_ELEMENT ? 'element' :
|
||||
domNode.nodeType == CKEDITOR.NODE_TEXT ? 'text' :
|
||||
domNode.nodeType == CKEDITOR.NODE_COMMENT ? 'comment' :
|
||||
domNode.nodeType == CKEDITOR.NODE_DOCUMENT_FRAGMENT ? 'documentFragment' :
|
||||
'domObject'; // Call the base constructor otherwise.
|
||||
|
||||
return new CKEDITOR.dom[ type ]( domNode );
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
CKEDITOR.dom.node.prototype = new CKEDITOR.dom.domObject();
|
||||
|
||||
/**
|
||||
* Element node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_ELEMENT = 1;
|
||||
|
||||
/**
|
||||
* Document node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=9]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_DOCUMENT = 9;
|
||||
|
||||
/**
|
||||
* Text node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=3]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_TEXT = 3;
|
||||
|
||||
/**
|
||||
* Comment node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=8]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_COMMENT = 8;
|
||||
|
||||
/**
|
||||
* Document fragment node type.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=11]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.NODE_DOCUMENT_FRAGMENT = 11;
|
||||
|
||||
/**
|
||||
* Indicates that positions of both nodes are identical (this is the same node). See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=0]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_IDENTICAL = 0;
|
||||
|
||||
/**
|
||||
* Indicates that nodes are in different (detached) trees. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_DISCONNECTED = 1;
|
||||
|
||||
/**
|
||||
* Indicates that the context node follows the other node. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_FOLLOWING = 2;
|
||||
|
||||
/**
|
||||
* Indicates that the context node precedes the other node. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=4]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_PRECEDING = 4;
|
||||
|
||||
/**
|
||||
* Indicates that the context node is a descendant of the other node. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=8]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_IS_CONTAINED = 8;
|
||||
|
||||
/**
|
||||
* Indicates that the context node contains the other node. See {@link CKEDITOR.dom.node#getPosition}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=16]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.POSITION_CONTAINS = 16;
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.node.prototype, {
|
||||
/**
|
||||
* Makes this node a child of another element.
|
||||
*
|
||||
* var p = new CKEDITOR.dom.element( 'p' );
|
||||
* var strong = new CKEDITOR.dom.element( 'strong' );
|
||||
* strong.appendTo( p );
|
||||
*
|
||||
* // Result: '<p><strong></strong></p>'.
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} element The target element to which this node will be appended.
|
||||
* @returns {CKEDITOR.dom.element} The target element.
|
||||
*/
|
||||
appendTo: function( element, toStart ) {
|
||||
element.append( this, toStart );
|
||||
return element;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clones this node.
|
||||
*
|
||||
* **Note**: Values set by {#setCustomData} will not be available in the clone.
|
||||
*
|
||||
* @param {Boolean} [includeChildren=false] If `true` then all node's
|
||||
* children will be cloned recursively.
|
||||
* @param {Boolean} [cloneId=false] Whether ID attributes should be cloned, too.
|
||||
* @returns {CKEDITOR.dom.node} Clone of this node.
|
||||
*/
|
||||
clone: function( includeChildren, cloneId ) {
|
||||
var $clone = this.$.cloneNode( includeChildren );
|
||||
|
||||
// The "id" attribute should never be cloned to avoid duplication.
|
||||
removeIds( $clone );
|
||||
|
||||
var node = new CKEDITOR.dom.node( $clone );
|
||||
|
||||
// On IE8 we need to fixed HTML5 node name, see details below.
|
||||
if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 &&
|
||||
( this.type == CKEDITOR.NODE_ELEMENT || this.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) ) {
|
||||
renameNodes( node );
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
function removeIds( node ) {
|
||||
// Reset data-cke-expando only when has been cloned (IE and only for some types of objects).
|
||||
if ( node[ 'data-cke-expando' ] )
|
||||
node[ 'data-cke-expando' ] = false;
|
||||
|
||||
if ( node.nodeType != CKEDITOR.NODE_ELEMENT && node.nodeType != CKEDITOR.NODE_DOCUMENT_FRAGMENT )
|
||||
return;
|
||||
|
||||
if ( !cloneId && node.nodeType == CKEDITOR.NODE_ELEMENT )
|
||||
node.removeAttribute( 'id', false );
|
||||
|
||||
if ( includeChildren ) {
|
||||
var childs = node.childNodes;
|
||||
for ( var i = 0; i < childs.length; i++ )
|
||||
removeIds( childs[ i ] );
|
||||
}
|
||||
}
|
||||
|
||||
// IE8 rename HTML5 nodes by adding `:` at the begging of the tag name when the node is cloned,
|
||||
// so `<figure>` will be `<:figure>` after 'cloneNode'. We need to fix it (https://dev.ckeditor.com/ticket/13101).
|
||||
function renameNodes( node ) {
|
||||
if ( node.type != CKEDITOR.NODE_ELEMENT && node.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT )
|
||||
return;
|
||||
|
||||
if ( node.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT ) {
|
||||
var name = node.getName();
|
||||
if ( name[ 0 ] == ':' ) {
|
||||
node.renameNode( name.substring( 1 ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( includeChildren ) {
|
||||
for ( var i = 0; i < node.getChildCount(); i++ )
|
||||
renameNodes( node.getChild( i ) );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the node is preceded by any sibling.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasPrevious: function() {
|
||||
return !!this.$.previousSibling;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the node is succeeded by any sibling.
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasNext: function() {
|
||||
return !!this.$.nextSibling;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts this element after a node.
|
||||
*
|
||||
* var em = new CKEDITOR.dom.element( 'em' );
|
||||
* var strong = new CKEDITOR.dom.element( 'strong' );
|
||||
* strong.insertAfter( em );
|
||||
*
|
||||
* // Result: '<em></em><strong></strong>'
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} node The node that will precede this element.
|
||||
* @returns {CKEDITOR.dom.node} The node preceding this one after insertion.
|
||||
*/
|
||||
insertAfter: function( node ) {
|
||||
node.$.parentNode.insertBefore( this.$, node.$.nextSibling );
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts this element before a node.
|
||||
*
|
||||
* var em = new CKEDITOR.dom.element( 'em' );
|
||||
* var strong = new CKEDITOR.dom.element( 'strong' );
|
||||
* strong.insertBefore( em );
|
||||
*
|
||||
* // result: '<strong></strong><em></em>'
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} node The node that will succeed this element.
|
||||
* @returns {CKEDITOR.dom.node} The node being inserted.
|
||||
*/
|
||||
insertBefore: function( node ) {
|
||||
node.$.parentNode.insertBefore( this.$, node.$ );
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts a node before this node.
|
||||
*
|
||||
* var em = new CKEDITOR.dom.element( 'em' );
|
||||
* var strong = new CKEDITOR.dom.element( 'strong' );
|
||||
* strong.insertBeforeMe( em );
|
||||
*
|
||||
* // result: '<em></em><strong></strong>'
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} node The node that will preceed this element.
|
||||
* @returns {CKEDITOR.dom.node} The node being inserted.
|
||||
*/
|
||||
insertBeforeMe: function( node ) {
|
||||
this.$.parentNode.insertBefore( node.$, this.$ );
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves a uniquely identifiable tree address for this node.
|
||||
* The tree address returned is an array of integers, with each integer
|
||||
* indicating a child index of a DOM node, starting from
|
||||
* `document.documentElement`.
|
||||
*
|
||||
* For example, assuming `<body>` is the second child
|
||||
* of `<html>` (`<head>` being the first),
|
||||
* and we would like to address the third child under the
|
||||
* fourth child of `<body>`, the tree address returned would be:
|
||||
* `[1, 3, 2]`.
|
||||
*
|
||||
* The tree address cannot be used for finding back the DOM tree node once
|
||||
* the DOM tree structure has been modified.
|
||||
*
|
||||
* @param {Boolean} [normalized=false] See {@link #getIndex}.
|
||||
* @returns {Array} The address.
|
||||
*/
|
||||
getAddress: function( normalized ) {
|
||||
var address = [];
|
||||
var $documentElement = this.getDocument().$.documentElement;
|
||||
var node = this;
|
||||
|
||||
while ( node && node != $documentElement ) {
|
||||
var parentNode = node.getParent();
|
||||
|
||||
if ( parentNode ) {
|
||||
// Get the node index. For performance, call getIndex
|
||||
// directly, instead of creating a new node object.
|
||||
address.unshift( this.getIndex.call( node, normalized ) );
|
||||
}
|
||||
|
||||
node = parentNode;
|
||||
}
|
||||
|
||||
return address;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the document containing this element.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'example' );
|
||||
* alert( element.getDocument().equals( CKEDITOR.document ) ); // true
|
||||
*
|
||||
* @returns {CKEDITOR.dom.document} The document.
|
||||
*/
|
||||
getDocument: function() {
|
||||
return new CKEDITOR.dom.document( this.$.ownerDocument || this.$.parentNode.ownerDocument );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the index of a node in an array of its `parent.childNodes`.
|
||||
* Returns `-1` if a node does not have a parent or when the `normalized` argument is set to `true`
|
||||
* and the text node is empty and will be removed during the normalization.
|
||||
*
|
||||
* Let us assume having the following `childNodes` array:
|
||||
*
|
||||
* [ emptyText, element1, text, text, element2, emptyText2 ]
|
||||
*
|
||||
* emptyText.getIndex() // 0
|
||||
* emptyText.getIndex( true ) // -1
|
||||
* element1.getIndex(); // 1
|
||||
* element1.getIndex( true ); // 0
|
||||
* element2.getIndex(); // 4
|
||||
* element2.getIndex( true ); // 2
|
||||
* emptyText2.getIndex(); // 5
|
||||
* emptyText2.getIndex( true ); // -1
|
||||
*
|
||||
* @param {Boolean} normalized When `true`, adjacent text nodes are merged and empty text nodes are removed.
|
||||
* @returns {Number} Index of a node or `-1` if a node does not have a parent or is removed during the normalization.
|
||||
*/
|
||||
getIndex: function( normalized ) {
|
||||
// Attention: getAddress depends on this.$
|
||||
// getIndex is called on a plain object: { $ : node }
|
||||
|
||||
var current = this,
|
||||
index = -1,
|
||||
isNormalizing;
|
||||
|
||||
if ( !this.getParent() )
|
||||
return -1;
|
||||
|
||||
// The idea is - all empty text nodes will be virtually merged into their adjacent text nodes.
|
||||
// If an empty text node does not have an adjacent non-empty text node we can return -1 straight away,
|
||||
// because it and all its sibling text nodes will be merged into an empty text node and then totally ignored.
|
||||
if ( normalized && current.type == CKEDITOR.NODE_TEXT && current.isEmpty() ) {
|
||||
var adjacent = getAdjacentNonEmptyTextNode( current ) || getAdjacentNonEmptyTextNode( current, true );
|
||||
|
||||
if ( !adjacent )
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
// Bypass blank node and adjacent text nodes.
|
||||
if ( normalized && !current.equals( this ) && current.type == CKEDITOR.NODE_TEXT && ( isNormalizing || current.isEmpty() ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
index++;
|
||||
isNormalizing = current.type == CKEDITOR.NODE_TEXT;
|
||||
}
|
||||
while ( ( current = current.getPrevious() ) );
|
||||
|
||||
return index;
|
||||
|
||||
function getAdjacentNonEmptyTextNode( node, lookForward ) {
|
||||
var sibling = lookForward ? node.getNext() : node.getPrevious();
|
||||
|
||||
if ( !sibling || sibling.type != CKEDITOR.NODE_TEXT ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If found a non-empty text node, then return it.
|
||||
// If not, then continue search.
|
||||
return sibling.isEmpty() ? getAdjacentNonEmptyTextNode( sibling, lookForward ) : sibling;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
getNextSourceNode: function( startFromSibling, nodeType, guard ) {
|
||||
// If "guard" is a node, transform it in a function.
|
||||
if ( guard && !guard.call ) {
|
||||
var guardNode = guard;
|
||||
guard = function( node ) {
|
||||
return !node.equals( guardNode );
|
||||
};
|
||||
}
|
||||
|
||||
var node = ( !startFromSibling && this.getFirst && this.getFirst() ),
|
||||
parent;
|
||||
|
||||
// Guarding when we're skipping the current element( no children or 'startFromSibling' ).
|
||||
// send the 'moving out' signal even we don't actually dive into.
|
||||
if ( !node ) {
|
||||
if ( this.type == CKEDITOR.NODE_ELEMENT && guard && guard( this, true ) === false )
|
||||
return null;
|
||||
node = this.getNext();
|
||||
}
|
||||
|
||||
while ( !node && ( parent = ( parent || this ).getParent() ) ) {
|
||||
// The guard check sends the "true" paramenter to indicate that
|
||||
// we are moving "out" of the element.
|
||||
if ( guard && guard( parent, true ) === false )
|
||||
return null;
|
||||
|
||||
node = parent.getNext();
|
||||
}
|
||||
|
||||
if ( !node )
|
||||
return null;
|
||||
|
||||
if ( guard && guard( node ) === false )
|
||||
return null;
|
||||
|
||||
if ( nodeType && nodeType != node.type )
|
||||
return node.getNextSourceNode( false, nodeType, guard );
|
||||
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
getPreviousSourceNode: function( startFromSibling, nodeType, guard ) {
|
||||
if ( guard && !guard.call ) {
|
||||
var guardNode = guard;
|
||||
guard = function( node ) {
|
||||
return !node.equals( guardNode );
|
||||
};
|
||||
}
|
||||
|
||||
var node = ( !startFromSibling && this.getLast && this.getLast() ),
|
||||
parent;
|
||||
|
||||
// Guarding when we're skipping the current element( no children or 'startFromSibling' ).
|
||||
// send the 'moving out' signal even we don't actually dive into.
|
||||
if ( !node ) {
|
||||
if ( this.type == CKEDITOR.NODE_ELEMENT && guard && guard( this, true ) === false )
|
||||
return null;
|
||||
node = this.getPrevious();
|
||||
}
|
||||
|
||||
while ( !node && ( parent = ( parent || this ).getParent() ) ) {
|
||||
// The guard check sends the "true" paramenter to indicate that
|
||||
// we are moving "out" of the element.
|
||||
if ( guard && guard( parent, true ) === false )
|
||||
return null;
|
||||
|
||||
node = parent.getPrevious();
|
||||
}
|
||||
|
||||
if ( !node )
|
||||
return null;
|
||||
|
||||
if ( guard && guard( node ) === false )
|
||||
return null;
|
||||
|
||||
if ( nodeType && node.type != nodeType )
|
||||
return node.getPreviousSourceNode( false, nodeType, guard );
|
||||
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the node that preceeds this element in its parent's child list.
|
||||
*
|
||||
* var element = CKEDITOR.dom.element.createFromHtml( '<div><i>prev</i><b>Example</b></div>' );
|
||||
* var first = element.getLast().getPrev();
|
||||
* alert( first.getName() ); // 'i'
|
||||
*
|
||||
* @param {Function} [evaluator] Filtering the result node.
|
||||
* @returns {CKEDITOR.dom.node} The previous node or null if not available.
|
||||
*/
|
||||
getPrevious: function( evaluator ) {
|
||||
var previous = this.$,
|
||||
retval;
|
||||
do {
|
||||
previous = previous.previousSibling;
|
||||
|
||||
// Avoid returning the doc type node.
|
||||
// http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-412266927
|
||||
retval = previous && previous.nodeType != 10 && new CKEDITOR.dom.node( previous );
|
||||
}
|
||||
while ( retval && evaluator && !evaluator( retval ) );
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the node that follows this element in its parent's child list.
|
||||
*
|
||||
* var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b><i>next</i></div>' );
|
||||
* var last = element.getFirst().getNext();
|
||||
* alert( last.getName() ); // 'i'
|
||||
*
|
||||
* @param {Function} [evaluator] Filtering the result node.
|
||||
* @returns {CKEDITOR.dom.node} The next node or null if not available.
|
||||
*/
|
||||
getNext: function( evaluator ) {
|
||||
var next = this.$,
|
||||
retval;
|
||||
do {
|
||||
next = next.nextSibling;
|
||||
retval = next && new CKEDITOR.dom.node( next );
|
||||
}
|
||||
while ( retval && evaluator && !evaluator( retval ) );
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the parent element for this node.
|
||||
*
|
||||
* var node = editor.document.getBody().getFirst();
|
||||
* var parent = node.getParent();
|
||||
* alert( parent.getName() ); // 'body'
|
||||
*
|
||||
* @param {Boolean} [allowFragmentParent=false] Consider also parent node that is of
|
||||
* fragment type {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
|
||||
* @returns {CKEDITOR.dom.element} The parent element.
|
||||
*/
|
||||
getParent: function( allowFragmentParent ) {
|
||||
var parent = this.$.parentNode;
|
||||
return ( parent && ( parent.nodeType == CKEDITOR.NODE_ELEMENT || allowFragmentParent && parent.nodeType == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) ) ? new CKEDITOR.dom.node( parent ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an array containing node parents and the node itself. By default nodes are in _descending_ order.
|
||||
*
|
||||
* // Assuming that body has paragraph as the first child.
|
||||
* var node = editor.document.getBody().getFirst();
|
||||
* var parents = node.getParents();
|
||||
* alert( parents[ 0 ].getName() + ',' + parents[ 2 ].getName() ); // 'html,p'
|
||||
*
|
||||
* @param {Boolean} [closerFirst=false] Determines the order of returned nodes.
|
||||
* @returns {Array} Returns an array of {@link CKEDITOR.dom.node}.
|
||||
*/
|
||||
getParents: function( closerFirst ) {
|
||||
var node = this;
|
||||
var parents = [];
|
||||
|
||||
do {
|
||||
parents[ closerFirst ? 'push' : 'unshift' ]( node );
|
||||
}
|
||||
while ( ( node = node.getParent() ) );
|
||||
|
||||
return parents;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
getCommonAncestor: function( node ) {
|
||||
if ( node.equals( this ) )
|
||||
return this;
|
||||
|
||||
if ( node.contains && node.contains( this ) )
|
||||
return node;
|
||||
|
||||
var start = this.contains ? this : this.getParent();
|
||||
|
||||
do {
|
||||
if ( start.contains( node ) ) return start;
|
||||
}
|
||||
while ( ( start = start.getParent() ) );
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines the position relation between this node and the given {@link CKEDITOR.dom.node} in the document.
|
||||
* This node can be preceding ({@link CKEDITOR#POSITION_PRECEDING}) or following ({@link CKEDITOR#POSITION_FOLLOWING})
|
||||
* the given node. This node can also contain ({@link CKEDITOR#POSITION_CONTAINS}) or be contained by
|
||||
* ({@link CKEDITOR#POSITION_IS_CONTAINED}) the given node. The function returns a bitmask of constants
|
||||
* listed above or {@link CKEDITOR#POSITION_IDENTICAL} if the given node is the same as this node.
|
||||
*
|
||||
* @param {CKEDITOR.dom.node} otherNode A node to check relation with.
|
||||
* @returns {Number} Position relation between this node and given node.
|
||||
*/
|
||||
getPosition: function( otherNode ) {
|
||||
var $ = this.$;
|
||||
var $other = otherNode.$;
|
||||
|
||||
if ( $.compareDocumentPosition )
|
||||
return $.compareDocumentPosition( $other );
|
||||
|
||||
// IE and Safari have no support for compareDocumentPosition.
|
||||
|
||||
if ( $ == $other )
|
||||
return CKEDITOR.POSITION_IDENTICAL;
|
||||
|
||||
// Only element nodes support contains and sourceIndex.
|
||||
if ( this.type == CKEDITOR.NODE_ELEMENT && otherNode.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( $.contains ) {
|
||||
if ( $.contains( $other ) )
|
||||
return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING;
|
||||
|
||||
if ( $other.contains( $ ) )
|
||||
return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
|
||||
}
|
||||
|
||||
if ( 'sourceIndex' in $ )
|
||||
return ( $.sourceIndex < 0 || $other.sourceIndex < 0 ) ? CKEDITOR.POSITION_DISCONNECTED : ( $.sourceIndex < $other.sourceIndex ) ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
|
||||
|
||||
}
|
||||
|
||||
// For nodes that don't support compareDocumentPosition, contains
|
||||
// or sourceIndex, their "address" is compared.
|
||||
|
||||
var addressOfThis = this.getAddress(),
|
||||
addressOfOther = otherNode.getAddress(),
|
||||
minLevel = Math.min( addressOfThis.length, addressOfOther.length );
|
||||
|
||||
// Determinate preceding/following relationship.
|
||||
for ( var i = 0; i < minLevel; i++ ) {
|
||||
if ( addressOfThis[ i ] != addressOfOther[ i ] ) {
|
||||
return addressOfThis[ i ] < addressOfOther[ i ] ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
|
||||
}
|
||||
}
|
||||
|
||||
// Determinate contains/contained relationship.
|
||||
return ( addressOfThis.length < addressOfOther.length ) ? CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the closest ancestor node of this node, specified by its name or using an evaluator function.
|
||||
*
|
||||
* // Suppose we have the following HTML structure:
|
||||
* // <div id="outer"><div id="inner"><p><b>Some text</b></p></div></div>
|
||||
* // If node == <b>
|
||||
* ascendant = node.getAscendant( 'div' ); // ascendant == <div id="inner">
|
||||
* ascendant = node.getAscendant( 'b' ); // ascendant == null
|
||||
* ascendant = node.getAscendant( 'b', true ); // ascendant == <b>
|
||||
* ascendant = node.getAscendant( { div:1, p:1 } ); // Searches for the first 'div' or 'p': ascendant == <div id="inner">
|
||||
*
|
||||
* // Using custom evaluator:
|
||||
* ascendant = node.getAscendant( function( el ) {
|
||||
* return el.getId() == 'inner';
|
||||
* } );
|
||||
* // ascendant == <div id="inner">
|
||||
*
|
||||
* @since 3.6.1
|
||||
* @param {String/Function/Object} query The name of the ancestor node to search or
|
||||
* an object with the node names to search for or an evaluator function.
|
||||
* @param {Boolean} [includeSelf] Whether to include the current
|
||||
* node in the search.
|
||||
* @returns {CKEDITOR.dom.node} The located ancestor node or `null` if not found.
|
||||
*/
|
||||
getAscendant: function( query, includeSelf ) {
|
||||
var $ = this.$,
|
||||
evaluator,
|
||||
isCustomEvaluator;
|
||||
|
||||
if ( !includeSelf ) {
|
||||
$ = $.parentNode;
|
||||
}
|
||||
|
||||
// Custom checker provided in an argument.
|
||||
if ( typeof query == 'function' ) {
|
||||
isCustomEvaluator = true;
|
||||
evaluator = query;
|
||||
} else {
|
||||
// Predefined tag name checker.
|
||||
isCustomEvaluator = false;
|
||||
evaluator = function( $ ) {
|
||||
var name = ( typeof $.nodeName == 'string' ? $.nodeName.toLowerCase() : '' );
|
||||
|
||||
return ( typeof query == 'string' ? name == query : name in query );
|
||||
};
|
||||
}
|
||||
|
||||
while ( $ ) {
|
||||
// For user provided checker we use CKEDITOR.dom.node.
|
||||
if ( evaluator( isCustomEvaluator ? new CKEDITOR.dom.node( $ ) : $ ) ) {
|
||||
return new CKEDITOR.dom.node( $ );
|
||||
}
|
||||
|
||||
try {
|
||||
$ = $.parentNode;
|
||||
} catch ( e ) {
|
||||
$ = null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
hasAscendant: function( name, includeSelf ) {
|
||||
var $ = this.$;
|
||||
|
||||
if ( !includeSelf )
|
||||
$ = $.parentNode;
|
||||
|
||||
while ( $ ) {
|
||||
if ( $.nodeName && $.nodeName.toLowerCase() == name )
|
||||
return true;
|
||||
|
||||
$ = $.parentNode;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
move: function( target, toStart ) {
|
||||
target.append( this.remove(), toStart );
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes this node from the document DOM.
|
||||
*
|
||||
* var element = CKEDITOR.document.getById( 'MyElement' );
|
||||
* element.remove();
|
||||
*
|
||||
* @param {Boolean} [preserveChildren=false] Indicates that the children
|
||||
* elements must remain in the document, removing only the outer tags.
|
||||
*/
|
||||
remove: function( preserveChildren ) {
|
||||
var $ = this.$;
|
||||
var parent = $.parentNode;
|
||||
|
||||
if ( parent ) {
|
||||
if ( preserveChildren ) {
|
||||
// Move all children before the node.
|
||||
for ( var child;
|
||||
( child = $.firstChild ); ) {
|
||||
parent.insertBefore( $.removeChild( child ), $ );
|
||||
}
|
||||
}
|
||||
|
||||
parent.removeChild( $ );
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
replace: function( nodeToReplace ) {
|
||||
this.insertBefore( nodeToReplace );
|
||||
nodeToReplace.remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
trim: function() {
|
||||
this.ltrim();
|
||||
this.rtrim();
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
ltrim: function() {
|
||||
var child;
|
||||
while ( this.getFirst && ( child = this.getFirst() ) ) {
|
||||
if ( child.type == CKEDITOR.NODE_TEXT ) {
|
||||
var trimmed = CKEDITOR.tools.ltrim( child.getText() ),
|
||||
originalLength = child.getLength();
|
||||
|
||||
if ( !trimmed ) {
|
||||
child.remove();
|
||||
continue;
|
||||
} else if ( trimmed.length < originalLength ) {
|
||||
child.split( originalLength - trimmed.length );
|
||||
|
||||
// IE BUG: child.remove() may raise JavaScript errors here. (https://dev.ckeditor.com/ticket/81)
|
||||
this.$.removeChild( this.$.firstChild );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
rtrim: function() {
|
||||
var child;
|
||||
while ( this.getLast && ( child = this.getLast() ) ) {
|
||||
if ( child.type == CKEDITOR.NODE_TEXT ) {
|
||||
var trimmed = CKEDITOR.tools.rtrim( child.getText() ),
|
||||
originalLength = child.getLength();
|
||||
|
||||
if ( !trimmed ) {
|
||||
child.remove();
|
||||
continue;
|
||||
} else if ( trimmed.length < originalLength ) {
|
||||
child.split( trimmed.length );
|
||||
|
||||
// IE BUG: child.getNext().remove() may raise JavaScript errors here.
|
||||
// (https://dev.ckeditor.com/ticket/81)
|
||||
this.$.lastChild.parentNode.removeChild( this.$.lastChild );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( CKEDITOR.env.needsBrFiller ) {
|
||||
child = this.$.lastChild;
|
||||
|
||||
if ( child && child.type == 1 && child.nodeName.toLowerCase() == 'br' ) {
|
||||
// Use "eChildNode.parentNode" instead of "node" to avoid IE bug (https://dev.ckeditor.com/ticket/324).
|
||||
child.parentNode.removeChild( child );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if this node is read-only (should not be changed).
|
||||
*
|
||||
* // For the following HTML:
|
||||
* // <b>foo</b><div contenteditable="false"><i>bar</i></div>
|
||||
*
|
||||
* elB.isReadOnly(); // -> false
|
||||
* foo.isReadOnly(); // -> false
|
||||
* elDiv.isReadOnly(); // -> true
|
||||
* elI.isReadOnly(); // -> true
|
||||
*
|
||||
* This method works in two modes depending on browser support for the `element.isContentEditable` property and
|
||||
* the value of the `checkOnlyAttributes` parameter. The `element.isContentEditable` check is faster, but it is known
|
||||
* to malfunction in hidden or detached nodes. Additionally, when processing some detached DOM tree you may want to imitate
|
||||
* that this happens inside an editable container (like it would happen inside the {@link CKEDITOR.editable}). To do so,
|
||||
* you can temporarily attach this tree to an element with the `data-cke-editable` attribute and use the
|
||||
* `checkOnlyAttributes` mode.
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @param {Boolean} [checkOnlyAttributes=false] If `true`, only attributes will be checked, native methods will not
|
||||
* be used. This parameter needs to be `true` to check hidden or detached elements. Introduced in 4.5.0.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isReadOnly: function( checkOnlyAttributes ) {
|
||||
var element = this;
|
||||
if ( this.type != CKEDITOR.NODE_ELEMENT )
|
||||
element = this.getParent();
|
||||
|
||||
// Prevent Edge crash (https://dev.ckeditor.com/ticket/13609, https://dev.ckeditor.com/ticket/13919).
|
||||
if ( CKEDITOR.env.edge && element && element.is( 'textarea', 'input' ) ) {
|
||||
checkOnlyAttributes = true;
|
||||
}
|
||||
|
||||
if ( !checkOnlyAttributes && element && typeof element.$.isContentEditable != 'undefined' ) {
|
||||
return !( element.$.isContentEditable || element.data( 'cke-editable' ) );
|
||||
}
|
||||
else {
|
||||
// Degrade for old browsers which don't support "isContentEditable", e.g. FF3
|
||||
|
||||
while ( element ) {
|
||||
if ( element.data( 'cke-editable' ) ) {
|
||||
return false;
|
||||
} else if ( element.hasAttribute( 'contenteditable' ) ) {
|
||||
return element.getAttribute( 'contenteditable' ) == 'false';
|
||||
}
|
||||
|
||||
element = element.getParent();
|
||||
}
|
||||
|
||||
// Reached the root of DOM tree, no editable found.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} );
|
||||
54
Admin/plugins/ckeditor/core/dom/nodelist.js
Normal file
54
Admin/plugins/ckeditor/core/dom/nodelist.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a list of {@link CKEDITOR.dom.node} objects.
|
||||
* It is a wrapper for a native nodes list.
|
||||
*
|
||||
* var nodeList = CKEDITOR.document.getBody().getChildren();
|
||||
* alert( nodeList.count() ); // number [0;N]
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a document class instance.
|
||||
* @param {Object} nativeList
|
||||
*/
|
||||
CKEDITOR.dom.nodeList = function( nativeList ) {
|
||||
this.$ = nativeList;
|
||||
};
|
||||
|
||||
CKEDITOR.dom.nodeList.prototype = {
|
||||
/**
|
||||
* Gets the count of nodes in this list.
|
||||
*
|
||||
* @returns {Number}
|
||||
*/
|
||||
count: function() {
|
||||
return this.$.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the node from the list.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node}
|
||||
*/
|
||||
getItem: function( index ) {
|
||||
if ( index < 0 || index >= this.$.length )
|
||||
return null;
|
||||
|
||||
var $node = this.$[ index ];
|
||||
return $node ? new CKEDITOR.dom.node( $node ) : null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a node list as an array.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node[]}
|
||||
*/
|
||||
toArray: function() {
|
||||
return CKEDITOR.tools.array.map( this.$, function( nativeEl ) {
|
||||
return new CKEDITOR.dom.node( nativeEl );
|
||||
} );
|
||||
}
|
||||
};
|
||||
3417
Admin/plugins/ckeditor/core/dom/range.js
Normal file
3417
Admin/plugins/ckeditor/core/dom/range.js
Normal file
File diff suppressed because it is too large
Load Diff
199
Admin/plugins/ckeditor/core/dom/rangelist.js
Normal file
199
Admin/plugins/ckeditor/core/dom/rangelist.js
Normal file
@@ -0,0 +1,199 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Represents a list os CKEDITOR.dom.range objects, which can be easily
|
||||
* iterated sequentially.
|
||||
*
|
||||
* @class
|
||||
* @extends Array
|
||||
* @constructor Creates a rangeList class instance.
|
||||
* @param {CKEDITOR.dom.range/CKEDITOR.dom.range[]} [ranges] The ranges contained on this list.
|
||||
* Note that, if an array of ranges is specified, the range sequence
|
||||
* should match its DOM order. This class will not help to sort them.
|
||||
*/
|
||||
CKEDITOR.dom.rangeList = function( ranges ) {
|
||||
if ( ranges instanceof CKEDITOR.dom.rangeList )
|
||||
return ranges;
|
||||
|
||||
if ( !ranges )
|
||||
ranges = [];
|
||||
else if ( ranges instanceof CKEDITOR.dom.range )
|
||||
ranges = [ ranges ];
|
||||
|
||||
return CKEDITOR.tools.extend( ranges, mixins );
|
||||
};
|
||||
|
||||
var mixins = {
|
||||
/**
|
||||
* Creates an instance of the rangeList iterator, it should be used
|
||||
* only when the ranges processing could be DOM intrusive, which
|
||||
* means it may pollute and break other ranges in this list.
|
||||
* Otherwise, it's enough to just iterate over this array in a for loop.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.rangeListIterator}
|
||||
*/
|
||||
createIterator: function() {
|
||||
var rangeList = this,
|
||||
bookmark = CKEDITOR.dom.walker.bookmark(),
|
||||
bookmarks = [],
|
||||
current;
|
||||
|
||||
return {
|
||||
/**
|
||||
* Retrieves the next range in the list.
|
||||
*
|
||||
* @member CKEDITOR.dom.rangeListIterator
|
||||
* @param {Boolean} [mergeConsequent=false] Whether join two adjacent
|
||||
* ranges into single, e.g. consequent table cells.
|
||||
*/
|
||||
getNextRange: function( mergeConsequent ) {
|
||||
current = current === undefined ? 0 : current + 1;
|
||||
|
||||
var range = rangeList[ current ];
|
||||
|
||||
// Multiple ranges might be mangled by each other.
|
||||
if ( range && rangeList.length > 1 ) {
|
||||
// Bookmarking all other ranges on the first iteration,
|
||||
// the range correctness after it doesn't matter since we'll
|
||||
// restore them before the next iteration.
|
||||
if ( !current ) {
|
||||
// Make sure bookmark correctness by reverse processing.
|
||||
for ( var i = rangeList.length - 1; i >= 0; i-- )
|
||||
bookmarks.unshift( rangeList[ i ].createBookmark( true ) );
|
||||
}
|
||||
|
||||
if ( mergeConsequent ) {
|
||||
// Figure out how many ranges should be merged.
|
||||
var mergeCount = 0;
|
||||
while ( rangeList[ current + mergeCount + 1 ] ) {
|
||||
var doc = range.document,
|
||||
found = 0,
|
||||
left = doc.getById( bookmarks[ mergeCount ].endNode ),
|
||||
right = doc.getById( bookmarks[ mergeCount + 1 ].startNode ),
|
||||
next;
|
||||
|
||||
// Check subsequent range.
|
||||
while ( 1 ) {
|
||||
next = left.getNextSourceNode( false );
|
||||
if ( !right.equals( next ) ) {
|
||||
// This could be yet another bookmark or
|
||||
// walking across block boundaries.
|
||||
if ( bookmark( next ) || ( next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() ) ) {
|
||||
left = next;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
found = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !found )
|
||||
break;
|
||||
|
||||
mergeCount++;
|
||||
}
|
||||
}
|
||||
|
||||
range.moveToBookmark( bookmarks.shift() );
|
||||
|
||||
// Merge ranges finally after moving to bookmarks.
|
||||
while ( mergeCount-- ) {
|
||||
next = rangeList[ ++current ];
|
||||
next.moveToBookmark( bookmarks.shift() );
|
||||
range.setEnd( next.endContainer, next.endOffset );
|
||||
}
|
||||
}
|
||||
|
||||
return range;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Create bookmarks for all ranges. See {@link CKEDITOR.dom.range#createBookmark}.
|
||||
*
|
||||
* @param {Boolean} [serializable=false] See {@link CKEDITOR.dom.range#createBookmark}.
|
||||
* @returns {Array} Array of bookmarks.
|
||||
*/
|
||||
createBookmarks: function( serializable ) {
|
||||
var retval = [],
|
||||
bookmark;
|
||||
for ( var i = 0; i < this.length; i++ ) {
|
||||
retval.push( bookmark = this[ i ].createBookmark( serializable, true ) );
|
||||
|
||||
// Updating the container & offset values for ranges
|
||||
// that have been touched.
|
||||
for ( var j = i + 1; j < this.length; j++ ) {
|
||||
this[ j ] = updateDirtyRange( bookmark, this[ j ] );
|
||||
this[ j ] = updateDirtyRange( bookmark, this[ j ], true );
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create "unobtrusive" bookmarks for all ranges. See {@link CKEDITOR.dom.range#createBookmark2}.
|
||||
*
|
||||
* @param {Boolean} [normalized=false] See {@link CKEDITOR.dom.range#createBookmark2}.
|
||||
* @returns {Array} Array of bookmarks.
|
||||
*/
|
||||
createBookmarks2: function( normalized ) {
|
||||
var bookmarks = [];
|
||||
|
||||
for ( var i = 0; i < this.length; i++ )
|
||||
bookmarks.push( this[ i ].createBookmark2( normalized ) );
|
||||
|
||||
return bookmarks;
|
||||
},
|
||||
|
||||
/**
|
||||
* Move each range in the list to the position specified by a list of bookmarks.
|
||||
*
|
||||
* @param {Array} bookmarks The list of bookmarks, each one matching a range in the list.
|
||||
*/
|
||||
moveToBookmarks: function( bookmarks ) {
|
||||
for ( var i = 0; i < this.length; i++ )
|
||||
this[ i ].moveToBookmark( bookmarks[ i ] );
|
||||
}
|
||||
};
|
||||
|
||||
// Update the specified range which has been mangled by previous insertion of
|
||||
// range bookmark nodes.(https://dev.ckeditor.com/ticket/3256)
|
||||
function updateDirtyRange( bookmark, dirtyRange, checkEnd ) {
|
||||
var serializable = bookmark.serializable,
|
||||
container = dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ],
|
||||
offset = checkEnd ? 'endOffset' : 'startOffset';
|
||||
|
||||
var bookmarkStart = serializable ? dirtyRange.document.getById( bookmark.startNode ) : bookmark.startNode;
|
||||
|
||||
var bookmarkEnd = serializable ? dirtyRange.document.getById( bookmark.endNode ) : bookmark.endNode;
|
||||
|
||||
if ( container.equals( bookmarkStart.getPrevious() ) ) {
|
||||
dirtyRange.startOffset = dirtyRange.startOffset - container.getLength() - bookmarkEnd.getPrevious().getLength();
|
||||
container = bookmarkEnd.getNext();
|
||||
} else if ( container.equals( bookmarkEnd.getPrevious() ) ) {
|
||||
dirtyRange.startOffset = dirtyRange.startOffset - container.getLength();
|
||||
container = bookmarkEnd.getNext();
|
||||
}
|
||||
|
||||
container.equals( bookmarkStart.getParent() ) && dirtyRange[ offset ]++;
|
||||
container.equals( bookmarkEnd.getParent() ) && dirtyRange[ offset ]++;
|
||||
|
||||
// Update and return this range.
|
||||
dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ] = container;
|
||||
return dirtyRange;
|
||||
}
|
||||
} )();
|
||||
|
||||
/**
|
||||
* (Virtual Class) Do not call this constructor. This class is not really part
|
||||
* of the API. It just describes the return type of {@link CKEDITOR.dom.rangeList#createIterator}.
|
||||
*
|
||||
* @class CKEDITOR.dom.rangeListIterator
|
||||
*/
|
||||
74
Admin/plugins/ckeditor/core/dom/rect.js
Normal file
74
Admin/plugins/ckeditor/core/dom/rect.js
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.dom.rect} class
|
||||
* that contains the definition of the element's DOM rectangle. This file is for
|
||||
* documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Virtual class that illustrates the {@link CKEDITOR.dom.element} DOM rectangle (dimensions and coordinates
|
||||
* of the area that the element occupies on the page).
|
||||
*
|
||||
* @class CKEDITOR.dom.rect
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's offset from the viewport's top edge.
|
||||
*
|
||||
* @property {Number} top
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's bottom edge offset from the viewport's top edge.
|
||||
*
|
||||
* This value is the same as the {@link CKEDITOR.dom.rect#top} value plus the {@link CKEDITOR.dom.rect#height} value.
|
||||
*
|
||||
* @property {Number} bottom
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's offset from the viewport's left edge.
|
||||
*
|
||||
* @property {Number} left
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's right edge offset from the viewport's left edge.
|
||||
*
|
||||
* This value is the same as the {@link CKEDITOR.dom.rect#left} value plus the {@link CKEDITOR.dom.rect#width} value.
|
||||
*
|
||||
* @property {Number} right
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's height.
|
||||
*
|
||||
* @property {Number} height
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's width.
|
||||
*
|
||||
* @property {Number} width
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's offset from the viewport's left edge.
|
||||
*
|
||||
* This property is not available in Internet Explorer or Edge.
|
||||
*
|
||||
* @property {Number} x
|
||||
*/
|
||||
|
||||
/**
|
||||
* Element's offset from the viewport's top edge.
|
||||
*
|
||||
* This property is not available in Internet Explorer or Edge.
|
||||
*
|
||||
* @property {Number} y
|
||||
*/
|
||||
154
Admin/plugins/ckeditor/core/dom/text.js
Normal file
154
Admin/plugins/ckeditor/core/dom/text.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.text} class, which represents
|
||||
* a DOM text node.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM text node.
|
||||
*
|
||||
* var nativeNode = document.createTextNode( 'Example' );
|
||||
* var text = new CKEDITOR.dom.text( nativeNode );
|
||||
*
|
||||
* var text = new CKEDITOR.dom.text( 'Example' );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.node
|
||||
* @constructor Creates a text class instance.
|
||||
* @param {Object/String} text A native DOM text node or a string containing
|
||||
* the text to use to create a new text node.
|
||||
* @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
|
||||
* the node in case of new node creation. Defaults to the current document.
|
||||
*/
|
||||
CKEDITOR.dom.text = function( text, ownerDocument ) {
|
||||
if ( typeof text == 'string' )
|
||||
text = ( ownerDocument ? ownerDocument.$ : document ).createTextNode( text );
|
||||
|
||||
// Theoretically, we should call the base constructor here
|
||||
// (not CKEDITOR.dom.node though). But, IE doesn't support expando
|
||||
// properties on text node, so the features provided by domObject will not
|
||||
// work for text nodes (which is not a big issue for us).
|
||||
//
|
||||
// CKEDITOR.dom.domObject.call( this, element );
|
||||
|
||||
this.$ = text;
|
||||
};
|
||||
|
||||
CKEDITOR.dom.text.prototype = new CKEDITOR.dom.node();
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.text.prototype, {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_TEXT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_TEXT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_TEXT,
|
||||
|
||||
/**
|
||||
* Gets length of node's value.
|
||||
*
|
||||
* @returns {Number}
|
||||
*/
|
||||
getLength: function() {
|
||||
return this.$.nodeValue.length;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets node's value.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
getText: function() {
|
||||
return this.$.nodeValue;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets node's value.
|
||||
*
|
||||
* @param {String} text
|
||||
*/
|
||||
setText: function( text ) {
|
||||
this.$.nodeValue = text;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether a node is empty or is a
|
||||
* {@link CKEDITOR.dom.selection#FILLING_CHAR_SEQUENCE FILLING_CHAR_SEQUENCE} string.
|
||||
*
|
||||
* @since 4.13.0
|
||||
* @param {Boolean} [ignoreWhiteSpace] Specifies whether the content that consists of only whitespace characters
|
||||
* should be treated as an empty one.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
isEmpty: function( ignoreWhiteSpace ) {
|
||||
var text = this.getText();
|
||||
|
||||
if ( ignoreWhiteSpace ) {
|
||||
text = CKEDITOR.tools.trim( text );
|
||||
}
|
||||
|
||||
return !text || text === CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE;
|
||||
},
|
||||
|
||||
/**
|
||||
* Breaks this text node into two nodes at the specified offset,
|
||||
* keeping both in the tree as siblings. This node then only contains
|
||||
* all the content up to the offset point. A new text node, which is
|
||||
* inserted as the next sibling of this node, contains all the content
|
||||
* at and after the offset point. When the offset is equal to the
|
||||
* length of this node, the new node has no data.
|
||||
*
|
||||
* @param {Number} The position at which to split, starting from zero.
|
||||
* @returns {CKEDITOR.dom.text} The new text node.
|
||||
*/
|
||||
split: function( offset ) {
|
||||
|
||||
// Saved the children count and text length beforehand.
|
||||
var parent = this.$.parentNode,
|
||||
count = parent.childNodes.length,
|
||||
length = this.getLength();
|
||||
|
||||
var doc = this.getDocument();
|
||||
var retval = new CKEDITOR.dom.text( this.$.splitText( offset ), doc );
|
||||
|
||||
if ( parent.childNodes.length == count ) {
|
||||
// If the offset is after the last char, IE creates the text node
|
||||
// on split, but don't include it into the DOM. So, we have to do
|
||||
// that manually here.
|
||||
if ( offset >= length ) {
|
||||
retval = doc.createText( '' );
|
||||
retval.insertAfter( this );
|
||||
} else {
|
||||
// IE BUG: IE8+ does not update the childNodes array in DOM after splitText(),
|
||||
// we need to make some DOM changes to make it update. (https://dev.ckeditor.com/ticket/3436)
|
||||
var workaround = doc.createText( '' );
|
||||
workaround.insertAfter( retval );
|
||||
workaround.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts characters from indexA up to but not including `indexB`.
|
||||
*
|
||||
* @param {Number} indexA An integer between `0` and one less than the
|
||||
* length of the text.
|
||||
* @param {Number} [indexB] An integer between `0` and the length of the
|
||||
* string. If omitted, extracts characters to the end of the text.
|
||||
*/
|
||||
substring: function( indexA, indexB ) {
|
||||
// We need the following check due to a Firefox bug
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=458886
|
||||
if ( typeof indexB != 'number' )
|
||||
return this.$.nodeValue.substr( indexA );
|
||||
else
|
||||
return this.$.nodeValue.substring( indexA, indexB );
|
||||
}
|
||||
} );
|
||||
652
Admin/plugins/ckeditor/core/dom/walker.js
Normal file
652
Admin/plugins/ckeditor/core/dom/walker.js
Normal file
@@ -0,0 +1,652 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
( function() {
|
||||
// This function is to be called under a "walker" instance scope.
|
||||
function iterate( rtl, breakOnFalse ) {
|
||||
var range = this.range;
|
||||
|
||||
// Return null if we have reached the end.
|
||||
if ( this._.end )
|
||||
return null;
|
||||
|
||||
// This is the first call. Initialize it.
|
||||
if ( !this._.start ) {
|
||||
this._.start = 1;
|
||||
|
||||
// A collapsed range must return null at first call.
|
||||
if ( range.collapsed ) {
|
||||
this.end();
|
||||
return null;
|
||||
}
|
||||
|
||||
// Move outside of text node edges.
|
||||
range.optimize();
|
||||
}
|
||||
|
||||
var node,
|
||||
startCt = range.startContainer,
|
||||
endCt = range.endContainer,
|
||||
startOffset = range.startOffset,
|
||||
endOffset = range.endOffset,
|
||||
guard,
|
||||
userGuard = this.guard,
|
||||
type = this.type,
|
||||
getSourceNodeFn = ( rtl ? 'getPreviousSourceNode' : 'getNextSourceNode' );
|
||||
|
||||
// Create the LTR guard function, if necessary.
|
||||
if ( !rtl && !this._.guardLTR ) {
|
||||
// The node that stops walker from moving up.
|
||||
var limitLTR = endCt.type == CKEDITOR.NODE_ELEMENT ? endCt : endCt.getParent();
|
||||
|
||||
// The node that stops the walker from going to next.
|
||||
var blockerLTR = endCt.type == CKEDITOR.NODE_ELEMENT ? endCt.getChild( endOffset ) : endCt.getNext();
|
||||
|
||||
this._.guardLTR = function( node, movingOut ) {
|
||||
return ( ( !movingOut || !limitLTR.equals( node ) ) && ( !blockerLTR || !node.equals( blockerLTR ) ) && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || !node.equals( range.root ) ) );
|
||||
};
|
||||
}
|
||||
|
||||
// Create the RTL guard function, if necessary.
|
||||
if ( rtl && !this._.guardRTL ) {
|
||||
// The node that stops walker from moving up.
|
||||
var limitRTL = startCt.type == CKEDITOR.NODE_ELEMENT ? startCt : startCt.getParent();
|
||||
|
||||
// The node that stops the walker from going to next.
|
||||
var blockerRTL = startCt.type == CKEDITOR.NODE_ELEMENT ? startOffset ? startCt.getChild( startOffset - 1 ) : null : startCt.getPrevious();
|
||||
|
||||
this._.guardRTL = function( node, movingOut ) {
|
||||
return ( ( !movingOut || !limitRTL.equals( node ) ) && ( !blockerRTL || !node.equals( blockerRTL ) ) && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || !node.equals( range.root ) ) );
|
||||
};
|
||||
}
|
||||
|
||||
// Define which guard function to use.
|
||||
var stopGuard = rtl ? this._.guardRTL : this._.guardLTR;
|
||||
|
||||
// Make the user defined guard function participate in the process,
|
||||
// otherwise simply use the boundary guard.
|
||||
if ( userGuard ) {
|
||||
guard = function( node, movingOut ) {
|
||||
if ( stopGuard( node, movingOut ) === false )
|
||||
return false;
|
||||
|
||||
return userGuard( node, movingOut );
|
||||
};
|
||||
} else {
|
||||
guard = stopGuard;
|
||||
}
|
||||
|
||||
if ( this.current )
|
||||
node = this.current[ getSourceNodeFn ]( false, type, guard );
|
||||
else {
|
||||
// Get the first node to be returned.
|
||||
if ( rtl ) {
|
||||
node = endCt;
|
||||
|
||||
if ( node.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( endOffset > 0 )
|
||||
node = node.getChild( endOffset - 1 );
|
||||
else
|
||||
node = ( guard( node, true ) === false ) ? null : node.getPreviousSourceNode( true, type, guard );
|
||||
}
|
||||
} else {
|
||||
node = startCt;
|
||||
|
||||
if ( node.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( !( node = node.getChild( startOffset ) ) )
|
||||
node = ( guard( startCt, true ) === false ) ? null : startCt.getNextSourceNode( true, type, guard );
|
||||
}
|
||||
}
|
||||
|
||||
if ( node && guard( node ) === false )
|
||||
node = null;
|
||||
}
|
||||
|
||||
while ( node && !this._.end ) {
|
||||
this.current = node;
|
||||
|
||||
if ( !this.evaluator || this.evaluator( node ) !== false ) {
|
||||
if ( !breakOnFalse )
|
||||
return node;
|
||||
} else if ( breakOnFalse && this.evaluator ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node = node[ getSourceNodeFn ]( false, type, guard );
|
||||
}
|
||||
|
||||
this.end();
|
||||
return this.current = null;
|
||||
}
|
||||
|
||||
function iterateToLast( rtl ) {
|
||||
var node,
|
||||
last = null;
|
||||
|
||||
while ( ( node = iterate.call( this, rtl ) ) )
|
||||
last = node;
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility class to "walk" the DOM inside range boundaries. If the
|
||||
* range starts or ends in the middle of the text node, this node will
|
||||
* be included as a whole. Outside changes to the range may break the walker.
|
||||
*
|
||||
* The walker may return nodes that are not totally included in the
|
||||
* range boundaries. Let us take the following range representation,
|
||||
* where the square brackets indicate the boundaries:
|
||||
*
|
||||
* [<p>Some <b>sample] text</b>
|
||||
*
|
||||
* While walking forward into the above range, the following nodes are
|
||||
* returned: `<p>`, `"Some "`, `<b>` and `"sample"`. Going
|
||||
* backwards instead we have: `"sample"` and `"Some "`. So note that the
|
||||
* walker always returns nodes when "entering" them, but not when
|
||||
* "leaving" them. The {@link #guard} function is instead called both when
|
||||
* entering and when leaving nodes.
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
CKEDITOR.dom.walker = CKEDITOR.tools.createClass( {
|
||||
/**
|
||||
* Creates a walker class instance.
|
||||
*
|
||||
* @constructor
|
||||
* @param {CKEDITOR.dom.range} range The range within which to walk.
|
||||
*/
|
||||
$: function( range ) {
|
||||
this.range = range;
|
||||
|
||||
/**
|
||||
* A function executed for every matched node to check whether
|
||||
* it is to be considered in the walk or not. If not provided, all
|
||||
* matched nodes are considered good.
|
||||
*
|
||||
* If the function returns `false`, the node is ignored.
|
||||
*
|
||||
* @property {Function} evaluator
|
||||
*/
|
||||
// this.evaluator = null;
|
||||
|
||||
/**
|
||||
* A function executed for every node the walk passes by to check
|
||||
* whether the walk is to be finished. It is called both when
|
||||
* entering and when exiting nodes, as well as for the matched nodes.
|
||||
*
|
||||
* If this function returns `false`, the walking ends and no more
|
||||
* nodes are evaluated.
|
||||
|
||||
* @property {Function} guard
|
||||
*/
|
||||
// this.guard = null;
|
||||
|
||||
/** @private */
|
||||
this._ = {};
|
||||
},
|
||||
|
||||
// statics :
|
||||
// {
|
||||
// /* Creates a CKEDITOR.dom.walker instance to walk inside DOM boundaries set by nodes.
|
||||
// * @param {CKEDITOR.dom.node} startNode The node from which the walk
|
||||
// * will start.
|
||||
// * @param {CKEDITOR.dom.node} [endNode] The last node to be considered
|
||||
// * in the walk. No more nodes are retrieved after touching or
|
||||
// * passing it. If not provided, the walker stops at the
|
||||
// * <body> closing boundary.
|
||||
// * @returns {CKEDITOR.dom.walker} A DOM walker for the nodes between the
|
||||
// * provided nodes.
|
||||
// */
|
||||
// createOnNodes : function( startNode, endNode, startInclusive, endInclusive )
|
||||
// {
|
||||
// var range = new CKEDITOR.dom.range();
|
||||
// if ( startNode )
|
||||
// range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ;
|
||||
// else
|
||||
// range.setStartAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_AFTER_START ) ;
|
||||
//
|
||||
// if ( endNode )
|
||||
// range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ;
|
||||
// else
|
||||
// range.setEndAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_BEFORE_END ) ;
|
||||
//
|
||||
// return new CKEDITOR.dom.walker( range );
|
||||
// }
|
||||
// },
|
||||
//
|
||||
proto: {
|
||||
/**
|
||||
* Stops walking. No more nodes are retrieved if this function is called.
|
||||
*/
|
||||
end: function() {
|
||||
this._.end = 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the next node (on the right).
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The next node or `null` if no more
|
||||
* nodes are available.
|
||||
*/
|
||||
next: function() {
|
||||
return iterate.call( this );
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the previous node (on the left).
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The previous node or `null` if no more
|
||||
* nodes are available.
|
||||
*/
|
||||
previous: function() {
|
||||
return iterate.call( this, 1 );
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks all nodes on the right, executing the evaluation function.
|
||||
*
|
||||
* @returns {Boolean} `false` if the evaluator function returned
|
||||
* `false` for any of the matched nodes. Otherwise `true`.
|
||||
*/
|
||||
checkForward: function() {
|
||||
return iterate.call( this, 0, 1 ) !== false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check all nodes on the left, executing the evaluation function.
|
||||
*
|
||||
* @returns {Boolean} `false` if the evaluator function returned
|
||||
* `false` for any of the matched nodes. Otherwise `true`.
|
||||
*/
|
||||
checkBackward: function() {
|
||||
return iterate.call( this, 1, 1 ) !== false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes a full walk forward (to the right), until no more nodes
|
||||
* are available, returning the last valid node.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The last node on the right or `null`
|
||||
* if no valid nodes are available.
|
||||
*/
|
||||
lastForward: function() {
|
||||
return iterateToLast.call( this );
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes a full walk backwards (to the left), until no more nodes
|
||||
* are available, returning the last valid node.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.node} The last node on the left or `null`
|
||||
* if no valid nodes are available.
|
||||
*/
|
||||
lastBackward: function() {
|
||||
return iterateToLast.call( this, 1 );
|
||||
},
|
||||
|
||||
/**
|
||||
* Resets the walker.
|
||||
*/
|
||||
reset: function() {
|
||||
delete this.current;
|
||||
this._ = {};
|
||||
}
|
||||
|
||||
}
|
||||
} );
|
||||
|
||||
// Anything whose display computed style is block, list-item, table,
|
||||
// table-row-group, table-header-group, table-footer-group, table-row,
|
||||
// table-column-group, table-column, table-cell, table-caption, or whose node
|
||||
// name is hr, br (when enterMode is br only) is a block boundary.
|
||||
var blockBoundaryDisplayMatch = {
|
||||
block: 1, 'list-item': 1, table: 1, 'table-row-group': 1,
|
||||
'table-header-group': 1, 'table-footer-group': 1, 'table-row': 1, 'table-column-group': 1,
|
||||
'table-column': 1, 'table-cell': 1, 'table-caption': 1
|
||||
},
|
||||
outOfFlowPositions = { absolute: 1, fixed: 1 };
|
||||
|
||||
/**
|
||||
* Checks whether an element is displayed as a block.
|
||||
*
|
||||
* @member CKEDITOR.dom.element
|
||||
* @param [customNodeNames] Custom list of nodes which will extend
|
||||
* the default {@link CKEDITOR.dtd#$block} list.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
CKEDITOR.dom.element.prototype.isBlockBoundary = function( customNodeNames ) {
|
||||
// Whether element is in normal page flow. Floated or positioned elements are out of page flow.
|
||||
// Don't consider floated or positioned formatting as block boundary, fall back to dtd check in that case. (https://dev.ckeditor.com/ticket/6297)
|
||||
var inPageFlow = this.getComputedStyle( 'float' ) == 'none' && !( this.getComputedStyle( 'position' ) in outOfFlowPositions );
|
||||
|
||||
if ( inPageFlow && blockBoundaryDisplayMatch[ this.getComputedStyle( 'display' ) ] )
|
||||
return true;
|
||||
|
||||
// Either in $block or in customNodeNames if defined.
|
||||
return !!( this.is( CKEDITOR.dtd.$block ) || customNodeNames && this.is( customNodeNames ) );
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a block boundary.
|
||||
* See {@link CKEDITOR.dom.element#isBlockBoundary}.
|
||||
*
|
||||
* @static
|
||||
* @param customNodeNames
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.blockBoundary = function( customNodeNames ) {
|
||||
return function( node ) {
|
||||
return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary( customNodeNames ) );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @todo
|
||||
*/
|
||||
CKEDITOR.dom.walker.listItemBoundary = function() {
|
||||
return this.blockBoundary( { br: 1 } );
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a bookmark node or the bookmark node
|
||||
* inner content.
|
||||
*
|
||||
* @static
|
||||
* @param {Boolean} [contentOnly=false] Whether only test against the text content of
|
||||
* a bookmark node instead of the element itself (default).
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the bookmark
|
||||
* node instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.bookmark = function( contentOnly, isReject ) {
|
||||
function isBookmarkNode( node ) {
|
||||
return ( node && node.getName && node.getName() == 'span' && node.data( 'cke-bookmark' ) );
|
||||
}
|
||||
|
||||
return function( node ) {
|
||||
var isBookmark, parent;
|
||||
// Is bookmark inner text node?
|
||||
isBookmark = ( node && node.type != CKEDITOR.NODE_ELEMENT && ( parent = node.getParent() ) && isBookmarkNode( parent ) );
|
||||
// Is bookmark node?
|
||||
isBookmark = contentOnly ? isBookmark : isBookmark || isBookmarkNode( node );
|
||||
return !!( isReject ^ isBookmark );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a text node containing only whitespace characters.
|
||||
*
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false]
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.whitespaces = function( isReject ) {
|
||||
return function( node ) {
|
||||
var isWhitespace;
|
||||
if ( node && node.type == CKEDITOR.NODE_TEXT ) {
|
||||
// Whitespace, as well as the Filling Char Sequence text node used in Webkit. (https://dev.ckeditor.com/ticket/9384, https://dev.ckeditor.com/ticket/13816)
|
||||
isWhitespace = !CKEDITOR.tools.trim( node.getText() ) ||
|
||||
CKEDITOR.env.webkit && node.getText() == CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE;
|
||||
}
|
||||
|
||||
return !!( isReject ^ isWhitespace );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is invisible in the WYSIWYG mode.
|
||||
*
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false]
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.invisible = function( isReject ) {
|
||||
var whitespace = CKEDITOR.dom.walker.whitespaces(),
|
||||
// https://dev.ckeditor.com/ticket/12221 (Chrome) plus https://dev.ckeditor.com/ticket/11111 (Safari).
|
||||
offsetWidth0 = CKEDITOR.env.webkit ? 1 : 0;
|
||||
|
||||
return function( node ) {
|
||||
var invisible;
|
||||
|
||||
if ( whitespace( node ) )
|
||||
invisible = 1;
|
||||
else {
|
||||
// Visibility should be checked on element.
|
||||
if ( node.type == CKEDITOR.NODE_TEXT )
|
||||
node = node.getParent();
|
||||
|
||||
// Nodes that take no spaces in wysiwyg:
|
||||
// 1. White-spaces but not including NBSP.
|
||||
// 2. Empty inline elements, e.g. <b></b>.
|
||||
// 3. <br> elements (bogus, surrounded by text) (https://dev.ckeditor.com/ticket/12423).
|
||||
invisible = node.$.offsetWidth <= offsetWidth0;
|
||||
}
|
||||
|
||||
return !!( isReject ^ invisible );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node type is equal to the passed one.
|
||||
*
|
||||
* @static
|
||||
* @param {Number} type
|
||||
* @param {Boolean} [isReject=false]
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.nodeType = function( type, isReject ) {
|
||||
return function( node ) {
|
||||
return !!( isReject ^ ( node.type == type ) );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a bogus (filler) node from
|
||||
* `contenteditable` element's point of view.
|
||||
*
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false]
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.bogus = function( isReject ) {
|
||||
function nonEmpty( node ) {
|
||||
return !isWhitespaces( node ) && !isBookmark( node );
|
||||
}
|
||||
|
||||
return function( node ) {
|
||||
var isBogus = CKEDITOR.env.needsBrFiller ? node.is && node.is( 'br' ) : node.getText && tailNbspRegex.test( node.getText() );
|
||||
|
||||
if ( isBogus ) {
|
||||
var parent = node.getParent(),
|
||||
next = node.getNext( nonEmpty );
|
||||
|
||||
isBogus = parent.isBlockBoundary() && ( !next || next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() );
|
||||
}
|
||||
|
||||
return !!( isReject ^ isBogus );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is a temporary element
|
||||
* (element with the `data-cke-temp` attribute) or its child.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the
|
||||
* temporary element instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.temp = function( isReject ) {
|
||||
return function( node ) {
|
||||
if ( node.type != CKEDITOR.NODE_ELEMENT )
|
||||
node = node.getParent();
|
||||
|
||||
var isTemp = node && node.hasAttribute( 'data-cke-temp' );
|
||||
|
||||
return !!( isReject ^ isTemp );
|
||||
};
|
||||
};
|
||||
|
||||
var tailNbspRegex = /^[\t\r\n ]*(?: |\xa0)$/,
|
||||
isWhitespaces = CKEDITOR.dom.walker.whitespaces(),
|
||||
isBookmark = CKEDITOR.dom.walker.bookmark(),
|
||||
isTemp = CKEDITOR.dom.walker.temp(),
|
||||
toSkip = function( node ) {
|
||||
return isBookmark( node ) ||
|
||||
isWhitespaces( node ) ||
|
||||
node.type == CKEDITOR.NODE_ELEMENT && node.is( CKEDITOR.dtd.$inline ) && !node.is( CKEDITOR.dtd.$empty );
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node should be ignored in terms of "editability".
|
||||
*
|
||||
* This includes:
|
||||
*
|
||||
* * whitespaces (see {@link CKEDITOR.dom.walker#whitespaces}),
|
||||
* * bookmarks (see {@link CKEDITOR.dom.walker#bookmark}),
|
||||
* * temporary elements (see {@link CKEDITOR.dom.walker#temp}).
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the
|
||||
* ignored element instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.ignored = function( isReject ) {
|
||||
return function( node ) {
|
||||
var isIgnored = isWhitespaces( node ) || isBookmark( node ) || isTemp( node );
|
||||
|
||||
return !!( isReject ^ isIgnored );
|
||||
};
|
||||
};
|
||||
|
||||
var isIgnored = CKEDITOR.dom.walker.ignored();
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node is empty.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the
|
||||
* ignored element instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.empty = function( isReject ) {
|
||||
return function( node ) {
|
||||
var i = 0,
|
||||
l = node.getChildCount();
|
||||
|
||||
for ( ; i < l; ++i ) {
|
||||
if ( !isIgnored( node.getChild( i ) ) ) {
|
||||
return !!isReject;
|
||||
}
|
||||
}
|
||||
|
||||
return !isReject;
|
||||
};
|
||||
};
|
||||
|
||||
var isEmpty = CKEDITOR.dom.walker.empty();
|
||||
|
||||
function filterTextContainers( dtd ) {
|
||||
var hash = {},
|
||||
name;
|
||||
|
||||
for ( name in dtd ) {
|
||||
if ( CKEDITOR.dtd[ name ][ '#' ] )
|
||||
hash[ name ] = 1;
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* A hash of element names which in browsers that {@link CKEDITOR.env#needsBrFiller do not need `<br>` fillers}
|
||||
* can be selection containers despite being empty.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @static
|
||||
* @property {Object} validEmptyBlockContainers
|
||||
*/
|
||||
var validEmptyBlocks = CKEDITOR.dom.walker.validEmptyBlockContainers = CKEDITOR.tools.extend(
|
||||
filterTextContainers( CKEDITOR.dtd.$block ),
|
||||
{ caption: 1, td: 1, th: 1 }
|
||||
);
|
||||
|
||||
function isEditable( node ) {
|
||||
// Skip temporary elements, bookmarks and whitespaces.
|
||||
if ( isIgnored( node ) )
|
||||
return false;
|
||||
|
||||
if ( node.type == CKEDITOR.NODE_TEXT )
|
||||
return true;
|
||||
|
||||
if ( node.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
// All inline and non-editable elements are valid editable places.
|
||||
// Note: the <hr> is currently the only element in CKEDITOR.dtd.$empty and CKEDITOR.dtd.$block,
|
||||
// but generally speaking we need an intersection of these two sets.
|
||||
// Note: non-editable block has to be treated differently (should be selected entirely).
|
||||
if ( node.is( CKEDITOR.dtd.$inline ) || node.is( 'hr' ) || node.getAttribute( 'contenteditable' ) == 'false' )
|
||||
return true;
|
||||
|
||||
// Empty blocks are editable on IE.
|
||||
if ( !CKEDITOR.env.needsBrFiller && node.is( validEmptyBlocks ) && isEmpty( node ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
// Skip all other nodes.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function which checks whether the node can be a container or a sibling
|
||||
* of the selection end.
|
||||
*
|
||||
* This includes:
|
||||
*
|
||||
* * text nodes (but not whitespaces),
|
||||
* * inline elements,
|
||||
* * intersection of {@link CKEDITOR.dtd#$empty} and {@link CKEDITOR.dtd#$block} (currently
|
||||
* it is only `<hr>`),
|
||||
* * non-editable blocks (special case — such blocks cannot be containers nor
|
||||
* siblings, they need to be selected entirely),
|
||||
* * empty {@link #validEmptyBlockContainers blocks} which can contain text
|
||||
* ({@link CKEDITOR.env#needsBrFiller old IEs only}).
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @static
|
||||
* @param {Boolean} [isReject=false] Whether to return `false` for the
|
||||
* ignored element instead of `true` (default).
|
||||
* @returns {Function}
|
||||
*/
|
||||
CKEDITOR.dom.walker.editable = function( isReject ) {
|
||||
return function( node ) {
|
||||
return !!( isReject ^ isEditable( node ) );
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if there is a filler node at the end of an element, and returns it.
|
||||
*
|
||||
* @member CKEDITOR.dom.element
|
||||
* @returns {CKEDITOR.dom.node/Boolean} Bogus node or `false`.
|
||||
*/
|
||||
CKEDITOR.dom.element.prototype.getBogus = function() {
|
||||
// Bogus are not always at the end, e.g. <p><a>text<br /></a></p> (https://dev.ckeditor.com/ticket/7070).
|
||||
var tail = this;
|
||||
do {
|
||||
tail = tail.getPreviousSourceNode();
|
||||
}
|
||||
while ( toSkip( tail ) );
|
||||
|
||||
if ( tail && ( CKEDITOR.env.needsBrFiller ? tail.is && tail.is( 'br' ) : tail.getText && tailNbspRegex.test( tail.getText() ) ) )
|
||||
return tail;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
} )();
|
||||
95
Admin/plugins/ckeditor/core/dom/window.js
Normal file
95
Admin/plugins/ckeditor/core/dom/window.js
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dom.document} class, which
|
||||
* represents a DOM document.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a DOM window.
|
||||
*
|
||||
* var document = new CKEDITOR.dom.window( window );
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.dom.domObject
|
||||
* @constructor Creates a window class instance.
|
||||
* @param {Object} domWindow A native DOM window.
|
||||
*/
|
||||
CKEDITOR.dom.window = function( domWindow ) {
|
||||
CKEDITOR.dom.domObject.call( this, domWindow );
|
||||
};
|
||||
|
||||
CKEDITOR.dom.window.prototype = new CKEDITOR.dom.domObject();
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.dom.window.prototype, {
|
||||
/**
|
||||
* Moves the selection focus to this window.
|
||||
*
|
||||
* var win = new CKEDITOR.dom.window( window );
|
||||
* win.focus();
|
||||
*/
|
||||
focus: function() {
|
||||
this.$.focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the width and height of this window's viewable area.
|
||||
*
|
||||
* var win = new CKEDITOR.dom.window( window );
|
||||
* var size = win.getViewPaneSize();
|
||||
* alert( size.width );
|
||||
* alert( size.height );
|
||||
*
|
||||
* @returns {Object} An object with the `width` and `height`
|
||||
* properties containing the size.
|
||||
*/
|
||||
getViewPaneSize: function() {
|
||||
var doc = this.$.document,
|
||||
stdMode = doc.compatMode == 'CSS1Compat';
|
||||
return {
|
||||
width: ( stdMode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0,
|
||||
height: ( stdMode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the current position of the window's scroll.
|
||||
*
|
||||
* var win = new CKEDITOR.dom.window( window );
|
||||
* var pos = win.getScrollPosition();
|
||||
* alert( pos.x );
|
||||
* alert( pos.y );
|
||||
*
|
||||
* @returns {Object} An object with the `x` and `y` properties
|
||||
* containing the scroll position.
|
||||
*/
|
||||
getScrollPosition: function() {
|
||||
var $ = this.$;
|
||||
|
||||
if ( 'pageXOffset' in $ ) {
|
||||
return {
|
||||
x: $.pageXOffset || 0,
|
||||
y: $.pageYOffset || 0
|
||||
};
|
||||
} else {
|
||||
var doc = $.document;
|
||||
return {
|
||||
x: doc.documentElement.scrollLeft || doc.body.scrollLeft || 0,
|
||||
y: doc.documentElement.scrollTop || doc.body.scrollTop || 0
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the frame element containing this window context.
|
||||
*
|
||||
* @returns {CKEDITOR.dom.element} The frame element or `null` if not in a frame context.
|
||||
*/
|
||||
getFrame: function() {
|
||||
var iframe = this.$.frameElement;
|
||||
return iframe ? new CKEDITOR.dom.element.get( iframe ) : null;
|
||||
}
|
||||
} );
|
||||
370
Admin/plugins/ckeditor/core/dtd.js
Normal file
370
Admin/plugins/ckeditor/core/dtd.js
Normal file
@@ -0,0 +1,370 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.dtd} object, which holds the DTD
|
||||
* mapping for XHTML 1.0 Transitional. This file was automatically
|
||||
* generated from the file: xhtml1-transitional.dtd.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Holds and object representation of the HTML DTD to be used by the
|
||||
* editor in its internal operations.
|
||||
*
|
||||
* Each element in the DTD is represented by a property in this object. Each
|
||||
* property contains the list of elements that can be contained by the element.
|
||||
* Text is represented by the `#` property.
|
||||
*
|
||||
* Several special grouping properties are also available. Their names start
|
||||
* with the `$` character.
|
||||
*
|
||||
* // Check if <div> can be contained in a <p> element.
|
||||
* alert( !!CKEDITOR.dtd[ 'p' ][ 'div' ] ); // false
|
||||
*
|
||||
* // Check if <p> can be contained in a <div> element.
|
||||
* alert( !!CKEDITOR.dtd[ 'div' ][ 'p' ] ); // true
|
||||
*
|
||||
* // Check if <p> is a block element.
|
||||
* alert( !!CKEDITOR.dtd.$block[ 'p' ] ); // true
|
||||
*
|
||||
* It is also possible to add a new element to DTD. It will ensure it is handled correctly e.g. in terms of nesting or positioning.
|
||||
*
|
||||
* For example, you can define a block element, which can be empty:
|
||||
*
|
||||
* ```js
|
||||
* // Let's add a DTD for a new element <signature>
|
||||
* // and specify it can contain <p> and <img> elements:
|
||||
* CKEDITOR.dtd[ 'signature' ] = {
|
||||
* p: 1,
|
||||
* img: 1
|
||||
* };
|
||||
*
|
||||
* // Define <signature> as a block element.
|
||||
* CKEDITOR.dtd.$block[ 'signature' ] = 1;
|
||||
*
|
||||
* // Allow <signature> element to be empty.
|
||||
* CKEDITOR.dtd.$empty[ 'signature' ] = 1;
|
||||
* ```
|
||||
*
|
||||
* **Note**: Editing the DTD for existing elements is also possible this way, but may cause an unexpected outcome and inconsistent editing behaviour, so **it is not recommended**.
|
||||
*
|
||||
* @class CKEDITOR.dtd
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.dtd = ( function() {
|
||||
'use strict';
|
||||
|
||||
var X = CKEDITOR.tools.extend,
|
||||
// Subtraction rest of sets, from the first set.
|
||||
Y = function( source, removed ) {
|
||||
var substracted = CKEDITOR.tools.clone( source );
|
||||
for ( var i = 1; i < arguments.length; i++ ) {
|
||||
removed = arguments[ i ];
|
||||
for ( var name in removed )
|
||||
delete substracted[ name ];
|
||||
}
|
||||
return substracted;
|
||||
};
|
||||
|
||||
// Phrasing elements.
|
||||
// P = { a: 1, em: 1, strong: 1, small: 1, abbr: 1, dfn: 1, i: 1, b: 1, s: 1,
|
||||
// u: 1, code: 1, 'var': 1, samp: 1, kbd: 1, sup: 1, sub: 1, q: 1, cite: 1,
|
||||
// span: 1, bdo: 1, bdi: 1, br: 1, wbr: 1, ins: 1, del: 1, img: 1, embed: 1,
|
||||
// object: 1, iframe: 1, map: 1, area: 1, script: 1, noscript: 1, ruby: 1,
|
||||
// video: 1, audio: 1, input: 1, textarea: 1, select: 1, button: 1, label: 1,
|
||||
// output: 1, keygen: 1, progress: 1, command: 1, canvas: 1, time: 1,
|
||||
// meter: 1, detalist: 1 },
|
||||
|
||||
// Flow elements.
|
||||
// F = { a: 1, p: 1, hr: 1, pre: 1, ul: 1, ol: 1, dl: 1, div: 1, h1: 1, h2: 1,
|
||||
// h3: 1, h4: 1, h5: 1, h6: 1, hgroup: 1, address: 1, blockquote: 1, ins: 1,
|
||||
// del: 1, object: 1, map: 1, noscript: 1, section: 1, nav: 1, article: 1,
|
||||
// aside: 1, header: 1, footer: 1, video: 1, audio: 1, figure: 1, table: 1,
|
||||
// form: 1, fieldset: 1, menu: 1, canvas: 1, details:1 },
|
||||
|
||||
// Text can be everywhere.
|
||||
// X( P, T );
|
||||
// Flow elements set consists of phrasing elements set.
|
||||
// X( F, P );
|
||||
|
||||
var P = {}, F = {},
|
||||
// Intersection of flow elements set and phrasing elements set.
|
||||
PF = {
|
||||
a: 1, abbr: 1, area: 1, audio: 1, b: 1, bdi: 1, bdo: 1, br: 1, button: 1, canvas: 1, cite: 1,
|
||||
code: 1, command: 1, datalist: 1, del: 1, dfn: 1, em: 1, embed: 1, i: 1, iframe: 1, img: 1,
|
||||
input: 1, ins: 1, kbd: 1, keygen: 1, label: 1, map: 1, mark: 1, meter: 1, noscript: 1, object: 1,
|
||||
output: 1, progress: 1, q: 1, ruby: 1, s: 1, samp: 1, script: 1, select: 1, small: 1, span: 1,
|
||||
strong: 1, sub: 1, sup: 1, textarea: 1, time: 1, u: 1, 'var': 1, video: 1, wbr: 1
|
||||
},
|
||||
// F - PF (Flow Only).
|
||||
FO = {
|
||||
address: 1, article: 1, aside: 1, blockquote: 1, details: 1, div: 1, dl: 1, fieldset: 1,
|
||||
figure: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1,
|
||||
hr: 1, main: 1, menu: 1, nav: 1, ol: 1, p: 1, pre: 1, section: 1, table: 1, ul: 1
|
||||
},
|
||||
// Metadata elements.
|
||||
M = { command: 1, link: 1, meta: 1, noscript: 1, script: 1, style: 1 },
|
||||
// Empty.
|
||||
E = {},
|
||||
// Text.
|
||||
T = { '#': 1 },
|
||||
|
||||
// Deprecated phrasing elements.
|
||||
DP = { acronym: 1, applet: 1, basefont: 1, big: 1, font: 1, isindex: 1, strike: 1, style: 1, tt: 1 }, // TODO remove "style".
|
||||
// Deprecated flow only elements.
|
||||
DFO = { center: 1, dir: 1, noframes: 1 };
|
||||
|
||||
// Phrasing elements := PF + T + DP
|
||||
X( P, PF, T, DP );
|
||||
// Flow elements := FO + P + DFO
|
||||
X( F, FO, P, DFO );
|
||||
|
||||
var dtd = {
|
||||
a: Y( P, { a: 1, button: 1 } ), // Treat as normal inline element (not a transparent one).
|
||||
abbr: P,
|
||||
address: F,
|
||||
area: E,
|
||||
article: F,
|
||||
aside: F,
|
||||
audio: X( { source: 1, track: 1 }, F ),
|
||||
b: P,
|
||||
base: E,
|
||||
bdi: P,
|
||||
bdo: P,
|
||||
blockquote: F,
|
||||
body: F,
|
||||
br: E,
|
||||
button: Y( P, { a: 1, button: 1 } ),
|
||||
canvas: P, // Treat as normal inline element (not a transparent one).
|
||||
caption: F,
|
||||
cite: P,
|
||||
code: P,
|
||||
col: E,
|
||||
colgroup: { col: 1 },
|
||||
command: E,
|
||||
datalist: X( { option: 1 }, P ),
|
||||
dd: F,
|
||||
del: P, // Treat as normal inline element (not a transparent one).
|
||||
details: X( { summary: 1 }, F ),
|
||||
dfn: P,
|
||||
div: F,
|
||||
dl: { dt: 1, dd: 1 },
|
||||
dt: F,
|
||||
em: P,
|
||||
embed: E,
|
||||
fieldset: X( { legend: 1 }, F ),
|
||||
figcaption: F,
|
||||
figure: X( { figcaption: 1 }, F ),
|
||||
footer: F,
|
||||
form: F,
|
||||
h1: P,
|
||||
h2: P,
|
||||
h3: P,
|
||||
h4: P,
|
||||
h5: P,
|
||||
h6: P,
|
||||
head: X( { title: 1, base: 1 }, M ),
|
||||
header: F,
|
||||
hgroup: { h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 },
|
||||
hr: E,
|
||||
html: X( { head: 1, body: 1 }, F, M ), // Head and body are optional...
|
||||
i: P,
|
||||
iframe: T,
|
||||
img: E,
|
||||
input: E,
|
||||
ins: P, // Treat as normal inline element (not a transparent one).
|
||||
kbd: P,
|
||||
keygen: E,
|
||||
label: P,
|
||||
legend: P,
|
||||
li: F,
|
||||
link: E,
|
||||
// Can't be a descendant of article, aside, footer, header, nav, but we don't need this
|
||||
// complication. As well as checking if it's used only once.
|
||||
main: F,
|
||||
map: F,
|
||||
mark: P, // Treat as normal inline element (not a transparent one).
|
||||
menu: X( { li: 1 }, F ),
|
||||
meta: E,
|
||||
meter: Y( P, { meter: 1 } ),
|
||||
nav: F,
|
||||
noscript: X( { link: 1, meta: 1, style: 1 }, P ), // Treat as normal inline element (not a transparent one).
|
||||
object: X( { param: 1 }, P ), // Treat as normal inline element (not a transparent one).
|
||||
ol: { li: 1 },
|
||||
optgroup: { option: 1 },
|
||||
option: T,
|
||||
output: P,
|
||||
p: P,
|
||||
param: E,
|
||||
pre: P,
|
||||
progress: Y( P, { progress: 1 } ),
|
||||
q: P,
|
||||
rp: P,
|
||||
rt: P,
|
||||
ruby: X( { rp: 1, rt: 1 }, P ),
|
||||
s: P,
|
||||
samp: P,
|
||||
script: T,
|
||||
section: F,
|
||||
select: { optgroup: 1, option: 1 },
|
||||
small: P,
|
||||
source: E,
|
||||
span: P,
|
||||
strong: P,
|
||||
style: T,
|
||||
sub: P,
|
||||
summary: X( { h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 }, P ),
|
||||
sup: P,
|
||||
table: { caption: 1, colgroup: 1, thead: 1, tfoot: 1, tbody: 1, tr: 1 },
|
||||
tbody: { tr: 1 },
|
||||
td: F,
|
||||
textarea: T,
|
||||
tfoot: { tr: 1 },
|
||||
th: F,
|
||||
thead: { tr: 1 },
|
||||
time: Y( P, { time: 1 } ),
|
||||
title: T,
|
||||
tr: { th: 1, td: 1 },
|
||||
track: E,
|
||||
u: P,
|
||||
ul: { li: 1 },
|
||||
'var': P,
|
||||
video: X( { source: 1, track: 1 }, F ),
|
||||
wbr: E,
|
||||
|
||||
// Deprecated tags.
|
||||
acronym: P,
|
||||
applet: X( { param: 1 }, F ),
|
||||
basefont: E,
|
||||
big: P,
|
||||
center: F,
|
||||
dialog: E,
|
||||
dir: { li: 1 },
|
||||
font: P,
|
||||
isindex: E,
|
||||
noframes: F,
|
||||
strike: P,
|
||||
tt: P
|
||||
};
|
||||
|
||||
X( dtd, {
|
||||
/**
|
||||
* List of block elements, like `<p>` or `<div>`.
|
||||
*/
|
||||
$block: X( { audio: 1, dd: 1, dt: 1, figcaption: 1, li: 1, video: 1 }, FO, DFO ),
|
||||
|
||||
/**
|
||||
* List of elements that contain other blocks, in which block-level operations should be limited,
|
||||
* this property is not intended to be checked directly, use {@link CKEDITOR.dom.elementPath#blockLimit} instead.
|
||||
*
|
||||
* Some examples of editor behaviors that are impacted by block limits:
|
||||
*
|
||||
* * Enter key never split a block-limit element;
|
||||
* * Style application is constraint by the block limit of the current selection.
|
||||
* * Pasted html will be inserted into the block limit of the current selection.
|
||||
*
|
||||
* **Note:** As an exception `<li>` is not considered as a block limit, as it's generally used as a text block.
|
||||
*/
|
||||
$blockLimit: {
|
||||
article: 1, aside: 1, audio: 1, body: 1, caption: 1, details: 1, dir: 1, div: 1, dl: 1,
|
||||
fieldset: 1, figcaption: 1, figure: 1, footer: 1, form: 1, header: 1, hgroup: 1, main: 1, menu: 1, nav: 1,
|
||||
ol: 1, section: 1, table: 1, td: 1, th: 1, tr: 1, ul: 1, video: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of elements that contain character data.
|
||||
*/
|
||||
$cdata: { script: 1, style: 1 },
|
||||
|
||||
/**
|
||||
* List of elements that are accepted as inline editing hosts.
|
||||
*/
|
||||
$editable: {
|
||||
address: 1, article: 1, aside: 1, blockquote: 1, body: 1, details: 1, div: 1, fieldset: 1,
|
||||
figcaption: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1,
|
||||
main: 1, nav: 1, p: 1, pre: 1, section: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of empty (self-closing) elements, like `<br>` or `<img>`.
|
||||
*/
|
||||
$empty: {
|
||||
area: 1, base: 1, basefont: 1, br: 1, col: 1, command: 1, dialog: 1, embed: 1, hr: 1, img: 1,
|
||||
input: 1, isindex: 1, keygen: 1, link: 1, meta: 1, param: 1, source: 1, track: 1, wbr: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of inline (`<span>` like) elements.
|
||||
*/
|
||||
$inline: P,
|
||||
|
||||
/**
|
||||
* List of list root elements.
|
||||
*/
|
||||
$list: { dl: 1, ol: 1, ul: 1 },
|
||||
|
||||
/**
|
||||
* List of list item elements, like `<li>` or `<dd>`.
|
||||
*/
|
||||
$listItem: { dd: 1, dt: 1, li: 1 },
|
||||
|
||||
/**
|
||||
* List of elements which may live outside body.
|
||||
*/
|
||||
$nonBodyContent: X( { body: 1, head: 1, html: 1 }, dtd.head ),
|
||||
|
||||
/**
|
||||
* Elements that accept text nodes, but are not possible to edit into the browser.
|
||||
*/
|
||||
$nonEditable: {
|
||||
applet: 1, audio: 1, button: 1, embed: 1, iframe: 1, map: 1, object: 1, option: 1,
|
||||
param: 1, script: 1, textarea: 1, video: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* Elements that are considered objects, therefore selected as a whole in the editor.
|
||||
*/
|
||||
$object: {
|
||||
applet: 1, audio: 1, button: 1, hr: 1, iframe: 1, img: 1, input: 1, object: 1, select: 1,
|
||||
table: 1, textarea: 1, video: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of elements that can be ignored if empty, like `<b>` or `<span>`.
|
||||
*/
|
||||
$removeEmpty: {
|
||||
abbr: 1, acronym: 1, b: 1, bdi: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1, dfn: 1,
|
||||
em: 1, font: 1, i: 1, ins: 1, label: 1, kbd: 1, mark: 1, meter: 1, output: 1, q: 1, ruby: 1, s: 1,
|
||||
samp: 1, small: 1, span: 1, strike: 1, strong: 1, sub: 1, sup: 1, time: 1, tt: 1, u: 1, 'var': 1
|
||||
},
|
||||
|
||||
/**
|
||||
* List of elements that have tabindex set to zero by default.
|
||||
*/
|
||||
$tabIndex: { a: 1, area: 1, button: 1, input: 1, object: 1, select: 1, textarea: 1 },
|
||||
|
||||
/**
|
||||
* List of elements used inside the `<table>` element, like `<tbody>` or `<td>`.
|
||||
*/
|
||||
$tableContent: { caption: 1, col: 1, colgroup: 1, tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, tr: 1 },
|
||||
|
||||
/**
|
||||
* List of "transparent" elements. See [W3C's definition of "transparent" element](http://dev.w3.org/html5/markup/terminology.html#transparent).
|
||||
*/
|
||||
$transparent: { a: 1, audio: 1, canvas: 1, del: 1, ins: 1, map: 1, noscript: 1, object: 1, video: 1 },
|
||||
|
||||
/**
|
||||
* List of elements that are not to exist standalone that must live under it's parent element.
|
||||
*/
|
||||
$intermediate: {
|
||||
caption: 1, colgroup: 1, dd: 1, dt: 1, figcaption: 1, legend: 1, li: 1, optgroup: 1,
|
||||
option: 1, rp: 1, rt: 1, summary: 1, tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, tr: 1
|
||||
}
|
||||
} );
|
||||
|
||||
return dtd;
|
||||
} )();
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.dtd )
|
||||
3507
Admin/plugins/ckeditor/core/editable.js
Normal file
3507
Admin/plugins/ckeditor/core/editable.js
Normal file
File diff suppressed because it is too large
Load Diff
2453
Admin/plugins/ckeditor/core/editor.js
Normal file
2453
Admin/plugins/ckeditor/core/editor.js
Normal file
File diff suppressed because it is too large
Load Diff
36
Admin/plugins/ckeditor/core/editor_basic.js
Normal file
36
Admin/plugins/ckeditor/core/editor_basic.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
if ( !CKEDITOR.editor ) {
|
||||
// Documented at editor.js.
|
||||
CKEDITOR.editor = function() {
|
||||
// Push this editor to the pending list. It'll be processed later once
|
||||
// the full editor code is loaded.
|
||||
CKEDITOR._.pending.push( [ this, arguments ] );
|
||||
|
||||
// Call the CKEDITOR.event constructor to initialize this instance.
|
||||
CKEDITOR.event.call( this );
|
||||
};
|
||||
|
||||
// Both fire and fireOnce will always pass this editor instance as the
|
||||
// "editor" param in CKEDITOR.event.fire. So, we override it to do that
|
||||
// automaticaly.
|
||||
CKEDITOR.editor.prototype.fire = function( eventName, data ) {
|
||||
if ( eventName in { instanceReady: 1, loaded: 1 } )
|
||||
this[ eventName ] = true;
|
||||
|
||||
return CKEDITOR.event.prototype.fire.call( this, eventName, data, this );
|
||||
};
|
||||
|
||||
CKEDITOR.editor.prototype.fireOnce = function( eventName, data ) {
|
||||
if ( eventName in { instanceReady: 1, loaded: 1 } )
|
||||
this[ eventName ] = true;
|
||||
|
||||
return CKEDITOR.event.prototype.fireOnce.call( this, eventName, data, this );
|
||||
};
|
||||
|
||||
// "Inherit" (copy actually) from CKEDITOR.event.
|
||||
CKEDITOR.event.implementOn( CKEDITOR.editor.prototype );
|
||||
}
|
||||
361
Admin/plugins/ckeditor/core/env.js
Normal file
361
Admin/plugins/ckeditor/core/env.js
Normal file
@@ -0,0 +1,361 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.env} object which contains
|
||||
* environment and browser information.
|
||||
*/
|
||||
|
||||
if ( !CKEDITOR.env ) {
|
||||
/**
|
||||
* Environment and browser information.
|
||||
*
|
||||
* @class CKEDITOR.env
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.env = ( function() {
|
||||
var agent = navigator.userAgent.toLowerCase(),
|
||||
edge = agent.match( /edge[ \/](\d+.?\d*)/ ),
|
||||
trident = agent.indexOf( 'trident/' ) > -1,
|
||||
ie = !!( edge || trident );
|
||||
|
||||
var env = {
|
||||
/**
|
||||
* Indicates that CKEditor is running in Internet Explorer.
|
||||
*
|
||||
* if ( CKEDITOR.env.ie )
|
||||
* alert( 'I\'m running in IE!' );
|
||||
*
|
||||
* **Note:** This property is also set to `true` if CKEditor is running
|
||||
* in {@link #edge Microsoft Edge}.
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
ie: ie,
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Microsoft Edge.
|
||||
*
|
||||
* if ( CKEDITOR.env.edge )
|
||||
* alert( 'I\'m running in Edge!' );
|
||||
*
|
||||
* See also {@link #ie}.
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @property {Boolean}
|
||||
*/
|
||||
edge: !!edge,
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a WebKit-based browser, like Safari,
|
||||
* or Blink-based browser, like Chrome.
|
||||
*
|
||||
* if ( CKEDITOR.env.webkit )
|
||||
* alert( 'I\'m running in a WebKit browser!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
webkit: !ie && ( agent.indexOf( ' applewebkit/' ) > -1 ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Adobe AIR.
|
||||
*
|
||||
* if ( CKEDITOR.env.air )
|
||||
* alert( 'I\'m on AIR!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
air: ( agent.indexOf( ' adobeair/' ) > -1 ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running on Macintosh.
|
||||
*
|
||||
* if ( CKEDITOR.env.mac )
|
||||
* alert( 'I love apples!'' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
mac: ( agent.indexOf( 'macintosh' ) > -1 ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a Quirks Mode environment.
|
||||
*
|
||||
* if ( CKEDITOR.env.quirks )
|
||||
* alert( 'Nooooo!' );
|
||||
*
|
||||
* Internet Explorer 10 introduced the _New Quirks Mode_, which is similar to the _Quirks Mode_
|
||||
* implemented in other modern browsers and defined in the HTML5 specification. It can be handled
|
||||
* as the Standards mode, so the value of this property will be set to `false`.
|
||||
*
|
||||
* The _Internet Explorer 5 Quirks_ mode which is still available in Internet Explorer 10+
|
||||
* sets this value to `true` and {@link #version} to `7`.
|
||||
*
|
||||
* Read more: [IEBlog](http://blogs.msdn.com/b/ie/archive/2011/12/14/interoperable-html5-quirks-mode-in-ie10.aspx)
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
quirks: ( document.compatMode == 'BackCompat' && ( !document.documentMode || document.documentMode < 10 ) ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a mobile environemnt.
|
||||
*
|
||||
* if ( CKEDITOR.env.mobile )
|
||||
* alert( 'I\'m running with CKEditor today!' );
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean}
|
||||
*/
|
||||
mobile: ( agent.indexOf( 'mobile' ) > -1 ),
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running on Apple iPhone/iPad/iPod devices.
|
||||
*
|
||||
* if ( CKEDITOR.env.iOS )
|
||||
* alert( 'I like little apples!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
iOS: /(ipad|iphone|ipod)/.test( agent ),
|
||||
|
||||
/**
|
||||
* Indicates that the browser has a custom domain enabled. This has
|
||||
* been set with `document.domain`.
|
||||
*
|
||||
* if ( CKEDITOR.env.isCustomDomain() )
|
||||
* alert( 'I\'m in a custom domain!' );
|
||||
*
|
||||
* @returns {Boolean} `true` if a custom domain is enabled.
|
||||
* @deprecated
|
||||
*/
|
||||
isCustomDomain: function() {
|
||||
if ( !this.ie )
|
||||
return false;
|
||||
|
||||
var domain = document.domain,
|
||||
hostname = window.location.hostname;
|
||||
|
||||
return domain != hostname && domain != ( '[' + hostname + ']' ); // IPv6 IP support (https://dev.ckeditor.com/ticket/5434)
|
||||
},
|
||||
|
||||
/**
|
||||
* Indicates that the page is running under an encrypted connection.
|
||||
*
|
||||
* if ( CKEDITOR.env.secure )
|
||||
* alert( 'I\'m on SSL!' );
|
||||
*
|
||||
* @returns {Boolean} `true` if the page has an encrypted connection.
|
||||
*/
|
||||
secure: location.protocol == 'https:'
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a Gecko-based browser, like
|
||||
* Firefox.
|
||||
*
|
||||
* if ( CKEDITOR.env.gecko )
|
||||
* alert( 'I\'m riding a gecko!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.gecko = ( navigator.product == 'Gecko' && !env.webkit && !env.ie );
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a Blink-based browser like Chrome.
|
||||
*
|
||||
* if ( CKEDITOR.env.chrome )
|
||||
* alert( 'I\'m running in Chrome!' );
|
||||
*
|
||||
* @property {Boolean} chrome
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Safari (including the mobile version).
|
||||
*
|
||||
* if ( CKEDITOR.env.safari )
|
||||
* alert( 'I\'m on Safari!' );
|
||||
*
|
||||
* @property {Boolean} safari
|
||||
*/
|
||||
if ( env.webkit ) {
|
||||
if ( agent.indexOf( 'chrome' ) > -1 )
|
||||
env.chrome = true;
|
||||
else
|
||||
env.safari = true;
|
||||
}
|
||||
|
||||
var version = 0;
|
||||
|
||||
// Internet Explorer 6.0+
|
||||
if ( env.ie ) {
|
||||
// We use env.version for feature detection, so set it properly.
|
||||
if ( edge ) {
|
||||
version = parseFloat( edge[ 1 ] );
|
||||
} else if ( env.quirks || !document.documentMode ) {
|
||||
version = parseFloat( agent.match( /msie (\d+)/ )[ 1 ] );
|
||||
} else {
|
||||
version = document.documentMode;
|
||||
}
|
||||
|
||||
// Deprecated features available just for backwards compatibility.
|
||||
env.ie9Compat = version == 9;
|
||||
env.ie8Compat = version == 8;
|
||||
env.ie7Compat = version == 7;
|
||||
env.ie6Compat = version < 7 || env.quirks;
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in an IE6-like environment, which
|
||||
* includes IE6 itself as well as IE7, IE8 and IE9 in Quirks Mode.
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean} ie6Compat
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in an IE7-like environment, which
|
||||
* includes IE7 itself and IE8's IE7 Document Mode.
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean} ie7Compat
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Internet Explorer 8 on
|
||||
* Standards Mode.
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean} ie8Compat
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in Internet Explorer 9 on
|
||||
* Standards Mode.
|
||||
*
|
||||
* @deprecated
|
||||
* @property {Boolean} ie9Compat
|
||||
*/
|
||||
}
|
||||
|
||||
// Gecko.
|
||||
if ( env.gecko ) {
|
||||
var geckoRelease = agent.match( /rv:([\d\.]+)/ );
|
||||
if ( geckoRelease ) {
|
||||
geckoRelease = geckoRelease[ 1 ].split( '.' );
|
||||
version = geckoRelease[ 0 ] * 10000 + ( geckoRelease[ 1 ] || 0 ) * 100 + ( geckoRelease[ 2 ] || 0 ) * 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Adobe AIR 1.0+
|
||||
// Checked before Safari because AIR have the WebKit rich text editor
|
||||
// features from Safari 3.0.4, but the version reported is 420.
|
||||
if ( env.air )
|
||||
version = parseFloat( agent.match( / adobeair\/(\d+)/ )[ 1 ] );
|
||||
|
||||
// WebKit 522+ (Safari 3+)
|
||||
if ( env.webkit )
|
||||
version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[ 1 ] );
|
||||
|
||||
/**
|
||||
* Contains the browser version.
|
||||
*
|
||||
* For Gecko-based browsers (like Firefox) it contains the revision
|
||||
* number with first three parts concatenated with a padding zero
|
||||
* (e.g. for revision 1.9.0.2 we have 10900).
|
||||
*
|
||||
* For WebKit-based browsers (like Safari and Chrome) it contains the
|
||||
* WebKit build version (e.g. 522).
|
||||
*
|
||||
* For IE browsers, it matches the "Document Mode".
|
||||
*
|
||||
* if ( CKEDITOR.env.ie && CKEDITOR.env.version <= 6 )
|
||||
* alert( 'Ouch!' );
|
||||
*
|
||||
* @property {Number}
|
||||
*/
|
||||
env.version = version;
|
||||
|
||||
/**
|
||||
* Since CKEditor 4.5.0 this property is a blacklist of browsers incompatible with CKEditor. It means that it is
|
||||
* set to `false` only in browsers that are known to be incompatible. Before CKEditor 4.5.0 this
|
||||
* property was a whitelist of browsers that were known to be compatible with CKEditor.
|
||||
*
|
||||
* The reason for this change is the rising fragmentation of the browser market (especially the mobile segment).
|
||||
* It became too complicated to check in which new environments CKEditor is going to work.
|
||||
*
|
||||
* In order to enable CKEditor 4.4.x and below in unsupported environments see the
|
||||
* {@glink guide/dev_unsupported_environments Enabling CKEditor in Unsupported Environments} article.
|
||||
*
|
||||
* if ( CKEDITOR.env.isCompatible )
|
||||
* alert( 'Your browser is not known to be incompatible with CKEditor!' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.isCompatible =
|
||||
// IE 7+ (IE 7 is not supported, but IE Compat Mode is and it is recognized as IE7).
|
||||
!( env.ie && version < 7 ) &&
|
||||
// Firefox 4.0+.
|
||||
!( env.gecko && version < 40000 ) &&
|
||||
// Chrome 6+, Safari 5.1+, iOS 5+.
|
||||
!( env.webkit && version < 534 );
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in the HiDPI environment.
|
||||
*
|
||||
* if ( CKEDITOR.env.hidpi )
|
||||
* alert( 'You are using a screen with high pixel density.' );
|
||||
*
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.hidpi = window.devicePixelRatio >= 2;
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a browser which uses a bogus
|
||||
* `<br>` filler in order to correctly display caret in empty blocks.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.needsBrFiller = env.gecko || env.webkit || ( env.ie && version > 10 );
|
||||
|
||||
/**
|
||||
* Indicates that CKEditor is running in a browser which needs a
|
||||
* non-breaking space filler in order to correctly display caret in empty blocks.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @property {Boolean}
|
||||
*/
|
||||
env.needsNbspFiller = env.ie && version < 11;
|
||||
|
||||
/**
|
||||
* A CSS class that denotes the browser where CKEditor runs and is appended
|
||||
* to the HTML element that contains the editor. It makes it easier to apply
|
||||
* browser-specific styles to editor instances.
|
||||
*
|
||||
* myDiv.className = CKEDITOR.env.cssClass;
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
env.cssClass = 'cke_browser_' + ( env.ie ? 'ie' : env.gecko ? 'gecko' : env.webkit ? 'webkit' : 'unknown' );
|
||||
|
||||
if ( env.quirks )
|
||||
env.cssClass += ' cke_browser_quirks';
|
||||
|
||||
if ( env.ie )
|
||||
env.cssClass += ' cke_browser_ie' + ( env.quirks ? '6 cke_browser_iequirks' : env.version );
|
||||
|
||||
if ( env.air )
|
||||
env.cssClass += ' cke_browser_air';
|
||||
|
||||
if ( env.iOS )
|
||||
env.cssClass += ' cke_browser_ios';
|
||||
|
||||
if ( env.hidpi )
|
||||
env.cssClass += ' cke_hidpi';
|
||||
|
||||
return env;
|
||||
} )();
|
||||
}
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.env )
|
||||
// PACKAGER_RENAME( CKEDITOR.env.ie )
|
||||
413
Admin/plugins/ckeditor/core/event.js
Normal file
413
Admin/plugins/ckeditor/core/event.js
Normal file
@@ -0,0 +1,413 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.event} class, which serves as the
|
||||
* base for classes and objects that require event handling features.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
'use strict';
|
||||
|
||||
// Instead of false, we mark event cancellation with unique object (#4652).
|
||||
var EVENT_CANCELED = {};
|
||||
|
||||
if ( !CKEDITOR.event ) {
|
||||
/**
|
||||
* Creates an event class instance. This constructor is rarely used, being
|
||||
* the {@link #implementOn} function used in class prototypes directly
|
||||
* instead.
|
||||
*
|
||||
* This is a base class for classes and objects that require event
|
||||
* handling features.
|
||||
*
|
||||
* Do not confuse this class with {@link CKEDITOR.dom.event} which is
|
||||
* instead used for DOM events. The CKEDITOR.event class implements the
|
||||
* internal event system used by the CKEditor to fire API related events.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates an event class instance.
|
||||
*/
|
||||
CKEDITOR.event = function() {};
|
||||
|
||||
/**
|
||||
* Implements the {@link CKEDITOR.event} features in an object.
|
||||
*
|
||||
* var myObject = { message: 'Example' };
|
||||
* CKEDITOR.event.implementOn( myObject );
|
||||
*
|
||||
* myObject.on( 'testEvent', function() {
|
||||
* alert( this.message );
|
||||
* } );
|
||||
* myObject.fire( 'testEvent' ); // 'Example'
|
||||
*
|
||||
* @static
|
||||
* @param {Object} targetObject The object into which implement the features.
|
||||
*/
|
||||
CKEDITOR.event.implementOn = function( targetObject ) {
|
||||
var eventProto = CKEDITOR.event.prototype;
|
||||
|
||||
for ( var prop in eventProto ) {
|
||||
if ( targetObject[ prop ] == null )
|
||||
targetObject[ prop ] = eventProto[ prop ];
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.event.prototype = ( function() {
|
||||
// Returns the private events object for a given object.
|
||||
var getPrivate = function( obj ) {
|
||||
var _ = ( obj.getPrivate && obj.getPrivate() ) || obj._ || ( obj._ = {} );
|
||||
return _.events || ( _.events = {} );
|
||||
};
|
||||
|
||||
var eventEntry = function( eventName ) {
|
||||
this.name = eventName;
|
||||
this.listeners = [];
|
||||
};
|
||||
|
||||
eventEntry.prototype = {
|
||||
// Get the listener index for a specified function.
|
||||
// Returns -1 if not found.
|
||||
getListenerIndex: function( listenerFunction ) {
|
||||
for ( var i = 0, listeners = this.listeners; i < listeners.length; i++ ) {
|
||||
if ( listeners[ i ].fn == listenerFunction )
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
// Retrieve the event entry on the event host (create it if needed).
|
||||
function getEntry( name ) {
|
||||
// Get the event entry (create it if needed).
|
||||
var events = getPrivate( this );
|
||||
return events[ name ] || ( events[ name ] = new eventEntry( name ) );
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Predefine some intrinsic properties on a specific event name.
|
||||
*
|
||||
* @param {String} name The event name
|
||||
* @param meta
|
||||
* @param [meta.errorProof=false] Whether the event firing should catch error thrown from a per listener call.
|
||||
*/
|
||||
define: function( name, meta ) {
|
||||
var entry = getEntry.call( this, name );
|
||||
CKEDITOR.tools.extend( entry, meta, true );
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a listener to a specific event in the current object.
|
||||
*
|
||||
* ```javascript
|
||||
* someObject.on( 'someEvent', function() {
|
||||
* alert( this == someObject ); // true
|
||||
* } );
|
||||
*
|
||||
* someObject.on( 'someEvent', function() {
|
||||
* alert( this == anotherObject ); // true
|
||||
* }, anotherObject );
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.listenerData ); // 'Example'
|
||||
* }, null, 'Example' );
|
||||
*
|
||||
* someObject.on( 'someEvent', function() { ... } ); // 2nd called
|
||||
* someObject.on( 'someEvent', function() { ... }, null, null, 100 ); // 3rd called
|
||||
* someObject.on( 'someEvent', function() { ... }, null, null, 1 ); // 1st called
|
||||
* ```
|
||||
*
|
||||
* **Note**: CKEditor's event system has a limitation that one function cannot be used as a listener for the same event more than once.
|
||||
* Hence, to reuse it with multiple listeners, it should be wrapped into additional wrapper function:
|
||||
*
|
||||
* ```javascript
|
||||
* function listener( evt ) { ... };
|
||||
*
|
||||
* someObject.on( 'someEvent', function() {
|
||||
* listener();
|
||||
* } );
|
||||
*
|
||||
* someObject.on( 'someEvent', function( evt ) {
|
||||
* listener( evt );
|
||||
* } );
|
||||
* ```
|
||||
*
|
||||
* @param {String} eventName The event name to which listen.
|
||||
* @param {Function} listenerFunction The function listening to the
|
||||
* event. A single {@link CKEDITOR.eventInfo} object instanced
|
||||
* is passed to this function containing all the event data.
|
||||
* @param {Object} [scopeObj] The object used to scope the listener
|
||||
* call (the `this` object). If omitted, the current object is used.
|
||||
* @param {Object} [listenerData] Data to be sent as the
|
||||
* {@link CKEDITOR.eventInfo#listenerData} when calling the
|
||||
* listener.
|
||||
* @param {Number} [priority=10] The listener priority. Lower priority
|
||||
* listeners are called first. Listeners with the same priority
|
||||
* value are called in registration order.
|
||||
* @returns {Object} An object containing the `removeListener`
|
||||
* function, which can be used to remove the listener at any time.
|
||||
*/
|
||||
on: function( eventName, listenerFunction, scopeObj, listenerData, priority ) {
|
||||
var me = this;
|
||||
|
||||
// Create the function to be fired for this listener.
|
||||
function listenerFirer( editor, publisherData, stopFn, cancelFn ) {
|
||||
var ev = {
|
||||
name: eventName,
|
||||
sender: this,
|
||||
editor: editor,
|
||||
data: publisherData,
|
||||
listenerData: listenerData,
|
||||
stop: stopFn,
|
||||
cancel: cancelFn,
|
||||
removeListener: removeListener
|
||||
};
|
||||
|
||||
var ret = listenerFunction.call( scopeObj, ev );
|
||||
|
||||
return ret === false ? EVENT_CANCELED : ev.data;
|
||||
}
|
||||
|
||||
function removeListener() {
|
||||
me.removeListener( eventName, listenerFunction );
|
||||
}
|
||||
|
||||
var event = getEntry.call( this, eventName );
|
||||
|
||||
if ( event.getListenerIndex( listenerFunction ) < 0 ) {
|
||||
// Get the listeners.
|
||||
var listeners = event.listeners;
|
||||
|
||||
// Fill the scope.
|
||||
if ( !scopeObj )
|
||||
scopeObj = this;
|
||||
|
||||
// Default the priority, if needed.
|
||||
if ( isNaN( priority ) )
|
||||
priority = 10;
|
||||
|
||||
listenerFirer.fn = listenerFunction;
|
||||
listenerFirer.priority = priority;
|
||||
|
||||
// Search for the right position for this new listener, based on its
|
||||
// priority.
|
||||
for ( var i = listeners.length - 1; i >= 0; i-- ) {
|
||||
// Find the item which should be before the new one.
|
||||
if ( listeners[ i ].priority <= priority ) {
|
||||
// Insert the listener in the array.
|
||||
listeners.splice( i + 1, 0, listenerFirer );
|
||||
return { removeListener: removeListener };
|
||||
}
|
||||
}
|
||||
|
||||
// If no position has been found (or zero length), put it in
|
||||
// the front of list.
|
||||
listeners.unshift( listenerFirer );
|
||||
}
|
||||
|
||||
return { removeListener: removeListener };
|
||||
},
|
||||
|
||||
/**
|
||||
* Similiar with {@link #on} but the listener will be called only once upon the next event firing.
|
||||
*
|
||||
* @see CKEDITOR.event#on
|
||||
*/
|
||||
once: function() {
|
||||
var args = Array.prototype.slice.call( arguments ),
|
||||
fn = args[ 1 ];
|
||||
|
||||
args[ 1 ] = function( evt ) {
|
||||
evt.removeListener();
|
||||
return fn.apply( this, arguments );
|
||||
};
|
||||
|
||||
return this.on.apply( this, args );
|
||||
},
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @property {Boolean} useCapture
|
||||
* @todo
|
||||
*/
|
||||
|
||||
/**
|
||||
* Register event handler under the capturing stage on supported target.
|
||||
*/
|
||||
capture: function() {
|
||||
CKEDITOR.event.useCapture = 1;
|
||||
var retval = this.on.apply( this, arguments );
|
||||
CKEDITOR.event.useCapture = 0;
|
||||
return retval;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fires an specific event in the object. All registered listeners are
|
||||
* called at this point.
|
||||
*
|
||||
* someObject.on( 'someEvent', function() { ... } );
|
||||
* someObject.on( 'someEvent', function() { ... } );
|
||||
* someObject.fire( 'someEvent' ); // Both listeners are called.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.data ); // 'Example'
|
||||
* } );
|
||||
* someObject.fire( 'someEvent', 'Example' );
|
||||
*
|
||||
* @method
|
||||
* @param {String} eventName The event name to fire.
|
||||
* @param {Object} [data] Data to be sent as the
|
||||
* {@link CKEDITOR.eventInfo#data} when calling the listeners.
|
||||
* @param {CKEDITOR.editor} [editor] The editor instance to send as the
|
||||
* {@link CKEDITOR.eventInfo#editor} when calling the listener.
|
||||
* @returns {Boolean/Object} A boolean indicating that the event is to be
|
||||
* canceled, or data returned by one of the listeners.
|
||||
*/
|
||||
fire: ( function() {
|
||||
// Create the function that marks the event as stopped.
|
||||
var stopped = 0;
|
||||
var stopEvent = function() {
|
||||
stopped = 1;
|
||||
};
|
||||
|
||||
// Create the function that marks the event as canceled.
|
||||
var canceled = 0;
|
||||
var cancelEvent = function() {
|
||||
canceled = 1;
|
||||
};
|
||||
|
||||
return function( eventName, data, editor ) {
|
||||
// Get the event entry.
|
||||
var event = getPrivate( this )[ eventName ];
|
||||
|
||||
// Save the previous stopped and cancelled states. We may
|
||||
// be nesting fire() calls.
|
||||
var previousStopped = stopped,
|
||||
previousCancelled = canceled;
|
||||
|
||||
// Reset the stopped and canceled flags.
|
||||
stopped = canceled = 0;
|
||||
|
||||
if ( event ) {
|
||||
var listeners = event.listeners;
|
||||
|
||||
if ( listeners.length ) {
|
||||
// As some listeners may remove themselves from the
|
||||
// event, the original array length is dinamic. So,
|
||||
// let's make a copy of all listeners, so we are
|
||||
// sure we'll call all of them.
|
||||
listeners = listeners.slice( 0 );
|
||||
|
||||
var retData;
|
||||
// Loop through all listeners.
|
||||
for ( var i = 0; i < listeners.length; i++ ) {
|
||||
// Call the listener, passing the event data.
|
||||
if ( event.errorProof ) {
|
||||
try {
|
||||
retData = listeners[ i ].call( this, editor, data, stopEvent, cancelEvent );
|
||||
} catch ( er ) {}
|
||||
} else {
|
||||
retData = listeners[ i ].call( this, editor, data, stopEvent, cancelEvent );
|
||||
}
|
||||
|
||||
if ( retData === EVENT_CANCELED )
|
||||
canceled = 1;
|
||||
else if ( typeof retData != 'undefined' )
|
||||
data = retData;
|
||||
|
||||
// No further calls is stopped or canceled.
|
||||
if ( stopped || canceled )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ret = canceled ? false : ( typeof data == 'undefined' ? true : data );
|
||||
|
||||
// Restore the previous stopped and canceled states.
|
||||
stopped = previousStopped;
|
||||
canceled = previousCancelled;
|
||||
|
||||
return ret;
|
||||
};
|
||||
} )(),
|
||||
|
||||
/**
|
||||
* Fires an specific event in the object, releasing all listeners
|
||||
* registered to that event. The same listeners are not called again on
|
||||
* successive calls of it or of {@link #fire}.
|
||||
*
|
||||
* someObject.on( 'someEvent', function() { ... } );
|
||||
* someObject.fire( 'someEvent' ); // Above listener called.
|
||||
* someObject.fireOnce( 'someEvent' ); // Above listener called.
|
||||
* someObject.fire( 'someEvent' ); // No listeners called.
|
||||
*
|
||||
* @param {String} eventName The event name to fire.
|
||||
* @param {Object} [data] Data to be sent as the
|
||||
* {@link CKEDITOR.eventInfo#data} when calling the listeners.
|
||||
* @param {CKEDITOR.editor} [editor] The editor instance to send as the
|
||||
* {@link CKEDITOR.eventInfo#editor} when calling the listener.
|
||||
* @returns {Boolean/Object} A booloan indicating that the event is to be
|
||||
* canceled, or data returned by one of the listeners.
|
||||
*/
|
||||
fireOnce: function( eventName, data, editor ) {
|
||||
var ret = this.fire( eventName, data, editor );
|
||||
delete getPrivate( this )[ eventName ];
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Unregisters a listener function from being called at the specified
|
||||
* event. No errors are thrown if the listener has not been registered previously.
|
||||
*
|
||||
* var myListener = function() { ... };
|
||||
* someObject.on( 'someEvent', myListener );
|
||||
* someObject.fire( 'someEvent' ); // myListener called.
|
||||
* someObject.removeListener( 'someEvent', myListener );
|
||||
* someObject.fire( 'someEvent' ); // myListener not called.
|
||||
*
|
||||
* @param {String} eventName The event name.
|
||||
* @param {Function} listenerFunction The listener function to unregister.
|
||||
*/
|
||||
removeListener: function( eventName, listenerFunction ) {
|
||||
// Get the event entry.
|
||||
var event = getPrivate( this )[ eventName ];
|
||||
|
||||
if ( event ) {
|
||||
var index = event.getListenerIndex( listenerFunction );
|
||||
if ( index >= 0 )
|
||||
event.listeners.splice( index, 1 );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all existing listeners on this object, for cleanup purpose.
|
||||
*/
|
||||
removeAllListeners: function() {
|
||||
var events = getPrivate( this );
|
||||
for ( var i in events )
|
||||
delete events[ i ];
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if there is any listener registered to a given event.
|
||||
*
|
||||
* var myListener = function() { ... };
|
||||
* someObject.on( 'someEvent', myListener );
|
||||
* alert( someObject.hasListeners( 'someEvent' ) ); // true
|
||||
* alert( someObject.hasListeners( 'noEvent' ) ); // false
|
||||
*
|
||||
* @param {String} eventName The event name.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
hasListeners: function( eventName ) {
|
||||
var event = getPrivate( this )[ eventName ];
|
||||
return ( event && event.listeners.length > 0 );
|
||||
}
|
||||
};
|
||||
} )();
|
||||
}
|
||||
} )();
|
||||
115
Admin/plugins/ckeditor/core/eventInfo.js
Normal file
115
Admin/plugins/ckeditor/core/eventInfo.js
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.eventInfo} class, which
|
||||
* contains the defintions of the event object passed to event listeners.
|
||||
* This file is for documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Virtual class that illustrates the features of the event object to be
|
||||
* passed to event listeners by a {@link CKEDITOR.event} based object.
|
||||
*
|
||||
* This class is not really part of the API.
|
||||
*
|
||||
* @class CKEDITOR.eventInfo
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* The event name.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.name ); // 'someEvent'
|
||||
* } );
|
||||
* someObject.fire( 'someEvent' );
|
||||
*
|
||||
* @property {String} name
|
||||
*/
|
||||
|
||||
/**
|
||||
* The object that publishes (sends) the event.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.sender == someObject ); // true
|
||||
* } );
|
||||
* someObject.fire( 'someEvent' );
|
||||
*
|
||||
* @property sender
|
||||
*/
|
||||
|
||||
/**
|
||||
* The editor instance that holds the sender. May be the same as sender. May be
|
||||
* null if the sender is not part of an editor instance, like a component
|
||||
* running in standalone mode.
|
||||
*
|
||||
* myButton.on( 'someEvent', function( event ) {
|
||||
* alert( event.editor == myEditor ); // true
|
||||
* } );
|
||||
* myButton.fire( 'someEvent', null, myEditor );
|
||||
*
|
||||
* @property {CKEDITOR.editor} editor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Any kind of additional data. Its format and usage is event dependent.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.data ); // 'Example'
|
||||
* } );
|
||||
* someObject.fire( 'someEvent', 'Example' );
|
||||
*
|
||||
* @property data
|
||||
*/
|
||||
|
||||
/**
|
||||
* Any extra data appended during the listener registration.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* alert( event.listenerData ); // 'Example'
|
||||
* }, null, 'Example' );
|
||||
*
|
||||
* @property listenerData
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that no further listeners are to be called.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* event.stop();
|
||||
* } );
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* // This one will not be called.
|
||||
* } );
|
||||
* alert( someObject.fire( 'someEvent' ) ); // true
|
||||
*
|
||||
* @method stop
|
||||
*/
|
||||
|
||||
/**
|
||||
* Indicates that the event is to be cancelled (if cancelable).
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* event.cancel();
|
||||
* } );
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* // This one will not be called.
|
||||
* } );
|
||||
* alert( someObject.fire( 'someEvent' ) ); // false
|
||||
*
|
||||
* @method cancel
|
||||
*/
|
||||
|
||||
/**
|
||||
* Removes the current listener.
|
||||
*
|
||||
* someObject.on( 'someEvent', function( event ) {
|
||||
* event.removeListener();
|
||||
* // Now this function won't be called again by 'someEvent'.
|
||||
* } );
|
||||
*
|
||||
* @method removeListener
|
||||
*/
|
||||
2584
Admin/plugins/ckeditor/core/filter.js
Normal file
2584
Admin/plugins/ckeditor/core/filter.js
Normal file
File diff suppressed because it is too large
Load Diff
275
Admin/plugins/ckeditor/core/focusmanager.js
Normal file
275
Admin/plugins/ckeditor/core/focusmanager.js
Normal file
@@ -0,0 +1,275 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.focusManager} class, which is used
|
||||
* to handle the focus in editor instances.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Manages the focus activity in an editor instance. This class is to be
|
||||
* used mainly by UI element coders when adding interface elements that need
|
||||
* to set the focus state of the editor.
|
||||
*
|
||||
* var focusManager = new CKEDITOR.focusManager( editor );
|
||||
* focusManager.focus();
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a focusManager class instance.
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
CKEDITOR.focusManager = function( editor ) {
|
||||
if ( editor.focusManager )
|
||||
return editor.focusManager;
|
||||
|
||||
/**
|
||||
* Indicates that the editor instance has focus.
|
||||
*
|
||||
* alert( CKEDITOR.instances.editor1.focusManager.hasFocus ); // e.g. true
|
||||
*/
|
||||
this.hasFocus = false;
|
||||
|
||||
/**
|
||||
* Indicates the currently focused DOM element that makes the editor activated.
|
||||
*
|
||||
* @property {CKEDITOR.dom.domObject}
|
||||
*/
|
||||
this.currentActive = null;
|
||||
|
||||
/**
|
||||
* Object used to store private stuff.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
this._ = {
|
||||
editor: editor
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
var SLOT_NAME = 'focusmanager',
|
||||
SLOT_NAME_LISTENERS = 'focusmanager_handlers';
|
||||
|
||||
/**
|
||||
* Object used to store private stuff.
|
||||
*
|
||||
* @private
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.focusManager._ = {
|
||||
/**
|
||||
* The delay (in milliseconds) to deactivate the editor when a UI DOM element has lost focus.
|
||||
*
|
||||
* @private
|
||||
* @property {Number} [blurDelay=200]
|
||||
* @member CKEDITOR.focusManager._
|
||||
*/
|
||||
blurDelay: 200
|
||||
};
|
||||
|
||||
CKEDITOR.focusManager.prototype = {
|
||||
|
||||
/**
|
||||
* Indicates that this editor instance is activated (due to a DOM focus change).
|
||||
* The `activated` state is a symbolic indicator of an active user
|
||||
* interaction session.
|
||||
*
|
||||
* **Note:** This method will not introduce UI focus
|
||||
* impact on DOM, it is here to record the editor UI focus state internally.
|
||||
* If you want to make the cursor blink inside the editable, use
|
||||
* {@link CKEDITOR.editor#method-focus} instead.
|
||||
*
|
||||
* var editor = CKEDITOR.instances.editor1;
|
||||
* editor.focusManager.focus( editor.editable() );
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} [currentActive] The new value of the {@link #currentActive} property.
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
focus: function( currentActive ) {
|
||||
if ( this._.timer )
|
||||
clearTimeout( this._.timer );
|
||||
|
||||
if ( currentActive )
|
||||
this.currentActive = currentActive;
|
||||
|
||||
if ( !( this.hasFocus || this._.locked ) ) {
|
||||
// If another editor has the current focus, we first "blur" it. In
|
||||
// this way the events happen in a more logical sequence, like:
|
||||
// "focus 1" > "blur 1" > "focus 2"
|
||||
// ... instead of:
|
||||
// "focus 1" > "focus 2" > "blur 1"
|
||||
var current = CKEDITOR.currentInstance;
|
||||
current && current.focusManager.blur( 1 );
|
||||
|
||||
this.hasFocus = true;
|
||||
|
||||
var ct = this._.editor.container;
|
||||
ct && ct.addClass( 'cke_focus' );
|
||||
this._.editor.fire( 'focus' );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Prevents from changing the focus manager state until the next {@link #unlock} is called.
|
||||
*
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
lock: function() {
|
||||
this._.locked = 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Restores the automatic focus management if {@link #lock} is called.
|
||||
*
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
unlock: function() {
|
||||
delete this._.locked;
|
||||
},
|
||||
|
||||
/**
|
||||
* Used to indicate that the editor instance has been deactivated by the specified
|
||||
* element which has just lost focus.
|
||||
*
|
||||
* **Note:** This function acts asynchronously with a delay of 100ms to
|
||||
* avoid temporary deactivation. Use the `noDelay` parameter instead
|
||||
* to deactivate immediately.
|
||||
*
|
||||
* var editor = CKEDITOR.instances.editor1;
|
||||
* editor.focusManager.blur();
|
||||
*
|
||||
* @param {Boolean} [noDelay=false] Immediately deactivate the editor instance synchronously.
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
blur: function( noDelay ) {
|
||||
if ( this._.locked ) {
|
||||
return;
|
||||
}
|
||||
|
||||
function doBlur() {
|
||||
if ( this.hasFocus ) {
|
||||
this.hasFocus = false;
|
||||
|
||||
var ct = this._.editor.container;
|
||||
ct && ct.removeClass( 'cke_focus' );
|
||||
this._.editor.fire( 'blur' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( this._.timer ) {
|
||||
clearTimeout( this._.timer );
|
||||
}
|
||||
|
||||
var delay = CKEDITOR.focusManager._.blurDelay;
|
||||
if ( noDelay || !delay ) {
|
||||
doBlur.call( this );
|
||||
} else {
|
||||
this._.timer = CKEDITOR.tools.setTimeout( function() {
|
||||
delete this._.timer;
|
||||
doBlur.call( this );
|
||||
}, delay, this );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers a UI DOM element to the focus manager, which will make the focus manager "hasFocus"
|
||||
* once the input focus is relieved on the element.
|
||||
* This method is designed to be used by plugins to expand the jurisdiction of the editor focus.
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} element The container (topmost) element of one UI part.
|
||||
* @param {Boolean} isCapture If specified, {@link CKEDITOR.event#useCapture} will be used when listening to the focus event.
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
add: function( element, isCapture ) {
|
||||
var fm = element.getCustomData( SLOT_NAME );
|
||||
if ( !fm || fm != this ) {
|
||||
// If this element is already taken by another instance, dismiss it first.
|
||||
fm && fm.remove( element );
|
||||
|
||||
var focusEvent = 'focus',
|
||||
blurEvent = 'blur';
|
||||
|
||||
// Bypass the element's internal DOM focus change.
|
||||
if ( isCapture ) {
|
||||
|
||||
// Use "focusin/focusout" events instead of capture phase in IEs,
|
||||
// which fires synchronously.
|
||||
if ( CKEDITOR.env.ie ) {
|
||||
focusEvent = 'focusin';
|
||||
blurEvent = 'focusout';
|
||||
} else {
|
||||
CKEDITOR.event.useCapture = 1;
|
||||
}
|
||||
}
|
||||
|
||||
var listeners = {
|
||||
blur: function() {
|
||||
if ( element.equals( this.currentActive ) )
|
||||
this.blur();
|
||||
},
|
||||
focus: function() {
|
||||
this.focus( element );
|
||||
}
|
||||
};
|
||||
|
||||
element.on( focusEvent, listeners.focus, this );
|
||||
element.on( blurEvent, listeners.blur, this );
|
||||
|
||||
if ( isCapture )
|
||||
CKEDITOR.event.useCapture = 0;
|
||||
|
||||
element.setCustomData( SLOT_NAME, this );
|
||||
element.setCustomData( SLOT_NAME_LISTENERS, listeners );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dismisses an element from the focus manager delegations added by {@link #add}.
|
||||
*
|
||||
* @param {CKEDITOR.dom.element} element The element to be removed from the focus manager.
|
||||
* @member CKEDITOR.focusManager
|
||||
*/
|
||||
remove: function( element ) {
|
||||
element.removeCustomData( SLOT_NAME );
|
||||
var listeners = element.removeCustomData( SLOT_NAME_LISTENERS );
|
||||
element.removeListener( 'blur', listeners.blur );
|
||||
element.removeListener( 'focus', listeners.focus );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} )();
|
||||
|
||||
/**
|
||||
* Fired when the editor instance receives the input focus.
|
||||
*
|
||||
* editor.on( 'focus', function( e ) {
|
||||
* alert( 'The editor named ' + e.editor.name + ' is now focused' );
|
||||
* } );
|
||||
*
|
||||
* @event focus
|
||||
* @member CKEDITOR.editor
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when the editor instance loses the input focus.
|
||||
*
|
||||
* **Note:** This event will **NOT** be triggered when focus is moved internally, e.g. from
|
||||
* an editable to another part of the editor UI like a dialog window.
|
||||
* If you are interested only in the focus state of the editable, listen to the `focus`
|
||||
* and `blur` events of the {@link CKEDITOR.editable} instead.
|
||||
*
|
||||
* editor.on( 'blur', function( e ) {
|
||||
* alert( 'The editor named ' + e.editor.name + ' lost the focus' );
|
||||
* } );
|
||||
*
|
||||
* @event blur
|
||||
* @member CKEDITOR.editor
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
1218
Admin/plugins/ckeditor/core/htmldataprocessor.js
Normal file
1218
Admin/plugins/ckeditor/core/htmldataprocessor.js
Normal file
File diff suppressed because it is too large
Load Diff
205
Admin/plugins/ckeditor/core/htmlparser.js
Normal file
205
Admin/plugins/ckeditor/core/htmlparser.js
Normal file
@@ -0,0 +1,205 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides an "event like" system to parse strings of HTML data.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onTagOpen = function( tagName, attributes, selfClosing ) {
|
||||
* alert( tagName );
|
||||
* };
|
||||
* parser.parse( '<p>Some <b>text</b>.</p>' ); // Alerts 'p', 'b'.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a htmlParser class instance.
|
||||
*/
|
||||
CKEDITOR.htmlParser = function() {
|
||||
this._ = {
|
||||
htmlPartsRegex: /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)--!?>)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))/g
|
||||
};
|
||||
};
|
||||
|
||||
( function() {
|
||||
var attribsRegex = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,
|
||||
emptyAttribs = { checked: 1, compact: 1, declare: 1, defer: 1, disabled: 1, ismap: 1, multiple: 1, nohref: 1, noresize: 1, noshade: 1, nowrap: 1, readonly: 1, selected: 1 };
|
||||
|
||||
CKEDITOR.htmlParser.prototype = {
|
||||
/**
|
||||
* Function to be fired when a tag opener is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onTagOpen = function( tagName, attributes, selfClosing ) {
|
||||
* alert( tagName ); // e.g. 'b'
|
||||
* } );
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} tagName The tag name. The name is guarantted to be lowercased.
|
||||
* @param {Object} attributes An object containing all tag attributes. Each
|
||||
* property in this object represent and attribute name and its value is the attribute value.
|
||||
* @param {Boolean} selfClosing `true` if the tag closes itself, false if the tag doesn't.
|
||||
*/
|
||||
onTagOpen: function() {},
|
||||
|
||||
/**
|
||||
* Function to be fired when a tag closer is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onTagClose = function( tagName ) {
|
||||
* alert( tagName ); // 'b'
|
||||
* } );
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} tagName The tag name. The name is guarantted to be lowercased.
|
||||
*/
|
||||
onTagClose: function() {},
|
||||
|
||||
/**
|
||||
* Function to be fired when text is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onText = function( text ) {
|
||||
* alert( text ); // 'Hello'
|
||||
* } );
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} text The text found.
|
||||
*/
|
||||
onText: function() {},
|
||||
|
||||
/**
|
||||
* Function to be fired when CDATA section is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onCDATA = function( cdata ) {
|
||||
* alert( cdata ); // 'var hello;'
|
||||
* } );
|
||||
* parser.parse( '<script>var hello;</script>' );
|
||||
*
|
||||
* @param {String} cdata The CDATA been found.
|
||||
*/
|
||||
onCDATA: function() {},
|
||||
|
||||
/**
|
||||
* Function to be fired when a commend is found. This function
|
||||
* should be overriden when using this class.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* parser.onComment = function( comment ) {
|
||||
* alert( comment ); // ' Example '
|
||||
* } );
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} comment The comment text.
|
||||
*/
|
||||
onComment: function() {},
|
||||
|
||||
/**
|
||||
* Parses text, looking for HTML tokens, like tag openers or closers,
|
||||
* or comments. This function fires the onTagOpen, onTagClose, onText
|
||||
* and onComment function during its execution.
|
||||
*
|
||||
* var parser = new CKEDITOR.htmlParser();
|
||||
* // The onTagOpen, onTagClose, onText and onComment should be overriden
|
||||
* // at this point.
|
||||
* parser.parse( '<!-- Example --><b>Hello</b>' );
|
||||
*
|
||||
* @param {String} html The HTML to be parsed.
|
||||
*/
|
||||
parse: function( html ) {
|
||||
var parts, tagName,
|
||||
nextIndex = 0,
|
||||
cdata; // The collected data inside a CDATA section.
|
||||
|
||||
while ( ( parts = this._.htmlPartsRegex.exec( html ) ) ) {
|
||||
var tagIndex = parts.index;
|
||||
if ( tagIndex > nextIndex ) {
|
||||
var text = html.substring( nextIndex, tagIndex );
|
||||
|
||||
if ( cdata )
|
||||
cdata.push( text );
|
||||
else
|
||||
this.onText( text );
|
||||
}
|
||||
|
||||
nextIndex = this._.htmlPartsRegex.lastIndex;
|
||||
|
||||
// "parts" is an array with the following items:
|
||||
// 0 : The entire match for opening/closing tags and comments.
|
||||
// : Group filled with the tag name for closing tags.
|
||||
// 2 : Group filled with the comment text.
|
||||
// 3 : Group filled with the tag name for opening tags.
|
||||
// 4 : Group filled with the attributes part of opening tags.
|
||||
|
||||
// Closing tag
|
||||
if ( ( tagName = parts[ 1 ] ) ) {
|
||||
tagName = tagName.toLowerCase();
|
||||
|
||||
if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] ) {
|
||||
// Send the CDATA data.
|
||||
this.onCDATA( cdata.join( '' ) );
|
||||
cdata = null;
|
||||
}
|
||||
|
||||
if ( !cdata ) {
|
||||
this.onTagClose( tagName );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If CDATA is enabled, just save the raw match.
|
||||
if ( cdata ) {
|
||||
cdata.push( parts[ 0 ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Opening tag
|
||||
if ( ( tagName = parts[ 3 ] ) ) {
|
||||
tagName = tagName.toLowerCase();
|
||||
|
||||
// There are some tag names that can break things, so let's
|
||||
// simply ignore them when parsing. (https://dev.ckeditor.com/ticket/5224)
|
||||
if ( /="/.test( tagName ) )
|
||||
continue;
|
||||
|
||||
var attribs = {},
|
||||
attribMatch,
|
||||
attribsPart = parts[ 4 ],
|
||||
selfClosing = !!parts[ 5 ];
|
||||
|
||||
if ( attribsPart ) {
|
||||
while ( ( attribMatch = attribsRegex.exec( attribsPart ) ) ) {
|
||||
var attName = attribMatch[ 1 ].toLowerCase(),
|
||||
attValue = attribMatch[ 2 ] || attribMatch[ 3 ] || attribMatch[ 4 ] || '';
|
||||
|
||||
if ( !attValue && emptyAttribs[ attName ] )
|
||||
attribs[ attName ] = attName;
|
||||
else
|
||||
attribs[ attName ] = CKEDITOR.tools.htmlDecodeAttr( attValue );
|
||||
}
|
||||
}
|
||||
|
||||
this.onTagOpen( tagName, attribs, selfClosing );
|
||||
|
||||
// Open CDATA mode when finding the appropriate tags.
|
||||
if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] )
|
||||
cdata = [];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Comment
|
||||
if ( ( tagName = parts[ 2 ] ) )
|
||||
this.onComment( tagName );
|
||||
}
|
||||
|
||||
if ( html.length > nextIndex )
|
||||
this.onText( html.substring( nextIndex, html.length ) );
|
||||
}
|
||||
};
|
||||
} )();
|
||||
152
Admin/plugins/ckeditor/core/htmlparser/basicwriter.js
Normal file
152
Admin/plugins/ckeditor/core/htmlparser/basicwriter.js
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @class
|
||||
* @todo
|
||||
*/
|
||||
CKEDITOR.htmlParser.basicWriter = CKEDITOR.tools.createClass( {
|
||||
/**
|
||||
* Creates a basicWriter class instance.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
$: function() {
|
||||
this._ = {
|
||||
output: []
|
||||
};
|
||||
},
|
||||
|
||||
proto: {
|
||||
/**
|
||||
* Writes the tag opening part for a opener tag.
|
||||
*
|
||||
* // Writes '<p'.
|
||||
* writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } );
|
||||
*
|
||||
* @param {String} tagName The element name for this tag.
|
||||
* @param {Object} attributes The attributes defined for this tag. The
|
||||
* attributes could be used to inspect the tag.
|
||||
*/
|
||||
openTag: function( tagName ) {
|
||||
this._.output.push( '<', tagName );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the tag closing part for a opener tag.
|
||||
*
|
||||
* // Writes '>'.
|
||||
* writer.openTagClose( 'p', false );
|
||||
*
|
||||
* // Writes ' />'.
|
||||
* writer.openTagClose( 'br', true );
|
||||
*
|
||||
* @param {String} tagName The element name for this tag.
|
||||
* @param {Boolean} isSelfClose Indicates that this is a self-closing tag,
|
||||
* like `<br>` or `<img>`.
|
||||
*/
|
||||
openTagClose: function( tagName, isSelfClose ) {
|
||||
if ( isSelfClose )
|
||||
this._.output.push( ' />' );
|
||||
else
|
||||
this._.output.push( '>' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes an attribute. This function should be called after opening the
|
||||
* tag with {@link #openTagClose}.
|
||||
*
|
||||
* // Writes ' class="MyClass"'.
|
||||
* writer.attribute( 'class', 'MyClass' );
|
||||
*
|
||||
* @param {String} attName The attribute name.
|
||||
* @param {String} attValue The attribute value.
|
||||
*/
|
||||
attribute: function( attName, attValue ) {
|
||||
// Browsers don't always escape special character in attribute values. (https://dev.ckeditor.com/ticket/4683, https://dev.ckeditor.com/ticket/4719).
|
||||
if ( typeof attValue == 'string' )
|
||||
attValue = CKEDITOR.tools.htmlEncodeAttr( attValue );
|
||||
|
||||
this._.output.push( ' ', attName, '="', attValue, '"' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes a closer tag.
|
||||
*
|
||||
* // Writes '</p>'.
|
||||
* writer.closeTag( 'p' );
|
||||
*
|
||||
* @param {String} tagName The element name for this tag.
|
||||
*/
|
||||
closeTag: function( tagName ) {
|
||||
this._.output.push( '</', tagName, '>' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes text.
|
||||
*
|
||||
* // Writes 'Hello Word'.
|
||||
* writer.text( 'Hello Word' );
|
||||
*
|
||||
* @param {String} text The text value.
|
||||
*/
|
||||
text: function( text ) {
|
||||
this._.output.push( text );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes a comment.
|
||||
*
|
||||
* // Writes '<!-- My comment -->'.
|
||||
* writer.comment( ' My comment ' );
|
||||
*
|
||||
* @param {String} comment The comment text.
|
||||
*/
|
||||
comment: function( comment ) {
|
||||
this._.output.push( '<!--', comment, '-->' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes any kind of data to the ouput.
|
||||
*
|
||||
* writer.write( 'This is an <b>example</b>.' );
|
||||
*
|
||||
* @param {String} data
|
||||
*/
|
||||
write: function( data ) {
|
||||
this._.output.push( data );
|
||||
},
|
||||
|
||||
/**
|
||||
* Empties the current output buffer.
|
||||
*
|
||||
* writer.reset();
|
||||
*/
|
||||
reset: function() {
|
||||
this._.output = [];
|
||||
this._.indent = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Empties the current output buffer.
|
||||
*
|
||||
* var html = writer.getHtml();
|
||||
*
|
||||
* @param {Boolean} reset Indicates that the {@link #reset} method is to
|
||||
* be automatically called after retrieving the HTML.
|
||||
* @returns {String} The HTML written to the writer so far.
|
||||
*/
|
||||
getHtml: function( reset ) {
|
||||
var html = this._.output.join( '' );
|
||||
|
||||
if ( reset )
|
||||
this.reset();
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
} );
|
||||
70
Admin/plugins/ckeditor/core/htmlparser/cdata.js
Normal file
70
Admin/plugins/ckeditor/core/htmlparser/cdata.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
|
||||
/**
|
||||
* A lightweight representation of HTML CDATA.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.htmlParser.node
|
||||
* @constructor Creates a cdata class instance.
|
||||
* @param {String} value The CDATA section value.
|
||||
*/
|
||||
CKEDITOR.htmlParser.cdata = function( value ) {
|
||||
/**
|
||||
* The CDATA value.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.value = value;
|
||||
};
|
||||
|
||||
CKEDITOR.htmlParser.cdata.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
|
||||
/**
|
||||
* CDATA has the same type as {@link CKEDITOR.htmlParser.text} This is
|
||||
* a constant value set to {@link CKEDITOR#NODE_TEXT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_TEXT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_TEXT,
|
||||
|
||||
filter: function( filter ) {
|
||||
var style = this.getAscendant( 'style' );
|
||||
|
||||
if ( !style ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// MathML and SVG namespaces processing parsers `style` content as a normal HTML, not text.
|
||||
// Make sure to filter such content also.
|
||||
var nonHtmlElementNamespace = style.getAscendant( { math: 1, svg: 1 } );
|
||||
|
||||
if ( !nonHtmlElementNamespace ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fragment = CKEDITOR.htmlParser.fragment.fromHtml( this.value ),
|
||||
writer = new CKEDITOR.htmlParser.basicWriter();
|
||||
|
||||
filter.applyTo( fragment );
|
||||
fragment.writeHtml( writer );
|
||||
|
||||
this.value = writer.getHtml();
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the CDATA with no special manipulations.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
*/
|
||||
writeHtml: function( writer ) {
|
||||
writer.write( this.value );
|
||||
}
|
||||
} );
|
||||
} )();
|
||||
80
Admin/plugins/ckeditor/core/htmlparser/comment.js
Normal file
80
Admin/plugins/ckeditor/core/htmlparser/comment.js
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A lightweight representation of an HTML comment.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.htmlParser.node
|
||||
* @constructor Creates a comment class instance.
|
||||
* @param {String} value The comment text value.
|
||||
*/
|
||||
CKEDITOR.htmlParser.comment = function( value ) {
|
||||
/**
|
||||
* The comment text.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.value = value;
|
||||
|
||||
/** @private */
|
||||
this._ = {
|
||||
isBlockLike: false
|
||||
};
|
||||
};
|
||||
|
||||
CKEDITOR.htmlParser.comment.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_COMMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_COMMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_COMMENT,
|
||||
|
||||
/**
|
||||
* Filter this comment with given filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
* @returns {Boolean} Method returns `false` when this comment has
|
||||
* been removed or replaced with other node. This is an information for
|
||||
* {@link CKEDITOR.htmlParser.element#filterChildren} that it has
|
||||
* to repeat filter on current position in parent's children array.
|
||||
*/
|
||||
filter: function( filter, context ) {
|
||||
var comment = this.value;
|
||||
|
||||
if ( !( comment = filter.onComment( context, comment, this ) ) ) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( typeof comment != 'string' ) {
|
||||
this.replaceWith( comment );
|
||||
return false;
|
||||
}
|
||||
|
||||
this.value = comment;
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the HTML representation of this comment to a CKEDITOR.htmlWriter.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
|
||||
* **Note:** it's unsafe to filter offline (not appended) node.
|
||||
*/
|
||||
writeHtml: function( writer, filter ) {
|
||||
if ( filter )
|
||||
this.filter( filter );
|
||||
|
||||
writer.comment( this.value );
|
||||
}
|
||||
} );
|
||||
593
Admin/plugins/ckeditor/core/htmlparser/element.js
Normal file
593
Admin/plugins/ckeditor/core/htmlparser/element.js
Normal file
@@ -0,0 +1,593 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A lightweight representation of an HTML element.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.htmlParser.node
|
||||
* @constructor Creates an element class instance.
|
||||
* @param {String} name The element name.
|
||||
* @param {Object} attributes An object storing all attributes defined for
|
||||
* this element.
|
||||
*/
|
||||
CKEDITOR.htmlParser.element = function( name, attributes ) {
|
||||
/**
|
||||
* The element name.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.name = name;
|
||||
|
||||
/**
|
||||
* Stores the attributes defined for this element.
|
||||
*
|
||||
* @property {Object}
|
||||
*/
|
||||
this.attributes = attributes || {};
|
||||
|
||||
/**
|
||||
* The nodes that are direct children of this element.
|
||||
*/
|
||||
this.children = [];
|
||||
|
||||
// Reveal the real semantic of our internal custom tag name (https://dev.ckeditor.com/ticket/6639),
|
||||
// when resolving whether it's block like.
|
||||
var realName = name || '',
|
||||
prefixed = realName.match( /^cke:(.*)/ );
|
||||
prefixed && ( realName = prefixed[ 1 ] );
|
||||
|
||||
var isBlockLike = !!( CKEDITOR.dtd.$nonBodyContent[ realName ] || CKEDITOR.dtd.$block[ realName ] ||
|
||||
CKEDITOR.dtd.$listItem[ realName ] || CKEDITOR.dtd.$tableContent[ realName ] ||
|
||||
CKEDITOR.dtd.$nonEditable[ realName ] || realName == 'br' );
|
||||
|
||||
this.isEmpty = !!CKEDITOR.dtd.$empty[ name ];
|
||||
this.isUnknown = !CKEDITOR.dtd[ name ];
|
||||
|
||||
/** @private */
|
||||
this._ = {
|
||||
isBlockLike: isBlockLike,
|
||||
hasInlineStarted: this.isEmpty || !isBlockLike
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Object presentation of the CSS style declaration text.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a `cssStyle` class instance.
|
||||
* @param {CKEDITOR.htmlParser.element/String} elementOrStyleText
|
||||
* An HTML parser element or the inline style text.
|
||||
*/
|
||||
CKEDITOR.htmlParser.cssStyle = function() {
|
||||
var styleText,
|
||||
arg = arguments[ 0 ],
|
||||
rules = {};
|
||||
|
||||
styleText = arg instanceof CKEDITOR.htmlParser.element ? arg.attributes.style : arg;
|
||||
|
||||
// html-encoded quote might be introduced by 'font-family'
|
||||
// from MS-Word which confused the following regexp. e.g.
|
||||
//'font-family: "Lucida, Console"'
|
||||
// TODO reuse CSS methods from tools.
|
||||
( styleText || '' ).replace( /"/g, '"' ).replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g, function( match, name, value ) {
|
||||
name == 'font-family' && ( value = value.replace( /["']/g, '' ) );
|
||||
rules[ name.toLowerCase() ] = value;
|
||||
} );
|
||||
|
||||
return {
|
||||
|
||||
rules: rules,
|
||||
|
||||
/**
|
||||
* Applies the styles to the specified element or object.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.element/CKEDITOR.dom.element/Object} obj
|
||||
*/
|
||||
populate: function( obj ) {
|
||||
var style = this.toString();
|
||||
if ( style )
|
||||
obj instanceof CKEDITOR.dom.element ? obj.setAttribute( 'style', style ) : obj instanceof CKEDITOR.htmlParser.element ? obj.attributes.style = style : obj.style = style;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Serializes CSS style declaration to a string.
|
||||
*
|
||||
* @returns {String}
|
||||
*/
|
||||
toString: function() {
|
||||
var output = [];
|
||||
for ( var i in rules )
|
||||
rules[ i ] && output.push( i, ':', rules[ i ], ';' );
|
||||
return output.join( '' );
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/** @class CKEDITOR.htmlParser.element */
|
||||
( function() {
|
||||
// Used to sort attribute entries in an array, where the first element of
|
||||
// each object is the attribute name.
|
||||
var sortAttribs = function( a, b ) {
|
||||
a = a[ 0 ];
|
||||
b = b[ 0 ];
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
},
|
||||
fragProto = CKEDITOR.htmlParser.fragment.prototype;
|
||||
|
||||
CKEDITOR.htmlParser.element.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_ELEMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_ELEMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_ELEMENT,
|
||||
|
||||
/**
|
||||
* Adds a node to the element children list.
|
||||
*
|
||||
* @method
|
||||
* @param {CKEDITOR.htmlParser.node} node The node to be added.
|
||||
* @param {Number} [index] From where the insertion happens.
|
||||
*/
|
||||
add: fragProto.add,
|
||||
|
||||
/**
|
||||
* Clones this element.
|
||||
*
|
||||
* @returns {CKEDITOR.htmlParser.element} The element clone.
|
||||
*/
|
||||
clone: function() {
|
||||
return new CKEDITOR.htmlParser.element( this.name, this.attributes );
|
||||
},
|
||||
|
||||
/**
|
||||
* Filters this element and its children with the given filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
* @returns {Boolean} The method returns `false` when this element has
|
||||
* been removed or replaced with another. This information means that
|
||||
* {@link #filterChildren} has to repeat the filter on the current
|
||||
* position in parent's children array.
|
||||
*/
|
||||
filter: function( filter, context ) {
|
||||
var element = this,
|
||||
originalName, name;
|
||||
|
||||
context = element.getFilterContext( context );
|
||||
|
||||
// Filtering if it's the root node.
|
||||
if ( !element.parent )
|
||||
filter.onRoot( context, element );
|
||||
|
||||
while ( true ) {
|
||||
originalName = element.name;
|
||||
|
||||
if ( !( name = filter.onElementName( context, originalName ) ) ) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
element.name = name;
|
||||
|
||||
if ( !( element = filter.onElement( context, element ) ) ) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
|
||||
// New element has been returned - replace current one
|
||||
// and process it (stop processing this and return false, what
|
||||
// means that element has been removed).
|
||||
if ( element !== this ) {
|
||||
this.replaceWith( element );
|
||||
return false;
|
||||
}
|
||||
|
||||
// If name has been changed - continue loop, so in next iteration
|
||||
// filters for new name will be applied to this element.
|
||||
// If name hasn't been changed - stop.
|
||||
if ( element.name == originalName )
|
||||
break;
|
||||
|
||||
// If element has been replaced with something of a
|
||||
// different type, then make the replacement filter itself.
|
||||
if ( element.type != CKEDITOR.NODE_ELEMENT ) {
|
||||
this.replaceWith( element );
|
||||
return false;
|
||||
}
|
||||
|
||||
// This indicate that the element has been dropped by
|
||||
// filter but not the children.
|
||||
if ( !element.name ) {
|
||||
this.replaceWithChildren();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var attributes = element.attributes,
|
||||
a, value, newAttrName;
|
||||
|
||||
for ( a in attributes ) {
|
||||
newAttrName = a;
|
||||
value = attributes[ a ];
|
||||
|
||||
// Loop until name isn't modified.
|
||||
// A little bit senseless, but IE would do that anyway
|
||||
// because it iterates with for-in loop even over properties
|
||||
// created during its run.
|
||||
while ( true ) {
|
||||
if ( !( newAttrName = filter.onAttributeName( context, a ) ) ) {
|
||||
delete attributes[ a ];
|
||||
break;
|
||||
} else if ( newAttrName != a ) {
|
||||
delete attributes[ a ];
|
||||
a = newAttrName;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( newAttrName ) {
|
||||
if ( ( value = filter.onAttribute( context, element, newAttrName, value ) ) === false )
|
||||
delete attributes[ newAttrName ];
|
||||
else
|
||||
attributes[ newAttrName ] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !element.isEmpty )
|
||||
this.filterChildren( filter, false, context );
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Filters this element's children with the given filter.
|
||||
*
|
||||
* Element's children may only be filtered once by one
|
||||
* instance of the filter.
|
||||
*
|
||||
* @method filterChildren
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
*/
|
||||
filterChildren: fragProto.filterChildren,
|
||||
|
||||
/**
|
||||
* Writes the element HTML to the CKEDITOR.htmlWriter.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which HTML will be written.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
|
||||
* **Note:** It is unsafe to filter an offline (not appended) node.
|
||||
*/
|
||||
writeHtml: function( writer, filter ) {
|
||||
if ( filter )
|
||||
this.filter( filter );
|
||||
|
||||
var name = this.name,
|
||||
attribsArray = [],
|
||||
attributes = this.attributes,
|
||||
attrName,
|
||||
attr, i, l;
|
||||
|
||||
// Open element tag.
|
||||
writer.openTag( name, attributes );
|
||||
|
||||
// Copy all attributes to an array.
|
||||
for ( attrName in attributes )
|
||||
attribsArray.push( [ attrName, attributes[ attrName ] ] );
|
||||
|
||||
// Sort the attributes by name.
|
||||
if ( writer.sortAttributes )
|
||||
attribsArray.sort( sortAttribs );
|
||||
|
||||
// Send the attributes.
|
||||
for ( i = 0, l = attribsArray.length; i < l; i++ ) {
|
||||
attr = attribsArray[ i ];
|
||||
writer.attribute( attr[ 0 ], attr[ 1 ] );
|
||||
}
|
||||
|
||||
// Close the tag.
|
||||
writer.openTagClose( name, this.isEmpty );
|
||||
|
||||
this.writeChildrenHtml( writer );
|
||||
|
||||
// Close the element.
|
||||
if ( !this.isEmpty )
|
||||
writer.closeTag( name );
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends children of this element to the writer.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which HTML will be written.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter]
|
||||
*/
|
||||
writeChildrenHtml: fragProto.writeChildrenHtml,
|
||||
|
||||
/**
|
||||
* Replaces this element with its children.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
replaceWithChildren: function() {
|
||||
var children = this.children;
|
||||
|
||||
for ( var i = children.length; i; )
|
||||
children[ --i ].insertAfter( this );
|
||||
|
||||
this.remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes a callback on each node (of the given type) in this element.
|
||||
*
|
||||
* // Create a <p> element with foo<b>bar</b>bom as its content.
|
||||
* var elP = CKEDITOR.htmlParser.fragment.fromHtml( 'foo<b>bar</b>bom', 'p' );
|
||||
* elP.forEach( function( node ) {
|
||||
* console.log( node );
|
||||
* } );
|
||||
* // Will log:
|
||||
* // 1. document fragment,
|
||||
* // 2. <p> element,
|
||||
* // 3. "foo" text node,
|
||||
* // 4. <b> element,
|
||||
* // 5. "bar" text node,
|
||||
* // 6. "bom" text node.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {Function} callback Function to be executed on every node.
|
||||
* **Since 4.3**: If `callback` returned `false`, the descendants of the current node will be ignored.
|
||||
* @param {CKEDITOR.htmlParser.node} callback.node Node passed as an argument.
|
||||
* @param {Number} [type] Whether the specified `callback` will be executed only on nodes of this type.
|
||||
* @param {Boolean} [skipRoot] Do not execute `callback` on this element.
|
||||
*/
|
||||
forEach: fragProto.forEach,
|
||||
|
||||
/**
|
||||
* Gets this element's first child. If `condition` is given, this method returns
|
||||
* the first child which satisfies that condition.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String/Object/Function} condition Name of a child, a hash of names, or a validator function.
|
||||
* @returns {CKEDITOR.htmlParser.node}
|
||||
*/
|
||||
getFirst: function( condition ) {
|
||||
if ( !condition )
|
||||
return this.children.length ? this.children[ 0 ] : null;
|
||||
|
||||
if ( typeof condition != 'function' )
|
||||
condition = nameCondition( condition );
|
||||
|
||||
for ( var i = 0, l = this.children.length; i < l; ++i ) {
|
||||
if ( condition( this.children[ i ] ) )
|
||||
return this.children[ i ];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets this element's inner HTML.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @returns {String}
|
||||
*/
|
||||
getHtml: function() {
|
||||
var writer = new CKEDITOR.htmlParser.basicWriter();
|
||||
this.writeChildrenHtml( writer );
|
||||
return writer.getHtml();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets this element's inner HTML.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} html
|
||||
*/
|
||||
setHtml: function( html ) {
|
||||
var children = this.children = CKEDITOR.htmlParser.fragment.fromHtml( html ).children;
|
||||
|
||||
for ( var i = 0, l = children.length; i < l; ++i )
|
||||
children[ i ].parent = this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets this element's outer HTML.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @returns {String}
|
||||
*/
|
||||
getOuterHtml: function() {
|
||||
var writer = new CKEDITOR.htmlParser.basicWriter();
|
||||
this.writeHtml( writer );
|
||||
return writer.getHtml();
|
||||
},
|
||||
|
||||
/**
|
||||
* Splits this element at the given index.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {Number} index Index at which the element will be split — `0` means the beginning,
|
||||
* `1` after the first child node, etc.
|
||||
* @returns {CKEDITOR.htmlParser.element} The new element following this one.
|
||||
*/
|
||||
split: function( index ) {
|
||||
var cloneChildren = this.children.splice( index, this.children.length - index ),
|
||||
clone = this.clone();
|
||||
|
||||
for ( var i = 0; i < cloneChildren.length; ++i )
|
||||
cloneChildren[ i ].parent = clone;
|
||||
|
||||
clone.children = cloneChildren;
|
||||
|
||||
if ( cloneChildren[ 0 ] )
|
||||
cloneChildren[ 0 ].previous = null;
|
||||
|
||||
if ( index > 0 )
|
||||
this.children[ index - 1 ].next = null;
|
||||
|
||||
this.parent.add( clone, this.getIndex() + 1 );
|
||||
|
||||
return clone;
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches through the current node children to find nodes matching the `criteria`.
|
||||
*
|
||||
* @param {String/Function} criteria Tag name or evaluator function.
|
||||
* @param {Boolean} [recursive=false]
|
||||
* @returns {CKEDITOR.htmlParser.node[]}
|
||||
*/
|
||||
find: function( criteria, recursive ) {
|
||||
if ( recursive === undefined ) {
|
||||
recursive = false;
|
||||
}
|
||||
|
||||
var ret = [],
|
||||
i;
|
||||
|
||||
for ( i = 0; i < this.children.length; i++ ) {
|
||||
var curChild = this.children[ i ];
|
||||
|
||||
if ( typeof criteria == 'function' && criteria( curChild ) ) {
|
||||
ret.push( curChild );
|
||||
} else if ( typeof criteria == 'string' && curChild.name === criteria ) {
|
||||
ret.push( curChild );
|
||||
}
|
||||
|
||||
if ( recursive && curChild.find ) {
|
||||
ret = ret.concat( curChild.find( criteria, recursive ) );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Searches through the children of the current element to find the first child matching the `criteria`.
|
||||
*
|
||||
* ```js
|
||||
* element.findOne( function( child ) {
|
||||
* return child.name === 'span' || child.name === 'strong';
|
||||
* } ); // Will return the first child which is a <span> or a <strong> element.
|
||||
* ```
|
||||
*
|
||||
* @param {String/Function} criteria Tag name or evaluator function.
|
||||
* @param {Boolean} [recursive=false] If set to `true`, it will iterate over all descendants. Otherwise the method will
|
||||
* only iterate over direct children.
|
||||
* @returns {CKEDITOR.htmlParser.node/null} The first matched child, `null` otherwise.
|
||||
*/
|
||||
findOne: function( criteria, recursive ) {
|
||||
var nestedMatch = null,
|
||||
match = CKEDITOR.tools.array.find( this.children, function( child ) {
|
||||
var isMatching = typeof criteria === 'function' ? criteria( child ) : child.name === criteria;
|
||||
|
||||
if ( isMatching || !recursive ) {
|
||||
return isMatching;
|
||||
}
|
||||
|
||||
if ( child.children && child.findOne ) {
|
||||
nestedMatch = child.findOne( criteria, true );
|
||||
}
|
||||
|
||||
return !!nestedMatch;
|
||||
} );
|
||||
|
||||
return nestedMatch || match || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a class name to the list of classes.
|
||||
*
|
||||
* @since 4.4.0
|
||||
* @param {String} className The class name to be added.
|
||||
*/
|
||||
addClass: function( className ) {
|
||||
if ( this.hasClass( className ) )
|
||||
return;
|
||||
|
||||
var c = this.attributes[ 'class' ] || '';
|
||||
|
||||
this.attributes[ 'class' ] = c + ( c ? ' ' : '' ) + className;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a class name from the list of classes.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} className The class name to be removed.
|
||||
*/
|
||||
removeClass: function( className ) {
|
||||
var classes = this.attributes[ 'class' ];
|
||||
|
||||
if ( !classes )
|
||||
return;
|
||||
|
||||
// We can safely assume that className won't break regexp.
|
||||
// http://stackoverflow.com/questions/448981/what-characters-are-valid-in-css-class-names
|
||||
classes = CKEDITOR.tools.trim( classes.replace( new RegExp( '(?:\\s+|^)' + className + '(?:\\s+|$)' ), ' ' ) );
|
||||
|
||||
if ( classes )
|
||||
this.attributes[ 'class' ] = classes;
|
||||
else
|
||||
delete this.attributes[ 'class' ];
|
||||
},
|
||||
|
||||
/**
|
||||
* Checkes whether this element has a class name.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String} className The class name to be checked.
|
||||
* @returns {Boolean} Whether this element has a `className`.
|
||||
*/
|
||||
hasClass: function( className ) {
|
||||
var classes = this.attributes[ 'class' ];
|
||||
|
||||
if ( !classes )
|
||||
return false;
|
||||
|
||||
return ( new RegExp( '(?:^|\\s)' + className + '(?=\\s|$)' ) ).test( classes );
|
||||
},
|
||||
|
||||
getFilterContext: function( ctx ) {
|
||||
var changes = [];
|
||||
|
||||
if ( !ctx ) {
|
||||
ctx = {
|
||||
nonEditable: false,
|
||||
nestedEditable: false
|
||||
};
|
||||
}
|
||||
|
||||
if ( !ctx.nonEditable && this.attributes.contenteditable == 'false' )
|
||||
changes.push( 'nonEditable', true );
|
||||
// A context to be given nestedEditable must be nonEditable first (by inheritance) (https://dev.ckeditor.com/ticket/11372, https://dev.ckeditor.com/ticket/11698).
|
||||
// Special case: https://dev.ckeditor.com/ticket/11504 - filter starts on <body contenteditable=true>,
|
||||
// so ctx.nonEditable has not been yet set to true.
|
||||
else if ( ctx.nonEditable && !ctx.nestedEditable && this.attributes.contenteditable == 'true' )
|
||||
changes.push( 'nestedEditable', true );
|
||||
|
||||
if ( changes.length ) {
|
||||
ctx = CKEDITOR.tools.copy( ctx );
|
||||
for ( var i = 0; i < changes.length; i += 2 )
|
||||
ctx[ changes[ i ] ] = changes[ i + 1 ];
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
}, true );
|
||||
|
||||
function nameCondition( condition ) {
|
||||
return function( el ) {
|
||||
return el.type == CKEDITOR.NODE_ELEMENT &&
|
||||
( typeof condition == 'string' ? el.name == condition : el.name in condition );
|
||||
};
|
||||
}
|
||||
} )();
|
||||
402
Admin/plugins/ckeditor/core/htmlparser/filter.js
Normal file
402
Admin/plugins/ckeditor/core/htmlparser/filter.js
Normal file
@@ -0,0 +1,402 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Filter is a configurable tool for transforming and filtering {@link CKEDITOR.htmlParser.node nodes}.
|
||||
* It is mainly used during data processing phase which is done not on real DOM nodes,
|
||||
* but on their simplified form represented by {@link CKEDITOR.htmlParser.node} class and its subclasses.
|
||||
*
|
||||
* var filter = new CKEDITOR.htmlParser.filter( {
|
||||
* text: function( value ) {
|
||||
* return '@' + value + '@';
|
||||
* },
|
||||
* elements: {
|
||||
* p: function( element ) {
|
||||
* element.attributes.foo = '1';
|
||||
* }
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>Foo<b>bar!</b></p>' ),
|
||||
* writer = new CKEDITOR.htmlParser.basicWriter();
|
||||
* filter.applyTo( fragment );
|
||||
* fragment.writeHtml( writer );
|
||||
* writer.getHtml(); // '<p foo="1">@Foo@<b>@bar!@</b></p>'
|
||||
*
|
||||
* @class
|
||||
*/
|
||||
CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass( {
|
||||
/**
|
||||
* @constructor Creates a filter class instance.
|
||||
* @param {CKEDITOR.htmlParser.filterRulesDefinition} [rules]
|
||||
*/
|
||||
$: function( rules ) {
|
||||
/**
|
||||
* ID of filter instance, which is used to mark elements
|
||||
* to which this filter has been already applied.
|
||||
*
|
||||
* @property {Number} id
|
||||
* @readonly
|
||||
*/
|
||||
this.id = CKEDITOR.tools.getNextNumber();
|
||||
|
||||
/**
|
||||
* Rules for element names.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.elementNameRules = new filterRulesGroup();
|
||||
|
||||
/**
|
||||
* Rules for attribute names.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.attributeNameRules = new filterRulesGroup();
|
||||
|
||||
/**
|
||||
* Hash of elementName => {@link CKEDITOR.htmlParser.filterRulesGroup rules for elements}.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
this.elementsRules = {};
|
||||
|
||||
/**
|
||||
* Hash of attributeName => {@link CKEDITOR.htmlParser.filterRulesGroup rules for attributes}.
|
||||
*
|
||||
* @readonly
|
||||
*/
|
||||
this.attributesRules = {};
|
||||
|
||||
/**
|
||||
* Rules for text nodes.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.textRules = new filterRulesGroup();
|
||||
|
||||
/**
|
||||
* Rules for comment nodes.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.commentRules = new filterRulesGroup();
|
||||
|
||||
/**
|
||||
* Rules for a root node.
|
||||
*
|
||||
* @property {CKEDITOR.htmlParser.filterRulesGroup}
|
||||
* @readonly
|
||||
*/
|
||||
this.rootRules = new filterRulesGroup();
|
||||
|
||||
if ( rules )
|
||||
this.addRules( rules, 10 );
|
||||
},
|
||||
|
||||
proto: {
|
||||
/**
|
||||
* Add rules to this filter.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.filterRulesDefinition} rules Object containing filter rules.
|
||||
* @param {Object/Number} [options] Object containing rules' options or a priority
|
||||
* (for a backward compatibility with CKEditor versions up to 4.2.x).
|
||||
* @param {Number} [options.priority=10] The priority of a rule.
|
||||
* @param {Boolean} [options.applyToAll=false] Whether to apply rule to non-editable
|
||||
* elements and their descendants too.
|
||||
*/
|
||||
addRules: function( rules, options ) {
|
||||
var priority;
|
||||
|
||||
// Backward compatibility.
|
||||
if ( typeof options == 'number' )
|
||||
priority = options;
|
||||
// New version - try reading from options.
|
||||
else if ( options && ( 'priority' in options ) )
|
||||
priority = options.priority;
|
||||
|
||||
// Defaults.
|
||||
if ( typeof priority != 'number' )
|
||||
priority = 10;
|
||||
if ( typeof options != 'object' )
|
||||
options = {};
|
||||
|
||||
// Add the elementNames.
|
||||
if ( rules.elementNames )
|
||||
this.elementNameRules.addMany( rules.elementNames, priority, options );
|
||||
|
||||
// Add the attributeNames.
|
||||
if ( rules.attributeNames )
|
||||
this.attributeNameRules.addMany( rules.attributeNames, priority, options );
|
||||
|
||||
// Add the elements.
|
||||
if ( rules.elements )
|
||||
addNamedRules( this.elementsRules, rules.elements, priority, options );
|
||||
|
||||
// Add the attributes.
|
||||
if ( rules.attributes )
|
||||
addNamedRules( this.attributesRules, rules.attributes, priority, options );
|
||||
|
||||
// Add the text.
|
||||
if ( rules.text )
|
||||
this.textRules.add( rules.text, priority, options );
|
||||
|
||||
// Add the comment.
|
||||
if ( rules.comment )
|
||||
this.commentRules.add( rules.comment, priority, options );
|
||||
|
||||
// Add root node rules.
|
||||
if ( rules.root )
|
||||
this.rootRules.add( rules.root, priority, options );
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply this filter to given node.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.node} node The node to be filtered.
|
||||
*/
|
||||
applyTo: function( node ) {
|
||||
node.filter( this );
|
||||
},
|
||||
|
||||
onElementName: function( context, name ) {
|
||||
return this.elementNameRules.execOnName( context, name );
|
||||
},
|
||||
|
||||
onAttributeName: function( context, name ) {
|
||||
return this.attributeNameRules.execOnName( context, name );
|
||||
},
|
||||
|
||||
onText: function( context, text, node ) {
|
||||
return this.textRules.exec( context, text, node );
|
||||
},
|
||||
|
||||
onComment: function( context, commentText, comment ) {
|
||||
return this.commentRules.exec( context, commentText, comment );
|
||||
},
|
||||
|
||||
onRoot: function( context, element ) {
|
||||
return this.rootRules.exec( context, element );
|
||||
},
|
||||
|
||||
onElement: function( context, element ) {
|
||||
// We must apply filters set to the specific element name as
|
||||
// well as those set to the generic ^/$ name. So, add both to an
|
||||
// array and process them in a small loop.
|
||||
var rulesGroups = [ this.elementsRules[ '^' ], this.elementsRules[ element.name ], this.elementsRules.$ ],
|
||||
rulesGroup, ret;
|
||||
|
||||
for ( var i = 0; i < 3; i++ ) {
|
||||
rulesGroup = rulesGroups[ i ];
|
||||
if ( rulesGroup ) {
|
||||
ret = rulesGroup.exec( context, element, this );
|
||||
|
||||
if ( ret === false )
|
||||
return null;
|
||||
|
||||
if ( ret && ret != element )
|
||||
return this.onNode( context, ret );
|
||||
|
||||
// The non-root element has been dismissed by one of the filters.
|
||||
if ( element.parent && !element.name )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
},
|
||||
|
||||
onNode: function( context, node ) {
|
||||
var type = node.type;
|
||||
|
||||
return type == CKEDITOR.NODE_ELEMENT ? this.onElement( context, node ) :
|
||||
type == CKEDITOR.NODE_TEXT ? new CKEDITOR.htmlParser.text( this.onText( context, node.value, node ) ) :
|
||||
type == CKEDITOR.NODE_COMMENT ? new CKEDITOR.htmlParser.comment( this.onComment( context, node.value, node ) ) : null;
|
||||
},
|
||||
|
||||
onAttribute: function( context, element, name, value ) {
|
||||
var rulesGroup = this.attributesRules[ name ];
|
||||
|
||||
if ( rulesGroup )
|
||||
return rulesGroup.exec( context, value, element, this );
|
||||
return value;
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
/**
|
||||
* Class grouping filter rules for one subject (like element or attribute names).
|
||||
*
|
||||
* @class CKEDITOR.htmlParser.filterRulesGroup
|
||||
*/
|
||||
function filterRulesGroup() {
|
||||
/**
|
||||
* Array of objects containing rule, priority and options.
|
||||
*
|
||||
* @property {Object[]}
|
||||
* @readonly
|
||||
*/
|
||||
this.rules = [];
|
||||
}
|
||||
|
||||
CKEDITOR.htmlParser.filterRulesGroup = filterRulesGroup;
|
||||
|
||||
filterRulesGroup.prototype = {
|
||||
/**
|
||||
* Adds specified rule to this group.
|
||||
*
|
||||
* @param {Function/Array} rule Function for function based rule or [ pattern, replacement ] array for
|
||||
* rule applicable to names.
|
||||
* @param {Number} priority
|
||||
* @param options
|
||||
*/
|
||||
add: function( rule, priority, options ) {
|
||||
this.rules.splice( this.findIndex( priority ), 0, {
|
||||
value: rule,
|
||||
priority: priority,
|
||||
options: options
|
||||
} );
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds specified rules to this group.
|
||||
*
|
||||
* @param {Array} rules Array of rules - see {@link #add}.
|
||||
* @param {Number} priority
|
||||
* @param options
|
||||
*/
|
||||
addMany: function( rules, priority, options ) {
|
||||
var args = [ this.findIndex( priority ), 0 ];
|
||||
|
||||
for ( var i = 0, len = rules.length; i < len; i++ ) {
|
||||
args.push( {
|
||||
value: rules[ i ],
|
||||
priority: priority,
|
||||
options: options
|
||||
} );
|
||||
}
|
||||
|
||||
this.rules.splice.apply( this.rules, args );
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds an index at which rule with given priority should be inserted.
|
||||
*
|
||||
* @param {Number} priority
|
||||
* @returns {Number} Index.
|
||||
*/
|
||||
findIndex: function( priority ) {
|
||||
var rules = this.rules,
|
||||
len = rules.length,
|
||||
i = len - 1;
|
||||
|
||||
// Search from the end, because usually rules will be added with default priority, so
|
||||
// we will be able to stop loop quickly.
|
||||
while ( i >= 0 && priority < rules[ i ].priority )
|
||||
i--;
|
||||
|
||||
return i + 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes this rules group on given value. Applicable only if function based rules were added.
|
||||
*
|
||||
* All arguments passed to this function will be forwarded to rules' functions.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.node/CKEDITOR.htmlParser.fragment/String} currentValue The value to be filtered.
|
||||
* @returns {CKEDITOR.htmlParser.node/CKEDITOR.htmlParser.fragment/String} Filtered value.
|
||||
*/
|
||||
exec: function( context, currentValue ) {
|
||||
var isNode = currentValue instanceof CKEDITOR.htmlParser.node || currentValue instanceof CKEDITOR.htmlParser.fragment,
|
||||
// Splice '1' to remove context, which we don't want to pass to filter rules.
|
||||
args = Array.prototype.slice.call( arguments, 1 ),
|
||||
rules = this.rules,
|
||||
len = rules.length,
|
||||
orgType, orgName, ret, i, rule;
|
||||
|
||||
for ( i = 0; i < len; i++ ) {
|
||||
// Backup the node info before filtering.
|
||||
if ( isNode ) {
|
||||
orgType = currentValue.type;
|
||||
orgName = currentValue.name;
|
||||
}
|
||||
|
||||
rule = rules[ i ];
|
||||
if ( isRuleApplicable( context, rule ) ) {
|
||||
ret = rule.value.apply( null, args );
|
||||
|
||||
if ( ret === false )
|
||||
return ret;
|
||||
|
||||
// We're filtering node (element/fragment).
|
||||
// No further filtering if it's not anymore fitable for the subsequent filters.
|
||||
if ( isNode && ret && ( ret.name != orgName || ret.type != orgType ) )
|
||||
return ret;
|
||||
|
||||
// Update currentValue and corresponding argument in args array.
|
||||
// Updated values will be used in next for-loop step.
|
||||
if ( ret != null )
|
||||
args[ 0 ] = currentValue = ret;
|
||||
|
||||
// ret == undefined will continue loop as nothing has happened.
|
||||
}
|
||||
}
|
||||
|
||||
return currentValue;
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes this rules group on name. Applicable only if filter rules for names were added.
|
||||
*
|
||||
* @param {String} currentName The name to be filtered.
|
||||
* @returns {String} Filtered name.
|
||||
*/
|
||||
execOnName: function( context, currentName ) {
|
||||
var i = 0,
|
||||
rules = this.rules,
|
||||
len = rules.length,
|
||||
rule;
|
||||
|
||||
for ( ; currentName && i < len; i++ ) {
|
||||
rule = rules[ i ];
|
||||
if ( isRuleApplicable( context, rule ) )
|
||||
currentName = currentName.replace( rule.value[ 0 ], rule.value[ 1 ] );
|
||||
}
|
||||
|
||||
return currentName;
|
||||
}
|
||||
};
|
||||
|
||||
function addNamedRules( rulesGroups, newRules, priority, options ) {
|
||||
var ruleName, rulesGroup;
|
||||
|
||||
for ( ruleName in newRules ) {
|
||||
rulesGroup = rulesGroups[ ruleName ];
|
||||
|
||||
if ( !rulesGroup )
|
||||
rulesGroup = rulesGroups[ ruleName ] = new filterRulesGroup();
|
||||
|
||||
rulesGroup.add( newRules[ ruleName ], priority, options );
|
||||
}
|
||||
}
|
||||
|
||||
function isRuleApplicable( context, rule ) {
|
||||
if ( context.nonEditable && !rule.options.applyToAll )
|
||||
return false;
|
||||
|
||||
if ( context.nestedEditable && rule.options.excludeNestedEditable )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} )();
|
||||
156
Admin/plugins/ckeditor/core/htmlparser/filterRulesDefinition.js
Normal file
156
Admin/plugins/ckeditor/core/htmlparser/filterRulesDefinition.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.htmlParser.filterRulesDefinition} class
|
||||
* that contains the definition of filter rules. This file is for
|
||||
* documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class describing the definition of {@link CKEDITOR.htmlParser.filter} rules.
|
||||
*
|
||||
* Definition object represents rules as a set of properties with callback functions
|
||||
* to be applied for transforming and filtering content upon data processing.
|
||||
*
|
||||
* It can be used with {@link CKEDITOR.htmlParser.filter} and {@link CKEDITOR.htmlParser.filter#addRules}.
|
||||
*
|
||||
* @class CKEDITOR.htmlParser.filterRulesDefinition
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {CKEDITOR.htmlParser.nameTransformRule[]} elementNames An array of rules for element names transformation.
|
||||
* Every rule match will be replaced by the given string.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* elementNames: [
|
||||
* [ /^div$/, 'p' ], // Converts 'div' into 'p'.
|
||||
* [ /^cke:?/, '' ] // Removes 'cke:' prefixes.
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {CKEDITOR.htmlParser.nameTransformRule[]} attributeNames An array of rules for attribute names transformation.
|
||||
* Every matching string from the first item will be converted into the second.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* attributeNames: [
|
||||
* [ 'data-foo', 'data-bar' ],
|
||||
* // Converts the string in the attribute name from 'data-foo' into 'data-bar'.
|
||||
* // Note that the 'data-foo-baz' attribute will be converted into 'data-bar-baz'.
|
||||
*
|
||||
* [ /^data-custom$/, 'data-cke' ]
|
||||
* // Converts the 'data-custom' attribute into 'data-cke'.
|
||||
* ]
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Object.<String, Function>} elements An object containing pairs of element selectors
|
||||
* and functions used upon element filtering and transformation.
|
||||
*
|
||||
* A selector can be either an element name or one of the following: `^`, `$`.
|
||||
*
|
||||
* `^` and `$` are to be applied on every filtered element. The first is applied before the element-specific filter,
|
||||
* and the second is applied after the element-specific filter.
|
||||
*
|
||||
* The function can contain a return statement:
|
||||
*
|
||||
* * If `false` is returned, the element is removed.
|
||||
* * If another element is returned, it overwrites the original element.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* elements: {
|
||||
* '^': function( element ) {
|
||||
* // Element transformation to be applied on every filtered element.
|
||||
* // This will be applied as the first filter.
|
||||
* },
|
||||
* div: function( element ) {
|
||||
* // Element transformation.
|
||||
* },
|
||||
* p: function() {
|
||||
* return false; // Removes each '<p>' element.
|
||||
* },
|
||||
* '$': function( element ) {
|
||||
* // Element transformation to be applied on every filtered element.
|
||||
* // This will be applied after other defined filters.
|
||||
* },
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Object.<String, Function>} attributes An object containing pairs of element attribute names
|
||||
* and functions used upon attribute filtering and transformation.
|
||||
*
|
||||
* Returning `false` removes the attribute.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* attributes: {
|
||||
* 'class': function( value, element ) {
|
||||
* if ( element.name === 'div' ) {
|
||||
* return value + ' cke_div' // Adds the 'cke_div' class to every filtered div element.
|
||||
* }
|
||||
* },
|
||||
* id: function() {
|
||||
* return false; // Removes the 'id' attribute from every filtered element.
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Function} text Function for text content transforming. Returned value replaces text.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* text: function( value, element ) {
|
||||
* return value.toLowerCase(); // Transforms each text into lower case.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Function} comment Function for comments filtering and transforming. Returned value replaces comment text.
|
||||
* If `false` is returned, the comment is removed.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* comment: function( value, element ) {
|
||||
* return false; // Removes the comment.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {Function} root Function for root element transforming.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* ```javascript
|
||||
* root: function( element ) {
|
||||
* element.children.push( someElement ); // Appends a child to the root element.
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
743
Admin/plugins/ckeditor/core/htmlparser/fragment.js
Normal file
743
Admin/plugins/ckeditor/core/htmlparser/fragment.js
Normal file
@@ -0,0 +1,743 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* A lightweight representation of an HTML DOM structure.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a fragment class instance.
|
||||
*/
|
||||
CKEDITOR.htmlParser.fragment = function() {
|
||||
/**
|
||||
* The nodes contained in the root of this fragment.
|
||||
*
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' );
|
||||
* alert( fragment.children.length ); // 2
|
||||
*/
|
||||
this.children = [];
|
||||
|
||||
/**
|
||||
* Get the fragment parent. Should always be null.
|
||||
*
|
||||
* @property {Object} [=null]
|
||||
*/
|
||||
this.parent = null;
|
||||
|
||||
/** @private */
|
||||
this._ = {
|
||||
isBlockLike: true,
|
||||
hasInlineStarted: false
|
||||
};
|
||||
};
|
||||
|
||||
( function() {
|
||||
// Block-level elements whose internal structure should be respected during
|
||||
// parser fixing.
|
||||
var nonBreakingBlocks = CKEDITOR.tools.extend( { table: 1, ul: 1, ol: 1, dl: 1 }, CKEDITOR.dtd.table, CKEDITOR.dtd.ul, CKEDITOR.dtd.ol, CKEDITOR.dtd.dl );
|
||||
|
||||
var listBlocks = { ol: 1, ul: 1 };
|
||||
|
||||
// Dtd of the fragment element, basically it accept anything except for intermediate structure, e.g. orphan <li>.
|
||||
var rootDtd = CKEDITOR.tools.extend( {}, { html: 1 }, CKEDITOR.dtd.html, CKEDITOR.dtd.body, CKEDITOR.dtd.head, { style: 1, script: 1 } );
|
||||
|
||||
// Which element to create when encountered not allowed content.
|
||||
var structureFixes = {
|
||||
ul: 'li',
|
||||
ol: 'li',
|
||||
dl: 'dd',
|
||||
table: 'tbody',
|
||||
tbody: 'tr',
|
||||
thead: 'tr',
|
||||
tfoot: 'tr',
|
||||
tr: 'td'
|
||||
};
|
||||
|
||||
function isRemoveEmpty( node ) {
|
||||
// Keep marked element event if it is empty.
|
||||
if ( node.attributes[ 'data-cke-survive' ] )
|
||||
return false;
|
||||
|
||||
// Empty link is to be removed when empty but not anchor. (https://dev.ckeditor.com/ticket/7894)
|
||||
return node.name == 'a' && node.attributes.href || CKEDITOR.dtd.$removeEmpty[ node.name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link CKEDITOR.htmlParser.fragment} from an HTML string.
|
||||
*
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' );
|
||||
* alert( fragment.children[ 0 ].name ); // 'b'
|
||||
* alert( fragment.children[ 1 ].value ); // ' Text'
|
||||
*
|
||||
* @static
|
||||
* @param {String} fragmentHtml The HTML to be parsed, filling the fragment.
|
||||
* @param {CKEDITOR.htmlParser.element/String} [parent] Optional contextual
|
||||
* element which makes the content been parsed as the content of this element and fix
|
||||
* to match it.
|
||||
* If not provided, then {@link CKEDITOR.htmlParser.fragment} will be used
|
||||
* as the parent and it will be returned.
|
||||
* @param {String/Boolean} [fixingBlock] When `parent` is a block limit element,
|
||||
* and the param is a string value other than `false`, it is to
|
||||
* avoid having block-less content as the direct children of parent by wrapping
|
||||
* the content with a block element of the specified tag, e.g.
|
||||
* when `fixingBlock` specified as `p`, the content `<body><i>foo</i></body>`
|
||||
* will be fixed into `<body><p><i>foo</i></p></body>`.
|
||||
* @returns {CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} The created fragment or passed `parent`.
|
||||
*/
|
||||
CKEDITOR.htmlParser.fragment.fromHtml = function( fragmentHtml, parent, fixingBlock ) {
|
||||
var parser = new CKEDITOR.htmlParser();
|
||||
|
||||
var root = parent instanceof CKEDITOR.htmlParser.element ? parent : typeof parent == 'string' ? new CKEDITOR.htmlParser.element( parent ) : new CKEDITOR.htmlParser.fragment();
|
||||
|
||||
var pendingInline = [],
|
||||
pendingBRs = [],
|
||||
currentNode = root,
|
||||
// Indicate we're inside a <textarea> element, spaces should be touched differently.
|
||||
inTextarea = root.name == 'textarea',
|
||||
// Indicate we're inside a <pre> element, spaces should be touched differently.
|
||||
inPre = root.name == 'pre';
|
||||
|
||||
function checkPending( newTagName ) {
|
||||
var pendingBRsSent;
|
||||
|
||||
if ( pendingInline.length > 0 ) {
|
||||
for ( var i = 0; i < pendingInline.length; i++ ) {
|
||||
var pendingElement = pendingInline[ i ],
|
||||
pendingName = pendingElement.name,
|
||||
pendingDtd = CKEDITOR.dtd[ pendingName ],
|
||||
currentDtd = currentNode.name && CKEDITOR.dtd[ currentNode.name ];
|
||||
|
||||
if ( ( !currentDtd || currentDtd[ pendingName ] ) && ( !newTagName || !pendingDtd || pendingDtd[ newTagName ] || !CKEDITOR.dtd[ newTagName ] ) ) {
|
||||
if ( !pendingBRsSent ) {
|
||||
sendPendingBRs();
|
||||
pendingBRsSent = 1;
|
||||
}
|
||||
|
||||
// Get a clone for the pending element.
|
||||
pendingElement = pendingElement.clone();
|
||||
|
||||
// Add it to the current node and make it the current,
|
||||
// so the new element will be added inside of it.
|
||||
pendingElement.parent = currentNode;
|
||||
currentNode = pendingElement;
|
||||
|
||||
// Remove the pending element (back the index by one
|
||||
// to properly process the next entry).
|
||||
pendingInline.splice( i, 1 );
|
||||
i--;
|
||||
} else {
|
||||
// Some element of the same type cannot be nested, flat them,
|
||||
// e.g. <a href="#">foo<a href="#">bar</a></a>. (https://dev.ckeditor.com/ticket/7894)
|
||||
if ( pendingName == currentNode.name )
|
||||
addElement( currentNode, currentNode.parent, 1 ), i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sendPendingBRs() {
|
||||
while ( pendingBRs.length )
|
||||
addElement( pendingBRs.shift(), currentNode );
|
||||
}
|
||||
|
||||
function shiftBRsPosition() {
|
||||
var shiftLineBreaks = CKEDITOR.config.shiftLineBreaks;
|
||||
|
||||
if ( shiftLineBreaks === true || !pendingBRs.length ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( typeof shiftLineBreaks !== 'function' ) {
|
||||
sendPendingBRs();
|
||||
return;
|
||||
}
|
||||
|
||||
var result = shiftLineBreaks( pendingBRs[ pendingBRs.length - 1 ] );
|
||||
|
||||
if ( result === true ) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendPendingBRs();
|
||||
|
||||
if ( result instanceof CKEDITOR.htmlParser.text ) {
|
||||
currentNode.add( result );
|
||||
}
|
||||
|
||||
if ( result instanceof CKEDITOR.htmlParser.element ) {
|
||||
addElement( result, currentNode );
|
||||
}
|
||||
}
|
||||
|
||||
// Rtrim empty spaces on block end boundary. (https://dev.ckeditor.com/ticket/3585)
|
||||
function removeTailWhitespace( element ) {
|
||||
if ( element._.isBlockLike && element.name != 'pre' && element.name != 'textarea' ) {
|
||||
|
||||
var length = element.children.length,
|
||||
lastChild = element.children[ length - 1 ],
|
||||
text;
|
||||
if ( lastChild && lastChild.type == CKEDITOR.NODE_TEXT ) {
|
||||
if ( !( text = CKEDITOR.tools.rtrim( lastChild.value ) ) )
|
||||
element.children.length = length - 1;
|
||||
else
|
||||
lastChild.value = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Beside of simply append specified element to target, this function also takes
|
||||
// care of other dirty lifts like forcing block in body, trimming spaces at
|
||||
// the block boundaries etc.
|
||||
//
|
||||
// @param {Element} element The element to be added as the last child of {@link target}.
|
||||
// @param {Element} target The parent element to relieve the new node.
|
||||
// @param {Boolean} [moveCurrent=false] Don't change the "currentNode" global unless
|
||||
// there's a return point node specified on the element, otherwise move current onto {@link target} node.
|
||||
//
|
||||
function addElement( element, target, moveCurrent ) {
|
||||
target = target || currentNode || root;
|
||||
|
||||
// Current element might be mangled by fix body below,
|
||||
// save it for restore later.
|
||||
var savedCurrent = currentNode;
|
||||
|
||||
// Ignore any element that has already been added.
|
||||
if ( element.previous === undefined ) {
|
||||
if ( checkAutoParagraphing( target, element ) ) {
|
||||
// Create a <p> in the fragment.
|
||||
currentNode = target;
|
||||
parser.onTagOpen( fixingBlock, {} );
|
||||
|
||||
// The new target now is the <p>.
|
||||
element.returnPoint = target = currentNode;
|
||||
}
|
||||
|
||||
removeTailWhitespace( element );
|
||||
|
||||
// Avoid adding empty inline.
|
||||
if ( !( isRemoveEmpty( element ) && !element.children.length ) )
|
||||
target.add( element );
|
||||
|
||||
if ( element.name == 'pre' )
|
||||
inPre = false;
|
||||
|
||||
if ( element.name == 'textarea' )
|
||||
inTextarea = false;
|
||||
}
|
||||
|
||||
if ( element.returnPoint ) {
|
||||
currentNode = element.returnPoint;
|
||||
delete element.returnPoint;
|
||||
} else {
|
||||
currentNode = moveCurrent ? target : savedCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
// Auto paragraphing should happen when inline content enters the root element.
|
||||
function checkAutoParagraphing( parent, node ) {
|
||||
|
||||
// Check for parent that can contain block.
|
||||
if ( ( parent == root || parent.name == 'body' ) && fixingBlock &&
|
||||
( !parent.name || CKEDITOR.dtd[ parent.name ][ fixingBlock ] ) ) {
|
||||
var name, realName;
|
||||
|
||||
if ( node.attributes && ( realName = node.attributes[ 'data-cke-real-element-type' ] ) )
|
||||
name = realName;
|
||||
else
|
||||
name = node.name;
|
||||
|
||||
// Text node, inline elements are subjected, except for <script>/<style>.
|
||||
return name && name in CKEDITOR.dtd.$inline &&
|
||||
!( name in CKEDITOR.dtd.head ) &&
|
||||
!node.isOrphan ||
|
||||
node.type == CKEDITOR.NODE_TEXT;
|
||||
}
|
||||
}
|
||||
|
||||
// Judge whether two element tag names are likely the siblings from the same
|
||||
// structural element.
|
||||
function possiblySibling( tag1, tag2 ) {
|
||||
|
||||
if ( tag1 in CKEDITOR.dtd.$listItem || tag1 in CKEDITOR.dtd.$tableContent )
|
||||
return tag1 == tag2 || tag1 == 'dt' && tag2 == 'dd' || tag1 == 'dd' && tag2 == 'dt';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
parser.onTagOpen = function( tagName, attributes, selfClosing, optionalClose ) {
|
||||
var element = new CKEDITOR.htmlParser.element( tagName, attributes );
|
||||
|
||||
// "isEmpty" will be always "false" for unknown elements, so we
|
||||
// must force it if the parser has identified it as a selfClosing tag.
|
||||
if ( element.isUnknown && selfClosing )
|
||||
element.isEmpty = true;
|
||||
|
||||
// Check for optional closed elements, including browser quirks and manually opened blocks.
|
||||
element.isOptionalClose = optionalClose;
|
||||
|
||||
// This is a tag to be removed if empty, so do not add it immediately.
|
||||
if ( isRemoveEmpty( element ) ) {
|
||||
pendingInline.push( element );
|
||||
return;
|
||||
} else if ( tagName == 'pre' )
|
||||
inPre = true;
|
||||
else if ( tagName == 'br' && inPre ) {
|
||||
currentNode.add( new CKEDITOR.htmlParser.text( '\n' ) );
|
||||
return;
|
||||
} else if ( tagName == 'textarea' ) {
|
||||
inTextarea = true;
|
||||
}
|
||||
|
||||
if ( tagName == 'br' ) {
|
||||
pendingBRs.push( element );
|
||||
return;
|
||||
}
|
||||
|
||||
while ( 1 ) {
|
||||
var currentName = currentNode.name;
|
||||
|
||||
var currentDtd = currentName ? ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ) : rootDtd;
|
||||
|
||||
// If the element cannot be child of the current element.
|
||||
if ( !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) {
|
||||
// Current node doesn't have a close tag, time for a close
|
||||
// as this element isn't fit in. (https://dev.ckeditor.com/ticket/7497)
|
||||
if ( currentNode.isOptionalClose )
|
||||
parser.onTagClose( currentName );
|
||||
// Fixing malformed nested lists by moving it into a previous list item. (https://dev.ckeditor.com/ticket/3828)
|
||||
else if ( tagName in listBlocks && currentName in listBlocks ) {
|
||||
var children = currentNode.children,
|
||||
lastChild = children[ children.length - 1 ];
|
||||
|
||||
// Establish the list item if it's not existed.
|
||||
if ( !( lastChild && lastChild.name == 'li' ) )
|
||||
addElement( ( lastChild = new CKEDITOR.htmlParser.element( 'li' ) ), currentNode );
|
||||
|
||||
!element.returnPoint && ( element.returnPoint = currentNode );
|
||||
currentNode = lastChild;
|
||||
}
|
||||
// Establish new list root for orphan list items, but NOT to create
|
||||
// new list for the following ones, fix them instead. (https://dev.ckeditor.com/ticket/6975)
|
||||
// <dl><dt>foo<dd>bar</dl>
|
||||
// <ul><li>foo<li>bar</ul>
|
||||
else if ( tagName in CKEDITOR.dtd.$listItem &&
|
||||
!possiblySibling( tagName, currentName ) ) {
|
||||
parser.onTagOpen( tagName == 'li' ? 'ul' : 'dl', {}, 0, 1 );
|
||||
}
|
||||
// We're inside a structural block like table and list, AND the incoming element
|
||||
// is not of the same type (e.g. <td>td1<td>td2</td>), we simply add this new one before it,
|
||||
// and most importantly, return back to here once this element is added,
|
||||
// e.g. <table><tr><td>td1</td><p>p1</p><td>td2</td></tr></table>
|
||||
else if ( currentName in nonBreakingBlocks &&
|
||||
!possiblySibling( tagName, currentName ) ) {
|
||||
!element.returnPoint && ( element.returnPoint = currentNode );
|
||||
currentNode = currentNode.parent;
|
||||
} else {
|
||||
// The current element is an inline element, which
|
||||
// need to be continued even after the close, so put
|
||||
// it in the pending list.
|
||||
if ( currentName in CKEDITOR.dtd.$inline )
|
||||
pendingInline.unshift( currentNode );
|
||||
|
||||
// The most common case where we just need to close the
|
||||
// current one and append the new one to the parent.
|
||||
if ( currentNode.parent )
|
||||
addElement( currentNode, currentNode.parent, 1 );
|
||||
// We've tried our best to fix the embarrassment here, while
|
||||
// this element still doesn't find it's parent, mark it as
|
||||
// orphan and show our tolerance to it.
|
||||
else {
|
||||
element.isOrphan = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
checkPending( tagName );
|
||||
sendPendingBRs();
|
||||
|
||||
element.parent = currentNode;
|
||||
|
||||
if ( element.isEmpty )
|
||||
addElement( element );
|
||||
else
|
||||
currentNode = element;
|
||||
};
|
||||
|
||||
parser.onTagClose = function( tagName ) {
|
||||
// Check if there is any pending tag to be closed.
|
||||
for ( var i = pendingInline.length - 1; i >= 0; i-- ) {
|
||||
// If found, just remove it from the list.
|
||||
if ( tagName == pendingInline[ i ].name ) {
|
||||
pendingInline.splice( i, 1 );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var pendingAdd = [],
|
||||
newPendingInline = [],
|
||||
candidate = currentNode;
|
||||
|
||||
while ( candidate != root && candidate.name != tagName ) {
|
||||
// If this is an inline element, add it to the pending list, if we're
|
||||
// really closing one of the parents element later, they will continue
|
||||
// after it.
|
||||
if ( !candidate._.isBlockLike )
|
||||
newPendingInline.unshift( candidate );
|
||||
|
||||
// This node should be added to it's parent at this point. But,
|
||||
// it should happen only if the closing tag is really closing
|
||||
// one of the nodes. So, for now, we just cache it.
|
||||
pendingAdd.push( candidate );
|
||||
|
||||
// Make sure return point is properly restored.
|
||||
candidate = candidate.returnPoint || candidate.parent;
|
||||
}
|
||||
|
||||
if ( candidate != root ) {
|
||||
// Add all elements that have been found in the above loop.
|
||||
for ( i = 0; i < pendingAdd.length; i++ ) {
|
||||
var node = pendingAdd[ i ];
|
||||
addElement( node, node.parent );
|
||||
}
|
||||
|
||||
currentNode = candidate;
|
||||
|
||||
if ( candidate._.isBlockLike ) {
|
||||
sendPendingBRs();
|
||||
} else {
|
||||
shiftBRsPosition();
|
||||
}
|
||||
|
||||
addElement( candidate, candidate.parent );
|
||||
|
||||
// The parent should start receiving new nodes now, except if
|
||||
// addElement changed the currentNode.
|
||||
if ( candidate == currentNode )
|
||||
currentNode = currentNode.parent;
|
||||
|
||||
pendingInline = pendingInline.concat( newPendingInline );
|
||||
}
|
||||
|
||||
if ( tagName == 'body' )
|
||||
fixingBlock = false;
|
||||
};
|
||||
|
||||
parser.onText = function( text ) {
|
||||
// Trim empty spaces at beginning of text contents except <pre> and <textarea>.
|
||||
if ( ( !currentNode._.hasInlineStarted || pendingBRs.length ) && !inPre && !inTextarea ) {
|
||||
text = CKEDITOR.tools.ltrim( text );
|
||||
|
||||
if ( text.length === 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
var currentName = currentNode.name,
|
||||
currentDtd = currentName ? ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ) : rootDtd;
|
||||
|
||||
// Fix orphan text in list/table. (https://dev.ckeditor.com/ticket/8540) (https://dev.ckeditor.com/ticket/8870)
|
||||
if ( !inTextarea && !currentDtd[ '#' ] && currentName in nonBreakingBlocks ) {
|
||||
parser.onTagOpen( structureFixes[ currentName ] || '' );
|
||||
parser.onText( text );
|
||||
return;
|
||||
}
|
||||
|
||||
sendPendingBRs();
|
||||
checkPending();
|
||||
|
||||
// Shrinking consequential spaces into one single for all elements
|
||||
// text contents.
|
||||
if ( !inPre && !inTextarea )
|
||||
text = text.replace( /[\t\r\n ]{2,}|[\t\r\n]/g, ' ' );
|
||||
|
||||
text = new CKEDITOR.htmlParser.text( text );
|
||||
|
||||
|
||||
if ( checkAutoParagraphing( currentNode, text ) )
|
||||
this.onTagOpen( fixingBlock, {}, 0, 1 );
|
||||
|
||||
currentNode.add( text );
|
||||
};
|
||||
|
||||
parser.onCDATA = function( cdata ) {
|
||||
currentNode.add( new CKEDITOR.htmlParser.cdata( cdata ) );
|
||||
};
|
||||
|
||||
parser.onComment = function( comment ) {
|
||||
sendPendingBRs();
|
||||
checkPending();
|
||||
currentNode.add( new CKEDITOR.htmlParser.comment( comment ) );
|
||||
};
|
||||
|
||||
// Parse it.
|
||||
parser.parse( fragmentHtml );
|
||||
|
||||
sendPendingBRs();
|
||||
|
||||
// Close all pending nodes, make sure return point is properly restored.
|
||||
while ( currentNode != root )
|
||||
addElement( currentNode, currentNode.parent, 1 );
|
||||
|
||||
removeTailWhitespace( root );
|
||||
|
||||
return root;
|
||||
};
|
||||
|
||||
CKEDITOR.htmlParser.fragment.prototype = {
|
||||
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_DOCUMENT_FRAGMENT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_DOCUMENT_FRAGMENT,
|
||||
|
||||
/**
|
||||
* Adds a node to this fragment.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.node} node The node to be added.
|
||||
* @param {Number} [index] From where the insertion happens.
|
||||
*/
|
||||
add: function( node, index ) {
|
||||
isNaN( index ) && ( index = this.children.length );
|
||||
|
||||
var previous = index > 0 ? this.children[ index - 1 ] : null;
|
||||
if ( previous ) {
|
||||
// If the block to be appended is following text, trim spaces at
|
||||
// the right of it.
|
||||
if ( node._.isBlockLike && previous.type == CKEDITOR.NODE_TEXT ) {
|
||||
previous.value = CKEDITOR.tools.rtrim( previous.value );
|
||||
|
||||
// If we have completely cleared the previous node.
|
||||
if ( previous.value.length === 0 ) {
|
||||
// Remove it from the list and add the node again.
|
||||
this.children.pop();
|
||||
this.add( node );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
previous.next = node;
|
||||
}
|
||||
|
||||
node.previous = previous;
|
||||
node.parent = this;
|
||||
|
||||
this.children.splice( index, 0, node );
|
||||
|
||||
if ( !this._.hasInlineStarted )
|
||||
this._.hasInlineStarted = node.type == CKEDITOR.NODE_TEXT || ( node.type == CKEDITOR.NODE_ELEMENT && !node._.isBlockLike );
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter this fragment's content with given filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
*/
|
||||
filter: function( filter, context ) {
|
||||
context = this.getFilterContext( context );
|
||||
|
||||
// Apply the root filter.
|
||||
filter.onRoot( context, this );
|
||||
|
||||
this.filterChildren( filter, false, context );
|
||||
},
|
||||
|
||||
/**
|
||||
* Filter this fragment's children with given filter.
|
||||
*
|
||||
* Element's children may only be filtered once by one
|
||||
* instance of filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
* @param {Boolean} [filterRoot] Whether to apply the "root" filter rule specified in the `filter`.
|
||||
*/
|
||||
filterChildren: function( filter, filterRoot, context ) {
|
||||
// If this element's children were already filtered
|
||||
// by current filter, don't filter them 2nd time.
|
||||
// This situation may occur when filtering bottom-up
|
||||
// (filterChildren() called manually in element's filter),
|
||||
// or in unpredictable edge cases when filter
|
||||
// is manipulating DOM structure.
|
||||
if ( this.childrenFilteredBy == filter.id )
|
||||
return;
|
||||
|
||||
context = this.getFilterContext( context );
|
||||
|
||||
// Filtering root if enforced.
|
||||
if ( filterRoot && !this.parent )
|
||||
filter.onRoot( context, this );
|
||||
|
||||
this.childrenFilteredBy = filter.id;
|
||||
|
||||
// Don't cache anything, children array may be modified by filter rule.
|
||||
for ( var i = 0; i < this.children.length; i++ ) {
|
||||
// Stay in place if filter returned false, what means
|
||||
// that node has been removed.
|
||||
if ( this.children[ i ].filter( filter, context ) === false )
|
||||
i--;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the fragment HTML to a {@link CKEDITOR.htmlParser.basicWriter}.
|
||||
*
|
||||
* var writer = new CKEDITOR.htmlWriter();
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<P><B>Example' );
|
||||
* fragment.writeHtml( writer );
|
||||
* alert( writer.getHtml() ); // '<p><b>Example</b></p>'
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to use when writing the HTML.
|
||||
*/
|
||||
writeHtml: function( writer, filter ) {
|
||||
if ( filter )
|
||||
this.filter( filter );
|
||||
|
||||
this.writeChildrenHtml( writer );
|
||||
},
|
||||
|
||||
/**
|
||||
* Write and filtering the child nodes of this fragment.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to use when writing the HTML.
|
||||
* @param {Boolean} [filterRoot] Whether to apply the "root" filter rule specified in the `filter`.
|
||||
*/
|
||||
writeChildrenHtml: function( writer, filter, filterRoot ) {
|
||||
var context = this.getFilterContext();
|
||||
|
||||
// Filtering root if enforced.
|
||||
if ( filterRoot && !this.parent && filter )
|
||||
filter.onRoot( context, this );
|
||||
|
||||
if ( filter )
|
||||
this.filterChildren( filter, false, context );
|
||||
|
||||
for ( var i = 0, children = this.children, l = children.length; i < l; i++ )
|
||||
children[ i ].writeHtml( writer );
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute callback on each node (of a given type) in this document fragment.
|
||||
*
|
||||
* var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>foo<b>bar</b>bom</p>' );
|
||||
* fragment.forEach( function( node ) {
|
||||
* console.log( node );
|
||||
* } );
|
||||
* // Will log:
|
||||
* // 1. document fragment,
|
||||
* // 2. <p> element,
|
||||
* // 3. "foo" text node,
|
||||
* // 4. <b> element,
|
||||
* // 5. "bar" text node,
|
||||
* // 6. "bom" text node.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {Function} callback Function to be executed on every node.
|
||||
* **Since 4.3.0** if `callback` returned `false` descendants of current node will be ignored.
|
||||
* @param {CKEDITOR.htmlParser.node} callback.node Node passed as argument.
|
||||
* @param {Number} [type] If specified `callback` will be executed only on nodes of this type.
|
||||
* @param {Boolean} [skipRoot] Don't execute `callback` on this fragment.
|
||||
*/
|
||||
forEach: function( callback, type, skipRoot ) {
|
||||
if ( !skipRoot && ( !type || this.type == type ) )
|
||||
var ret = callback( this );
|
||||
|
||||
// Do not filter children if callback returned false.
|
||||
if ( ret === false )
|
||||
return;
|
||||
|
||||
var children = this.children,
|
||||
node,
|
||||
i = 0;
|
||||
|
||||
// We do not cache the size, because the list of nodes may be changed by the callback.
|
||||
for ( ; i < children.length; i++ ) {
|
||||
node = children[ i ];
|
||||
if ( node.type == CKEDITOR.NODE_ELEMENT )
|
||||
node.forEach( callback, type );
|
||||
else if ( !type || node.type == type )
|
||||
callback( node );
|
||||
}
|
||||
},
|
||||
|
||||
getFilterContext: function( context ) {
|
||||
return context || {};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Indicates if line breaks (`br`) should be moved outside inline elements.
|
||||
*
|
||||
* **Note:** This is a global configuration that applies to all instances.
|
||||
*
|
||||
* By default, all children `br` elements, placed at the end of an inline element,
|
||||
* are shifted outside that element. Shifted elements are attached at the end of the parent block element.
|
||||
* It allows producing more clean HTML output without an abundance of
|
||||
* orphaned styling markers. This logic can be changed by disabling shifting line breaks or providing
|
||||
* a custom function allowing to conditionally choose proper behavior.
|
||||
*
|
||||
* * `shiftLineBreaks = true`
|
||||
*
|
||||
* Shift line breaks outside inline element:
|
||||
*
|
||||
* <p><strong>hello, world!<br><br></strong></p>
|
||||
*
|
||||
* will become:
|
||||
*
|
||||
* <p><strong>hello, world!</strong><br><br></p>
|
||||
*
|
||||
* * `shiftLineBreaks = false`
|
||||
*
|
||||
* Keep line breaks inside an inline element:
|
||||
*
|
||||
* <p><strong>hello, world!<br><br></strong></p>
|
||||
*
|
||||
* * `shiftLineBreaks = customFunction`
|
||||
*
|
||||
* Provide a callback function allowing to decide if a line break should be shifted:
|
||||
*
|
||||
* ```javascript
|
||||
* CKEDITOR.config.shiftLineBreaks = function() {
|
||||
* if ( condition ) {
|
||||
* // Shift line break outside element.
|
||||
* return true;
|
||||
* }
|
||||
* // Keep line break inside element.
|
||||
* return false;
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* You can also decide to return the {@link CKEDITOR.htmlParser.text} or {@link CKEDITOR.htmlParser.element}
|
||||
* node that will be attached **at the end of the last `br` node** inside an inline element.
|
||||
*
|
||||
* As an example, you may want to add an additional ` ` filler to make sure that a user will be
|
||||
* able to place caret after break lines:
|
||||
*
|
||||
* ```javascript
|
||||
* CKEDITOR.config.shiftLineBreaks = function() {
|
||||
* // Append `nbsp;` character at the end.
|
||||
* return new CKEDITOR.htmlParser.text( ' ' );
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* resulting in:
|
||||
*
|
||||
* <p><strong>hello, world!<br><br> </strong></p>
|
||||
*
|
||||
* @cfg {Boolean/Function} [shiftLineBreaks=true]
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
|
||||
CKEDITOR.config.shiftLineBreaks = true;
|
||||
} )();
|
||||
29
Admin/plugins/ckeditor/core/htmlparser/nameTransformRule.js
Normal file
29
Admin/plugins/ckeditor/core/htmlparser/nameTransformRule.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.htmlParser.nameTransformRule} class
|
||||
* that contains the definition of rule for filtering element names or attribute names. This file is for
|
||||
* documentation purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract class describing the definition of {@link CKEDITOR.htmlParser.filterRulesDefinition} `elementNames` and `attributesNames` filtering rules.
|
||||
*
|
||||
* ```javascript
|
||||
* var rule = [ /^div$/, 'p' ];
|
||||
* ```
|
||||
*
|
||||
* @class CKEDITOR.htmlParser.nameTransformRule
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {RegExp} 0 A regular expression to match the element name or attribute.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {String} 1 A string used to replace the match.
|
||||
*/
|
||||
156
Admin/plugins/ckeditor/core/htmlparser/node.js
Normal file
156
Admin/plugins/ckeditor/core/htmlparser/node.js
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* A lightweight representation of HTML node.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @class
|
||||
* @constructor Creates a node class instance.
|
||||
*/
|
||||
CKEDITOR.htmlParser.node = function() {};
|
||||
|
||||
CKEDITOR.htmlParser.node.prototype = {
|
||||
/**
|
||||
* Remove this node from a tree.
|
||||
*
|
||||
* @since 4.1.0
|
||||
*/
|
||||
remove: function() {
|
||||
var children = this.parent.children,
|
||||
index = CKEDITOR.tools.indexOf( children, this ),
|
||||
previous = this.previous,
|
||||
next = this.next;
|
||||
|
||||
previous && ( previous.next = next );
|
||||
next && ( next.previous = previous );
|
||||
children.splice( index, 1 );
|
||||
this.parent = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Replace this node with given one.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.node} node The node that will replace this one.
|
||||
*/
|
||||
replaceWith: function( node ) {
|
||||
var children = this.parent.children,
|
||||
index = CKEDITOR.tools.indexOf( children, this ),
|
||||
previous = node.previous = this.previous,
|
||||
next = node.next = this.next;
|
||||
|
||||
previous && ( previous.next = node );
|
||||
next && ( next.previous = node );
|
||||
|
||||
children[ index ] = node;
|
||||
|
||||
node.parent = this.parent;
|
||||
this.parent = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Insert this node after given one.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.node} node The node that will precede this element.
|
||||
*/
|
||||
insertAfter: function( node ) {
|
||||
var children = node.parent.children,
|
||||
index = CKEDITOR.tools.indexOf( children, node ),
|
||||
next = node.next;
|
||||
|
||||
children.splice( index + 1, 0, this );
|
||||
|
||||
this.next = node.next;
|
||||
this.previous = node;
|
||||
node.next = this;
|
||||
next && ( next.previous = this );
|
||||
|
||||
this.parent = node.parent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Insert this node before given one.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.node} node The node that will follow this element.
|
||||
*/
|
||||
insertBefore: function( node ) {
|
||||
var children = node.parent.children,
|
||||
index = CKEDITOR.tools.indexOf( children, node );
|
||||
|
||||
children.splice( index, 0, this );
|
||||
|
||||
this.next = node;
|
||||
this.previous = node.previous;
|
||||
node.previous && ( node.previous.next = this );
|
||||
node.previous = this;
|
||||
|
||||
this.parent = node.parent;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the closest ancestor element of this element which satisfies given condition
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {String/Object/Function} condition Name of an ancestor, hash of names or validator function.
|
||||
* @returns {CKEDITOR.htmlParser.element} The closest ancestor which satisfies given condition or `null`.
|
||||
*/
|
||||
getAscendant: function( condition ) {
|
||||
var checkFn =
|
||||
typeof condition == 'function' ?
|
||||
condition :
|
||||
typeof condition == 'string' ?
|
||||
function( el ) {
|
||||
return el.name == condition;
|
||||
} :
|
||||
function( el ) {
|
||||
return el.name in condition;
|
||||
};
|
||||
|
||||
var parent = this.parent;
|
||||
|
||||
// Parent has to be an element - don't check doc fragment.
|
||||
while ( parent && parent.type == CKEDITOR.NODE_ELEMENT ) {
|
||||
if ( checkFn( parent ) )
|
||||
return parent;
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Wraps this element with given `wrapper`.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @param {CKEDITOR.htmlParser.element} wrapper The element which will be this element's new parent.
|
||||
* @returns {CKEDITOR.htmlParser.element} Wrapper.
|
||||
*/
|
||||
wrapWith: function( wrapper ) {
|
||||
this.replaceWith( wrapper );
|
||||
wrapper.add( this );
|
||||
return wrapper;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets this node's index in its parent's children array.
|
||||
*
|
||||
* @since 4.3.0
|
||||
* @returns {Number}
|
||||
*/
|
||||
getIndex: function() {
|
||||
return CKEDITOR.tools.indexOf( this.parent.children, this );
|
||||
},
|
||||
|
||||
getFilterContext: function( context ) {
|
||||
return context || {};
|
||||
}
|
||||
};
|
||||
} )();
|
||||
70
Admin/plugins/ckeditor/core/htmlparser/text.js
Normal file
70
Admin/plugins/ckeditor/core/htmlparser/text.js
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* A lightweight representation of HTML text.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.htmlParser.node
|
||||
* @constructor Creates a text class instance.
|
||||
* @param {String} value The text node value.
|
||||
*/
|
||||
CKEDITOR.htmlParser.text = function( value ) {
|
||||
/**
|
||||
* The text value.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.value = value;
|
||||
|
||||
/** @private */
|
||||
this._ = {
|
||||
isBlockLike: false
|
||||
};
|
||||
};
|
||||
|
||||
CKEDITOR.htmlParser.text.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
|
||||
/**
|
||||
* The node type. This is a constant value set to {@link CKEDITOR#NODE_TEXT}.
|
||||
*
|
||||
* @readonly
|
||||
* @property {Number} [=CKEDITOR.NODE_TEXT]
|
||||
*/
|
||||
type: CKEDITOR.NODE_TEXT,
|
||||
|
||||
/**
|
||||
* Filter this text node with given filter.
|
||||
*
|
||||
* @since 4.1.0
|
||||
* @param {CKEDITOR.htmlParser.filter} filter
|
||||
* @returns {Boolean} Method returns `false` when this text node has
|
||||
* been removed. This is an information for {@link CKEDITOR.htmlParser.element#filterChildren}
|
||||
* that it has to repeat filter on current position in parent's children array.
|
||||
*/
|
||||
filter: function( filter, context ) {
|
||||
if ( !( this.value = filter.onText( context, this.value, this ) ) ) {
|
||||
this.remove();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Writes the HTML representation of this text to a {CKEDITOR.htmlParser.basicWriter}.
|
||||
*
|
||||
* @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
|
||||
* @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
|
||||
* **Note:** it's unsafe to filter offline (not appended) node.
|
||||
*/
|
||||
writeHtml: function( writer, filter ) {
|
||||
if ( filter )
|
||||
this.filter( filter );
|
||||
|
||||
writer.text( this.value );
|
||||
}
|
||||
} );
|
||||
} )();
|
||||
169
Admin/plugins/ckeditor/core/keystrokehandler.js
Normal file
169
Admin/plugins/ckeditor/core/keystrokehandler.js
Normal file
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Controls keystrokes typing in an editor instance.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a keystrokeHandler class instance.
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
CKEDITOR.keystrokeHandler = function( editor ) {
|
||||
if ( editor.keystrokeHandler )
|
||||
return editor.keystrokeHandler;
|
||||
|
||||
/**
|
||||
* A list of keystrokes associated with commands. Each entry points to the
|
||||
* command to be executed.
|
||||
*
|
||||
* Since CKEditor 4 there is no need to modify this property directly during the runtime.
|
||||
* Use {@link CKEDITOR.editor#setKeystroke} instead.
|
||||
*/
|
||||
this.keystrokes = {};
|
||||
|
||||
/**
|
||||
* A list of keystrokes that should be blocked if not defined in
|
||||
* {@link #keystrokes}. In this way it is possible to block the default
|
||||
* browser behavior for those keystrokes.
|
||||
*/
|
||||
this.blockedKeystrokes = {};
|
||||
|
||||
this._ = {
|
||||
editor: editor
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
( function() {
|
||||
var cancel;
|
||||
|
||||
var onKeyDown = function( event ) {
|
||||
// The DOM event object is passed by the "data" property.
|
||||
event = event.data;
|
||||
|
||||
var keyCombination = event.getKeystroke();
|
||||
var command = this.keystrokes[ keyCombination ];
|
||||
var editor = this._.editor;
|
||||
|
||||
cancel = ( editor.fire( 'key', { keyCode: keyCombination, domEvent: event } ) === false );
|
||||
|
||||
if ( !cancel ) {
|
||||
if ( command ) {
|
||||
var data = { from: 'keystrokeHandler' };
|
||||
cancel = ( editor.execCommand( command, data ) !== false );
|
||||
}
|
||||
|
||||
if ( !cancel )
|
||||
cancel = !!this.blockedKeystrokes[ keyCombination ];
|
||||
}
|
||||
|
||||
if ( cancel )
|
||||
event.preventDefault( true );
|
||||
|
||||
return !cancel;
|
||||
};
|
||||
|
||||
var onKeyPress = function( event ) {
|
||||
if ( cancel ) {
|
||||
cancel = false;
|
||||
event.data.preventDefault( true );
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.keystrokeHandler.prototype = {
|
||||
/**
|
||||
* Attaches this keystroke handle to a DOM object. Keystrokes typed
|
||||
* over this object will be handled by this keystrokeHandler.
|
||||
*
|
||||
* @param {CKEDITOR.dom.domObject} domObject The DOM object to attach to.
|
||||
*/
|
||||
attach: function( domObject ) {
|
||||
// For most browsers, it is enough to listen to the keydown event
|
||||
// only.
|
||||
domObject.on( 'keydown', onKeyDown, this );
|
||||
|
||||
// Some browsers instead, don't cancel key events in the keydown, but in the
|
||||
// keypress. So we must do a longer trip in those cases.
|
||||
if ( CKEDITOR.env.gecko && CKEDITOR.env.mac )
|
||||
domObject.on( 'keypress', onKeyPress, this );
|
||||
}
|
||||
};
|
||||
} )();
|
||||
|
||||
/**
|
||||
* A list associating keystrokes with editor commands. Each element in the list
|
||||
* is an array where the first item is the keystroke, and the second is the
|
||||
* name of the command to be executed.
|
||||
*
|
||||
* This setting should be used to define (as well as to overwrite or remove) keystrokes
|
||||
* set by plugins (like `link` and `basicstyles`). If you want to set a keystroke
|
||||
* for your plugin or during the runtime, use {@link CKEDITOR.editor#setKeystroke} instead.
|
||||
*
|
||||
* Since default keystrokes are set by the {@link CKEDITOR.editor#setKeystroke}
|
||||
* method, by default `config.keystrokes` is an empty array.
|
||||
*
|
||||
* See {@link CKEDITOR.editor#setKeystroke} documentation for more details
|
||||
* regarding the start up order.
|
||||
*
|
||||
* // Change default Ctrl+L keystroke for 'link' command to Ctrl+Shift+L.
|
||||
* config.keystrokes = [
|
||||
* ...
|
||||
* [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 76, 'link' ], // Ctrl+Shift+L
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* To reset a particular keystroke, the following approach can be used:
|
||||
*
|
||||
* // Disable default Ctrl+L keystroke which executes the 'link' command by default.
|
||||
* config.keystrokes = [
|
||||
* ...
|
||||
* [ CKEDITOR.CTRL + 76, null ], // Ctrl+L
|
||||
* ...
|
||||
* ];
|
||||
*
|
||||
* In order to reset all default keystrokes, a {@link CKEDITOR#instanceReady} callback should be
|
||||
* used. This is since editor defaults are merged rather than overwritten by
|
||||
* user keystrokes.
|
||||
*
|
||||
* **Note**: This can be potentially harmful for the editor. Avoid this unless you are
|
||||
* aware of the consequences.
|
||||
*
|
||||
* // Reset all default keystrokes.
|
||||
* config.on.instanceReady = function() {
|
||||
* this.keystrokeHandler.keystrokes = [];
|
||||
* };
|
||||
*
|
||||
* @cfg {Array} [keystrokes=[]]
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
|
||||
/**
|
||||
* Fired when any keyboard key (or a combination thereof) is pressed in the editing area.
|
||||
*
|
||||
* editor.on( 'key', function( evt ) {
|
||||
* if ( evt.data.keyCode == CKEDITOR.CTRL + 90 ) {
|
||||
* // Do something...
|
||||
*
|
||||
* // Cancel the event, so other listeners will not be executed and
|
||||
* // the keydown's default behavior will be prevented.
|
||||
* evt.cancel();
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* Usually you will want to use the {@link CKEDITOR.editor#setKeystroke} method or
|
||||
* the {@link CKEDITOR.config#keystrokes} option to attach a keystroke to some {@link CKEDITOR.command command}.
|
||||
* Key event listeners are usuful when some action should be executed conditionally, based
|
||||
* for example on precise selection location.
|
||||
*
|
||||
* @event key
|
||||
* @member CKEDITOR.editor
|
||||
* @param data
|
||||
* @param {Number} data.keyCode A number representing the key code (or a combination thereof).
|
||||
* It is the sum of the current key code and the {@link CKEDITOR#CTRL}, {@link CKEDITOR#SHIFT}
|
||||
* and {@link CKEDITOR#ALT} constants, if those are pressed.
|
||||
* @param {CKEDITOR.dom.event} data.domEvent A `keydown` DOM event instance. Available since CKEditor 4.4.1.
|
||||
* @param {CKEDITOR.editor} editor This editor instance.
|
||||
*/
|
||||
103
Admin/plugins/ckeditor/core/lang.js
Normal file
103
Admin/plugins/ckeditor/core/lang.js
Normal file
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
( function() {
|
||||
/**
|
||||
* Stores language-related functions.
|
||||
*
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.lang = {
|
||||
/**
|
||||
* The list of languages available in the editor core.
|
||||
*
|
||||
* alert( CKEDITOR.lang.languages.en ); // 1
|
||||
*/
|
||||
languages: {
|
||||
af: 1, ar: 1, az: 1, bg: 1, bn: 1, bs: 1, ca: 1, cs: 1, cy: 1, da: 1, de: 1, 'de-ch': 1, el: 1,
|
||||
'en-au': 1, 'en-ca': 1, 'en-gb': 1, en: 1, eo: 1, es: 1, 'es-mx':1, et: 1, eu: 1, fa: 1, fi: 1, fo: 1,
|
||||
'fr-ca': 1, fr: 1, gl: 1, gu: 1, he: 1, hi: 1, hr: 1, hu: 1, id: 1, is: 1, it: 1, ja: 1, ka: 1,
|
||||
km: 1, ko: 1, ku: 1, lt: 1, lv: 1, mk: 1, mn: 1, ms: 1, nb: 1, nl: 1, no: 1, oc: 1, pl: 1, 'pt-br': 1,
|
||||
pt: 1, ro: 1, ru: 1, si: 1, sk: 1, sl: 1, sq: 1, 'sr-latn': 1, sr: 1, sv: 1, th: 1, tr: 1, tt: 1, ug: 1,
|
||||
uk: 1, vi: 1, 'zh-cn': 1, zh: 1
|
||||
},
|
||||
|
||||
/**
|
||||
* The list of languages that are written Right-To-Left (RTL) and are supported by the editor.
|
||||
*/
|
||||
rtl: { ar: 1, fa: 1, he: 1, ku: 1, ug: 1 },
|
||||
|
||||
/**
|
||||
* Loads a specific language file, or auto detects it. A callback is
|
||||
* then called when the file gets loaded.
|
||||
*
|
||||
* @param {String} languageCode The code of the language file to be
|
||||
* loaded. If null or empty, autodetection will be performed. The
|
||||
* same happens if the language is not supported.
|
||||
* @param {String} defaultLanguage The language to be used if
|
||||
* `languageCode` is not supported or if the autodetection fails.
|
||||
* @param {Function} callback A function to be called once the
|
||||
* language file is loaded. Two parameters are passed to this
|
||||
* function: the language code and the loaded language entries.
|
||||
*/
|
||||
load: function( languageCode, defaultLanguage, callback ) {
|
||||
// If no languageCode - fallback to browser or default.
|
||||
// If languageCode - fallback to no-localized version or default.
|
||||
if ( !languageCode || !CKEDITOR.lang.languages[ languageCode ] )
|
||||
languageCode = this.detect( defaultLanguage, languageCode );
|
||||
|
||||
var that = this,
|
||||
loadedCallback = function() {
|
||||
that[ languageCode ].dir = that.rtl[ languageCode ] ? 'rtl' : 'ltr';
|
||||
callback( languageCode, that[ languageCode ] );
|
||||
};
|
||||
|
||||
if ( !this[ languageCode ] )
|
||||
CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( 'lang/' + languageCode + '.js' ), loadedCallback, this );
|
||||
else
|
||||
loadedCallback();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the language that best fits the user language. For example,
|
||||
* suppose that the user language is "pt-br". If this language is
|
||||
* supported by the editor, it is returned. Otherwise, if only "pt" is
|
||||
* supported, it is returned instead. If none of the previous are
|
||||
* supported, a default language is then returned.
|
||||
*
|
||||
* alert( CKEDITOR.lang.detect( 'en' ) ); // e.g., in a German browser: 'de'
|
||||
*
|
||||
* @param {String} defaultLanguage The default language to be returned
|
||||
* if the user language is not supported.
|
||||
* @param {String} [probeLanguage] A language code to try to use,
|
||||
* instead of the browser-based autodetection.
|
||||
* @returns {String} The detected language code.
|
||||
*/
|
||||
detect: function( defaultLanguage, probeLanguage ) {
|
||||
var languages = this.languages;
|
||||
probeLanguage = probeLanguage || navigator.userLanguage || navigator.language || defaultLanguage;
|
||||
|
||||
var parts = probeLanguage.toLowerCase().match( /([a-z]+)(?:-([a-z]+))?/ ),
|
||||
lang = parts[ 1 ],
|
||||
locale = parts[ 2 ];
|
||||
|
||||
if ( languages[ lang + '-' + locale ] )
|
||||
lang = lang + '-' + locale;
|
||||
else if ( !languages[ lang ] )
|
||||
lang = null;
|
||||
|
||||
CKEDITOR.lang.detect = lang ?
|
||||
function() {
|
||||
return lang;
|
||||
} : function( defaultLanguage ) {
|
||||
return defaultLanguage;
|
||||
};
|
||||
|
||||
return lang || defaultLanguage;
|
||||
}
|
||||
};
|
||||
|
||||
} )();
|
||||
233
Admin/plugins/ckeditor/core/loader.js
Normal file
233
Admin/plugins/ckeditor/core/loader.js
Normal file
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.loader} objects, which is used to
|
||||
* load core scripts and their dependencies from _source.
|
||||
*/
|
||||
|
||||
if ( typeof CKEDITOR == 'undefined' )
|
||||
CKEDITOR = {}; // jshint ignore:line
|
||||
|
||||
if ( !CKEDITOR.loader ) {
|
||||
/**
|
||||
* Load core scripts and their dependencies from `_source`.
|
||||
*
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.loader = ( function() {
|
||||
// Table of script names and their dependencies.
|
||||
var scripts = {
|
||||
'_bootstrap': [
|
||||
'config', 'creators/inline', 'creators/themedui', 'editable', 'ckeditor', 'plugins',
|
||||
'scriptloader', 'style', 'tools', 'promise', 'selection/optimization', 'tools/color',
|
||||
|
||||
// The following are entries that we want to force loading at the end to avoid dependence recursion.
|
||||
'dom/comment', 'dom/elementpath', 'dom/text', 'dom/rangelist', 'skin'
|
||||
],
|
||||
'ckeditor': [
|
||||
'ckeditor_basic', 'log', 'dom', 'dtd', 'dom/document', 'dom/element',
|
||||
'dom/iterator', 'editor', 'event', 'htmldataprocessor', 'htmlparser', 'htmlparser/element',
|
||||
'htmlparser/fragment', 'htmlparser/filter', 'htmlparser/basicwriter', 'template', 'tools',
|
||||
'ckeditor_version-check'
|
||||
],
|
||||
'ckeditor_base': [],
|
||||
'ckeditor_basic': [ 'editor_basic', 'env', 'event' ],
|
||||
'ckeditor_version-check': [ 'ckeditor_basic', 'config', 'tools' ],
|
||||
'command': [],
|
||||
'config': [ 'ckeditor_base' ],
|
||||
'dom': [],
|
||||
'dom/comment': [ 'dom/node' ],
|
||||
'dom/document': [ 'dom/node', 'dom/window' ],
|
||||
'dom/documentfragment': [ 'dom/element' ],
|
||||
'dom/element': [ 'dom', 'dom/document', 'dom/domobject', 'dom/node', 'dom/nodelist', 'tools' ],
|
||||
'dom/elementpath': [ 'dom/element' ],
|
||||
'dom/event': [],
|
||||
'dom/iterator': [ 'dom/range' ],
|
||||
'dom/node': [ 'dom/domobject', 'tools' ],
|
||||
'dom/nodelist': [ 'dom/node' ],
|
||||
'dom/domobject': [ 'dom/event' ],
|
||||
'dom/range': [ 'dom/document', 'dom/documentfragment', 'dom/element', 'dom/walker' ],
|
||||
'dom/rangelist': [ 'dom/range' ],
|
||||
'dom/text': [ 'dom/node', 'dom/domobject' ],
|
||||
'dom/walker': [ 'dom/node' ],
|
||||
'dom/window': [ 'dom/domobject' ],
|
||||
'dtd': [ 'tools' ],
|
||||
'editable': [ 'editor', 'tools' ],
|
||||
'editor': [
|
||||
'command', 'config', 'editor_basic', 'filter', 'focusmanager', 'keystrokehandler', 'lang',
|
||||
'plugins', 'tools', 'ui'
|
||||
],
|
||||
'editor_basic': [ 'event' ],
|
||||
'env': [],
|
||||
'event': [],
|
||||
'filter': [ 'dtd', 'tools' ],
|
||||
'focusmanager': [],
|
||||
'htmldataprocessor': [ 'htmlparser', 'htmlparser/basicwriter', 'htmlparser/fragment', 'htmlparser/filter' ],
|
||||
'htmlparser': [],
|
||||
'htmlparser/comment': [ 'htmlparser', 'htmlparser/node' ],
|
||||
'htmlparser/element': [ 'htmlparser', 'htmlparser/fragment', 'htmlparser/node' ],
|
||||
'htmlparser/fragment': [ 'htmlparser', 'htmlparser/comment', 'htmlparser/text', 'htmlparser/cdata' ],
|
||||
'htmlparser/text': [ 'htmlparser', 'htmlparser/node' ],
|
||||
'htmlparser/cdata': [ 'htmlparser', 'htmlparser/node' ],
|
||||
'htmlparser/filter': [ 'htmlparser' ],
|
||||
'htmlparser/basicwriter': [ 'htmlparser' ],
|
||||
'htmlparser/node': [ 'htmlparser' ],
|
||||
'keystrokehandler': [ 'event' ],
|
||||
'lang': [],
|
||||
'log': [ 'ckeditor_basic' ],
|
||||
'plugins': [ 'resourcemanager' ],
|
||||
'resourcemanager': [ 'scriptloader', 'tools' ],
|
||||
'scriptloader': [ 'dom/element', 'env' ],
|
||||
'selection': [ 'dom/range', 'dom/walker' ],
|
||||
'skin': [],
|
||||
'style': [ 'selection' ],
|
||||
'template': [],
|
||||
'tools': [ 'env' ],
|
||||
'ui': [],
|
||||
'creators/themedui': [],
|
||||
'creators/inline': [],
|
||||
'promise': [ 'tools' ],
|
||||
'selection/optimization': [ 'selection' ],
|
||||
'tools/color': [ 'tools' ]
|
||||
};
|
||||
|
||||
// The production implementation contains a fixed timestamp generated by the releaser.
|
||||
var timestamp = '%TIMESTAMP%';
|
||||
// The development implementation contains a current timestamp. // %REMOVE_LINE%
|
||||
timestamp = ( CKEDITOR && CKEDITOR.timestamp ) || ( new Date() ).valueOf(); // %REMOVE_LINE%
|
||||
|
||||
var getUrl = function( resource ) {
|
||||
if ( CKEDITOR && CKEDITOR.getUrl )
|
||||
return CKEDITOR.getUrl( resource );
|
||||
|
||||
return CKEDITOR.basePath + resource + ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + 't=' + timestamp;
|
||||
};
|
||||
|
||||
var pendingLoad = [];
|
||||
|
||||
return {
|
||||
/**
|
||||
* The list of loaded scripts in their loading order.
|
||||
*
|
||||
* // Alert the loaded script names.
|
||||
* alert( CKEDITOR.loader.loadedScripts );
|
||||
*/
|
||||
loadedScripts: [],
|
||||
/**
|
||||
* Table of script names and their dependencies.
|
||||
*
|
||||
* @property {Array}
|
||||
*/
|
||||
scripts: scripts,
|
||||
|
||||
/**
|
||||
* @todo
|
||||
*/
|
||||
loadPending: function() {
|
||||
var scriptName = pendingLoad.shift();
|
||||
|
||||
if ( !scriptName )
|
||||
return;
|
||||
|
||||
var scriptSrc = getUrl( 'core/' + scriptName + '.js' );
|
||||
|
||||
var script = document.createElement( 'script' );
|
||||
script.type = 'text/javascript';
|
||||
script.src = scriptSrc;
|
||||
|
||||
function onScriptLoaded() {
|
||||
// Append this script to the list of loaded scripts.
|
||||
CKEDITOR.loader.loadedScripts.push( scriptName );
|
||||
|
||||
// Load the next.
|
||||
CKEDITOR.loader.loadPending();
|
||||
}
|
||||
|
||||
// We must guarantee the execution order of the scripts, so we
|
||||
// need to load them one by one. (https://dev.ckeditor.com/ticket/4145)
|
||||
// The following if/else block has been taken from the scriptloader core code.
|
||||
if ( typeof script.onreadystatechange !== 'undefined' ) {
|
||||
/** @ignore */
|
||||
script.onreadystatechange = function() {
|
||||
if ( script.readyState == 'loaded' || script.readyState == 'complete' ) {
|
||||
script.onreadystatechange = null;
|
||||
onScriptLoaded();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
/** @ignore */
|
||||
script.onload = function() {
|
||||
// Some browsers, such as Safari, may call the onLoad function
|
||||
// immediately. Which will break the loading sequence. (https://dev.ckeditor.com/ticket/3661)
|
||||
setTimeout( function() {
|
||||
// Once the script is loaded, remove the listener as this might lead to memory leaks (#589).
|
||||
script.onload = null;
|
||||
onScriptLoaded( scriptName );
|
||||
}, 0 );
|
||||
};
|
||||
}
|
||||
|
||||
document.body.appendChild( script );
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads a specific script, including its dependencies. The loading process
|
||||
* is not synchronous, which means that the code to be loaded will
|
||||
* not necessarily be available after this call.
|
||||
*
|
||||
* CKEDITOR.loader.load( 'dom/element' );
|
||||
*
|
||||
* @param {String} scriptName
|
||||
* @param {Boolean} [defer=false]
|
||||
* @todo params
|
||||
*/
|
||||
load: function( scriptName, defer ) {
|
||||
// Check if the script has already been loaded.
|
||||
if ( ( 's:' + scriptName ) in this.loadedScripts )
|
||||
return;
|
||||
|
||||
// Get the script dependencies list.
|
||||
var dependencies = scripts[ scriptName ];
|
||||
if ( !dependencies )
|
||||
throw 'The script name"' + scriptName + '" is not defined.';
|
||||
|
||||
// Mark the script as loaded, even before really loading it, to
|
||||
// avoid cross references recursion.
|
||||
// Prepend script name with 's:' to avoid conflict with Array's methods.
|
||||
this.loadedScripts[ 's:' + scriptName ] = true;
|
||||
|
||||
// Load all dependencies first.
|
||||
for ( var i = 0; i < dependencies.length; i++ )
|
||||
this.load( dependencies[ i ], true );
|
||||
|
||||
var scriptSrc = getUrl( 'core/' + scriptName + '.js' );
|
||||
|
||||
// Append the <script> element to the DOM.
|
||||
// If the page is fully loaded, we can't use document.write
|
||||
// but if the script is run while the body is loading then it's safe to use it
|
||||
// Unfortunately, Firefox <3.6 doesn't support document.readyState, so it won't get this improvement
|
||||
if ( document.body && ( !document.readyState || document.readyState == 'complete' ) ) {
|
||||
pendingLoad.push( scriptName );
|
||||
|
||||
if ( !defer )
|
||||
this.loadPending();
|
||||
} else {
|
||||
// Append this script to the list of loaded scripts.
|
||||
this.loadedScripts.push( scriptName );
|
||||
|
||||
document.write( '<script src="' + scriptSrc + '" type="text/javascript"><\/script>' );
|
||||
}
|
||||
}
|
||||
};
|
||||
} )();
|
||||
}
|
||||
|
||||
// Check if any script has been defined for autoload.
|
||||
if ( CKEDITOR._autoLoad ) {
|
||||
CKEDITOR.loader.load( CKEDITOR._autoLoad );
|
||||
delete CKEDITOR._autoLoad;
|
||||
}
|
||||
127
Admin/plugins/ckeditor/core/log.js
Normal file
127
Admin/plugins/ckeditor/core/log.js
Normal file
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines {@link CKEDITOR#verbosity} and binary flags {@link CKEDITOR#VERBOSITY_WARN} and
|
||||
* {@link CKEDITOR#VERBOSITY_ERROR}. Defines also the {@link CKEDITOR#error} and {@link CKEDITOR#warn} functions
|
||||
* and the default handler for the {@link CKEDITOR#log} event.
|
||||
*/
|
||||
|
||||
/* global console */
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Warning reporting verbosity level. When {@link CKEDITOR#verbosity} is set to this value, only {@link CKEDITOR#warn}
|
||||
* messages will be output to the console. It is a binary flag so it might be combined with
|
||||
* the {@link CKEDITOR#VERBOSITY_ERROR} flag.
|
||||
*
|
||||
* @since 4.5.4
|
||||
* @readonly
|
||||
* @property {Number} [=1]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.VERBOSITY_WARN = 1;
|
||||
|
||||
/**
|
||||
* Error reporting verbosity level. When {@link CKEDITOR#verbosity} is set to this value, only {@link CKEDITOR#error}
|
||||
* messages will be output to the console. It is a binary flag so it might be combined with
|
||||
* the {@link CKEDITOR#VERBOSITY_WARN} flag.
|
||||
*
|
||||
* @since 4.5.4
|
||||
* @readonly
|
||||
* @property {Number} [=2]
|
||||
* @member CKEDITOR
|
||||
*/
|
||||
CKEDITOR.VERBOSITY_ERROR = 2;
|
||||
|
||||
/**
|
||||
* Verbosity of {@link CKEDITOR#error} and {@link CKEDITOR#warn} methods. Accepts binary flags
|
||||
* {@link CKEDITOR#VERBOSITY_WARN} and {@link CKEDITOR#VERBOSITY_ERROR}.
|
||||
*
|
||||
* CKEDITOR.verbosity = 0; // No console output after CKEDITOR.warn and CKEDITOR.error methods.
|
||||
* CKEDITOR.verbosity = CKEDITOR.VERBOSITY_WARN; // Console output after CKEDITOR.warn only.
|
||||
* CKEDITOR.verbosity = CKEDITOR.VERBOSITY_ERROR; // Console output after CKEDITOR.error only.
|
||||
* CKEDITOR.verbosity = CKEDITOR.VERBOSITY_WARN | CKEDITOR.VERBOSITY_ERROR; // Console output after both methods.
|
||||
*
|
||||
* Default value enables both {@link CKEDITOR#VERBOSITY_WARN} and {@link CKEDITOR#VERBOSITY_ERROR}.
|
||||
*
|
||||
* @since 4.5.4
|
||||
* @member CKEDITOR
|
||||
* @type {Number}
|
||||
*/
|
||||
CKEDITOR.verbosity = CKEDITOR.VERBOSITY_WARN | CKEDITOR.VERBOSITY_ERROR;
|
||||
|
||||
/**
|
||||
* Warning reporting function. When {@link CKEDITOR#verbosity} has the {@link CKEDITOR#VERBOSITY_WARN} flag set, it fires
|
||||
* the {@link CKEDITOR#log} event with type set to `warn`. Fired event contains also provided `errorCode` and `additionalData`.
|
||||
*
|
||||
* @since 4.5.4
|
||||
* @member CKEDITOR
|
||||
* @param {String} errorCode Error code describing reported problem.
|
||||
* @param {Object} [additionalData] Additional data associated with reported problem.
|
||||
*/
|
||||
CKEDITOR.warn = function( errorCode, additionalData ) {
|
||||
if ( CKEDITOR.verbosity & CKEDITOR.VERBOSITY_WARN ) {
|
||||
CKEDITOR.fire( 'log', { type: 'warn', errorCode: errorCode, additionalData: additionalData } );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Error reporting function. When {@link CKEDITOR#verbosity} has {@link CKEDITOR#VERBOSITY_ERROR} flag set, it fires
|
||||
* {@link CKEDITOR#log} event with the type set to `error`. The fired event also contains the provided `errorCode` and
|
||||
* `additionalData`.
|
||||
*
|
||||
* @since 4.5.4
|
||||
* @member CKEDITOR
|
||||
* @param {String} errorCode Error code describing the reported problem.
|
||||
* @param {Object} [additionalData] Additional data associated with the reported problem.
|
||||
*/
|
||||
CKEDITOR.error = function( errorCode, additionalData ) {
|
||||
if ( CKEDITOR.verbosity & CKEDITOR.VERBOSITY_ERROR ) {
|
||||
CKEDITOR.fire( 'log', { type: 'error', errorCode: errorCode, additionalData: additionalData } );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Fired by {@link CKEDITOR#warn} and {@link CKEDITOR#error} methods.
|
||||
* Default listener logs provided information to the console.
|
||||
*
|
||||
* This event can be used to provide a custom error/warning handler:
|
||||
*
|
||||
* CKEDTIOR.on( 'log', function( evt ) {
|
||||
* // Cancel default listener.
|
||||
* evt.cancel();
|
||||
* // Log event data.
|
||||
* console.log( evt.data.type, evt.data.errorCode, evt.data.additionalData );
|
||||
* } );
|
||||
*
|
||||
* @since 4.5.4
|
||||
* @event log
|
||||
* @member CKEDITOR
|
||||
* @param data
|
||||
* @param {String} data.type Log type. Can be `error` or `warn`.
|
||||
* @param {String} data.errorCode Error code describing the reported problem.
|
||||
* @param {Object} [data.additionalData] Additional data associated with this log event.
|
||||
*/
|
||||
CKEDITOR.on( 'log', function( evt ) {
|
||||
if ( !window.console || !window.console.log ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var type = console[ evt.data.type ] ? evt.data.type : 'log',
|
||||
errorCode = evt.data.errorCode,
|
||||
additionalData = evt.data.additionalData,
|
||||
prefix = '[CKEDITOR] ',
|
||||
errorCodeLabel = 'Error code: ';
|
||||
|
||||
if ( additionalData ) {
|
||||
console[ type ]( prefix + errorCodeLabel + errorCode + '.', additionalData );
|
||||
} else {
|
||||
console[ type ]( prefix + errorCodeLabel + errorCode + '.' );
|
||||
}
|
||||
|
||||
console[ type ]( prefix + 'For more information about this error go to https://ckeditor.com/docs/ckeditor4/latest/guide/dev_errors.html#' + errorCode );
|
||||
}, null, null, 999 );
|
||||
217
Admin/plugins/ckeditor/core/plugindefinition.js
Normal file
217
Admin/plugins/ckeditor/core/plugindefinition.js
Normal file
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the "virtual" {@link CKEDITOR.pluginDefinition} class which
|
||||
* contains the defintion of a plugin. This file serves documentation
|
||||
* purposes only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A virtual class that just illustrates the features of plugin objects which are
|
||||
* passed to the {@link CKEDITOR.plugins#add} method.
|
||||
*
|
||||
* This class is not really a part of the API, so its constructor should not be called.
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
* * {@glink guide/plugin_sdk_intro The Plugin SDK}
|
||||
* * {@glink guide/plugin_sdk_sample Creating a CKEditor plugin in 20 Lines of Code}
|
||||
* * {@glink guide/plugin_sdk_sample_1 Creating a Simple Plugin Tutorial}
|
||||
*
|
||||
* @class CKEDITOR.pluginDefinition
|
||||
* @abstract
|
||||
*/
|
||||
|
||||
/**
|
||||
* A list of plugins that are required by this plugin. Note that this property
|
||||
* does not determine the loading order of the plugins.
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample', {
|
||||
* requires: 'button,selection'
|
||||
* } );
|
||||
*
|
||||
* Or:
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample', {
|
||||
* requires: [ 'button', 'selection' ]
|
||||
* } );
|
||||
*
|
||||
* @property {String/String[]} requires
|
||||
*/
|
||||
|
||||
/**
|
||||
* The list of language files available for this plugin. These files are stored inside
|
||||
* the `lang` directory in the plugin directory, follow the name
|
||||
* pattern of `langCode.js`, and contain the language definition created with
|
||||
* {@link CKEDITOR.plugins#setLang}.
|
||||
*
|
||||
* When the plugin is being loaded, the editor checks this list to see if
|
||||
* a language file in the current editor language ({@link CKEDITOR.editor#langCode})
|
||||
* is available, and if so, loads it. Otherwise, the file represented by the first item
|
||||
* in the list is loaded.
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample', {
|
||||
* lang: 'en,fr'
|
||||
* } );
|
||||
*
|
||||
* Or:
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample', {
|
||||
* lang: [ 'en', 'fr' ]
|
||||
* } );
|
||||
*
|
||||
* @property {String/String[]} lang
|
||||
*/
|
||||
|
||||
/**
|
||||
* A function called when the plugin definition is loaded for the first time.
|
||||
* It is usually used to execute some code once for the entire page,
|
||||
* for instance code that uses the {@link CKEDITOR}'s methods such as the {@link CKEDITOR#addCss} method.
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample', {
|
||||
* onLoad: function() {
|
||||
* CKEDITOR.addCss( '.cke_some_class { ... }' );
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* Read more about the initialization order in the {@link #init} method documentation.
|
||||
*
|
||||
* @method onLoad
|
||||
*/
|
||||
|
||||
/**
|
||||
* A function called on initialization of every editor instance created on the
|
||||
* page before the {@link #init} call task. This feature makes it possible to
|
||||
* initialize things that could be used in the `init` function of other plugins.
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample1', {
|
||||
* beforeInit: function( editor ) {
|
||||
* editor.foo = 'bar';
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample2', {
|
||||
* init: function( editor ) {
|
||||
* // This will work regardless of order in which
|
||||
* // plugins sample1 and sample2 where initialized.
|
||||
* console.log( editor.foo ); // 'bar'
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* Read more about the initialization order in the {@link #init} method documentation.
|
||||
*
|
||||
* @method beforeInit
|
||||
* @param {CKEDITOR.editor} editor The editor instance being initialized.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A function called on initialization of every editor instance created on the page.
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample', {
|
||||
* init: function( editor ) {
|
||||
* console.log( 'Editor "' + editor.name + '" is being initialized!' );
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* Initialization order:
|
||||
*
|
||||
* 1. The {@link #beforeInit} methods of all enabled plugins are executed.
|
||||
* 2. The {@link #init} methods of all enabled plugins are executed.
|
||||
* 3. The {@link #afterInit} methods of all enabled plugins are executed.
|
||||
* 4. The {@link CKEDITOR.editor#pluginsLoaded} event is fired.
|
||||
*
|
||||
* **Note:** The order in which the `init` methods are called does not depend on the plugins' {@link #requires requirements}
|
||||
* or the order set in the {@link CKEDITOR.config#plugins} option. It may be random and therefore it is
|
||||
* recommended to use the {@link #beforeInit} and {@link #afterInit} methods in order to ensure
|
||||
* the right execution sequence.
|
||||
*
|
||||
* See also the {@link #onLoad} method.
|
||||
*
|
||||
* @method init
|
||||
* @param {CKEDITOR.editor} editor The editor instance being initialized.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A function called on initialization of every editor instance created on the
|
||||
* page after the {@link #init} call task. This feature makes it possible to use things
|
||||
* that were initialized in the `init` function of other plugins.
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample1', {
|
||||
* afterInit: function( editor ) {
|
||||
* // This will work regardless of order in which
|
||||
* // plugins sample1 and sample2 where initialized.
|
||||
* console.log( editor.foo ); // 'bar'
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample2', {
|
||||
* init: function( editor ) {
|
||||
* editor.foo = 'bar';
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* Read more about the initialization order in the {@link #init} method documentation.
|
||||
*
|
||||
* @method afterInit
|
||||
* @param {CKEDITOR.editor} editor The editor instance being initialized.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Announces the plugin as HiDPI-ready (optimized for high pixel density screens, e.g. *Retina*)
|
||||
* by providing high-resolution icons and images. HiDPI icons must be twice as big
|
||||
* (defaults are `16px x 16px`) and stored under `plugin_name/icons/hidpi/` directory.
|
||||
*
|
||||
* The common place for additional HiDPI images used by the plugin (**but not icons**)
|
||||
* is the `plugin_name/images/hidpi/` directory.
|
||||
*
|
||||
* This property is optional and only makes sense if `32px x 32px` icons
|
||||
* and high-resolution images actually exist. If this flag is set to `true`, the editor
|
||||
* will automatically detect the HiDPI environment and attempt to load the
|
||||
* high-resolution resources.
|
||||
*
|
||||
* @since 4.2.0
|
||||
* @property {Boolean} hidpi
|
||||
*/
|
||||
|
||||
/**
|
||||
* The list of icon files registered by this plugin. These files are stored inside
|
||||
* the `icons` directory in the plugin directory and follow the name
|
||||
* pattern of `name.png`.
|
||||
*
|
||||
* ```javascript
|
||||
* CKEDITOR.plugins.add( 'sample', {
|
||||
* icons: 'first,second'
|
||||
* } );
|
||||
* ```
|
||||
*
|
||||
* @property {String} [icons]
|
||||
*/
|
||||
|
||||
/**
|
||||
* A function that should be implemented if a plugin is not supported in every
|
||||
* available environment according to
|
||||
* [Browser Compatibility](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_browsers.html)
|
||||
* or a specific editor configuration.
|
||||
*
|
||||
* This function will not be called by the plugin loader itself and it is not required for a proper
|
||||
* plugin initialization. However, it is recommended to implement the function if a plugin
|
||||
* has environment requirements. This information may be important for related features
|
||||
* and the testing environment.
|
||||
*
|
||||
* ```javascript
|
||||
* CKEDITOR.plugins.add( 'sample', {
|
||||
* isSupportedEnvironment: function( editor ) {
|
||||
* // A plugin supported only in modern browsers.
|
||||
* return !CKEDITOR.env.ie || CKEDITOR.env.edge;
|
||||
* }
|
||||
* } );
|
||||
* ```
|
||||
*
|
||||
* @since 4.12.0
|
||||
* @method isSupportedEnvironment
|
||||
* @param {CKEDITOR.editor} editor
|
||||
* @returns {Boolean} Information whether the plugin is supported in the current environment.
|
||||
*/
|
||||
140
Admin/plugins/ckeditor/core/plugins.js
Normal file
140
Admin/plugins/ckeditor/core/plugins.js
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.plugins} object, which is used to
|
||||
* manage plugins registration and loading.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages plugins registration and loading.
|
||||
*
|
||||
* **Note** This object is an instance of {@link CKEDITOR.resourceManager}.
|
||||
*
|
||||
* @class
|
||||
* @extends CKEDITOR.resourceManager
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.plugins = new CKEDITOR.resourceManager( 'plugins/', 'plugin' );
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.plugins )
|
||||
|
||||
CKEDITOR.plugins.load = CKEDITOR.tools.override( CKEDITOR.plugins.load, function( originalLoad ) {
|
||||
var initialized = {};
|
||||
|
||||
return function( name, callback, scope ) {
|
||||
var allPlugins = {};
|
||||
|
||||
var loadPlugins = function( names ) {
|
||||
originalLoad.call( this, names, function( plugins ) {
|
||||
CKEDITOR.tools.extend( allPlugins, plugins );
|
||||
|
||||
var requiredPlugins = [];
|
||||
for ( var pluginName in plugins ) {
|
||||
var plugin = plugins[ pluginName ],
|
||||
requires = plugin && plugin.requires;
|
||||
|
||||
if ( !initialized[ pluginName ] ) {
|
||||
// Register all icons eventually defined by this plugin.
|
||||
if ( plugin.icons ) {
|
||||
var icons = plugin.icons.split( ',' );
|
||||
for ( var ic = icons.length; ic--; ) {
|
||||
CKEDITOR.skin.addIcon( icons[ ic ],
|
||||
plugin.path +
|
||||
'icons/' +
|
||||
( CKEDITOR.env.hidpi && plugin.hidpi ? 'hidpi/' : '' ) +
|
||||
icons[ ic ] +
|
||||
'.png' );
|
||||
}
|
||||
}
|
||||
|
||||
// Plugin is supported by default (#2692).
|
||||
plugin.isSupportedEnvironment = plugin.isSupportedEnvironment || function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
initialized[ pluginName ] = 1;
|
||||
}
|
||||
|
||||
if ( requires ) {
|
||||
// Trasnform it into an array, if it's not one.
|
||||
if ( requires.split )
|
||||
requires = requires.split( ',' );
|
||||
|
||||
for ( var i = 0; i < requires.length; i++ ) {
|
||||
if ( !allPlugins[ requires[ i ] ] )
|
||||
requiredPlugins.push( requires[ i ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( requiredPlugins.length )
|
||||
loadPlugins.call( this, requiredPlugins );
|
||||
else {
|
||||
// Call the "onLoad" function for all plugins.
|
||||
for ( pluginName in allPlugins ) {
|
||||
plugin = allPlugins[ pluginName ];
|
||||
if ( plugin.onLoad && !plugin.onLoad._called ) {
|
||||
// Make it possible to return false from plugin::onLoad to disable it.
|
||||
if ( plugin.onLoad() === false )
|
||||
delete allPlugins[ pluginName ];
|
||||
|
||||
plugin.onLoad._called = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Call the callback.
|
||||
if ( callback )
|
||||
callback.call( scope || window, allPlugins );
|
||||
}
|
||||
}, this );
|
||||
|
||||
};
|
||||
|
||||
loadPlugins.call( this, name );
|
||||
};
|
||||
} );
|
||||
|
||||
/**
|
||||
* Loads a specific language file, or auto detect it. A callback is
|
||||
* then called when the file gets loaded.
|
||||
*
|
||||
* CKEDITOR.plugins.setLang( 'myPlugin', 'en', {
|
||||
* title: 'My plugin',
|
||||
* selectOption: 'Please select an option'
|
||||
* } );
|
||||
*
|
||||
* @param {String} pluginName The name of the plugin to which the provided translation
|
||||
* should be attached.
|
||||
* @param {String} languageCode The code of the language translation provided.
|
||||
* @param {Object} languageEntries An object that contains pairs of label and
|
||||
* the respective translation.
|
||||
*/
|
||||
CKEDITOR.plugins.setLang = function( pluginName, languageCode, languageEntries ) {
|
||||
var plugin = this.get( pluginName ),
|
||||
pluginLangEntries = plugin.langEntries || ( plugin.langEntries = {} ),
|
||||
pluginLang = plugin.lang || ( plugin.lang = [] );
|
||||
|
||||
if ( pluginLang.split )
|
||||
pluginLang = pluginLang.split( ',' );
|
||||
|
||||
if ( CKEDITOR.tools.indexOf( pluginLang, languageCode ) == -1 )
|
||||
pluginLang.push( languageCode );
|
||||
|
||||
pluginLangEntries[ languageCode ] = languageEntries;
|
||||
};
|
||||
|
||||
/**
|
||||
* Virtual class that illustrates the API of {@link CKEDITOR.editor} instance plugins dictionary.
|
||||
*
|
||||
* Such object contains references to all plugins used by a related editor instance.
|
||||
*
|
||||
* See {@link CKEDITOR.editor#property-plugins} for example use.
|
||||
*
|
||||
* This class is not really a part of the API, so its constructor can not be called.
|
||||
*
|
||||
* @abstract
|
||||
* @class CKEDITOR.editor.plugins
|
||||
*/
|
||||
87
Admin/plugins/ckeditor/core/promise.js
Normal file
87
Admin/plugins/ckeditor/core/promise.js
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/* global Promise, ES6Promise */
|
||||
|
||||
( function() {
|
||||
'use strict';
|
||||
|
||||
if ( window.Promise ) {
|
||||
CKEDITOR.tools.promise = Promise;
|
||||
} else {
|
||||
var polyfillURL = CKEDITOR.getUrl( 'vendor/promise.js' ),
|
||||
isAmdEnv = typeof window.define === 'function' && window.define.amd && typeof window.require === 'function';
|
||||
|
||||
if ( isAmdEnv ) {
|
||||
return window.require( [ polyfillURL ], function( Promise ) {
|
||||
CKEDITOR.tools.promise = Promise;
|
||||
} );
|
||||
}
|
||||
|
||||
CKEDITOR.scriptLoader.load( polyfillURL, function( success ) {
|
||||
if ( !success ) {
|
||||
return CKEDITOR.error( 'no-vendor-lib', {
|
||||
path: polyfillURL
|
||||
} );
|
||||
}
|
||||
|
||||
if ( typeof window.ES6Promise !== 'undefined' ) {
|
||||
return CKEDITOR.tools.promise = ES6Promise;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* An alias for the [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
|
||||
* object representing an asynchronous operation.
|
||||
*
|
||||
* It uses the native `Promise` browser implementation if it is available. For older browsers with lack of `Promise` support,
|
||||
* the [`ES6-Promise`](https://github.com/stefanpenner/es6-promise) polyfill is used.
|
||||
* See the [Promise Browser Compatibility table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#Browser_compatibility)
|
||||
* to learn more.
|
||||
*
|
||||
* Refer to [MDN Using Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) guide for
|
||||
* more details on how to work with promises.
|
||||
*
|
||||
* **NOTE:** `catch` and `finally` are reserved keywords in IE<9 browsers. Use bracket notation instead:
|
||||
*
|
||||
* ```js
|
||||
* promise[ 'catch' ]( function( err ) {
|
||||
* // ...
|
||||
* } );
|
||||
*
|
||||
* promise[ 'finally' ]( function() {
|
||||
* // ...
|
||||
* } );
|
||||
* ```
|
||||
*
|
||||
* @since 4.12.0
|
||||
* @class CKEDITOR.tools.promise
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a new `Promise` instance.
|
||||
*
|
||||
* ```js
|
||||
* new CKEDITOR.tools.promise( function( resolve, reject ) {
|
||||
* setTimeout( function() {
|
||||
* var timestamp;
|
||||
* try {
|
||||
* timestamp = ( new Date() ).getTime();
|
||||
* } catch ( e ) {
|
||||
* reject( e );
|
||||
* }
|
||||
* resolve( timestamp );
|
||||
* }, 5000 );
|
||||
* } );
|
||||
* ```
|
||||
*
|
||||
* @param {Function} resolver
|
||||
* @param {Function} resolver.resolve
|
||||
* @param {Function} resolver.reject
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
} )();
|
||||
235
Admin/plugins/ckeditor/core/resourcemanager.js
Normal file
235
Admin/plugins/ckeditor/core/resourcemanager.js
Normal file
@@ -0,0 +1,235 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.resourceManager} class, which is
|
||||
* the base for resource managers, like plugins.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base class for resource managers, like plugins. This class is not
|
||||
* intended to be used out of the CKEditor core code.
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a resourceManager class instance.
|
||||
* @param {String} basePath The path for the resources folder.
|
||||
* @param {String} fileName The name used for resource files.
|
||||
*/
|
||||
CKEDITOR.resourceManager = function( basePath, fileName ) {
|
||||
/**
|
||||
* The base directory containing all resources.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.basePath = basePath;
|
||||
|
||||
/**
|
||||
* The name used for resource files.
|
||||
*
|
||||
* @property {String}
|
||||
*/
|
||||
this.fileName = fileName;
|
||||
|
||||
/**
|
||||
* Contains references to all resources that have already been registered
|
||||
* with {@link #add}.
|
||||
*/
|
||||
this.registered = {};
|
||||
|
||||
/**
|
||||
* Contains references to all resources that have already been loaded
|
||||
* with {@link #load}.
|
||||
*/
|
||||
this.loaded = {};
|
||||
|
||||
/**
|
||||
* Contains references to all resources that have already been registered
|
||||
* with {@link #addExternal}.
|
||||
*/
|
||||
this.externals = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this._ = {
|
||||
// List of callbacks waiting for plugins to be loaded.
|
||||
waitingList: {}
|
||||
};
|
||||
};
|
||||
|
||||
CKEDITOR.resourceManager.prototype = {
|
||||
/**
|
||||
* Registers a resource.
|
||||
*
|
||||
* CKEDITOR.plugins.add( 'sample', { ... plugin definition ... } );
|
||||
*
|
||||
* @param {String} name The resource name.
|
||||
* @param {Object} [definition] The resource definition.
|
||||
* @see CKEDITOR.pluginDefinition
|
||||
*/
|
||||
add: function( name, definition ) {
|
||||
if ( this.registered[ name ] )
|
||||
throw new Error( '[CKEDITOR.resourceManager.add] The resource name "' + name + '" is already registered.' );
|
||||
|
||||
var resource = this.registered[ name ] = definition || {};
|
||||
resource.name = name;
|
||||
resource.path = this.getPath( name );
|
||||
|
||||
CKEDITOR.fire( name + CKEDITOR.tools.capitalize( this.fileName ) + 'Ready', resource );
|
||||
|
||||
return this.get( name );
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the definition of a specific resource.
|
||||
*
|
||||
* var definition = CKEDITOR.plugins.get( 'sample' );
|
||||
*
|
||||
* @param {String} name The resource name.
|
||||
* @returns {Object} The registered object.
|
||||
*/
|
||||
get: function( name ) {
|
||||
return this.registered[ name ] || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the folder path for a specific loaded resource.
|
||||
*
|
||||
* alert( CKEDITOR.plugins.getPath( 'sample' ) ); // '<editor path>/plugins/sample/'
|
||||
*
|
||||
* @param {String} name The resource name.
|
||||
* @returns {String}
|
||||
*/
|
||||
getPath: function( name ) {
|
||||
var external = this.externals[ name ];
|
||||
return CKEDITOR.getUrl( ( external && external.dir ) || this.basePath + name + '/' );
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the file path for a specific loaded resource.
|
||||
*
|
||||
* alert( CKEDITOR.plugins.getFilePath( 'sample' ) ); // '<editor path>/plugins/sample/plugin.js'
|
||||
*
|
||||
* @param {String} name The resource name.
|
||||
* @returns {String}
|
||||
*/
|
||||
getFilePath: function( name ) {
|
||||
var external = this.externals[ name ];
|
||||
return CKEDITOR.getUrl( this.getPath( name ) + ( external ? external.file : this.fileName + '.js' ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Registers one or more resources to be loaded from an external path
|
||||
* instead of the core base path.
|
||||
*
|
||||
* ```js
|
||||
* // Loads a plugin from '/myplugins/sample/plugin.js'.
|
||||
* CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/' );
|
||||
*
|
||||
* // Loads a plugin from '/myplugins/sample/my_plugin.js'.
|
||||
* CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/', 'my_plugin.js' );
|
||||
*
|
||||
* // Loads a plugin from '/myplugins/sample/my_plugin.js'.
|
||||
* CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/my_plugin.js', '' );
|
||||
*
|
||||
* // Loads a plugin from '/myplugins/sample/my_plugin.js'.
|
||||
* CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/my_plugin.js' );
|
||||
* ```
|
||||
*
|
||||
* @param {String} names Comma-separated resource names.
|
||||
* @param {String} path The path of the folder containing the resource.
|
||||
* @param {String} [fileName] The resource file name. If not provided and
|
||||
* the `path` argument ends with a slash (`/`), the default `plugin.js` filename is used.
|
||||
* Otherwise, if not provided and the `path` argument does not end with a slash (`/`)
|
||||
* or if an empty string is provided, the function assumes that the `path` argument contains the full path.
|
||||
*/
|
||||
addExternal: function( names, path, fileName ) {
|
||||
// If "fileName" is not provided, we assume that it may be available
|
||||
// in "path". Try to extract it in this case.
|
||||
if ( !fileName ) {
|
||||
path = path.replace( /[^\/]+$/, function( match ) {
|
||||
fileName = match;
|
||||
return '';
|
||||
} );
|
||||
}
|
||||
|
||||
// Use the default file name if there is no "fileName" and it
|
||||
// was not found in "path".
|
||||
fileName = fileName || ( this.fileName + '.js' );
|
||||
names = names.split( ',' );
|
||||
|
||||
for ( var i = 0; i < names.length; i++ ) {
|
||||
var name = names[ i ];
|
||||
|
||||
this.externals[ name ] = {
|
||||
dir: path,
|
||||
file: fileName
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads one or more resources.
|
||||
*
|
||||
* CKEDITOR.plugins.load( 'myplugin', function( plugins ) {
|
||||
* alert( plugins[ 'myplugin' ] ); // object
|
||||
* } );
|
||||
*
|
||||
* @param {String/Array} name The name of the resource to load. It may be a
|
||||
* string with a single resource name, or an array with several names.
|
||||
* @param {Function} callback A function to be called when all resources
|
||||
* are loaded. The callback will receive an array containing all loaded names.
|
||||
* @param {Object} [scope] The scope object to be used for the callback call.
|
||||
*/
|
||||
load: function( names, callback, scope ) {
|
||||
// Ensure that we have an array of names.
|
||||
if ( !CKEDITOR.tools.isArray( names ) )
|
||||
names = names ? [ names ] : [];
|
||||
|
||||
var loaded = this.loaded,
|
||||
registered = this.registered,
|
||||
urls = [],
|
||||
urlsNames = {},
|
||||
resources = {};
|
||||
|
||||
// Loop through all names.
|
||||
for ( var i = 0; i < names.length; i++ ) {
|
||||
var name = names[ i ];
|
||||
|
||||
if ( !name )
|
||||
continue;
|
||||
|
||||
// If not available yet.
|
||||
if ( !loaded[ name ] && !registered[ name ] ) {
|
||||
var url = this.getFilePath( name );
|
||||
urls.push( url );
|
||||
if ( !( url in urlsNames ) )
|
||||
urlsNames[ url ] = [];
|
||||
urlsNames[ url ].push( name );
|
||||
} else {
|
||||
resources[ name ] = this.get( name );
|
||||
}
|
||||
}
|
||||
|
||||
CKEDITOR.scriptLoader.load( urls, function( completed, failed ) {
|
||||
if ( failed.length ) {
|
||||
throw new Error( '[CKEDITOR.resourceManager.load] Resource name "' + urlsNames[ failed[ 0 ] ].join( ',' ) +
|
||||
'" was not found at "' + failed[ 0 ] + '".' );
|
||||
}
|
||||
|
||||
for ( var i = 0; i < completed.length; i++ ) {
|
||||
var nameList = urlsNames[ completed[ i ] ];
|
||||
for ( var j = 0; j < nameList.length; j++ ) {
|
||||
var name = nameList[ j ];
|
||||
resources[ name ] = this.get( name );
|
||||
|
||||
loaded[ name ] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
callback.call( scope, resources );
|
||||
}, this );
|
||||
}
|
||||
};
|
||||
212
Admin/plugins/ckeditor/core/scriptloader.js
Normal file
212
Admin/plugins/ckeditor/core/scriptloader.js
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.scriptLoader} object, used to load scripts
|
||||
* asynchronously.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Load scripts asynchronously.
|
||||
*
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.scriptLoader = ( function() {
|
||||
var uniqueScripts = {},
|
||||
waitingList = {};
|
||||
|
||||
return {
|
||||
/**
|
||||
* Loads one or more external scripts checking if it has not been loaded
|
||||
* previously by this function.
|
||||
*
|
||||
* CKEDITOR.scriptLoader.load( '/myscript.js' );
|
||||
*
|
||||
* CKEDITOR.scriptLoader.load( '/myscript.js', function( success ) {
|
||||
* // Alerts true if the script has been properly loaded.
|
||||
* // HTTP error 404 should return false.
|
||||
* alert( success );
|
||||
* } );
|
||||
*
|
||||
* CKEDITOR.scriptLoader.load( [ '/myscript1.js', '/myscript2.js' ], function( completed, failed ) {
|
||||
* alert( 'Number of scripts loaded: ' + completed.length );
|
||||
* alert( 'Number of failures: ' + failed.length );
|
||||
* } );
|
||||
*
|
||||
* @param {String/Array} scriptUrl One or more URLs pointing to the
|
||||
* scripts to be loaded.
|
||||
* @param {Function} [callback] A function to be called when the script
|
||||
* is loaded and executed. If a string is passed to `scriptUrl`, a
|
||||
* Boolean parameter is passed to the callback, indicating the
|
||||
* success of the load. If an array is passed instead, two array
|
||||
* parameters are passed to the callback: the first contains the
|
||||
* URLs that have been properly loaded and the second the failed ones.
|
||||
* @param {Object} [scope] The scope (`this` reference) to be used for
|
||||
* the callback call. Defaults to {@link CKEDITOR}.
|
||||
* @param {Boolean} [showBusy] Changes the cursor of the document while
|
||||
* the script is loaded.
|
||||
*/
|
||||
load: function( scriptUrl, callback, scope, showBusy ) {
|
||||
var isString = ( typeof scriptUrl == 'string' );
|
||||
|
||||
if ( isString )
|
||||
scriptUrl = [ scriptUrl ];
|
||||
|
||||
if ( !scope )
|
||||
scope = CKEDITOR;
|
||||
|
||||
var scriptCount = scriptUrl.length,
|
||||
scriptCountDoCallback = scriptCount,
|
||||
completed = [],
|
||||
failed = [];
|
||||
|
||||
var doCallback = function( success ) {
|
||||
if ( callback ) {
|
||||
if ( isString )
|
||||
callback.call( scope, success );
|
||||
else
|
||||
callback.call( scope, completed, failed );
|
||||
}
|
||||
};
|
||||
|
||||
if ( scriptCountDoCallback === 0 ) {
|
||||
doCallback( true );
|
||||
return;
|
||||
}
|
||||
|
||||
var checkLoaded = function( url, success ) {
|
||||
( success ? completed : failed ).push( url );
|
||||
|
||||
if ( --scriptCountDoCallback <= 0 ) {
|
||||
showBusy && CKEDITOR.document.getDocumentElement().removeStyle( 'cursor' );
|
||||
doCallback( success );
|
||||
}
|
||||
};
|
||||
|
||||
var onLoad = function( url, success ) {
|
||||
// Mark this script as loaded.
|
||||
uniqueScripts[ url ] = 1;
|
||||
|
||||
// Get the list of callback checks waiting for this file.
|
||||
var waitingInfo = waitingList[ url ];
|
||||
delete waitingList[ url ];
|
||||
|
||||
// Check all callbacks waiting for this file.
|
||||
for ( var i = 0; i < waitingInfo.length; i++ )
|
||||
waitingInfo[ i ]( url, success );
|
||||
};
|
||||
|
||||
var loadScript = function( url ) {
|
||||
if ( uniqueScripts[ url ] ) {
|
||||
checkLoaded( url, true );
|
||||
return;
|
||||
}
|
||||
|
||||
var waitingInfo = waitingList[ url ] || ( waitingList[ url ] = [] );
|
||||
waitingInfo.push( checkLoaded );
|
||||
|
||||
// Load it only for the first request.
|
||||
if ( waitingInfo.length > 1 )
|
||||
return;
|
||||
|
||||
// Create the <script> element.
|
||||
var script = new CKEDITOR.dom.element( 'script' );
|
||||
script.setAttributes( {
|
||||
type: 'text/javascript',
|
||||
src: url
|
||||
} );
|
||||
|
||||
if ( callback ) {
|
||||
// The onload or onerror event does not fire in IE8 and IE9 Quirks Mode (https://dev.ckeditor.com/ticket/14849).
|
||||
if ( CKEDITOR.env.ie && ( CKEDITOR.env.version <= 8 || CKEDITOR.env.ie9Compat ) ) {
|
||||
script.$.onreadystatechange = function() {
|
||||
if ( script.$.readyState == 'loaded' || script.$.readyState == 'complete' ) {
|
||||
script.$.onreadystatechange = null;
|
||||
onLoad( url, true );
|
||||
}
|
||||
};
|
||||
} else {
|
||||
script.$.onload = function() {
|
||||
// Some browsers, such as Safari, may call the onLoad function
|
||||
// immediately. This will break the loading sequence. (https://dev.ckeditor.com/ticket/3661)
|
||||
setTimeout( function() {
|
||||
removeListeners( script );
|
||||
onLoad( url, true );
|
||||
}, 0 );
|
||||
};
|
||||
|
||||
script.$.onerror = function() {
|
||||
removeListeners( script );
|
||||
onLoad( url, false );
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Append it to <head>.
|
||||
script.appendTo( CKEDITOR.document.getHead() );
|
||||
|
||||
CKEDITOR.fire( 'download', url ); // %REMOVE_LINE%
|
||||
|
||||
};
|
||||
|
||||
showBusy && CKEDITOR.document.getDocumentElement().setStyle( 'cursor', 'wait' );
|
||||
for ( var i = 0; i < scriptCount; i++ ) {
|
||||
loadScript( scriptUrl[ i ] );
|
||||
}
|
||||
|
||||
function removeListeners( script ) {
|
||||
// Once the script loaded or failed to load, remove listeners as this might lead to memory leaks (#589).
|
||||
script.$.onload = null;
|
||||
script.$.onerror = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads a script in a queue, so only one is loaded at the same time.
|
||||
*
|
||||
* @since 4.1.2
|
||||
* @param {String} scriptUrl The URL pointing to the script to be loaded.
|
||||
* @param {Function} [callback] A function to be called when the script
|
||||
* is loaded and executed. A Boolean parameter is passed to the callback,
|
||||
* indicating the success of the load.
|
||||
*
|
||||
* @see CKEDITOR.scriptLoader#load
|
||||
*/
|
||||
queue: ( function() {
|
||||
var pending = [];
|
||||
|
||||
// Loads the very first script from queue and removes it.
|
||||
function loadNext() {
|
||||
var script;
|
||||
|
||||
if ( ( script = pending[ 0 ] ) )
|
||||
this.load( script.scriptUrl, script.callback, CKEDITOR, 0 );
|
||||
}
|
||||
|
||||
return function( scriptUrl, callback ) {
|
||||
var that = this;
|
||||
|
||||
// This callback calls the standard callback for the script
|
||||
// and loads the very next script from pending list.
|
||||
function callbackWrapper() {
|
||||
callback && callback.apply( this, arguments );
|
||||
|
||||
// Removed the just loaded script from the queue.
|
||||
pending.shift();
|
||||
|
||||
loadNext.call( that );
|
||||
}
|
||||
|
||||
// Let's add this script to the queue
|
||||
pending.push( { scriptUrl: scriptUrl, callback: callbackWrapper } );
|
||||
|
||||
// If the queue was empty, then start loading.
|
||||
if ( pending.length == 1 )
|
||||
loadNext.call( this );
|
||||
};
|
||||
} )()
|
||||
};
|
||||
} )();
|
||||
2608
Admin/plugins/ckeditor/core/selection.js
Normal file
2608
Admin/plugins/ckeditor/core/selection.js
Normal file
File diff suppressed because it is too large
Load Diff
163
Admin/plugins/ckeditor/core/selection/optimization.js
Normal file
163
Admin/plugins/ckeditor/core/selection/optimization.js
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines methods used for selection optimization.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
var preventListener = true,
|
||||
preventOptimization = false;
|
||||
|
||||
/**
|
||||
* Sets editor listeners up to optimize the selection.
|
||||
*
|
||||
* **Note**: This method is called automatically during the editor initialization and should not be called manually.
|
||||
*
|
||||
* @since 4.13.0
|
||||
* @static
|
||||
* @see CKEDITOR.dom.selection.optimizeInElementEnds
|
||||
* @param {CKEDITOR.editor} editor
|
||||
* @member CKEDITOR.dom.selection
|
||||
*/
|
||||
CKEDITOR.dom.selection.setupEditorOptimization = function( editor ) {
|
||||
editor.on( 'selectionCheck', function( evt ) {
|
||||
if ( evt.data && !preventOptimization ) {
|
||||
evt.data.optimizeInElementEnds();
|
||||
}
|
||||
preventOptimization = false;
|
||||
} );
|
||||
|
||||
editor.on( 'contentDom', function() {
|
||||
var editable = editor.editable();
|
||||
|
||||
if ( !editable ) {
|
||||
return;
|
||||
}
|
||||
|
||||
editable.attachListener( editable, 'keydown', function( evt ) {
|
||||
this._.shiftPressed = evt.data.$.shiftKey;
|
||||
}, this );
|
||||
|
||||
editable.attachListener( editable, 'keyup', function( evt ) {
|
||||
this._.shiftPressed = evt.data.$.shiftKey;
|
||||
}, this );
|
||||
} );
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs an optimization on the current selection if necessary.
|
||||
*
|
||||
* The general idea is to shrink the range to text when:
|
||||
*
|
||||
* * The range starts at the end of an element.
|
||||
* * The range ends at the start of an element.
|
||||
* * One of the range ends is anchored in a text node and another in an element.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* ```html
|
||||
* <p>{foo</p>
|
||||
* <p>]bar</p>
|
||||
* ```
|
||||
*
|
||||
* is optimized too:
|
||||
*
|
||||
* ```html
|
||||
* <p>{foo}</p>
|
||||
* <p>bar</p>
|
||||
* ```
|
||||
*
|
||||
* @since 4.13.0
|
||||
* @member CKEDITOR.dom.selection
|
||||
*/
|
||||
CKEDITOR.dom.selection.prototype.optimizeInElementEnds = function() {
|
||||
var range = this.getRanges()[ 0 ],
|
||||
editor = this.root.editor;
|
||||
|
||||
if ( !shouldOptimize( range, this ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var oldRange = range.clone();
|
||||
|
||||
range.shrink( CKEDITOR.SHRINK_TEXT, false, { skipBogus: !CKEDITOR.env.webkit } );
|
||||
|
||||
preventListener = false;
|
||||
|
||||
preventRecurrency( editor, range, oldRange );
|
||||
|
||||
range.select();
|
||||
|
||||
preventListener = true;
|
||||
};
|
||||
|
||||
function isText( node ) {
|
||||
return node.type === CKEDITOR.NODE_TEXT;
|
||||
}
|
||||
|
||||
// Returns `true` if any condition is met:
|
||||
// * The range starts at the end of an element.
|
||||
// * The range ends at the start of an element.
|
||||
// * One end of the range is in text and another one is not.
|
||||
//
|
||||
// Always returns `false` when:
|
||||
// * The Shift key is pressed.
|
||||
// * The selection is fake.
|
||||
// * The range is collapsed.
|
||||
// * The range start and end container is the same element.
|
||||
function shouldOptimize( range, selection ) {
|
||||
if ( selection.root.editor._.shiftPressed ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( selection.isFake || range.isCollapsed || range.startContainer.equals( range.endContainer ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The endContainer might be a text inside li element (in IE8).
|
||||
var isInList = range.endContainer.is ?
|
||||
range.endContainer.is( 'li' ) :
|
||||
range.endContainer.getParent().is && range.endContainer.getParent().is( 'li' );
|
||||
|
||||
// Prevent optimization in lists (#4931).
|
||||
if ( isInList ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( range.endOffset === 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var startsInText = isText( range.startContainer ),
|
||||
endsInText = isText( range.endContainer ),
|
||||
limit = startsInText ? range.startContainer.getLength() : range.startContainer.getChildCount();
|
||||
|
||||
return range.startOffset === limit || startsInText ^ endsInText;
|
||||
}
|
||||
|
||||
// Prevent infinite recurrency when the browser does not allow the expected selection.
|
||||
// There are two cases to handle:
|
||||
// - When the browser modified the range in a way that it is the same as before the optimization.
|
||||
// The second event is canceled, we do not need to fire listeners two times with the exact same selection.
|
||||
// - When the browser does not modify the range.
|
||||
// The event is not canceled, as the selection changed, however, the next optimization is prevented.
|
||||
function preventRecurrency( editor, targetRange, initialRange ) {
|
||||
editor.once( 'selectionCheck', function( evt ) {
|
||||
if ( preventListener ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var newRange = evt.data.getRanges()[ 0 ];
|
||||
|
||||
if ( initialRange.equals( newRange ) ) {
|
||||
evt.cancel();
|
||||
} else if ( targetRange.equals( newRange ) ) {
|
||||
preventOptimization = true;
|
||||
}
|
||||
|
||||
}, null, null, -1 );
|
||||
}
|
||||
} )();
|
||||
378
Admin/plugins/ckeditor/core/skin.js
Normal file
378
Admin/plugins/ckeditor/core/skin.js
Normal file
@@ -0,0 +1,378 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.skin} class that is used to manage skin parts.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
var cssLoaded = {};
|
||||
|
||||
function getName() {
|
||||
return CKEDITOR.skinName.split( ',' )[ 0 ];
|
||||
}
|
||||
|
||||
function getConfigPath() {
|
||||
return CKEDITOR.getUrl( CKEDITOR.skinName.split( ',' )[ 1 ] || ( 'skins/' + getName() + '/' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages the loading of skin parts among all editor instances.
|
||||
*
|
||||
* @class
|
||||
* @singleton
|
||||
*/
|
||||
CKEDITOR.skin = {
|
||||
/**
|
||||
* Returns the root path to the skin directory.
|
||||
*
|
||||
* @method
|
||||
* @todo
|
||||
*/
|
||||
path: getConfigPath,
|
||||
|
||||
/**
|
||||
* Loads a skin part into the page. Does nothing if the part has already been loaded.
|
||||
*
|
||||
* **Note:** The "editor" part is always auto loaded upon instance creation,
|
||||
* thus this function is mainly used to **lazy load** other parts of the skin
|
||||
* that do not have to be displayed until requested.
|
||||
*
|
||||
* // Load the dialog part.
|
||||
* editor.skin.loadPart( 'dialog' );
|
||||
*
|
||||
* @param {String} part The name of the skin part CSS file that resides in the skin directory.
|
||||
* @param {Function} fn The provided callback function which is invoked after the part is loaded.
|
||||
*/
|
||||
loadPart: function( part, fn ) {
|
||||
if ( CKEDITOR.skin.name != getName() ) {
|
||||
CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( getConfigPath() + 'skin.js' ), function() {
|
||||
loadCss( part, fn );
|
||||
} );
|
||||
} else {
|
||||
loadCss( part, fn );
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the real URL of a (CSS) skin part.
|
||||
*
|
||||
* @param {String} part
|
||||
*/
|
||||
getPath: function( part ) {
|
||||
return CKEDITOR.getUrl( getCssPath( part ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* The list of registered icons. To add new icons to this list, use {@link #addIcon}.
|
||||
*/
|
||||
icons: {},
|
||||
|
||||
/**
|
||||
* Registers an icon.
|
||||
*
|
||||
* @param {String} name The icon name.
|
||||
* @param {String} path The path to the icon image file.
|
||||
* @param {Number} [offset] The vertical offset position of the icon, if
|
||||
* available inside a strip image.
|
||||
* @param {String} [bgsize] The value of the CSS "background-size" property to
|
||||
* use for this icon
|
||||
*/
|
||||
addIcon: function( name, path, offset, bgsize ) {
|
||||
name = name.toLowerCase();
|
||||
if ( !this.icons[ name ] ) {
|
||||
this.icons[ name ] = {
|
||||
path: path,
|
||||
offset: offset || 0,
|
||||
bgsize: bgsize || '16px'
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the CSS background styles to be used to render a specific icon.
|
||||
*
|
||||
* @param {String} name The icon name, as registered with {@link #addIcon}.
|
||||
* @param {Boolean} [rtl] Indicates that the RTL version of the icon is
|
||||
* to be used, if available.
|
||||
* @param {String} [overridePath] The path to the icon image file. It
|
||||
* overrides the path defined by the named icon, if available, and is
|
||||
* used if the named icon was not registered.
|
||||
* @param {Number} [overrideOffset] The vertical offset position of the
|
||||
* icon. It overrides the offset defined by the named icon, if
|
||||
* available, and is used if the named icon was not registered.
|
||||
* @param {String} [overrideBgsize] The value of the CSS "background-size" property
|
||||
* to use for the icon. It overrides the value defined by the named icon,
|
||||
* if available, and is used if the named icon was not registered.
|
||||
*/
|
||||
getIconStyle: function( name, rtl, overridePath, overrideOffset, overrideBgsize ) {
|
||||
var icon, path, offset, bgsize;
|
||||
|
||||
if ( name ) {
|
||||
name = name.toLowerCase();
|
||||
// If we're in RTL, try to get the RTL version of the icon.
|
||||
if ( rtl )
|
||||
icon = this.icons[ name + '-rtl' ];
|
||||
|
||||
// If not in LTR or no RTL version available, get the generic one.
|
||||
if ( !icon )
|
||||
icon = this.icons[ name ];
|
||||
}
|
||||
|
||||
path = overridePath || ( icon && icon.path ) || '';
|
||||
offset = overrideOffset || ( icon && icon.offset );
|
||||
bgsize = overrideBgsize || ( icon && icon.bgsize ) || '16px';
|
||||
|
||||
// If we use apostrophes in background-image, we must escape apostrophes in path (just to be sure). (https://dev.ckeditor.com/ticket/13361)
|
||||
if ( path )
|
||||
path = path.replace( /'/g, '\\\'' );
|
||||
|
||||
return path &&
|
||||
( 'background-image:url(\'' + CKEDITOR.getUrl( path ) + '\');background-position:0 ' + offset + 'px;background-size:' + bgsize + ';' );
|
||||
}
|
||||
};
|
||||
|
||||
function getCssPath( part ) {
|
||||
// Check for ua-specific version of skin part.
|
||||
var uas = CKEDITOR.skin[ 'ua_' + part ], env = CKEDITOR.env;
|
||||
if ( uas ) {
|
||||
|
||||
// Having versioned UA checked first.
|
||||
uas = uas.split( ',' ).sort( function( a, b ) {
|
||||
return a > b ? -1 : 1;
|
||||
} );
|
||||
|
||||
// Loop through all ua entries, checking is any of them match the current ua.
|
||||
for ( var i = 0, ua; i < uas.length; i++ ) {
|
||||
ua = uas[ i ];
|
||||
|
||||
if ( env.ie ) {
|
||||
if ( ( ua.replace( /^ie/, '' ) == env.version ) || ( env.quirks && ua == 'iequirks' ) )
|
||||
ua = 'ie';
|
||||
}
|
||||
|
||||
if ( env[ ua ] ) {
|
||||
part += '_' + uas[ i ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CKEDITOR.getUrl( getConfigPath() + part + '.css' );
|
||||
}
|
||||
|
||||
function loadCss( part, callback ) {
|
||||
// Avoid reload.
|
||||
if ( !cssLoaded[ part ] ) {
|
||||
CKEDITOR.document.appendStyleSheet( getCssPath( part ) );
|
||||
cssLoaded[ part ] = 1;
|
||||
}
|
||||
|
||||
// CSS loading should not be blocking.
|
||||
callback && callback();
|
||||
}
|
||||
|
||||
CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
|
||||
/** Gets the color of the editor user interface.
|
||||
*
|
||||
* CKEDITOR.instances.editor1.getUiColor();
|
||||
*
|
||||
* @method
|
||||
* @member CKEDITOR.editor
|
||||
* @returns {String} uiColor The editor UI color or `undefined` if the UI color is not set.
|
||||
*/
|
||||
getUiColor: function() {
|
||||
return this.uiColor;
|
||||
},
|
||||
|
||||
/** Sets the color of the editor user interface. This method accepts a color value in
|
||||
* hexadecimal notation, with a `#` character (e.g. #ffffff).
|
||||
*
|
||||
* CKEDITOR.instances.editor1.setUiColor( '#ff00ff' );
|
||||
*
|
||||
* @method
|
||||
* @member CKEDITOR.editor
|
||||
* @param {String} color The desired editor UI color in hexadecimal notation.
|
||||
*/
|
||||
setUiColor: function( color ) {
|
||||
var uiStyle = getStylesheet( CKEDITOR.document );
|
||||
|
||||
return ( this.setUiColor = function( color ) {
|
||||
this.uiColor = color;
|
||||
|
||||
var chameleon = CKEDITOR.skin.chameleon,
|
||||
editorStyleContent = '',
|
||||
panelStyleContent = '';
|
||||
|
||||
if ( typeof chameleon == 'function' ) {
|
||||
editorStyleContent = chameleon( this, 'editor' );
|
||||
panelStyleContent = chameleon( this, 'panel' );
|
||||
}
|
||||
|
||||
var replace = [ [ uiColorRegexp, color ] ];
|
||||
|
||||
// Update general style.
|
||||
updateStylesheets( [ uiStyle ], editorStyleContent, replace );
|
||||
|
||||
// Update panel styles.
|
||||
updateStylesheets( uiColorMenus, panelStyleContent, replace );
|
||||
} ).call( this, color );
|
||||
}
|
||||
} );
|
||||
|
||||
var uiColorStylesheetId = 'cke_ui_color',
|
||||
uiColorMenus = [],
|
||||
uiColorRegexp = /\$color/g;
|
||||
|
||||
function getStylesheet( document ) {
|
||||
var node = document.getById( uiColorStylesheetId );
|
||||
if ( !node ) {
|
||||
node = document.getHead().append( 'style' );
|
||||
node.setAttribute( 'id', uiColorStylesheetId );
|
||||
node.setAttribute( 'type', 'text/css' );
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function updateStylesheets( styleNodes, styleContent, replace ) {
|
||||
var r, i, content;
|
||||
|
||||
// We have to split CSS declarations for webkit.
|
||||
if ( CKEDITOR.env.webkit ) {
|
||||
styleContent = styleContent.split( '}' ).slice( 0, -1 );
|
||||
for ( i = 0; i < styleContent.length; i++ )
|
||||
styleContent[ i ] = styleContent[ i ].split( '{' );
|
||||
}
|
||||
|
||||
for ( var id = 0; id < styleNodes.length; id++ ) {
|
||||
if ( CKEDITOR.env.webkit ) {
|
||||
for ( i = 0; i < styleContent.length; i++ ) {
|
||||
content = styleContent[ i ][ 1 ];
|
||||
for ( r = 0; r < replace.length; r++ )
|
||||
content = content.replace( replace[ r ][ 0 ], replace[ r ][ 1 ] );
|
||||
|
||||
styleNodes[ id ].$.sheet.addRule( styleContent[ i ][ 0 ], content );
|
||||
}
|
||||
} else {
|
||||
content = styleContent;
|
||||
for ( r = 0; r < replace.length; r++ )
|
||||
content = content.replace( replace[ r ][ 0 ], replace[ r ][ 1 ] );
|
||||
|
||||
if ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 )
|
||||
styleNodes[ id ].$.styleSheet.cssText += content;
|
||||
else
|
||||
styleNodes[ id ].$.innerHTML += content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CKEDITOR.on( 'instanceLoaded', function( evt ) {
|
||||
// The chameleon feature is not for IE quirks.
|
||||
if ( CKEDITOR.env.ie && CKEDITOR.env.quirks ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var editor = evt.editor,
|
||||
showCallback = function( event ) {
|
||||
var panel = event.data[ 0 ] || event.data,
|
||||
iframe = panel.element.getElementsByTag( 'iframe' ).getItem( 0 ).getFrameDocument();
|
||||
|
||||
// Add the stylesheet if missing.
|
||||
if ( !iframe.getById( 'cke_ui_color' ) ) {
|
||||
var node = getStylesheet( iframe );
|
||||
uiColorMenus.push( node );
|
||||
|
||||
// Cleanup after destroying the editor (#589).
|
||||
editor.on( 'destroy', function() {
|
||||
uiColorMenus = CKEDITOR.tools.array.filter( uiColorMenus, function( storedNode ) {
|
||||
return node !== storedNode;
|
||||
} );
|
||||
} );
|
||||
|
||||
var color = editor.getUiColor();
|
||||
// Set uiColor for the new panel.
|
||||
if ( color ) {
|
||||
updateStylesheets( [ node ], CKEDITOR.skin.chameleon( editor, 'panel' ), [ [ uiColorRegexp, color ] ] );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
editor.on( 'panelShow', showCallback );
|
||||
editor.on( 'menuShow', showCallback );
|
||||
|
||||
// Apply UI color if specified in config.
|
||||
if ( editor.config.uiColor )
|
||||
editor.setUiColor( editor.config.uiColor );
|
||||
} );
|
||||
} )();
|
||||
|
||||
/**
|
||||
* The list of file names matching the browser user agent string from
|
||||
* {@link CKEDITOR.env}. This is used to load the skin part file in addition
|
||||
* to the "main" skin file for a particular browser.
|
||||
*
|
||||
* **Note:** For each of the defined skin parts the corresponding
|
||||
* CSS file with the same name as the user agent must exist inside
|
||||
* the skin directory.
|
||||
*
|
||||
* @property ua
|
||||
* @todo type?
|
||||
*/
|
||||
|
||||
/**
|
||||
* The name of the skin that is currently used.
|
||||
*
|
||||
* @property {String} name
|
||||
* @todo
|
||||
*/
|
||||
|
||||
/**
|
||||
* The editor skin name. Note that it is not possible to have editors with
|
||||
* different skin settings in the same page. In such case just one of the
|
||||
* skins will be used for all editors.
|
||||
*
|
||||
* This is a shortcut to {@link CKEDITOR#skinName}.
|
||||
*
|
||||
* It is possible to install skins outside the default `skin` folder in the
|
||||
* editor installation. In that case, the absolute URL path to that folder
|
||||
* should be provided, separated by a comma (`'skin_name,skin_path'`).
|
||||
*
|
||||
* config.skin = 'moono';
|
||||
*
|
||||
* config.skin = 'myskin,/customstuff/myskin/';
|
||||
*
|
||||
* @cfg {String} skin
|
||||
* @member CKEDITOR.config
|
||||
*/
|
||||
|
||||
/**
|
||||
* A function that supports the chameleon (skin color switch) feature, providing
|
||||
* the skin color style updates to be applied in runtime.
|
||||
*
|
||||
* **Note:** The embedded `$color` variable is to be substituted with a specific UI color.
|
||||
*
|
||||
* @method chameleon
|
||||
* @param {String} editor The editor instance that the color changes apply to.
|
||||
* @param {String} part The name of the skin part where the color changes take place.
|
||||
*/
|
||||
|
||||
/**
|
||||
* To help implement browser-specific "hacks" to the skin files and make it easy to maintain,
|
||||
* it is possible to have dedicated files for such browsers. The browser files must be named after the main file names,
|
||||
* appended by an underscore and the browser name (e.g. `editor_ie.css`, `editor_ie8.css`). The accepted browser names
|
||||
* must match the {@link CKEDITOR.env} properties. You can find more information about browser "hacks" in the
|
||||
* {@glink guide/skin_sdk_browser_hacks Dedicated Browser Hacks} guide.
|
||||
*
|
||||
* CKEDITOR.skin.ua_editor = 'ie,iequirks,ie8,gecko';
|
||||
*
|
||||
* @property {String} ua_editor
|
||||
*/
|
||||
|
||||
/**
|
||||
* Similar to {@link #ua_editor} but used for dialog stylesheets.
|
||||
*
|
||||
* CKEDITOR.skin.ua_dialog = 'ie,iequirks,ie8,gecko';
|
||||
*
|
||||
* @property {String} ua_dialog
|
||||
*/
|
||||
2221
Admin/plugins/ckeditor/core/style.js
Normal file
2221
Admin/plugins/ckeditor/core/style.js
Normal file
File diff suppressed because it is too large
Load Diff
69
Admin/plugins/ckeditor/core/template.js
Normal file
69
Admin/plugins/ckeditor/core/template.js
Normal file
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.template} class, which represents
|
||||
* an UI template for an editor instance.
|
||||
*/
|
||||
|
||||
( function() {
|
||||
var rePlaceholder = /{([^}]+)}/g;
|
||||
|
||||
/**
|
||||
* Lightweight template used to build the output string from variables.
|
||||
*
|
||||
* // HTML template for presenting a label UI.
|
||||
* var tpl = new CKEDITOR.template( '<div class="{cls}">{label}</div>' );
|
||||
* alert( tpl.output( { cls: 'cke-label', label: 'foo'} ) ); // '<div class="cke-label">foo</div>'
|
||||
*
|
||||
* // Since 4.12.0 it is possible to pass a callback function that returns a template.
|
||||
* var tpl2 = new CKEDITOR.template( function( data ) {
|
||||
* return data.image ? '<img src="{image}" alt="{label}"/>' : '{label}';
|
||||
* } );
|
||||
* alert( tpl2.output( { image: null, label: 'foo'} ) ); // 'foo'
|
||||
* alert( tpl2.output( { image: '/some-image.jpg', label: 'foo'} ) ); // <img src="/some-image.jpg" alt="foo"/>
|
||||
*
|
||||
* @class
|
||||
* @constructor Creates a template class instance.
|
||||
* @param {String/Function} source A string with the template source or a callback that will return such string.
|
||||
* The handling of the `Function` type was added in version 4.12.0 .
|
||||
*/
|
||||
CKEDITOR.template = function( source ) {
|
||||
/**
|
||||
* The current template source.
|
||||
*
|
||||
* Note that support for the `Function` type was added in version 4.12.0 .
|
||||
*
|
||||
* @readonly
|
||||
* @member CKEDITOR.template
|
||||
* @property {String/Function} source
|
||||
*/
|
||||
this.source = typeof source === 'function' ? source : String( source );
|
||||
};
|
||||
|
||||
/**
|
||||
* Processes the template, filling its variables with the provided data.
|
||||
*
|
||||
* @method
|
||||
* @member CKEDITOR.template
|
||||
* @param {Object} data An object containing properties whose values will be
|
||||
* used to fill the template variables. The property names must match the
|
||||
* template variables names. Variables without matching properties will be
|
||||
* kept untouched.
|
||||
* @param {Array} [buffer] An array that the output data will be pushed into.
|
||||
* The number of entries appended to the array is unknown.
|
||||
* @returns {String/Number} If `buffer` has not been provided, the processed
|
||||
* template output data; otherwise the new length of `buffer`.
|
||||
*/
|
||||
CKEDITOR.template.prototype.output = function( data, buffer ) {
|
||||
|
||||
var template = typeof this.source === 'function' ? this.source( data ) : this.source,
|
||||
output = template.replace( rePlaceholder, function( fullMatch, dataKey ) {
|
||||
return data[ dataKey ] !== undefined ? data[ dataKey ] : fullMatch;
|
||||
} );
|
||||
|
||||
return buffer ? buffer.push( output ) : output;
|
||||
};
|
||||
} )();
|
||||
3086
Admin/plugins/ckeditor/core/tools.js
Normal file
3086
Admin/plugins/ckeditor/core/tools.js
Normal file
File diff suppressed because it is too large
Load Diff
1074
Admin/plugins/ckeditor/core/tools/color.js
Normal file
1074
Admin/plugins/ckeditor/core/tools/color.js
Normal file
File diff suppressed because it is too large
Load Diff
186
Admin/plugins/ckeditor/core/ui.js
Normal file
186
Admin/plugins/ckeditor/core/ui.js
Normal file
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains UI features related to an editor instance.
|
||||
*
|
||||
* @class
|
||||
* @mixins CKEDITOR.event
|
||||
* @constructor Creates a `ui` class instance.
|
||||
* @param {CKEDITOR.editor} editor The editor instance.
|
||||
*/
|
||||
CKEDITOR.ui = function( editor ) {
|
||||
if ( editor.ui )
|
||||
return editor.ui;
|
||||
|
||||
this.items = {};
|
||||
this.instances = {};
|
||||
this.editor = editor;
|
||||
|
||||
/**
|
||||
* Object used to store private stuff.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
this._ = {
|
||||
handlers: {}
|
||||
};
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// PACKAGER_RENAME( CKEDITOR.ui )
|
||||
|
||||
CKEDITOR.ui.prototype = {
|
||||
/**
|
||||
* Adds a UI item to the items collection. These items can be later used in
|
||||
* the interface.
|
||||
*
|
||||
* // Add a new button named 'MyBold'.
|
||||
* editorInstance.ui.add( 'MyBold', CKEDITOR.UI_BUTTON, {
|
||||
* label: 'My Bold',
|
||||
* command: 'bold'
|
||||
* } );
|
||||
*
|
||||
* @param {String} name The UI item name.
|
||||
* @param {Object} type The item type.
|
||||
* @param {Object} definition The item definition. The properties of this
|
||||
* object depend on the item type.
|
||||
*/
|
||||
add: function( name, type, definition ) {
|
||||
// Compensate the unique name of this ui item to definition.
|
||||
definition.name = name.toLowerCase();
|
||||
|
||||
var item = this.items[ name ] = {
|
||||
type: type,
|
||||
// The name of {@link CKEDITOR.command} which associate with this UI.
|
||||
command: definition.command || null,
|
||||
args: Array.prototype.slice.call( arguments, 2 )
|
||||
};
|
||||
|
||||
CKEDITOR.tools.extend( item, definition );
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieves the created UI objects by name.
|
||||
*
|
||||
* @param {String} name The name of the UI definition.
|
||||
* @returns {Object} The UI object.
|
||||
*/
|
||||
get: function( name ) {
|
||||
return this.instances[ name ];
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a UI object.
|
||||
*
|
||||
* @param {String} name The UI item name.
|
||||
* @returns {Object} The UI element.
|
||||
*/
|
||||
create: function( name ) {
|
||||
var item = this.items[ name ],
|
||||
handler = item && this._.handlers[ item.type ],
|
||||
command = item && item.command && this.editor.getCommand( item.command );
|
||||
|
||||
var result = handler && handler.create.apply( this, item.args );
|
||||
|
||||
this.instances[ name ] = result;
|
||||
|
||||
// Add reference inside command object.
|
||||
if ( command )
|
||||
command.uiItems.push( result );
|
||||
|
||||
if ( result && !result.type )
|
||||
result.type = item.type;
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a handler for a UI item type. The handler is responsible for
|
||||
* transforming UI item definitions into UI objects.
|
||||
*
|
||||
* @param {Object} type The item type.
|
||||
* @param {Object} handler The handler definition.
|
||||
*/
|
||||
addHandler: function( type, handler ) {
|
||||
this._.handlers[ type ] = handler;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the unique DOM element that represents one editor's UI part, also known as "space".
|
||||
* There are 3 main editor spaces available: `top`, `contents` and `bottom`
|
||||
* and their availability depends on editor type.
|
||||
*
|
||||
* // Hide the bottom space in the UI.
|
||||
* var bottom = editor.ui.space( 'bottom' );
|
||||
* bottom.setStyle( 'display', 'none' );
|
||||
*
|
||||
* @param {String} name The name of the space.
|
||||
* @returns {CKEDITOR.dom.element} The element that represents the space.
|
||||
*/
|
||||
space: function( name ) {
|
||||
return CKEDITOR.document.getById( this.spaceId( name ) );
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the HTML ID for a specific UI space name.
|
||||
*
|
||||
* @param {String} name The name of the space.
|
||||
* @returns {String} The ID of an element representing this space in the DOM.
|
||||
*/
|
||||
spaceId: function( name ) {
|
||||
return this.editor.id + '_' + name;
|
||||
}
|
||||
};
|
||||
|
||||
CKEDITOR.event.implementOn( CKEDITOR.ui );
|
||||
|
||||
/**
|
||||
* Internal event fired when a new UI element is ready.
|
||||
*
|
||||
* @event ready
|
||||
* @param {Object} data The new UI element.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Virtual class which just illustrates the features of handler objects to be
|
||||
* passed to the {@link CKEDITOR.ui#addHandler} function.
|
||||
* This class is not really a part of the API, so do not call its constructor.
|
||||
*
|
||||
* @class CKEDITOR.ui.handlerDefinition
|
||||
*/
|
||||
|
||||
/**
|
||||
* Transforms an item definition into a UI item object.
|
||||
*
|
||||
* editorInstance.ui.addHandler( CKEDITOR.UI_BUTTON, {
|
||||
* create: function( definition ) {
|
||||
* return new CKEDITOR.ui.button( definition );
|
||||
* }
|
||||
* } );
|
||||
*
|
||||
* @method create
|
||||
* @param {Object} definition The item definition.
|
||||
* @returns {Object} The UI element.
|
||||
* @todo We lack the "UI element" abstract super class.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The element in the {@link CKEDITOR#document host page's document} that contains the editor content.
|
||||
* If the {@glink features/uitypes#fixed-user-interface fixed editor UI} is used, then it will be set to
|
||||
* `editor.ui.space( 'contents' )` — i.e. the `<div>` which contains the editor `<iframe>` (in case of classic editor)
|
||||
* or {@link CKEDITOR.editable} (in case of inline editor). Otherwise it is set to the {@link CKEDITOR.editable} itself.
|
||||
*
|
||||
* Use the position of this element if you need to position elements placed in the host page's document relatively to the
|
||||
* editor content.
|
||||
*
|
||||
* var editor = CKEDITOR.instances.editor1;
|
||||
* console.log( editor.ui.contentsElement.getName() ); // 'div'
|
||||
*
|
||||
* @since 4.5.0
|
||||
* @readonly
|
||||
* @property {CKEDITOR.dom.element} contentsElement
|
||||
*/
|
||||
63
Admin/plugins/ckeditor/lang/_translationstatus.txt
Normal file
63
Admin/plugins/ckeditor/lang/_translationstatus.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
|
||||
af.js Found: 62 Missing: 4
|
||||
ar.js Found: 51 Missing: 15
|
||||
bg.js Found: 58 Missing: 8
|
||||
bn.js Found: 40 Missing: 26
|
||||
bs.js Found: 29 Missing: 37
|
||||
ca.js Found: 61 Missing: 5
|
||||
cs.js Found: 66 Missing: 0
|
||||
cy.js Found: 66 Missing: 0
|
||||
da.js Found: 66 Missing: 0
|
||||
de.js Found: 66 Missing: 0
|
||||
el.js Found: 59 Missing: 7
|
||||
en-au.js Found: 38 Missing: 28
|
||||
en-ca.js Found: 37 Missing: 29
|
||||
en-gb.js Found: 61 Missing: 5
|
||||
eo.js Found: 66 Missing: 0
|
||||
es.js Found: 66 Missing: 0
|
||||
et.js Found: 66 Missing: 0
|
||||
eu.js Found: 48 Missing: 18
|
||||
fa.js Found: 66 Missing: 0
|
||||
fi.js Found: 66 Missing: 0
|
||||
fo.js Found: 66 Missing: 0
|
||||
fr-ca.js Found: 42 Missing: 24
|
||||
fr.js Found: 66 Missing: 0
|
||||
gl.js Found: 40 Missing: 26
|
||||
gu.js Found: 66 Missing: 0
|
||||
he.js Found: 66 Missing: 0
|
||||
hi.js Found: 43 Missing: 23
|
||||
hr.js Found: 66 Missing: 0
|
||||
hu.js Found: 63 Missing: 3
|
||||
is.js Found: 41 Missing: 25
|
||||
it.js Found: 66 Missing: 0
|
||||
ja.js Found: 62 Missing: 4
|
||||
ka.js Found: 62 Missing: 4
|
||||
km.js Found: 40 Missing: 26
|
||||
ko.js Found: 40 Missing: 26
|
||||
lt.js Found: 66 Missing: 0
|
||||
lv.js Found: 40 Missing: 26
|
||||
mk.js Found: 0 Missing: 66
|
||||
mn.js Found: 40 Missing: 26
|
||||
ms.js Found: 39 Missing: 27
|
||||
nb.js Found: 66 Missing: 0
|
||||
nl.js Found: 65 Missing: 1
|
||||
no.js Found: 66 Missing: 0
|
||||
pl.js Found: 66 Missing: 0
|
||||
pt-br.js Found: 66 Missing: 0
|
||||
pt.js Found: 52 Missing: 14
|
||||
ro.js Found: 61 Missing: 5
|
||||
ru.js Found: 66 Missing: 0
|
||||
sk.js Found: 49 Missing: 17
|
||||
sl.js Found: 48 Missing: 18
|
||||
sr-latn.js Found: 40 Missing: 26
|
||||
sr.js Found: 40 Missing: 26
|
||||
sv.js Found: 62 Missing: 4
|
||||
th.js Found: 40 Missing: 26
|
||||
tr.js Found: 66 Missing: 0
|
||||
ug.js Found: 66 Missing: 0
|
||||
uk.js Found: 66 Missing: 0
|
||||
vi.js Found: 66 Missing: 0
|
||||
zh-cn.js Found: 66 Missing: 0
|
||||
zh.js Found: 58 Missing: 8
|
||||
154
Admin/plugins/ckeditor/lang/af.js
Normal file
154
Admin/plugins/ckeditor/lang/af.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Afrikaans language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'af' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Woordverwerker',
|
||||
editorPanel: 'Woordverwerkerpaneel',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Druk op ALT 0 vir hulp',
|
||||
|
||||
browseServer: 'Blaai op bediener',
|
||||
url: 'URL',
|
||||
protocol: 'Protokol',
|
||||
upload: 'Oplaai',
|
||||
uploadSubmit: 'Stuur aan die bediener',
|
||||
image: 'Beeld',
|
||||
form: 'Vorm',
|
||||
checkbox: 'Merkhokkie',
|
||||
radio: 'Radioknoppie',
|
||||
textField: 'Teksveld',
|
||||
textarea: 'Teksarea',
|
||||
hiddenField: 'Versteekteveld',
|
||||
button: 'Knop',
|
||||
select: 'Keuseveld',
|
||||
imageButton: 'Beeldknop',
|
||||
notSet: '<geen instelling>',
|
||||
id: 'Id',
|
||||
name: 'Naam',
|
||||
langDir: 'Skryfrigting',
|
||||
langDirLtr: 'Links na regs (LTR)',
|
||||
langDirRtl: 'Regs na links (RTL)',
|
||||
langCode: 'Taalkode',
|
||||
longDescr: 'Lang beskrywing URL',
|
||||
cssClass: 'CSS klasse',
|
||||
advisoryTitle: 'Aanbevole titel',
|
||||
cssStyle: 'Styl',
|
||||
ok: 'OK',
|
||||
cancel: 'Kanselleer',
|
||||
close: 'Sluit',
|
||||
preview: 'Voorbeeld',
|
||||
resize: 'Skalierung',
|
||||
generalTab: 'Algemeen',
|
||||
advancedTab: 'Gevorderd',
|
||||
validateNumberFailed: 'Hierdie waarde is nie \'n nommer nie.',
|
||||
confirmNewPage: 'Alle wysiginge sal verlore gaan. Is jy seker dat jy \'n nuwe bladsy wil laai?',
|
||||
confirmCancel: 'Sommige opsies is gewysig. Is jy seker dat jy hierdie dialoogvenster wil sluit?',
|
||||
options: 'Opsies',
|
||||
target: 'Teiken',
|
||||
targetNew: 'Nuwe venster (_blank)',
|
||||
targetTop: 'Boonste venster (_top)',
|
||||
targetSelf: 'Selfde venster (_self)',
|
||||
targetParent: 'Oorspronklike venster (_parent)',
|
||||
langDirLTR: 'Links na Regs (LTR)',
|
||||
langDirRTL: 'Regs na Links (RTL)',
|
||||
styles: 'Styl',
|
||||
cssClasses: 'CSS klasse',
|
||||
width: 'Breedte',
|
||||
height: 'Hoogte',
|
||||
align: 'Orienteerung',
|
||||
left: 'Links',
|
||||
right: 'Regs',
|
||||
center: 'Middel',
|
||||
justify: 'Eweredig',
|
||||
alignLeft: 'Links oplyn',
|
||||
alignRight: 'Regs oplyn',
|
||||
alignCenter: 'Middel oplyn',
|
||||
alignTop: 'Bo',
|
||||
alignMiddle: 'Middel',
|
||||
alignBottom: 'Onder',
|
||||
alignNone: 'Geen',
|
||||
invalidValue: 'Ongeldige waarde',
|
||||
invalidHeight: 'Hoogte moet \'n getal wees',
|
||||
invalidWidth: 'Breedte moet \'n getal wees.',
|
||||
invalidLength: 'Die waarde vir die veld "%1" moet \'n posetiewe nommer wees met of sonder die meeteenheid (%2).',
|
||||
invalidCssLength: 'Die waarde vir die "%1" veld moet \'n posetiewe getal wees met of sonder \'n geldige CSS eenheid (px, %, in, cm, mm, em, ex, pt, of pc).',
|
||||
invalidHtmlLength: 'Die waarde vir die "%1" veld moet \'n posetiewe getal wees met of sonder \'n geldige HTML eenheid (px of %).',
|
||||
invalidInlineStyle: 'Ongeldige CSS. Formaat is een of meer sleutel-wert paare, "naam : wert" met kommapunte gesky.',
|
||||
cssLengthTooltip: 'Voeg \'n getal wert in pixel in, of \'n waarde met geldige CSS eenheid (px, %, in, cm, mm, em, ex, pt, of pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, nie beskikbaar nie</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Enter',
|
||||
16: 'Skuif',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Spasie',
|
||||
35: 'Einde',
|
||||
36: 'Tuis',
|
||||
46: 'Verwyder',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Bevel'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Sleutel kombenasie',
|
||||
|
||||
optionDefault: 'Verstek'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/ar.js
Normal file
154
Admin/plugins/ckeditor/lang/ar.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Arabic language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'ar' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'محرر النص الغني',
|
||||
editorPanel: 'لائحة محرر النص المنسق',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'إضغط على ALT + 0 للحصول على المساعدة.',
|
||||
|
||||
browseServer: 'تصفح',
|
||||
url: 'الرابط',
|
||||
protocol: 'البروتوكول',
|
||||
upload: 'رفع',
|
||||
uploadSubmit: 'أرسل',
|
||||
image: 'صورة',
|
||||
form: 'نموذج',
|
||||
checkbox: 'خانة إختيار',
|
||||
radio: 'زر اختيار',
|
||||
textField: 'مربع نص',
|
||||
textarea: 'مساحة نصية',
|
||||
hiddenField: 'إدراج حقل خفي',
|
||||
button: 'زر ضغط',
|
||||
select: 'اختار',
|
||||
imageButton: 'زر صورة',
|
||||
notSet: '<بدون تحديد>',
|
||||
id: 'الرقم',
|
||||
name: 'إسم',
|
||||
langDir: 'إتجاه النص',
|
||||
langDirLtr: 'اليسار لليمين (LTR)',
|
||||
langDirRtl: 'اليمين لليسار (RTL)',
|
||||
langCode: 'رمز اللغة',
|
||||
longDescr: 'الوصف التفصيلى',
|
||||
cssClass: 'فئات التنسيق',
|
||||
advisoryTitle: 'عنوان التقرير',
|
||||
cssStyle: 'نمط',
|
||||
ok: 'موافق',
|
||||
cancel: 'إلغاء الأمر',
|
||||
close: 'أغلق',
|
||||
preview: 'استعراض',
|
||||
resize: 'تغيير الحجم',
|
||||
generalTab: 'عام',
|
||||
advancedTab: 'متقدم',
|
||||
validateNumberFailed: 'لايوجد نتيجة',
|
||||
confirmNewPage: 'ستفقد أي متغييرات اذا لم تقم بحفظها اولا. هل أنت متأكد أنك تريد صفحة جديدة؟',
|
||||
confirmCancel: 'بعض الخيارات قد تغيرت. هل أنت متأكد من إغلاق مربع النص؟',
|
||||
options: 'خيارات',
|
||||
target: 'هدف الرابط',
|
||||
targetNew: 'نافذة جديدة',
|
||||
targetTop: 'النافذة الأعلى',
|
||||
targetSelf: 'داخل النافذة',
|
||||
targetParent: 'النافذة الأم',
|
||||
langDirLTR: 'اليسار لليمين (LTR)',
|
||||
langDirRTL: 'اليمين لليسار (RTL)',
|
||||
styles: 'نمط',
|
||||
cssClasses: 'فئات التنسيق',
|
||||
width: 'العرض',
|
||||
height: 'الإرتفاع',
|
||||
align: 'محاذاة',
|
||||
left: 'يسار',
|
||||
right: 'يمين',
|
||||
center: 'وسط',
|
||||
justify: 'ضبط',
|
||||
alignLeft: 'محاذاة إلى اليسار',
|
||||
alignRight: 'محاذاة إلى اليمين',
|
||||
alignCenter: 'Align Center', // MISSING
|
||||
alignTop: 'أعلى',
|
||||
alignMiddle: 'وسط',
|
||||
alignBottom: 'أسفل',
|
||||
alignNone: 'None', // MISSING
|
||||
invalidValue: 'قيمة غير مفبولة.',
|
||||
invalidHeight: 'الارتفاع يجب أن يكون عدداً.',
|
||||
invalidWidth: 'العرض يجب أن يكون عدداً.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: 'قيمة الخانة المخصصة لـ "%1" يجب أن تكون رقما موجبا، باستخدام أو من غير استخدام وحدة CSS قياس مقبولة (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
invalidHtmlLength: 'قيمة الخانة المخصصة لـ "%1" يجب أن تكون رقما موجبا، باستخدام أو من غير استخدام وحدة HTML قياس مقبولة (px or %).',
|
||||
invalidInlineStyle: 'قيمة الخانة المخصصة لـ Inline Style يجب أن تختوي على مجموع واحد أو أكثر بالشكل التالي: "name : value", مفصولة بفاصلة منقزطة.',
|
||||
cssLengthTooltip: 'أدخل رقما للقيمة بالبكسل أو رقما بوحدة CSS مقبولة (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, غير متاح</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace', // MISSING
|
||||
13: 'Enter', // MISSING
|
||||
16: 'Shift', // MISSING
|
||||
17: 'Ctrl', // MISSING
|
||||
18: 'Alt', // MISSING
|
||||
32: 'Space', // MISSING
|
||||
35: 'End', // MISSING
|
||||
36: 'Home', // MISSING
|
||||
46: 'Delete', // MISSING
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Command' // MISSING
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut', // MISSING
|
||||
|
||||
optionDefault: 'Default' // MISSING
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/az.js
Normal file
154
Admin/plugins/ckeditor/lang/az.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object for the
|
||||
* Azerbaijani language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'az' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Redaktoru',
|
||||
editor: 'Redaktor',
|
||||
editorPanel: 'Mətn Redaktorun Paneli',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Yardım üçün ALT 0 düymələrini basın',
|
||||
|
||||
browseServer: 'Fayların siyahı',
|
||||
url: 'URL',
|
||||
protocol: 'Protokol',
|
||||
upload: 'Serverə yüklə',
|
||||
uploadSubmit: 'Göndər',
|
||||
image: 'Şəkil',
|
||||
form: 'Forma',
|
||||
checkbox: 'Çekboks',
|
||||
radio: 'Radio düyməsi',
|
||||
textField: 'Mətn xanası',
|
||||
textarea: 'Mətn',
|
||||
hiddenField: 'Gizli xana',
|
||||
button: 'Düymə',
|
||||
select: 'Opsiyaların seçilməsi',
|
||||
imageButton: 'Şəkil tipli düymə',
|
||||
notSet: '<seçilməmiş>',
|
||||
id: 'Id',
|
||||
name: 'Ad',
|
||||
langDir: 'Yaziların istiqaməti',
|
||||
langDirLtr: 'Soldan sağa (LTR)',
|
||||
langDirRtl: 'Sağdan sola (RTL)',
|
||||
langCode: 'Dilin kodu',
|
||||
longDescr: 'URL-ın ətraflı izahı',
|
||||
cssClass: 'CSS klassları',
|
||||
advisoryTitle: 'Başlıq',
|
||||
cssStyle: 'CSS',
|
||||
ok: 'Tədbiq et',
|
||||
cancel: 'İmtina et',
|
||||
close: 'Bağla',
|
||||
preview: 'Baxış',
|
||||
resize: 'Eni dəyiş',
|
||||
generalTab: 'Əsas',
|
||||
advancedTab: 'Əlavə',
|
||||
validateNumberFailed: 'Rəqəm deyil.',
|
||||
confirmNewPage: 'Yadda saxlanılmamış dəyişikliklər itiriləcək. Davam etmək istədiyinizə əminsinizmi?',
|
||||
confirmCancel: 'Dəyişikliklər edilib. Pəncərəni bağlamaq istəyirsizə əminsinizmi?',
|
||||
options: 'Seçimlər',
|
||||
target: 'Hədəf çərçivə',
|
||||
targetNew: 'Yeni pəncərə (_blank)',
|
||||
targetTop: 'Əsas pəncərə (_top)',
|
||||
targetSelf: 'Carı pəncərə (_self)',
|
||||
targetParent: 'Ana pəncərə (_parent)',
|
||||
langDirLTR: 'Soldan sağa (LTR)',
|
||||
langDirRTL: 'Sağdan sola (RTL)',
|
||||
styles: 'Üslub',
|
||||
cssClasses: 'Üslub klası',
|
||||
width: 'En',
|
||||
height: 'Uzunluq',
|
||||
align: 'Yerləşmə',
|
||||
left: 'Sol',
|
||||
right: 'Sağ',
|
||||
center: 'Mərkəz',
|
||||
justify: 'Eninə görə',
|
||||
alignLeft: 'Soldan düzləndir',
|
||||
alignRight: 'Sağdan düzləndir',
|
||||
alignCenter: 'Mərkəzə düzləndir',
|
||||
alignTop: 'Yuxarı',
|
||||
alignMiddle: 'Orta',
|
||||
alignBottom: 'Aşağı',
|
||||
alignNone: 'Yoxdur',
|
||||
invalidValue: 'Yanlışdır.',
|
||||
invalidHeight: 'Hündürlük rəqəm olmalıdır.',
|
||||
invalidWidth: 'En rəqəm olmalıdır.',
|
||||
invalidLength: '"%1" xanasına, ölçü vahidinin (%2) göstərilməsindən asılı olmayaraq, müsbət ədəd qeyd olunmalıdır.',
|
||||
invalidCssLength: '"%1" xanasında göstərilən məzmun tam və müsbət olmalıdır, CSS-də olan ölçü vahidlərin (px, %, in, cm, mm, em, ex, pt, or pc) istifadısinə icazə verilir.',
|
||||
invalidHtmlLength: '"%1" xanasında göstərilən məzmun tam və müsbət olmalıdır HTML-də olan ölçü vahidlərin (px və ya %) istifadısinə icazə verilir.',
|
||||
invalidInlineStyle: 'Teq içində olan üslub "ad : məzmun" şəklidə, nöqtə-verqül işarəsi ilə bitməlidir',
|
||||
cssLengthTooltip: 'Piksel sayı və ya digər CSS ölçü vahidləri (px, %, in, cm, mm, em, ex, pt, or pc) daxil edin.',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, mövcud deyil</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Enter',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Boşluq',
|
||||
35: 'Son',
|
||||
36: 'Evə',
|
||||
46: 'Sil',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Əmr'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Qısayol düymələri',
|
||||
|
||||
optionDefault: 'Standart'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/bg.js
Normal file
154
Admin/plugins/ckeditor/lang/bg.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Bulgarian language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'bg' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Редактор за форматиран текст',
|
||||
editorPanel: 'Панел на текстовия редактор',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'натиснете ALT+0 за помощ',
|
||||
|
||||
browseServer: 'Избор от сървъра',
|
||||
url: 'URL адрес',
|
||||
protocol: 'Протокол',
|
||||
upload: 'Качване',
|
||||
uploadSubmit: 'Изпращане към сървъра',
|
||||
image: 'Изображение',
|
||||
form: 'Форма',
|
||||
checkbox: 'Поле за избор',
|
||||
radio: 'Радио бутон',
|
||||
textField: 'Текстово поле',
|
||||
textarea: 'Текстова зона',
|
||||
hiddenField: 'Скрито поле',
|
||||
button: 'Бутон',
|
||||
select: 'Поле за избор',
|
||||
imageButton: 'Бутон за изображение',
|
||||
notSet: '<не е избрано>',
|
||||
id: 'ID',
|
||||
name: 'Име',
|
||||
langDir: 'Посока на езика',
|
||||
langDirLtr: 'От ляво надясно (LTR)',
|
||||
langDirRtl: 'От дясно наляво (RTL)',
|
||||
langCode: 'Код на езика',
|
||||
longDescr: 'Уеб адрес за дълго описание',
|
||||
cssClass: 'Класове за CSS',
|
||||
advisoryTitle: 'Заглавие',
|
||||
cssStyle: 'Стил',
|
||||
ok: 'ОК',
|
||||
cancel: 'Отказ',
|
||||
close: 'Затвори',
|
||||
preview: 'Преглед',
|
||||
resize: 'Влачете за да оразмерите',
|
||||
generalTab: 'Общи',
|
||||
advancedTab: 'Разширено',
|
||||
validateNumberFailed: 'Тази стойност не е число',
|
||||
confirmNewPage: 'Всички незапазени промени ще бъдат изгубени. Сигурни ли сте, че желаете да заредите нова страница?',
|
||||
confirmCancel: 'Някои от опциите са променени. Сигурни ли сте, че желаете да затворите прозореца?',
|
||||
options: 'Опции',
|
||||
target: 'Цел',
|
||||
targetNew: 'Нов прозорец (_blank)',
|
||||
targetTop: 'Най-горният прозорец (_top)',
|
||||
targetSelf: 'Текущият прозорец (_self)',
|
||||
targetParent: 'Горният прозорец (_parent)',
|
||||
langDirLTR: 'От ляво надясно (LTR)',
|
||||
langDirRTL: 'От дясно наляво (RTL)',
|
||||
styles: 'Стил',
|
||||
cssClasses: 'Класове за CSS',
|
||||
width: 'Ширина',
|
||||
height: 'Височина',
|
||||
align: 'Подравняване',
|
||||
left: 'Ляво',
|
||||
right: 'Дясно',
|
||||
center: 'Център',
|
||||
justify: 'Двустранно',
|
||||
alignLeft: 'Подравни ляво',
|
||||
alignRight: 'Подравни дясно',
|
||||
alignCenter: 'Подравни център',
|
||||
alignTop: 'Горе',
|
||||
alignMiddle: 'По средата',
|
||||
alignBottom: 'Долу',
|
||||
alignNone: 'Без подравняване',
|
||||
invalidValue: 'Невалидна стойност.',
|
||||
invalidHeight: 'Височината трябва да е число.',
|
||||
invalidWidth: 'Ширина трябва да е число.',
|
||||
invalidLength: 'Стойността на полето "%1" трябва да е положително число с или без валидна мерна единица (%2).',
|
||||
invalidCssLength: 'Стойността на полето "%1" трябва да е положително число с или без валидна CSS мерна единица (px, %, in, cm, mm, em, ex, pt, или pc).',
|
||||
invalidHtmlLength: 'Стойността на полето "%1" трябва да е положително число с или без валидна HTML мерна единица (px или %).',
|
||||
invalidInlineStyle: 'Стойността на стилa трябва да съдържат една или повече двойки във формат "name : value", разделени с двоеточие.',
|
||||
cssLengthTooltip: 'Въведете числена стойност в пиксели или друга валидна CSS единица (px, %, in, cm, mm, em, ex, pt, или pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, недостъпно</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Enter',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Space',
|
||||
35: 'End',
|
||||
36: 'Home',
|
||||
46: 'Delete',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Command'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Клавишна комбинация',
|
||||
|
||||
optionDefault: 'По подразбиране'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/bn.js
Normal file
154
Admin/plugins/ckeditor/lang/bn.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Bengali/Bangla language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'bn' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Editor', // MISSING
|
||||
editorPanel: 'Rich Text Editor panel', // MISSING
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Press ALT 0 for help', // MISSING
|
||||
|
||||
browseServer: 'ব্রাউজ সার্ভার',
|
||||
url: 'URL',
|
||||
protocol: 'প্রোটোকল',
|
||||
upload: 'আপলোড',
|
||||
uploadSubmit: 'ইহাকে সার্ভারে প্রেরন কর',
|
||||
image: 'ছবির লেবেল যুক্ত কর',
|
||||
form: 'ফর্ম',
|
||||
checkbox: 'চেক বাক্স',
|
||||
radio: 'রেডিও বাটন',
|
||||
textField: 'টেক্সট ফীল্ড',
|
||||
textarea: 'টেক্সট এরিয়া',
|
||||
hiddenField: 'গুপ্ত ফীল্ড',
|
||||
button: 'বাটন',
|
||||
select: 'বাছাই ফীল্ড',
|
||||
imageButton: 'ছবির বাটন',
|
||||
notSet: '<সেট নেই>',
|
||||
id: 'আইডি',
|
||||
name: 'নাম',
|
||||
langDir: 'ভাষা লেখার দিক',
|
||||
langDirLtr: 'বাম থেকে ডান (LTR)',
|
||||
langDirRtl: 'ডান থেকে বাম (RTL)',
|
||||
langCode: 'ভাষা কোড',
|
||||
longDescr: 'URL এর লম্বা বর্ণনা',
|
||||
cssClass: 'স্টাইল-শীট ক্লাস',
|
||||
advisoryTitle: 'পরামর্শ শীর্ষক',
|
||||
cssStyle: 'স্টাইল',
|
||||
ok: 'ওকে',
|
||||
cancel: 'বাতিল',
|
||||
close: 'Close', // MISSING
|
||||
preview: 'প্রিভিউ',
|
||||
resize: 'Resize', // MISSING
|
||||
generalTab: 'General', // MISSING
|
||||
advancedTab: 'এডভান্সড',
|
||||
validateNumberFailed: 'This value is not a number.', // MISSING
|
||||
confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
|
||||
confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
|
||||
options: 'Options', // MISSING
|
||||
target: 'টার্গেট',
|
||||
targetNew: 'New Window (_blank)', // MISSING
|
||||
targetTop: 'Topmost Window (_top)', // MISSING
|
||||
targetSelf: 'Same Window (_self)', // MISSING
|
||||
targetParent: 'Parent Window (_parent)', // MISSING
|
||||
langDirLTR: 'বাম থেকে ডান (LTR)',
|
||||
langDirRTL: 'ডান থেকে বাম (RTL)',
|
||||
styles: 'স্টাইল',
|
||||
cssClasses: 'স্টাইল-শীট ক্লাস',
|
||||
width: 'প্রস্থ',
|
||||
height: 'দৈর্ঘ্য',
|
||||
align: 'এলাইন',
|
||||
left: 'বামে',
|
||||
right: 'ডানে',
|
||||
center: 'মাঝখানে',
|
||||
justify: 'ব্লক জাস্টিফাই',
|
||||
alignLeft: 'বা দিকে ঘেঁষা',
|
||||
alignRight: 'ডান দিকে ঘেঁষা',
|
||||
alignCenter: 'Align Center', // MISSING
|
||||
alignTop: 'উপর',
|
||||
alignMiddle: 'মধ্য',
|
||||
alignBottom: 'নীচে',
|
||||
alignNone: 'None', // MISSING
|
||||
invalidValue: 'Invalid value.', // MISSING
|
||||
invalidHeight: 'Height must be a number.', // MISSING
|
||||
invalidWidth: 'Width must be a number.', // MISSING
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
|
||||
invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
|
||||
invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
|
||||
cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace', // MISSING
|
||||
13: 'Enter', // MISSING
|
||||
16: 'Shift', // MISSING
|
||||
17: 'Ctrl', // MISSING
|
||||
18: 'Alt', // MISSING
|
||||
32: 'Space', // MISSING
|
||||
35: 'End', // MISSING
|
||||
36: 'Home', // MISSING
|
||||
46: 'Delete', // MISSING
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Command' // MISSING
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut', // MISSING
|
||||
|
||||
optionDefault: 'Default' // MISSING
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/bs.js
Normal file
154
Admin/plugins/ckeditor/lang/bs.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Bosnian language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'bs' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Editor', // MISSING
|
||||
editorPanel: 'Rich Text Editor panel', // MISSING
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Press ALT 0 for help', // MISSING
|
||||
|
||||
browseServer: 'Browse Server', // MISSING
|
||||
url: 'URL',
|
||||
protocol: 'Protokol',
|
||||
upload: 'Šalji',
|
||||
uploadSubmit: 'Šalji na server',
|
||||
image: 'Slika',
|
||||
form: 'Forma',
|
||||
checkbox: 'Checkbox', // MISSING
|
||||
radio: 'Radio Button', // MISSING
|
||||
textField: 'Polje za unos teksta',
|
||||
textarea: 'Textarea', // MISSING
|
||||
hiddenField: 'Skriveno polje',
|
||||
button: 'Button',
|
||||
select: 'Selection Field', // MISSING
|
||||
imageButton: 'Image Button', // MISSING
|
||||
notSet: '<nije podešeno>',
|
||||
id: 'Id',
|
||||
name: 'Naziv',
|
||||
langDir: 'Smjer pisanja',
|
||||
langDirLtr: 'S lijeva na desno (LTR)',
|
||||
langDirRtl: 'S desna na lijevo (RTL)',
|
||||
langCode: 'Jezièni kôd',
|
||||
longDescr: 'Dugaèki opis URL-a',
|
||||
cssClass: 'Klase CSS stilova',
|
||||
advisoryTitle: 'Advisory title',
|
||||
cssStyle: 'Stil',
|
||||
ok: 'OK',
|
||||
cancel: 'Odustani',
|
||||
close: 'Zatvori',
|
||||
preview: 'Prikaži',
|
||||
resize: 'Promijeni veličinu',
|
||||
generalTab: 'Generalno',
|
||||
advancedTab: 'Naprednije',
|
||||
validateNumberFailed: 'Unesena vrijednost nije broj',
|
||||
confirmNewPage: 'Nesačuvane izmjene će biti izgubljene. Da li ste sigurni da želite otvoriti novu stranicu ?',
|
||||
confirmCancel: 'Napravili ste par izmjena. Da li želite zatvoriti prozor ?',
|
||||
options: 'Opcije',
|
||||
target: 'Prozor',
|
||||
targetNew: 'New Window (_blank)', // MISSING
|
||||
targetTop: 'Topmost Window (_top)', // MISSING
|
||||
targetSelf: 'Same Window (_self)', // MISSING
|
||||
targetParent: 'Parent Window (_parent)', // MISSING
|
||||
langDirLTR: 'S lijeva na desno (LTR)',
|
||||
langDirRTL: 'S desna na lijevo (RTL)',
|
||||
styles: 'Stil',
|
||||
cssClasses: 'Klase CSS stilova',
|
||||
width: 'Širina',
|
||||
height: 'Visina',
|
||||
align: 'Poravnanje',
|
||||
left: 'Lijevo',
|
||||
right: 'Desno',
|
||||
center: 'Centar',
|
||||
justify: 'Puno poravnanje',
|
||||
alignLeft: 'Lijevo poravnanje',
|
||||
alignRight: 'Desno poravnanje',
|
||||
alignCenter: 'Centriranje',
|
||||
alignTop: 'Vrh',
|
||||
alignMiddle: 'Sredina',
|
||||
alignBottom: 'Dno',
|
||||
alignNone: 'Bez poravnanja',
|
||||
invalidValue: 'Nepravilna vrijednost',
|
||||
invalidHeight: 'Vrijednost visine mora biti broj.',
|
||||
invalidWidth: 'Vrijednost širine mora biti broj.',
|
||||
invalidLength: 'Vrijednost za "%1" polje mora biti pozitivan broj ili bez ispravne mjerne jedinice (%2).',
|
||||
invalidCssLength: 'Vrijednost za "%1" polje mora biti pozitivan broj ili bez validne CSS mjerne jedinice (px, %, in, cm, mm, em, ex, pt ili pc).',
|
||||
invalidHtmlLength: 'Vrijednost za "%1" polje mora biti pozitivan broj ili bez validne HTML mjerne jedinice (px ili %).',
|
||||
invalidInlineStyle: 'Vrijednost za inline stil mora sadržavati jedan ili više parova u formatu "name: value", razdvojenih tačka-zarezom.',
|
||||
cssLengthTooltip: 'Unesite vrijednost u pikselima ili kao broj sa ispravnom CSS jedinicom (px, %, in, cm, mm, em, ex, pt ili pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '$1<span class="cke_accessibility">, nedostupno</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace', // MISSING
|
||||
13: 'Enter', // MISSING
|
||||
16: 'Shift', // MISSING
|
||||
17: 'Ctrl', // MISSING
|
||||
18: 'Alt', // MISSING
|
||||
32: 'Space', // MISSING
|
||||
35: 'End', // MISSING
|
||||
36: 'Home', // MISSING
|
||||
46: 'Delete', // MISSING
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Command' // MISSING
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut', // MISSING
|
||||
|
||||
optionDefault: 'Zadano'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/ca.js
Normal file
154
Admin/plugins/ckeditor/lang/ca.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Catalan language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'ca' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Editor de text enriquit',
|
||||
editorPanel: 'Panell de l\'editor de text enriquit',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Premeu ALT 0 per ajuda',
|
||||
|
||||
browseServer: 'Veure servidor',
|
||||
url: 'URL',
|
||||
protocol: 'Protocol',
|
||||
upload: 'Puja',
|
||||
uploadSubmit: 'Envia-la al servidor',
|
||||
image: 'Imatge',
|
||||
form: 'Formulari',
|
||||
checkbox: 'Casella de verificació',
|
||||
radio: 'Botó d\'opció',
|
||||
textField: 'Camp de text',
|
||||
textarea: 'Àrea de text',
|
||||
hiddenField: 'Camp ocult',
|
||||
button: 'Botó',
|
||||
select: 'Camp de selecció',
|
||||
imageButton: 'Botó d\'imatge',
|
||||
notSet: '<no definit>',
|
||||
id: 'Id',
|
||||
name: 'Nom',
|
||||
langDir: 'Direcció de l\'idioma',
|
||||
langDirLtr: 'D\'esquerra a dreta (LTR)',
|
||||
langDirRtl: 'De dreta a esquerra (RTL)',
|
||||
langCode: 'Codi d\'idioma',
|
||||
longDescr: 'Descripció llarga de la URL',
|
||||
cssClass: 'Classes del full d\'estil',
|
||||
advisoryTitle: 'Títol consultiu',
|
||||
cssStyle: 'Estil',
|
||||
ok: 'D\'acord',
|
||||
cancel: 'Cancel·la',
|
||||
close: 'Tanca',
|
||||
preview: 'Previsualitza',
|
||||
resize: 'Arrossegueu per redimensionar',
|
||||
generalTab: 'General',
|
||||
advancedTab: 'Avançat',
|
||||
validateNumberFailed: 'Aquest valor no és un número.',
|
||||
confirmNewPage: 'Els canvis en aquest contingut que no es desin es perdran. Esteu segur que voleu carregar una pàgina nova?',
|
||||
confirmCancel: 'Algunes opcions s\'han canviat. Esteu segur que voleu tancar el quadre de diàleg?',
|
||||
options: 'Opcions',
|
||||
target: 'Destí',
|
||||
targetNew: 'Nova finestra (_blank)',
|
||||
targetTop: 'Finestra superior (_top)',
|
||||
targetSelf: 'Mateixa finestra (_self)',
|
||||
targetParent: 'Finestra pare (_parent)',
|
||||
langDirLTR: 'D\'esquerra a dreta (LTR)',
|
||||
langDirRTL: 'De dreta a esquerra (RTL)',
|
||||
styles: 'Estil',
|
||||
cssClasses: 'Classes del full d\'estil',
|
||||
width: 'Amplada',
|
||||
height: 'Alçada',
|
||||
align: 'Alineació',
|
||||
left: 'Ajusta a l\'esquerra',
|
||||
right: 'Ajusta a la dreta',
|
||||
center: 'Centre',
|
||||
justify: 'Justificat',
|
||||
alignLeft: 'Alinea a l\'esquerra',
|
||||
alignRight: 'Alinea a la dreta',
|
||||
alignCenter: 'Align Center', // MISSING
|
||||
alignTop: 'Superior',
|
||||
alignMiddle: 'Centre',
|
||||
alignBottom: 'Inferior',
|
||||
alignNone: 'Cap',
|
||||
invalidValue: 'Valor no vàlid.',
|
||||
invalidHeight: 'L\'alçada ha de ser un número.',
|
||||
invalidWidth: 'L\'amplada ha de ser un número.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: 'El valor especificat per als "%1" camps ha de ser un número positiu amb o sense unitat de mesura vàlida de CSS (px, %, in, cm, mm, em, ex, pt o pc).',
|
||||
invalidHtmlLength: 'El valor especificat per als "%1" camps ha de ser un número positiu amb o sense unitat de mesura vàlida d\'HTML (px o %).',
|
||||
invalidInlineStyle: 'El valor especificat per l\'estil en línia ha de constar d\'una o més tuples amb el format "name: value", separats per punt i coma.',
|
||||
cssLengthTooltip: 'Introduïu un número per un valor en píxels o un número amb una unitat vàlida de CSS (px, %, in, cm, mm, em, ex, pt o pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, no disponible</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Retrocés',
|
||||
13: 'Intro',
|
||||
16: 'Majúscules',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Space', // MISSING
|
||||
35: 'Fi',
|
||||
36: 'Inici',
|
||||
46: 'Eliminar',
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Command' // MISSING
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut', // MISSING
|
||||
|
||||
optionDefault: 'Default' // MISSING
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/cs.js
Normal file
154
Admin/plugins/ckeditor/lang/cs.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Czech language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'cs' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Textový editor',
|
||||
editorPanel: 'Panel textového editoru',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Stiskněte ALT 0 pro nápovědu',
|
||||
|
||||
browseServer: 'Vybrat na serveru',
|
||||
url: 'URL',
|
||||
protocol: 'Protokol',
|
||||
upload: 'Odeslat',
|
||||
uploadSubmit: 'Odeslat na server',
|
||||
image: 'Obrázek',
|
||||
form: 'Formulář',
|
||||
checkbox: 'Zaškrtávací políčko',
|
||||
radio: 'Přepínač',
|
||||
textField: 'Textové pole',
|
||||
textarea: 'Textová oblast',
|
||||
hiddenField: 'Skryté pole',
|
||||
button: 'Tlačítko',
|
||||
select: 'Seznam',
|
||||
imageButton: 'Obrázkové tlačítko',
|
||||
notSet: '<nenastaveno>',
|
||||
id: 'Id',
|
||||
name: 'Jméno',
|
||||
langDir: 'Směr jazyka',
|
||||
langDirLtr: 'Zleva doprava (LTR)',
|
||||
langDirRtl: 'Zprava doleva (RTL)',
|
||||
langCode: 'Kód jazyka',
|
||||
longDescr: 'Dlouhý popis URL',
|
||||
cssClass: 'Třída stylu',
|
||||
advisoryTitle: 'Pomocný titulek',
|
||||
cssStyle: 'Styl',
|
||||
ok: 'OK',
|
||||
cancel: 'Zrušit',
|
||||
close: 'Zavřít',
|
||||
preview: 'Náhled',
|
||||
resize: 'Uchopit pro změnu velikosti',
|
||||
generalTab: 'Obecné',
|
||||
advancedTab: 'Rozšířené',
|
||||
validateNumberFailed: 'Zadaná hodnota není číselná.',
|
||||
confirmNewPage: 'Jakékoliv neuložené změny obsahu budou ztraceny. Skutečně chcete otevřít novou stránku?',
|
||||
confirmCancel: 'Některá z nastavení byla změněna. Skutečně chcete zavřít dialogové okno?',
|
||||
options: 'Nastavení',
|
||||
target: 'Cíl',
|
||||
targetNew: 'Nové okno (_blank)',
|
||||
targetTop: 'Okno nejvyšší úrovně (_top)',
|
||||
targetSelf: 'Stejné okno (_self)',
|
||||
targetParent: 'Rodičovské okno (_parent)',
|
||||
langDirLTR: 'Zleva doprava (LTR)',
|
||||
langDirRTL: 'Zprava doleva (RTL)',
|
||||
styles: 'Styly',
|
||||
cssClasses: 'Třídy stylů',
|
||||
width: 'Šířka',
|
||||
height: 'Výška',
|
||||
align: 'Zarovnání',
|
||||
left: 'Vlevo',
|
||||
right: 'Vpravo',
|
||||
center: 'Na střed',
|
||||
justify: 'Zarovnat do bloku',
|
||||
alignLeft: 'Zarovnat vlevo',
|
||||
alignRight: 'Zarovnat vpravo',
|
||||
alignCenter: 'Zarovnat na střed',
|
||||
alignTop: 'Nahoru',
|
||||
alignMiddle: 'Na střed',
|
||||
alignBottom: 'Dolů',
|
||||
alignNone: 'Žádné',
|
||||
invalidValue: 'Neplatná hodnota.',
|
||||
invalidHeight: 'Zadaná výška musí být číslo.',
|
||||
invalidWidth: 'Šířka musí být číslo.',
|
||||
invalidLength: 'Hodnota určená pro pole "%1" musí být kladné číslo bez nebo s platnou jednotkou míry (%2).',
|
||||
invalidCssLength: 'Hodnota určená pro pole "%1" musí být kladné číslo bez nebo s platnou jednotkou míry CSS (px, %, in, cm, mm, em, ex, pt, nebo pc).',
|
||||
invalidHtmlLength: 'Hodnota určená pro pole "%1" musí být kladné číslo bez nebo s platnou jednotkou míry HTML (px nebo %).',
|
||||
invalidInlineStyle: 'Hodnota určená pro řádkový styl se musí skládat z jedné nebo více n-tic ve formátu "název : hodnota", oddělené středníky',
|
||||
cssLengthTooltip: 'Zadejte číslo jako hodnotu v pixelech nebo číslo s platnou jednotkou CSS (px, %, v cm, mm, em, ex, pt, nebo pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, nedostupné</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Enter',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Mezerník',
|
||||
35: 'Konec',
|
||||
36: 'Domů',
|
||||
46: 'Smazat',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Command'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Klávesová zkratka',
|
||||
|
||||
optionDefault: 'Výchozí'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/cy.js
Normal file
154
Admin/plugins/ckeditor/lang/cy.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Welsh language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'cy' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Golygydd Testun Cyfoethog',
|
||||
editorPanel: 'Panel Golygydd Testun Cyfoethog',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Gwasgwch ALT 0 am gymorth',
|
||||
|
||||
browseServer: 'Pori\'r Gweinydd',
|
||||
url: 'URL',
|
||||
protocol: 'Protocol',
|
||||
upload: 'Lanlwytho',
|
||||
uploadSubmit: 'Anfon i\'r Gweinydd',
|
||||
image: 'Delwedd',
|
||||
form: 'Ffurflen',
|
||||
checkbox: 'Blwch ticio',
|
||||
radio: 'Botwm Radio',
|
||||
textField: 'Maes Testun',
|
||||
textarea: 'Ardal Testun',
|
||||
hiddenField: 'Maes Cudd',
|
||||
button: 'Botwm',
|
||||
select: 'Maes Dewis',
|
||||
imageButton: 'Botwm Delwedd',
|
||||
notSet: '<heb osod>',
|
||||
id: 'Id',
|
||||
name: 'Name',
|
||||
langDir: 'Cyfeiriad Iaith',
|
||||
langDirLtr: 'Chwith i\'r Dde (LTR)',
|
||||
langDirRtl: 'Dde i\'r Chwith (RTL)',
|
||||
langCode: 'Cod Iaith',
|
||||
longDescr: 'URL Disgrifiad Hir',
|
||||
cssClass: 'Dosbarthiadau Dalen Arddull',
|
||||
advisoryTitle: 'Teitl Cynghorol',
|
||||
cssStyle: 'Arddull',
|
||||
ok: 'Iawn',
|
||||
cancel: 'Diddymu',
|
||||
close: 'Cau',
|
||||
preview: 'Rhagolwg',
|
||||
resize: 'Ailfeintio',
|
||||
generalTab: 'Cyffredinol',
|
||||
advancedTab: 'Uwch',
|
||||
validateNumberFailed: '\'Dyw\'r gwerth hwn ddim yn rhif.',
|
||||
confirmNewPage: 'Byddwch chi\'n colli unrhyw newidiadau i\'r cynnwys sydd heb eu cadw. Ydych am barhau i lwytho tudalen newydd?',
|
||||
confirmCancel: 'Cafodd rhai o\'r opsiynau eu newid. Ydych chi wir am gau\'r deialog?',
|
||||
options: 'Opsiynau',
|
||||
target: 'Targed',
|
||||
targetNew: 'Ffenest Newydd (_blank)',
|
||||
targetTop: 'Ffenest ar y Brig (_top)',
|
||||
targetSelf: 'Yr un Ffenest (_self)',
|
||||
targetParent: 'Ffenest y Rhiant (_parent)',
|
||||
langDirLTR: 'Chwith i\'r Dde (LTR)',
|
||||
langDirRTL: 'Dde i\'r Chwith (RTL)',
|
||||
styles: 'Arddull',
|
||||
cssClasses: 'Dosbarthiadau Dalen Arddull',
|
||||
width: 'Lled',
|
||||
height: 'Uchder',
|
||||
align: 'Alinio',
|
||||
left: 'Chwith',
|
||||
right: 'Dde',
|
||||
center: 'Canol',
|
||||
justify: 'Unioni',
|
||||
alignLeft: 'Alinio i\'r Chwith',
|
||||
alignRight: 'Alinio i\'r Dde',
|
||||
alignCenter: 'Align Center', // MISSING
|
||||
alignTop: 'Brig',
|
||||
alignMiddle: 'Canol',
|
||||
alignBottom: 'Gwaelod',
|
||||
alignNone: 'None', // MISSING
|
||||
invalidValue: 'Gwerth annilys.',
|
||||
invalidHeight: 'Mae\'n rhaid i\'r uchder fod yn rhif.',
|
||||
invalidWidth: 'Mae\'n rhaid i\'r lled fod yn rhif.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: 'Mae\'n rhaid i\'r gwerth ar gyfer maes "%1" fod yn rhif positif gyda neu heb uned fesuriad CSS dilys (px, %, in, cm, mm, em, ex, pt, neu pc).',
|
||||
invalidHtmlLength: 'Mae\'n rhaid i\'r gwerth ar gyfer maes "%1" fod yn rhif positif gyda neu heb uned fesuriad HTML dilys (px neu %).',
|
||||
invalidInlineStyle: 'Mae\'n rhaid i\'r gwerth ar gyfer arddull mewn-llinell gynnwys un set neu fwy ar y fformat "enw : gwerth", wedi\'u gwahanu gyda hanner colon.',
|
||||
cssLengthTooltip: 'Rhowch rif am werth mewn picsel neu rhif gydag uned CSS dilys (px, %, in, cm, mm, em, pt neu pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, ddim ar gael</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace', // MISSING
|
||||
13: 'Enter', // MISSING
|
||||
16: 'Shift', // MISSING
|
||||
17: 'Ctrl', // MISSING
|
||||
18: 'Alt', // MISSING
|
||||
32: 'Space', // MISSING
|
||||
35: 'End', // MISSING
|
||||
36: 'Home', // MISSING
|
||||
46: 'Delete', // MISSING
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Command' // MISSING
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut', // MISSING
|
||||
|
||||
optionDefault: 'Default' // MISSING
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/da.js
Normal file
154
Admin/plugins/ckeditor/lang/da.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Danish language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'da' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Rich Text Editor',
|
||||
editorPanel: 'Rich Text Editor panel',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Tryk ALT 0 for hjælp',
|
||||
|
||||
browseServer: 'Gennemse...',
|
||||
url: 'URL',
|
||||
protocol: 'Protokol',
|
||||
upload: 'Upload',
|
||||
uploadSubmit: 'Upload',
|
||||
image: 'Indsæt billede',
|
||||
form: 'Indsæt formular',
|
||||
checkbox: 'Indsæt afkrydsningsfelt',
|
||||
radio: 'Indsæt alternativknap',
|
||||
textField: 'Indsæt tekstfelt',
|
||||
textarea: 'Indsæt tekstboks',
|
||||
hiddenField: 'Indsæt skjult felt',
|
||||
button: 'Indsæt knap',
|
||||
select: 'Indsæt liste',
|
||||
imageButton: 'Indsæt billedknap',
|
||||
notSet: '<intet valgt>',
|
||||
id: 'Id',
|
||||
name: 'Navn',
|
||||
langDir: 'Tekstretning',
|
||||
langDirLtr: 'Fra venstre mod højre (LTR)',
|
||||
langDirRtl: 'Fra højre mod venstre (RTL)',
|
||||
langCode: 'Sprogkode',
|
||||
longDescr: 'Udvidet beskrivelse',
|
||||
cssClass: 'Typografiark (CSS)',
|
||||
advisoryTitle: 'Titel',
|
||||
cssStyle: 'Typografi (CSS)',
|
||||
ok: 'OK',
|
||||
cancel: 'Annullér',
|
||||
close: 'Luk',
|
||||
preview: 'Forhåndsvisning',
|
||||
resize: 'Træk for at skalere',
|
||||
generalTab: 'Generelt',
|
||||
advancedTab: 'Avanceret',
|
||||
validateNumberFailed: 'Værdien er ikke et tal.',
|
||||
confirmNewPage: 'Alt indhold, der ikke er blevet gemt, vil gå tabt. Er du sikker på, at du vil indlæse en ny side?',
|
||||
confirmCancel: 'Nogle af indstillingerne er blevet ændret. Er du sikker på, at du vil lukke vinduet?',
|
||||
options: 'Vis muligheder',
|
||||
target: 'Mål',
|
||||
targetNew: 'Nyt vindue (_blank)',
|
||||
targetTop: 'Øverste vindue (_top)',
|
||||
targetSelf: 'Samme vindue (_self)',
|
||||
targetParent: 'Samme vindue (_parent)',
|
||||
langDirLTR: 'Venstre til højre (LTR)',
|
||||
langDirRTL: 'Højre til venstre (RTL)',
|
||||
styles: 'Style',
|
||||
cssClasses: 'Stylesheetklasser',
|
||||
width: 'Bredde',
|
||||
height: 'Højde',
|
||||
align: 'Justering',
|
||||
left: 'Venstre',
|
||||
right: 'Højre',
|
||||
center: 'Center',
|
||||
justify: 'Lige margener',
|
||||
alignLeft: 'Venstrestillet',
|
||||
alignRight: 'Højrestillet',
|
||||
alignCenter: 'Centreret',
|
||||
alignTop: 'Øverst',
|
||||
alignMiddle: 'Centreret',
|
||||
alignBottom: 'Nederst',
|
||||
alignNone: 'Ingen',
|
||||
invalidValue: 'Ugyldig værdi.',
|
||||
invalidHeight: 'Højde skal være et tal.',
|
||||
invalidWidth: 'Bredde skal være et tal.',
|
||||
invalidLength: 'Værdien angivet for feltet "%1" skal være et positivt heltal med eller uden en gyldig måleenhed (%2).',
|
||||
invalidCssLength: 'Værdien specificeret for "%1" feltet skal være et positivt nummer med eller uden en CSS måleenhed (px, %, in, cm, mm, em, ex, pt, eller pc).',
|
||||
invalidHtmlLength: 'Værdien specificeret for "%1" feltet skal være et positivt nummer med eller uden en CSS måleenhed (px eller %).',
|
||||
invalidInlineStyle: 'Værdien specificeret for inline style skal indeholde en eller flere elementer med et format som "name:value", separeret af semikoloner',
|
||||
cssLengthTooltip: 'Indsæt en numerisk værdi i pixel eller nummer med en gyldig CSS værdi (px, %, in, cm, mm, em, ex, pt, eller pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, ikke tilgængelig</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Retur',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Mellemrum',
|
||||
35: 'Slut',
|
||||
36: 'Hjem',
|
||||
46: 'Slet',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Kommando'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Tastatur genvej',
|
||||
|
||||
optionDefault: 'Standard'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
153
Admin/plugins/ckeditor/lang/de-ch.js
Normal file
153
Admin/plugins/ckeditor/lang/de-ch.js
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'de-ch' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'WYSIWYG-Editor',
|
||||
editorPanel: 'WYSIWYG-Editor-Leiste',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Drücken Sie ALT 0 für Hilfe',
|
||||
|
||||
browseServer: 'Server durchsuchen',
|
||||
url: 'URL',
|
||||
protocol: 'Protokoll',
|
||||
upload: 'Hochladen',
|
||||
uploadSubmit: 'Zum Server senden',
|
||||
image: 'Bild',
|
||||
form: 'Formular',
|
||||
checkbox: 'Kontrollbox',
|
||||
radio: 'Optionsfeld',
|
||||
textField: 'Textfeld',
|
||||
textarea: 'Textfeld',
|
||||
hiddenField: 'Verstecktes Feld',
|
||||
button: 'Schaltfläche',
|
||||
select: 'Auswahlfeld',
|
||||
imageButton: 'Bildschaltfläche',
|
||||
notSet: '<nicht festgelegt>',
|
||||
id: 'Kennung',
|
||||
name: 'Name',
|
||||
langDir: 'Schreibrichtung',
|
||||
langDirLtr: 'Links nach Rechts (LTR)',
|
||||
langDirRtl: 'Rechts nach Links (RTL)',
|
||||
langCode: 'Sprachcode',
|
||||
longDescr: 'Langbeschreibungs-URL',
|
||||
cssClass: 'Formatvorlagenklassen',
|
||||
advisoryTitle: 'Titel Beschreibung',
|
||||
cssStyle: 'Stil',
|
||||
ok: 'OK',
|
||||
cancel: 'Abbrechen',
|
||||
close: 'Schliessen',
|
||||
preview: 'Vorschau',
|
||||
resize: 'Grösse ändern',
|
||||
generalTab: 'Allgemein',
|
||||
advancedTab: 'Erweitert',
|
||||
validateNumberFailed: 'Dieser Wert ist keine Nummer.',
|
||||
confirmNewPage: 'Alle nicht gespeicherten Änderungen gehen verloren. Sind Sie sicher, die neue Seite zu laden?',
|
||||
confirmCancel: 'Einige Optionen wurden geändert. Wollen Sie den Dialog dennoch schliessen?',
|
||||
options: 'Optionen',
|
||||
target: 'Zielseite',
|
||||
targetNew: 'Neues Fenster (_blank)',
|
||||
targetTop: 'Oberstes Fenster (_top)',
|
||||
targetSelf: 'Gleiches Fenster (_self)',
|
||||
targetParent: 'Oberes Fenster (_parent)',
|
||||
langDirLTR: 'Links nach Rechts (LNR)',
|
||||
langDirRTL: 'Rechts nach Links (RNL)',
|
||||
styles: 'Style',
|
||||
cssClasses: 'Stylesheet Klasse',
|
||||
width: 'Breite',
|
||||
height: 'Höhe',
|
||||
align: 'Ausrichtung',
|
||||
left: 'Links',
|
||||
right: 'Rechts',
|
||||
center: 'Zentriert',
|
||||
justify: 'Blocksatz',
|
||||
alignLeft: 'Linksbündig',
|
||||
alignRight: 'Rechtsbündig',
|
||||
alignCenter: 'Zentriert',
|
||||
alignTop: 'Oben',
|
||||
alignMiddle: 'Mitte',
|
||||
alignBottom: 'Unten',
|
||||
alignNone: 'Keine',
|
||||
invalidValue: 'Ungültiger Wert.',
|
||||
invalidHeight: 'Höhe muss eine Zahl sein.',
|
||||
invalidWidth: 'Breite muss eine Zahl sein.',
|
||||
invalidLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekter HTML-Masseinheit (px oder %).',
|
||||
invalidCssLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekter CSS-Masseinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
|
||||
invalidHtmlLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekter HTML-Masseinheit (px oder %).',
|
||||
invalidInlineStyle: 'Wert spezifiziert für inline Stilart muss enthalten ein oder mehr Wertepaare mit dem Format "Name : Wert" getrennt durch Semikolons.',
|
||||
cssLengthTooltip: 'Geben Sie eine Zahl ein für ein Wert in Pixel oder eine Zahl mit einer korrekten CSS-Masseinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, nicht verfügbar</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Rücktaste',
|
||||
13: 'Eingabe',
|
||||
16: 'Umschalt',
|
||||
17: 'Strg',
|
||||
18: 'Alt',
|
||||
32: 'Leertaste',
|
||||
35: 'Ende',
|
||||
36: 'Pos1',
|
||||
46: 'Entfernen',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Befehl'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Tastaturkürzel',
|
||||
|
||||
optionDefault: 'Standard'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/de.js
Normal file
154
Admin/plugins/ckeditor/lang/de.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* German language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'de' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'WYSIWYG-Editor',
|
||||
editorPanel: 'WYSIWYG-Editor-Leiste',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Drücken Sie ALT 0 für Hilfe',
|
||||
|
||||
browseServer: 'Server durchsuchen',
|
||||
url: 'URL',
|
||||
protocol: 'Protokoll',
|
||||
upload: 'Hochladen',
|
||||
uploadSubmit: 'Zum Server senden',
|
||||
image: 'Bild',
|
||||
form: 'Formular',
|
||||
checkbox: 'Kontrollbox',
|
||||
radio: 'Optionsfeld',
|
||||
textField: 'Textfeld',
|
||||
textarea: 'Textfeld',
|
||||
hiddenField: 'Verstecktes Feld',
|
||||
button: 'Schaltfläche',
|
||||
select: 'Auswahlfeld',
|
||||
imageButton: 'Bildschaltfläche',
|
||||
notSet: '<nicht festgelegt>',
|
||||
id: 'Kennung',
|
||||
name: 'Name',
|
||||
langDir: 'Schreibrichtung',
|
||||
langDirLtr: 'Links nach Rechts (LTR)',
|
||||
langDirRtl: 'Rechts nach Links (RTL)',
|
||||
langCode: 'Sprachcode',
|
||||
longDescr: 'Langbeschreibungs-URL',
|
||||
cssClass: 'Formatvorlagenklassen',
|
||||
advisoryTitle: 'Titel Beschreibung',
|
||||
cssStyle: 'Stil',
|
||||
ok: 'OK',
|
||||
cancel: 'Abbrechen',
|
||||
close: 'Schließen',
|
||||
preview: 'Vorschau',
|
||||
resize: 'Größe ändern',
|
||||
generalTab: 'Allgemein',
|
||||
advancedTab: 'Erweitert',
|
||||
validateNumberFailed: 'Dieser Wert ist keine Nummer.',
|
||||
confirmNewPage: 'Alle nicht gespeicherten Änderungen gehen verloren. Sind Sie sicher, die neue Seite zu laden?',
|
||||
confirmCancel: 'Einige Optionen wurden geändert. Wollen Sie den Dialog dennoch schließen?',
|
||||
options: 'Optionen',
|
||||
target: 'Zielseite',
|
||||
targetNew: 'Neues Fenster (_blank)',
|
||||
targetTop: 'Oberstes Fenster (_top)',
|
||||
targetSelf: 'Gleiches Fenster (_self)',
|
||||
targetParent: 'Oberes Fenster (_parent)',
|
||||
langDirLTR: 'Links nach Rechts (LNR)',
|
||||
langDirRTL: 'Rechts nach Links (RNL)',
|
||||
styles: 'Style',
|
||||
cssClasses: 'Stylesheet Klasse',
|
||||
width: 'Breite',
|
||||
height: 'Höhe',
|
||||
align: 'Ausrichtung',
|
||||
left: 'Links',
|
||||
right: 'Rechts',
|
||||
center: 'Zentriert',
|
||||
justify: 'Blocksatz',
|
||||
alignLeft: 'Linksbündig',
|
||||
alignRight: 'Rechtsbündig',
|
||||
alignCenter: 'Zentriert',
|
||||
alignTop: 'Oben',
|
||||
alignMiddle: 'Mitte',
|
||||
alignBottom: 'Unten',
|
||||
alignNone: 'Keine',
|
||||
invalidValue: 'Ungültiger Wert.',
|
||||
invalidHeight: 'Höhe muss eine Zahl sein.',
|
||||
invalidWidth: 'Breite muss eine Zahl sein.',
|
||||
invalidLength: 'Der für das Feld "%1" angegebene Wert muss eine positive Zahl mit oder ohne gültige Maßeinheit (%2) sein. ',
|
||||
invalidCssLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
|
||||
invalidHtmlLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte HTML Messeinheit (px oder %).',
|
||||
invalidInlineStyle: 'Wert spezifiziert für inline Stilart muss enthalten ein oder mehr Tupels mit dem Format "Name : Wert" getrennt mit Semikolons.',
|
||||
cssLengthTooltip: 'Gebe eine Zahl ein für ein Wert in pixels oder eine Zahl mit einer korrekten CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, nicht verfügbar</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Rücktaste',
|
||||
13: 'Eingabe',
|
||||
16: 'Umschalt',
|
||||
17: 'Strg',
|
||||
18: 'Alt',
|
||||
32: 'Leer',
|
||||
35: 'Ende',
|
||||
36: 'Pos1',
|
||||
46: 'Entfernen',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Befehl'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Tastaturkürzel',
|
||||
|
||||
optionDefault: 'Standard'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/el.js
Normal file
154
Admin/plugins/ckeditor/lang/el.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Greek language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'el' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Επεξεργαστής Πλούσιου Κειμένου',
|
||||
editorPanel: 'Πίνακας Επεξεργαστή Πλούσιου Κειμένου',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Πατήστε το ALT 0 για βοήθεια',
|
||||
|
||||
browseServer: 'Εξερεύνηση Διακομιστή',
|
||||
url: 'URL',
|
||||
protocol: 'Πρωτόκολλο',
|
||||
upload: 'Αποστολή',
|
||||
uploadSubmit: 'Αποστολή στον Διακομιστή',
|
||||
image: 'Εικόνα',
|
||||
form: 'Φόρμα',
|
||||
checkbox: 'Κουτί Επιλογής',
|
||||
radio: 'Κουμπί Επιλογής',
|
||||
textField: 'Πεδίο Κειμένου',
|
||||
textarea: 'Περιοχή Κειμένου',
|
||||
hiddenField: 'Κρυφό Πεδίο',
|
||||
button: 'Κουμπί',
|
||||
select: 'Πεδίο Επιλογής',
|
||||
imageButton: 'Κουμπί Εικόνας',
|
||||
notSet: '<δεν έχει ρυθμιστεί>',
|
||||
id: 'Id',
|
||||
name: 'Όνομα',
|
||||
langDir: 'Κατεύθυνση Κειμένου',
|
||||
langDirLtr: 'Αριστερά προς Δεξιά (LTR)',
|
||||
langDirRtl: 'Δεξιά προς Αριστερά (RTL)',
|
||||
langCode: 'Κωδικός Γλώσσας',
|
||||
longDescr: 'Αναλυτική Περιγραφή URL',
|
||||
cssClass: 'Κλάσεις Φύλλων Στυλ',
|
||||
advisoryTitle: 'Ενδεικτικός Τίτλος',
|
||||
cssStyle: 'Μορφή Κειμένου',
|
||||
ok: 'OK',
|
||||
cancel: 'Ακύρωση',
|
||||
close: 'Κλείσιμο',
|
||||
preview: 'Προεπισκόπηση',
|
||||
resize: 'Αλλαγή Μεγέθους',
|
||||
generalTab: 'Γενικά',
|
||||
advancedTab: 'Για Προχωρημένους',
|
||||
validateNumberFailed: 'Αυτή η τιμή δεν είναι αριθμός.',
|
||||
confirmNewPage: 'Οι όποιες αλλαγές στο περιεχόμενο θα χαθούν. Είσαστε σίγουροι ότι θέλετε να φορτώσετε μια νέα σελίδα;',
|
||||
confirmCancel: 'Μερικές επιλογές έχουν αλλάξει. Είσαστε σίγουροι ότι θέλετε να κλείσετε το παράθυρο διαλόγου;',
|
||||
options: 'Επιλογές',
|
||||
target: 'Προορισμός',
|
||||
targetNew: 'Νέο Παράθυρο (_blank)',
|
||||
targetTop: 'Αρχική Περιοχή (_top)',
|
||||
targetSelf: 'Ίδιο Παράθυρο (_self)',
|
||||
targetParent: 'Γονεϊκό Παράθυρο (_parent)',
|
||||
langDirLTR: 'Αριστερά προς Δεξιά (LTR)',
|
||||
langDirRTL: 'Δεξιά προς Αριστερά (RTL)',
|
||||
styles: 'Μορφή',
|
||||
cssClasses: 'Κλάσεις Φύλλων Στυλ',
|
||||
width: 'Πλάτος',
|
||||
height: 'Ύψος',
|
||||
align: 'Στοίχιση',
|
||||
left: 'Αριστερά',
|
||||
right: 'Δεξιά',
|
||||
center: 'Κέντρο',
|
||||
justify: 'Πλήρης Στοίχιση',
|
||||
alignLeft: 'Στοίχιση Αριστερά',
|
||||
alignRight: 'Στοίχιση Δεξιά',
|
||||
alignCenter: 'Στοίχιση στο κέντρο',
|
||||
alignTop: 'Πάνω',
|
||||
alignMiddle: 'Μέση',
|
||||
alignBottom: 'Κάτω',
|
||||
alignNone: 'Χωρίς',
|
||||
invalidValue: 'Μη έγκυρη τιμή.',
|
||||
invalidHeight: 'Το ύψος πρέπει να είναι ένας αριθμός.',
|
||||
invalidWidth: 'Το πλάτος πρέπει να είναι ένας αριθμός.',
|
||||
invalidLength: 'Η τιμή που ορίζεται στο πεδίο «%1» πρέπει να είναι θετικός αριθμός με ή χωρίς μονάδα μέτρησης (%2).',
|
||||
invalidCssLength: 'Η τιμή που ορίζεται για το πεδίο "%1" πρέπει να είναι ένας θετικός αριθμός με ή χωρίς μια έγκυρη μονάδα μέτρησης CSS (px, %, in, cm, mm, em, ex, pt, ή pc).',
|
||||
invalidHtmlLength: 'Η τιμή που ορίζεται για το πεδίο "%1" πρέπει να είναι ένας θετικός αριθμός με ή χωρίς μια έγκυρη μονάδα μέτρησης HTML (px ή %).',
|
||||
invalidInlineStyle: 'Η τιμή για το εν σειρά στυλ πρέπει να περιέχει ένα ή περισσότερα ζεύγη με την μορφή "όνομα: τιμή" διαχωρισμένα με Ελληνικό ερωτηματικό.',
|
||||
cssLengthTooltip: 'Εισάγεται μια τιμή σε pixel ή έναν αριθμό μαζί με μια έγκυρη μονάδα μέτρησης CSS (px, %, in, cm, mm, em, ex, pt, ή pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, δεν είναι διαθέσιμο</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Enter',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Κενό',
|
||||
35: 'End',
|
||||
36: 'Home',
|
||||
46: 'Delete',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Εντολή'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Συντόμευση πληκτρολογίου',
|
||||
|
||||
optionDefault: 'Προεπιλογή'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/en-au.js
Normal file
154
Admin/plugins/ckeditor/lang/en-au.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* English (Australia) language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'en-au' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor',
|
||||
editor: 'Editor',
|
||||
editorPanel: 'Rich Text Editor panel',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Press ALT 0 for help',
|
||||
|
||||
browseServer: 'Browse Server',
|
||||
url: 'URL',
|
||||
protocol: 'Protocol',
|
||||
upload: 'Upload',
|
||||
uploadSubmit: 'Send it to the Server',
|
||||
image: 'Image',
|
||||
form: 'Form',
|
||||
checkbox: 'Checkbox',
|
||||
radio: 'Radio Button',
|
||||
textField: 'Text Field',
|
||||
textarea: 'Textarea',
|
||||
hiddenField: 'Hidden Field',
|
||||
button: 'Button',
|
||||
select: 'Selection Field',
|
||||
imageButton: 'Image Button',
|
||||
notSet: '<not set>',
|
||||
id: 'Id',
|
||||
name: 'Name',
|
||||
langDir: 'Language Direction',
|
||||
langDirLtr: 'Left to Right (LTR)',
|
||||
langDirRtl: 'Right to Left (RTL)',
|
||||
langCode: 'Language Code',
|
||||
longDescr: 'Long Description URL',
|
||||
cssClass: 'Stylesheet Classes',
|
||||
advisoryTitle: 'Advisory Title',
|
||||
cssStyle: 'Style',
|
||||
ok: 'OK',
|
||||
cancel: 'Cancel',
|
||||
close: 'Close',
|
||||
preview: 'Preview',
|
||||
resize: 'Resize',
|
||||
generalTab: 'General',
|
||||
advancedTab: 'Advanced',
|
||||
validateNumberFailed: 'This value is not a number.',
|
||||
confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
|
||||
confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
|
||||
options: 'Options',
|
||||
target: 'Target',
|
||||
targetNew: 'New Window (_blank)',
|
||||
targetTop: 'Topmost Window (_top)',
|
||||
targetSelf: 'Same Window (_self)',
|
||||
targetParent: 'Parent Window (_parent)',
|
||||
langDirLTR: 'Left to Right (LTR)',
|
||||
langDirRTL: 'Right to Left (RTL)',
|
||||
styles: 'Style',
|
||||
cssClasses: 'Stylesheet Classes',
|
||||
width: 'Width',
|
||||
height: 'Height',
|
||||
align: 'Align',
|
||||
left: 'Left',
|
||||
right: 'Right',
|
||||
center: 'Centre',
|
||||
justify: 'Justify',
|
||||
alignLeft: 'Align Left',
|
||||
alignRight: 'Align Right',
|
||||
alignCenter: 'Align Centre',
|
||||
alignTop: 'Top',
|
||||
alignMiddle: 'Middle',
|
||||
alignBottom: 'Bottom',
|
||||
alignNone: 'None',
|
||||
invalidValue: 'Invalid value.',
|
||||
invalidHeight: 'Height must be a number.',
|
||||
invalidWidth: 'Width must be a number.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).',
|
||||
invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).',
|
||||
invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.',
|
||||
cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, unavailable</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Enter',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Space',
|
||||
35: 'End',
|
||||
36: 'Home',
|
||||
46: 'Delete',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Command'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut',
|
||||
|
||||
optionDefault: 'Default'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/en-ca.js
Normal file
154
Admin/plugins/ckeditor/lang/en-ca.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* English (Canadian) language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'en-ca' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Editor', // MISSING
|
||||
editorPanel: 'Rich Text Editor panel', // MISSING
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Press ALT 0 for help', // MISSING
|
||||
|
||||
browseServer: 'Browse Server',
|
||||
url: 'URL',
|
||||
protocol: 'Protocol',
|
||||
upload: 'Upload',
|
||||
uploadSubmit: 'Send it to the Server',
|
||||
image: 'Image',
|
||||
form: 'Form',
|
||||
checkbox: 'Checkbox',
|
||||
radio: 'Radio Button',
|
||||
textField: 'Text Field',
|
||||
textarea: 'Textarea',
|
||||
hiddenField: 'Hidden Field',
|
||||
button: 'Button',
|
||||
select: 'Selection Field',
|
||||
imageButton: 'Image Button',
|
||||
notSet: '<not set>',
|
||||
id: 'Id',
|
||||
name: 'Name',
|
||||
langDir: 'Language Direction',
|
||||
langDirLtr: 'Left to Right (LTR)',
|
||||
langDirRtl: 'Right to Left (RTL)',
|
||||
langCode: 'Language Code',
|
||||
longDescr: 'Long Description URL',
|
||||
cssClass: 'Stylesheet Classes',
|
||||
advisoryTitle: 'Advisory Title',
|
||||
cssStyle: 'Style',
|
||||
ok: 'OK',
|
||||
cancel: 'Cancel',
|
||||
close: 'Close', // MISSING
|
||||
preview: 'Preview',
|
||||
resize: 'Resize', // MISSING
|
||||
generalTab: 'General',
|
||||
advancedTab: 'Advanced',
|
||||
validateNumberFailed: 'This value is not a number.',
|
||||
confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
|
||||
confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
|
||||
options: 'Options', // MISSING
|
||||
target: 'Target',
|
||||
targetNew: 'New Window (_blank)', // MISSING
|
||||
targetTop: 'Topmost Window (_top)', // MISSING
|
||||
targetSelf: 'Same Window (_self)', // MISSING
|
||||
targetParent: 'Parent Window (_parent)', // MISSING
|
||||
langDirLTR: 'Left to Right (LTR)',
|
||||
langDirRTL: 'Right to Left (RTL)',
|
||||
styles: 'Style',
|
||||
cssClasses: 'Stylesheet Classes',
|
||||
width: 'Width', // MISSING
|
||||
height: 'Height', // MISSING
|
||||
align: 'Align',
|
||||
left: 'Left', // MISSING
|
||||
right: 'Right', // MISSING
|
||||
center: 'Centre',
|
||||
justify: 'Justify',
|
||||
alignLeft: 'Align Left',
|
||||
alignRight: 'Align Right',
|
||||
alignCenter: 'Align Center', // MISSING
|
||||
alignTop: 'Top', // MISSING
|
||||
alignMiddle: 'Middle', // MISSING
|
||||
alignBottom: 'Bottom', // MISSING
|
||||
alignNone: 'None', // MISSING
|
||||
invalidValue: 'Invalid value.', // MISSING
|
||||
invalidHeight: 'Height must be a number.', // MISSING
|
||||
invalidWidth: 'Width must be a number.', // MISSING
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
|
||||
invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
|
||||
invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
|
||||
cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace', // MISSING
|
||||
13: 'Enter', // MISSING
|
||||
16: 'Shift', // MISSING
|
||||
17: 'Ctrl', // MISSING
|
||||
18: 'Alt', // MISSING
|
||||
32: 'Space', // MISSING
|
||||
35: 'End', // MISSING
|
||||
36: 'Home', // MISSING
|
||||
46: 'Delete', // MISSING
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Command' // MISSING
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut', // MISSING
|
||||
|
||||
optionDefault: 'Default' // MISSING
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/en-gb.js
Normal file
154
Admin/plugins/ckeditor/lang/en-gb.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* English (United Kingdom) language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'en-gb' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Rich Text Editor',
|
||||
editorPanel: 'Rich Text Editor panel',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Press ALT 0 for help',
|
||||
|
||||
browseServer: 'Browse Server',
|
||||
url: 'URL',
|
||||
protocol: 'Protocol',
|
||||
upload: 'Upload',
|
||||
uploadSubmit: 'Send it to the Server',
|
||||
image: 'Image',
|
||||
form: 'Form',
|
||||
checkbox: 'Checkbox',
|
||||
radio: 'Radio Button',
|
||||
textField: 'Text Field',
|
||||
textarea: 'Textarea',
|
||||
hiddenField: 'Hidden Field',
|
||||
button: 'Button',
|
||||
select: 'Selection Field',
|
||||
imageButton: 'Image Button',
|
||||
notSet: '<not set>',
|
||||
id: 'Id',
|
||||
name: 'Name',
|
||||
langDir: 'Language Direction',
|
||||
langDirLtr: 'Left to Right (LTR)',
|
||||
langDirRtl: 'Right to Left (RTL)',
|
||||
langCode: 'Language Code',
|
||||
longDescr: 'Long Description URL',
|
||||
cssClass: 'Stylesheet Classes',
|
||||
advisoryTitle: 'Advisory Title',
|
||||
cssStyle: 'Style',
|
||||
ok: 'OK',
|
||||
cancel: 'Cancel',
|
||||
close: 'Close',
|
||||
preview: 'Preview',
|
||||
resize: 'Drag to resize',
|
||||
generalTab: 'General',
|
||||
advancedTab: 'Advanced',
|
||||
validateNumberFailed: 'This value is not a number.',
|
||||
confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
|
||||
confirmCancel: 'You have changed some options. Are you sure you want to close the dialogue window?',
|
||||
options: 'Options',
|
||||
target: 'Target',
|
||||
targetNew: 'New Window (_blank)',
|
||||
targetTop: 'Topmost Window (_top)',
|
||||
targetSelf: 'Same Window (_self)',
|
||||
targetParent: 'Parent Window (_parent)',
|
||||
langDirLTR: 'Left to Right (LTR)',
|
||||
langDirRTL: 'Right to Left (RTL)',
|
||||
styles: 'Style',
|
||||
cssClasses: 'Stylesheet Classes',
|
||||
width: 'Width',
|
||||
height: 'Height',
|
||||
align: 'Align',
|
||||
left: 'Left', // MISSING
|
||||
right: 'Right', // MISSING
|
||||
center: 'Centre',
|
||||
justify: 'Justify', // MISSING
|
||||
alignLeft: 'Align Left', // MISSING
|
||||
alignRight: 'Align Right', // MISSING
|
||||
alignCenter: 'Align Centre',
|
||||
alignTop: 'Top',
|
||||
alignMiddle: 'Middle',
|
||||
alignBottom: 'Bottom',
|
||||
alignNone: 'None',
|
||||
invalidValue: 'Invalid value.',
|
||||
invalidHeight: 'Height must be a number.',
|
||||
invalidWidth: 'Width must be a number.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).',
|
||||
invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.',
|
||||
cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, unavailable</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace', // MISSING
|
||||
13: 'Enter', // MISSING
|
||||
16: 'Shift', // MISSING
|
||||
17: 'Ctrl', // MISSING
|
||||
18: 'Alt', // MISSING
|
||||
32: 'Space', // MISSING
|
||||
35: 'End', // MISSING
|
||||
36: 'Home', // MISSING
|
||||
46: 'Delete', // MISSING
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Command' // MISSING
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut', // MISSING
|
||||
|
||||
optionDefault: 'Default' // MISSING
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/en.js
Normal file
154
Admin/plugins/ckeditor/lang/en.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object for the English
|
||||
* language. This is the base file for all translations.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'en' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor',
|
||||
editor: 'Editor',
|
||||
editorPanel: 'Rich Text Editor panel',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Press ALT 0 for help',
|
||||
|
||||
browseServer: 'Browse Server',
|
||||
url: 'URL',
|
||||
protocol: 'Protocol',
|
||||
upload: 'Upload',
|
||||
uploadSubmit: 'Send it to the Server',
|
||||
image: 'Image',
|
||||
form: 'Form',
|
||||
checkbox: 'Checkbox',
|
||||
radio: 'Radio Button',
|
||||
textField: 'Text Field',
|
||||
textarea: 'Textarea',
|
||||
hiddenField: 'Hidden Field',
|
||||
button: 'Button',
|
||||
select: 'Selection Field',
|
||||
imageButton: 'Image Button',
|
||||
notSet: '<not set>',
|
||||
id: 'Id',
|
||||
name: 'Name',
|
||||
langDir: 'Language Direction',
|
||||
langDirLtr: 'Left to Right (LTR)',
|
||||
langDirRtl: 'Right to Left (RTL)',
|
||||
langCode: 'Language Code',
|
||||
longDescr: 'Long Description URL',
|
||||
cssClass: 'Stylesheet Classes',
|
||||
advisoryTitle: 'Advisory Title',
|
||||
cssStyle: 'Style',
|
||||
ok: 'OK',
|
||||
cancel: 'Cancel',
|
||||
close: 'Close',
|
||||
preview: 'Preview',
|
||||
resize: 'Resize',
|
||||
generalTab: 'General',
|
||||
advancedTab: 'Advanced',
|
||||
validateNumberFailed: 'This value is not a number.',
|
||||
confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
|
||||
confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
|
||||
options: 'Options',
|
||||
target: 'Target',
|
||||
targetNew: 'New Window (_blank)',
|
||||
targetTop: 'Topmost Window (_top)',
|
||||
targetSelf: 'Same Window (_self)',
|
||||
targetParent: 'Parent Window (_parent)',
|
||||
langDirLTR: 'Left to Right (LTR)',
|
||||
langDirRTL: 'Right to Left (RTL)',
|
||||
styles: 'Style',
|
||||
cssClasses: 'Stylesheet Classes',
|
||||
width: 'Width',
|
||||
height: 'Height',
|
||||
align: 'Alignment',
|
||||
left: 'Left',
|
||||
right: 'Right',
|
||||
center: 'Center',
|
||||
justify: 'Justify',
|
||||
alignLeft: 'Align Left',
|
||||
alignRight: 'Align Right',
|
||||
alignCenter: 'Align Center',
|
||||
alignTop: 'Top',
|
||||
alignMiddle: 'Middle',
|
||||
alignBottom: 'Bottom',
|
||||
alignNone: 'None',
|
||||
invalidValue: 'Invalid value.',
|
||||
invalidHeight: 'Height must be a number.',
|
||||
invalidWidth: 'Width must be a number.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).',
|
||||
invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).',
|
||||
invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.',
|
||||
cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, unavailable</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Enter',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Space',
|
||||
35: 'End',
|
||||
36: 'Home',
|
||||
46: 'Delete',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Command'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Keyboard shortcut',
|
||||
|
||||
optionDefault: 'Default'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.',
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link',
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>',
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>'
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/eo.js
Normal file
154
Admin/plugins/ckeditor/lang/eo.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Esperanto language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'eo' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'RiĉTeksta Redaktilo',
|
||||
editorPanel: 'Panelo de la RiĉTeksta Redaktilo',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Premu ALT 0 por helpilo',
|
||||
|
||||
browseServer: 'Foliumi en la Servilo',
|
||||
url: 'URL',
|
||||
protocol: 'Protokolo',
|
||||
upload: 'Alŝuti',
|
||||
uploadSubmit: 'Sendu al Servilo',
|
||||
image: 'Bildo',
|
||||
form: 'Formularo',
|
||||
checkbox: 'Markobutono',
|
||||
radio: 'Radiobutono',
|
||||
textField: 'Teksta kampo',
|
||||
textarea: 'Teksta Areo',
|
||||
hiddenField: 'Kaŝita Kampo',
|
||||
button: 'Butono',
|
||||
select: 'Elekta Kampo',
|
||||
imageButton: 'Bildbutono',
|
||||
notSet: '<Defaŭlta>',
|
||||
id: 'Id',
|
||||
name: 'Nomo',
|
||||
langDir: 'Skribdirekto',
|
||||
langDirLtr: 'De maldekstro dekstren (LTR)',
|
||||
langDirRtl: 'De dekstro maldekstren (RTL)',
|
||||
langCode: 'Lingva Kodo',
|
||||
longDescr: 'URL de Longa Priskribo',
|
||||
cssClass: 'Klasoj de Stilfolioj',
|
||||
advisoryTitle: 'Priskriba Titolo',
|
||||
cssStyle: 'Stilo',
|
||||
ok: 'Akcepti',
|
||||
cancel: 'Rezigni',
|
||||
close: 'Fermi',
|
||||
preview: 'Vidigi Aspekton',
|
||||
resize: 'Movigi por ŝanĝi la grandon',
|
||||
generalTab: 'Ĝenerala',
|
||||
advancedTab: 'Speciala',
|
||||
validateNumberFailed: 'Tiu valoro ne estas nombro.',
|
||||
confirmNewPage: 'La neregistritaj ŝanĝoj estas perdotaj. Ĉu vi certas, ke vi volas ŝargi novan paĝon?',
|
||||
confirmCancel: 'Iuj opcioj esta ŝanĝitaj. Ĉu vi certas, ke vi volas fermi la dialogon?',
|
||||
options: 'Opcioj',
|
||||
target: 'Celo',
|
||||
targetNew: 'Nova Fenestro (_blank)',
|
||||
targetTop: 'Supra Fenestro (_top)',
|
||||
targetSelf: 'Sama Fenestro (_self)',
|
||||
targetParent: 'Patra Fenestro (_parent)',
|
||||
langDirLTR: 'De maldekstro dekstren (LTR)',
|
||||
langDirRTL: 'De dekstro maldekstren (RTL)',
|
||||
styles: 'Stilo',
|
||||
cssClasses: 'Stilfoliaj Klasoj',
|
||||
width: 'Larĝo',
|
||||
height: 'Alto',
|
||||
align: 'Ĝisrandigo',
|
||||
left: 'Maldekstre',
|
||||
right: 'Dekstre',
|
||||
center: 'Centre',
|
||||
justify: 'Ĝisrandigi Ambaŭflanke',
|
||||
alignLeft: 'Ĝisrandigi maldekstren',
|
||||
alignRight: 'Ĝisrandigi dekstren',
|
||||
alignCenter: 'Align Center', // MISSING
|
||||
alignTop: 'Supre',
|
||||
alignMiddle: 'Centre',
|
||||
alignBottom: 'Malsupre',
|
||||
alignNone: 'Neniu',
|
||||
invalidValue: 'Nevalida Valoro',
|
||||
invalidHeight: 'Alto devas esti nombro.',
|
||||
invalidWidth: 'Larĝo devas esti nombro.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: 'La valoro indikita por la "%1" kampo devas esti pozitiva nombro kun aŭ sen valida CSSmezurunuo (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
invalidHtmlLength: 'La valoro indikita por la "%1" kampo devas esti pozitiva nombro kun aŭ sen valida HTMLmezurunuo (px or %).',
|
||||
invalidInlineStyle: 'La valoro indikita por la enlinia stilo devas konsisti el unu aŭ pluraj elementoj kun la formato de "nomo : valoro", apartigitaj per punktokomoj.',
|
||||
cssLengthTooltip: 'Entajpu nombron por rastrumera valoro aŭ nombron kun valida CSSunuo (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, nehavebla</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Retropaŝo',
|
||||
13: 'Enigi',
|
||||
16: 'Registrumo',
|
||||
17: 'Stirklavo',
|
||||
18: 'Alt-klavo',
|
||||
32: 'Spaco',
|
||||
35: 'Fino',
|
||||
36: 'Hejmo',
|
||||
46: 'Forigi',
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Komando'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Fulmoklavo',
|
||||
|
||||
optionDefault: 'Defaŭlta'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
153
Admin/plugins/ckeditor/lang/es-mx.js
Normal file
153
Admin/plugins/ckeditor/lang/es-mx.js
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'es-mx' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Editor de texto enriquecido',
|
||||
editorPanel: 'Panel del editor de texto',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Presiona ALT + 0 para ayuda',
|
||||
|
||||
browseServer: 'Examinar servidor',
|
||||
url: 'URL',
|
||||
protocol: 'Protocolo',
|
||||
upload: 'Subir',
|
||||
uploadSubmit: 'Enviar al servidor',
|
||||
image: 'Imagen',
|
||||
form: 'Formulario',
|
||||
checkbox: 'Casilla de verificación',
|
||||
radio: 'Botón de opción',
|
||||
textField: 'Campo de texto',
|
||||
textarea: 'Área de texto',
|
||||
hiddenField: 'Campo oculto',
|
||||
button: 'Botón',
|
||||
select: 'Campo de selección',
|
||||
imageButton: 'Botón de imagen',
|
||||
notSet: '<not set>',
|
||||
id: 'Id',
|
||||
name: 'Nombre',
|
||||
langDir: 'Dirección de idiomas',
|
||||
langDirLtr: 'Izquierda a derecha (LTR)',
|
||||
langDirRtl: 'Derecha a izquierda (RTL)',
|
||||
langCode: 'Código de lenguaje',
|
||||
longDescr: 'URL descripción larga',
|
||||
cssClass: 'Clases de hoja de estilo',
|
||||
advisoryTitle: 'Título del anuncio',
|
||||
cssStyle: 'Estilo',
|
||||
ok: 'OK',
|
||||
cancel: 'Cancelar',
|
||||
close: 'Cerrar',
|
||||
preview: 'Vista previa',
|
||||
resize: 'Redimensionar',
|
||||
generalTab: 'General',
|
||||
advancedTab: 'Avanzada',
|
||||
validateNumberFailed: 'Este valor no es un número.',
|
||||
confirmNewPage: 'Se perderán todos los cambios no guardados en este contenido. ¿Seguro que quieres cargar nueva página?',
|
||||
confirmCancel: 'Ha cambiado algunas opciones. ¿Está seguro de que desea cerrar la ventana de diálogo?',
|
||||
options: 'Opciones',
|
||||
target: 'Objetivo',
|
||||
targetNew: 'Nueva ventana (_blank)',
|
||||
targetTop: 'Ventana superior (_top)',
|
||||
targetSelf: 'Misma ventana (_self)',
|
||||
targetParent: 'Ventana principal (_parent)',
|
||||
langDirLTR: 'Izquierda a Derecha (LTR)',
|
||||
langDirRTL: 'Derecha a Izquierda (RTL)',
|
||||
styles: 'Estilo',
|
||||
cssClasses: 'Clases de hojas de estilo',
|
||||
width: 'Ancho',
|
||||
height: 'Alto',
|
||||
align: 'Alineación',
|
||||
left: 'Izquierda',
|
||||
right: 'Derecha',
|
||||
center: 'Centrado',
|
||||
justify: 'Justificado',
|
||||
alignLeft: 'Alinear a la izquierda',
|
||||
alignRight: 'Alinear a la derecha',
|
||||
alignCenter: 'Align Center', // MISSING
|
||||
alignTop: 'Arriba',
|
||||
alignMiddle: 'En medio',
|
||||
alignBottom: 'Abajo',
|
||||
alignNone: 'Ninguno',
|
||||
invalidValue: 'Valor inválido',
|
||||
invalidHeight: 'La altura debe ser un número.',
|
||||
invalidWidth: 'La anchura debe ser un número.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: 'El valor especificado para el campo "% 1" debe ser un número positivo con o sin una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
invalidHtmlLength: 'El valor especificado para el campo "% 1" debe ser un número positivo con o sin una unidad de medición HTML válida (px or %).',
|
||||
invalidInlineStyle: 'El valor especificado para el estilo en línea debe constar de una o más tuplas con el formato de "nombre: valor", separados por punto y coma',
|
||||
cssLengthTooltip: 'Introduzca un número para un valor en píxeles o un número con una unidad CSS válida (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, no disponible</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Retroceso',
|
||||
13: 'Intro',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Espacio',
|
||||
35: 'Fin',
|
||||
36: 'Inicio',
|
||||
46: 'Borrar',
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Comando'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Atajo de teclado',
|
||||
|
||||
optionDefault: 'Default' // MISSING
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/es.js
Normal file
154
Admin/plugins/ckeditor/lang/es.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Spanish language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'es' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Editor de Texto Enriquecido',
|
||||
editorPanel: 'Panel del Editor de Texto Enriquecido',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Pulse ALT 0 para ayuda',
|
||||
|
||||
browseServer: 'Ver Servidor',
|
||||
url: 'URL',
|
||||
protocol: 'Protocolo',
|
||||
upload: 'Cargar',
|
||||
uploadSubmit: 'Enviar al Servidor',
|
||||
image: 'Imagen',
|
||||
form: 'Formulario',
|
||||
checkbox: 'Casilla de Verificación',
|
||||
radio: 'Botones de Radio',
|
||||
textField: 'Campo de Texto',
|
||||
textarea: 'Area de Texto',
|
||||
hiddenField: 'Campo Oculto',
|
||||
button: 'Botón',
|
||||
select: 'Campo de Selección',
|
||||
imageButton: 'Botón Imagen',
|
||||
notSet: '<No definido>',
|
||||
id: 'Id',
|
||||
name: 'Nombre',
|
||||
langDir: 'Orientación',
|
||||
langDirLtr: 'Izquierda a Derecha (LTR)',
|
||||
langDirRtl: 'Derecha a Izquierda (RTL)',
|
||||
langCode: 'Cód. de idioma',
|
||||
longDescr: 'Descripción larga URL',
|
||||
cssClass: 'Clases de hojas de estilo',
|
||||
advisoryTitle: 'Título',
|
||||
cssStyle: 'Estilo',
|
||||
ok: 'Aceptar',
|
||||
cancel: 'Cancelar',
|
||||
close: 'Cerrar',
|
||||
preview: 'Previsualización',
|
||||
resize: 'Arrastre para redimensionar',
|
||||
generalTab: 'General',
|
||||
advancedTab: 'Avanzado',
|
||||
validateNumberFailed: 'El valor no es un número.',
|
||||
confirmNewPage: 'Cualquier cambio que no se haya guardado se perderá.\r\n¿Está seguro de querer crear una nueva página?',
|
||||
confirmCancel: 'Algunas de las opciones se han cambiado.\r\n¿Está seguro de querer cerrar el diálogo?',
|
||||
options: 'Opciones',
|
||||
target: 'Destino',
|
||||
targetNew: 'Nueva ventana (_blank)',
|
||||
targetTop: 'Ventana principal (_top)',
|
||||
targetSelf: 'Misma ventana (_self)',
|
||||
targetParent: 'Ventana padre (_parent)',
|
||||
langDirLTR: 'Izquierda a derecha (LTR)',
|
||||
langDirRTL: 'Derecha a izquierda (RTL)',
|
||||
styles: 'Estilos',
|
||||
cssClasses: 'Clase de la hoja de estilos',
|
||||
width: 'Anchura',
|
||||
height: 'Altura',
|
||||
align: 'Alineación',
|
||||
left: 'Izquierda',
|
||||
right: 'Derecha',
|
||||
center: 'Centrado',
|
||||
justify: 'Justificado',
|
||||
alignLeft: 'Alinear a Izquierda',
|
||||
alignRight: 'Alinear a Derecha',
|
||||
alignCenter: 'Centrar',
|
||||
alignTop: 'Tope',
|
||||
alignMiddle: 'Centro',
|
||||
alignBottom: 'Pie',
|
||||
alignNone: 'Ninguno',
|
||||
invalidValue: 'Valor no válido',
|
||||
invalidHeight: 'Altura debe ser un número.',
|
||||
invalidWidth: 'Anchura debe ser un número.',
|
||||
invalidLength: 'El valor especificado para el campo "%1" debe ser un número positivo, incluyendo opcionalmente una unidad de medida válida (%2).',
|
||||
invalidCssLength: 'El valor especificado para el campo "%1" debe ser un número positivo, incluyendo optionalmente una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, o pc).',
|
||||
invalidHtmlLength: 'El valor especificado para el campo "%1" debe ser un número positivo, incluyendo optionalmente una unidad de medida HTML válida (px o %).',
|
||||
invalidInlineStyle: 'El valor especificado para el estilo debe consistir en uno o más pares con el formato "nombre: valor", separados por punto y coma.',
|
||||
cssLengthTooltip: 'Introduca un número para el valor en pixels o un número con una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, o pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, no disponible</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Retroceso',
|
||||
13: 'Ingresar',
|
||||
16: 'Mayús.',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Espacio',
|
||||
35: 'Fin',
|
||||
36: 'Inicio',
|
||||
46: 'Suprimir',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Comando'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Atajos de teclado',
|
||||
|
||||
optionDefault: 'Default'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/et.js
Normal file
154
Admin/plugins/ckeditor/lang/et.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Estonian language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'et' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Rikkalik tekstiredaktor',
|
||||
editorPanel: 'Rikkaliku tekstiredaktori paneel',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Abi saamiseks vajuta ALT 0',
|
||||
|
||||
browseServer: 'Serveri sirvimine',
|
||||
url: 'URL',
|
||||
protocol: 'Protokoll',
|
||||
upload: 'Laadi üles',
|
||||
uploadSubmit: 'Saada serverisse',
|
||||
image: 'Pilt',
|
||||
form: 'Vorm',
|
||||
checkbox: 'Märkeruut',
|
||||
radio: 'Raadionupp',
|
||||
textField: 'Tekstilahter',
|
||||
textarea: 'Tekstiala',
|
||||
hiddenField: 'Varjatud lahter',
|
||||
button: 'Nupp',
|
||||
select: 'Valiklahter',
|
||||
imageButton: 'Piltnupp',
|
||||
notSet: '<määramata>',
|
||||
id: 'ID',
|
||||
name: 'Nimi',
|
||||
langDir: 'Keele suund',
|
||||
langDirLtr: 'Vasakult paremale (LTR)',
|
||||
langDirRtl: 'Paremalt vasakule (RTL)',
|
||||
langCode: 'Keele kood',
|
||||
longDescr: 'Pikk kirjeldus URL',
|
||||
cssClass: 'Stiilistiku klassid',
|
||||
advisoryTitle: 'Soovituslik pealkiri',
|
||||
cssStyle: 'Laad',
|
||||
ok: 'Olgu',
|
||||
cancel: 'Loobu',
|
||||
close: 'Sulge',
|
||||
preview: 'Eelvaade',
|
||||
resize: 'Suuruse muutmiseks lohista',
|
||||
generalTab: 'Üldine',
|
||||
advancedTab: 'Täpsemalt',
|
||||
validateNumberFailed: 'See väärtus pole number.',
|
||||
confirmNewPage: 'Kõik salvestamata muudatused lähevad kaotsi. Kas oled kindel, et tahad laadida uue lehe?',
|
||||
confirmCancel: 'Mõned valikud on muudetud. Kas oled kindel, et tahad dialoogi sulgeda?',
|
||||
options: 'Valikud',
|
||||
target: 'Sihtkoht',
|
||||
targetNew: 'Uus aken (_blank)',
|
||||
targetTop: 'Kõige ülemine aken (_top)',
|
||||
targetSelf: 'Sama aken (_self)',
|
||||
targetParent: 'Vanemaken (_parent)',
|
||||
langDirLTR: 'Vasakult paremale (LTR)',
|
||||
langDirRTL: 'Paremalt vasakule (RTL)',
|
||||
styles: 'Stiili',
|
||||
cssClasses: 'Stiililehe klassid',
|
||||
width: 'Laius',
|
||||
height: 'Kõrgus',
|
||||
align: 'Joondus',
|
||||
left: 'Vasak',
|
||||
right: 'Paremale',
|
||||
center: 'Kesk',
|
||||
justify: 'Rööpjoondus',
|
||||
alignLeft: 'Vasakjoondus',
|
||||
alignRight: 'Paremjoondus',
|
||||
alignCenter: 'Keskjoondus',
|
||||
alignTop: 'Üles',
|
||||
alignMiddle: 'Keskele',
|
||||
alignBottom: 'Alla',
|
||||
alignNone: 'Pole',
|
||||
invalidValue: 'Vigane väärtus.',
|
||||
invalidHeight: 'Kõrgus peab olema number.',
|
||||
invalidWidth: 'Laius peab olema number.',
|
||||
invalidLength: 'Välja "%1" väärtus peab olema positiivne arv korrektse ühikuga (%2) või ilma.',
|
||||
invalidCssLength: '"%1" välja jaoks määratud väärtus peab olema positiivne täisarv CSS ühikuga (px, %, in, cm, mm, em, ex, pt või pc) või ilma.',
|
||||
invalidHtmlLength: '"%1" välja jaoks määratud väärtus peab olema positiivne täisarv HTML ühikuga (px või %) või ilma.',
|
||||
invalidInlineStyle: 'Reasisese stiili määrangud peavad koosnema paarisväärtustest (tuples), mis on semikoolonitega eraldatult järgnevas vormingus: "nimi : väärtus".',
|
||||
cssLengthTooltip: 'Sisesta väärtus pikslites või number koos sobiva CSS-i ühikuga (px, %, in, cm, mm, em, ex, pt või pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, pole saadaval</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Backspace',
|
||||
13: 'Enter',
|
||||
16: 'Shift',
|
||||
17: 'Ctrl',
|
||||
18: 'Alt',
|
||||
32: 'Tühik',
|
||||
35: 'End',
|
||||
36: 'Home',
|
||||
46: 'Kustuta',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'Command'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Kiirklahv',
|
||||
|
||||
optionDefault: 'Vaikeväärtus'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/eu.js
Normal file
154
Admin/plugins/ckeditor/lang/eu.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object, for the
|
||||
* Basque language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'eu' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'Testu aberastuaren editorea',
|
||||
editorPanel: 'Testu aberastuaren editorearen panela',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'Sakatu ALT 0 laguntza jasotzeko',
|
||||
|
||||
browseServer: 'Arakatu zerbitzaria',
|
||||
url: 'URLa',
|
||||
protocol: 'Protokoloa',
|
||||
upload: 'Kargatu',
|
||||
uploadSubmit: 'Bidali zerbitzarira',
|
||||
image: 'Irudia',
|
||||
form: 'Formularioa',
|
||||
checkbox: 'Kontrol-laukia',
|
||||
radio: 'Aukera-botoia',
|
||||
textField: 'Testu-eremua',
|
||||
textarea: 'Testu-area',
|
||||
hiddenField: 'Ezkutuko eremua',
|
||||
button: 'Botoia',
|
||||
select: 'Hautespen-eremua',
|
||||
imageButton: 'Irudi-botoia',
|
||||
notSet: '<ezarri gabe>',
|
||||
id: 'Id',
|
||||
name: 'Izena',
|
||||
langDir: 'Hizkuntzaren norabidea',
|
||||
langDirLtr: 'Ezkerretik eskuinera (LTR)',
|
||||
langDirRtl: 'Eskuinetik ezkerrera (RTL)',
|
||||
langCode: 'Hizkuntzaren kodea',
|
||||
longDescr: 'URLaren deskribapen luzea',
|
||||
cssClass: 'Estilo-orriko klaseak',
|
||||
advisoryTitle: 'Aholkatutako izenburua',
|
||||
cssStyle: 'Estiloa',
|
||||
ok: 'Ados',
|
||||
cancel: 'Utzi',
|
||||
close: 'Itxi',
|
||||
preview: 'Aurrebista',
|
||||
resize: 'Aldatu tamainaz',
|
||||
generalTab: 'Orokorra',
|
||||
advancedTab: 'Aurreratua',
|
||||
validateNumberFailed: 'Balio hau ez da zenbaki bat.',
|
||||
confirmNewPage: 'Eduki honetan gorde gabe dauden aldaketak galduko dira. Ziur zaude orri berri bat kargatu nahi duzula?',
|
||||
confirmCancel: 'Aukera batzuk aldatu dituzu. Ziur zaude elkarrizketa-koadroa itxi nahi duzula?',
|
||||
options: 'Aukerak',
|
||||
target: 'Helburua',
|
||||
targetNew: 'Leiho berria (_blank)',
|
||||
targetTop: 'Goieneko leihoan (_top)',
|
||||
targetSelf: 'Leiho berean (_self)',
|
||||
targetParent: 'Leiho gurasoan (_parent)',
|
||||
langDirLTR: 'Ezkerretik eskuinera (LTR)',
|
||||
langDirRTL: 'Eskuinetik ezkerrera (RTL)',
|
||||
styles: 'Estiloa',
|
||||
cssClasses: 'Estilo-orriko klaseak',
|
||||
width: 'Zabalera',
|
||||
height: 'Altuera',
|
||||
align: 'Lerrokatzea',
|
||||
left: 'Ezkerrean',
|
||||
right: 'Eskuinean',
|
||||
center: 'Erdian',
|
||||
justify: 'Justifikatu',
|
||||
alignLeft: 'Lerrokatu ezkerrean',
|
||||
alignRight: 'Lerrokatu eskuinean',
|
||||
alignCenter: 'Align Center', // MISSING
|
||||
alignTop: 'Goian',
|
||||
alignMiddle: 'Erdian',
|
||||
alignBottom: 'Behean',
|
||||
alignNone: 'Bat ere ez',
|
||||
invalidValue: 'Balio desegokia.',
|
||||
invalidHeight: 'Altuera zenbaki bat izan behar da.',
|
||||
invalidWidth: 'Zabalera zenbaki bat izan behar da.',
|
||||
invalidLength: 'Value specified for the "%1" field must be a positive number with or without a valid measurement unit (%2).', // MISSING
|
||||
invalidCssLength: '"%1" eremurako zehaztutako balioak zenbaki positibo bat izan behar du, CSS neurri unitate batekin edo gabe (px, %, in, cm, mm, em, ex, pt edo pc).',
|
||||
invalidHtmlLength: '"%1" eremurako zehaztutako balioak zenbaki positibo bat izan behar du, HTML neurri unitate batekin edo gabe (px edo %).',
|
||||
invalidInlineStyle: 'Lineako estiloan zehaztutako balioak "izen : balio" formatuko tupla bat edo gehiago izan behar dira, komaz bereiztuak.',
|
||||
cssLengthTooltip: 'Sartu zenbaki bat edo zenbaki bat baliozko CSS unitate batekin (px, %, in, cm, mm, em, ex, pt, edo pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">, erabilezina</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'Atzera tekla',
|
||||
13: 'Sartu',
|
||||
16: 'Maius',
|
||||
17: 'Ktrl',
|
||||
18: 'Alt',
|
||||
32: 'Zuriunea',
|
||||
35: 'Buka',
|
||||
36: 'Etxea',
|
||||
46: 'Ezabatu',
|
||||
112: 'F1', // MISSING
|
||||
113: 'F2', // MISSING
|
||||
114: 'F3', // MISSING
|
||||
115: 'F4', // MISSING
|
||||
116: 'F5', // MISSING
|
||||
117: 'F6', // MISSING
|
||||
118: 'F7', // MISSING
|
||||
119: 'F8', // MISSING
|
||||
120: 'F9', // MISSING
|
||||
121: 'F10', // MISSING
|
||||
122: 'F11', // MISSING
|
||||
123: 'F12', // MISSING
|
||||
124: 'F13', // MISSING
|
||||
125: 'F14', // MISSING
|
||||
126: 'F15', // MISSING
|
||||
127: 'F16', // MISSING
|
||||
128: 'F17', // MISSING
|
||||
129: 'F18', // MISSING
|
||||
130: 'F19', // MISSING
|
||||
131: 'F20', // MISSING
|
||||
132: 'F21', // MISSING
|
||||
133: 'F22', // MISSING
|
||||
134: 'F23', // MISSING
|
||||
135: 'F24', // MISSING
|
||||
224: 'Komandoa'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'Laster-tekla',
|
||||
|
||||
optionDefault: 'Lehenetsia'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
154
Admin/plugins/ckeditor/lang/fa.js
Normal file
154
Admin/plugins/ckeditor/lang/fa.js
Normal file
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
|
||||
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileOverview Defines the {@link CKEDITOR.lang} object for the
|
||||
* Persian language.
|
||||
*/
|
||||
|
||||
/**#@+
|
||||
@type String
|
||||
@example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Contains the dictionary of language entries.
|
||||
* @namespace
|
||||
*/
|
||||
CKEDITOR.lang[ 'fa' ] = {
|
||||
// ARIA description.
|
||||
application: 'Rich Text Editor', // MISSING
|
||||
editor: 'ویرایشگر متن غنی',
|
||||
editorPanel: 'پنل ویرایشگر متن غنی',
|
||||
|
||||
// Common messages and labels.
|
||||
common: {
|
||||
// Screenreader titles. Please note that screenreaders are not always capable
|
||||
// of reading non-English words. So be careful while translating it.
|
||||
editorHelp: 'کلید Alt+0 را برای راهنمایی بفشارید',
|
||||
|
||||
browseServer: 'فهرستنمایی سرور',
|
||||
url: 'URL',
|
||||
protocol: 'قرارداد',
|
||||
upload: 'بالاگذاری',
|
||||
uploadSubmit: 'به سرور بفرست',
|
||||
image: 'تصویر',
|
||||
form: 'فرم',
|
||||
checkbox: 'چکباکس',
|
||||
radio: 'دکمهی رادیویی',
|
||||
textField: 'فیلد متنی',
|
||||
textarea: 'ناحیهٴ متنی',
|
||||
hiddenField: 'فیلد پنهان',
|
||||
button: 'دکمه',
|
||||
select: 'فیلد انتخاب چند گزینهای',
|
||||
imageButton: 'دکمهی تصویری',
|
||||
notSet: '<تعییننشده>',
|
||||
id: 'شناسه',
|
||||
name: 'نام',
|
||||
langDir: 'جهت زبان',
|
||||
langDirLtr: 'چپ به راست',
|
||||
langDirRtl: 'راست به چپ',
|
||||
langCode: 'کد زبان',
|
||||
longDescr: 'URL توصیف طولانی',
|
||||
cssClass: 'کلاسهای شیوهنامه (Stylesheet)',
|
||||
advisoryTitle: 'عنوان کمکی',
|
||||
cssStyle: 'سبک',
|
||||
ok: 'پذیرش',
|
||||
cancel: 'انصراف',
|
||||
close: 'بستن',
|
||||
preview: 'پیشنمایش',
|
||||
resize: 'تغییر اندازه',
|
||||
generalTab: 'عمومی',
|
||||
advancedTab: 'پیشرفته',
|
||||
validateNumberFailed: 'این مقدار یک عدد نیست.',
|
||||
confirmNewPage: 'هر تغییر ایجاد شدهی ذخیره نشده از بین خواهد رفت. آیا اطمینان دارید که قصد بارگیری صفحه جدیدی را دارید؟',
|
||||
confirmCancel: 'برخی از گزینهها تغییر کردهاند. آیا واقعا قصد بستن این پنجره را دارید؟',
|
||||
options: 'گزینهها',
|
||||
target: 'مقصد',
|
||||
targetNew: 'پنجره جدید',
|
||||
targetTop: 'بالاترین پنجره',
|
||||
targetSelf: 'همان پنجره',
|
||||
targetParent: 'پنجره والد',
|
||||
langDirLTR: 'چپ به راست',
|
||||
langDirRTL: 'راست به چپ',
|
||||
styles: 'سبک',
|
||||
cssClasses: 'کلاسهای سبکنامه',
|
||||
width: 'عرض',
|
||||
height: 'طول',
|
||||
align: 'چینش',
|
||||
left: 'چپ',
|
||||
right: 'راست',
|
||||
center: 'وسط',
|
||||
justify: 'بلوک چین',
|
||||
alignLeft: 'چپ چین',
|
||||
alignRight: 'راست چین',
|
||||
alignCenter: 'مرکز قرار بده',
|
||||
alignTop: 'بالا',
|
||||
alignMiddle: 'میانه',
|
||||
alignBottom: 'پائین',
|
||||
alignNone: 'هیچ',
|
||||
invalidValue: 'مقدار نامعتبر.',
|
||||
invalidHeight: 'ارتفاع باید یک عدد باشد.',
|
||||
invalidWidth: 'عرض باید یک عدد باشد.',
|
||||
invalidLength: 'عدد تعیین شده برای فیلد "%1" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری معتبر ("%2") باشد.',
|
||||
invalidCssLength: 'عدد تعیین شده برای فیلد "%1" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری CSS معتبر باشد (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
invalidHtmlLength: 'عدد تعیین شده برای فیلد "%1" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری HTML معتبر باشد (px or %).',
|
||||
invalidInlineStyle: 'عدد تعیین شده برای سبک درونخطی -Inline Style- باید دارای یک یا چند چندتایی با شکلی شبیه "name : value" که باید با یک ";" از هم جدا شوند.',
|
||||
cssLengthTooltip: 'یک عدد برای یک مقدار بر حسب پیکسل و یا یک عدد با یک واحد CSS معتبر وارد کنید (px, %, in, cm, mm, em, ex, pt, or pc).',
|
||||
|
||||
// Put the voice-only part of the label in the span.
|
||||
unavailable: '%1<span class="cke_accessibility">، غیر قابل دسترس</span>',
|
||||
|
||||
// Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
|
||||
keyboard: {
|
||||
8: 'عقبگرد',
|
||||
13: 'ورود',
|
||||
16: 'تعویض',
|
||||
17: 'کنترل',
|
||||
18: 'دگرساز',
|
||||
32: 'فاصله',
|
||||
35: 'پایان',
|
||||
36: 'خانه',
|
||||
46: 'حذف',
|
||||
112: 'F1',
|
||||
113: 'F2',
|
||||
114: 'F3',
|
||||
115: 'F4',
|
||||
116: 'F5',
|
||||
117: 'F6',
|
||||
118: 'F7',
|
||||
119: 'F8',
|
||||
120: 'F9',
|
||||
121: 'F10',
|
||||
122: 'F11',
|
||||
123: 'F12',
|
||||
124: 'F13',
|
||||
125: 'F14',
|
||||
126: 'F15',
|
||||
127: 'F16',
|
||||
128: 'F17',
|
||||
129: 'F18',
|
||||
130: 'F19',
|
||||
131: 'F20',
|
||||
132: 'F21',
|
||||
133: 'F22',
|
||||
134: 'F23',
|
||||
135: 'F24',
|
||||
224: 'فرمان'
|
||||
},
|
||||
|
||||
// Prepended to ARIA labels with shortcuts.
|
||||
keyboardShortcut: 'میانبر صفحه کلید',
|
||||
|
||||
optionDefault: 'پیش فرض'
|
||||
},
|
||||
|
||||
versionCheck: {
|
||||
notificationMessage: 'This CKEditor %current version is not secure. Consider <a target="_blank" href="%link">upgrading to the latest one</a>, %latest.', // MISSING
|
||||
consoleMessage: 'This CKEditor %current version is not secure. Consider upgrading to the latest one, %latest: %link', // MISSING
|
||||
aboutDialogInsecureMessage: 'This CKEditor %current version is not secure.<br>Consider upgrading to the latest one, %latest:<br><a target="_blank" href="%link">%link</a>', // MISSING
|
||||
aboutDialogUpgradeMessage: 'Consider upgrading to the latest editor version, %latest:<br><a target="_blank" href="%link">%link</a>' // MISSING
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user