From c4fd44822319a9e70806334d31097e615ebcccf4 Mon Sep 17 00:00:00 2001 From: juanf <juanf> Date: Mon, 30 Jan 2017 13:41:49 +0000 Subject: [PATCH] SSDM-4687 : Placeholders on rich text editor SVN: 37642 --- .../eln-lims/html/lib/ckeditor/js/config.js | 1 + .../js/plugins/confighelper/docs/install.html | 124 ++++++ .../js/plugins/confighelper/docs/styles.css | 59 +++ .../js/plugins/confighelper/plugin.js | 389 ++++++++++++++++++ 4 files changed, 573 insertions(+) create mode 100644 openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/docs/install.html create mode 100644 openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/docs/styles.css create mode 100644 openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/plugin.js diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/config.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/config.js index cf6eb0ea1a5..073b69f0a8f 100644 --- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/config.js +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/config.js @@ -7,6 +7,7 @@ CKEDITOR.editorConfig = function( config ) { // Define changes to default configuration here. For example: // config.language = 'fr'; // config.uiColor = '#AADC6E'; + config.extraPlugins='confighelper'; config.stylesSet = false; config.toolbarGroups = [ { name: 'document', groups: [ 'mode', 'document', 'doctools' ] }, diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/docs/install.html b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/docs/install.html new file mode 100644 index 00000000000..7b229535e1b --- /dev/null +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/docs/install.html @@ -0,0 +1,124 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html4/loose.dtd"> +<html lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> +<title>Configuration Helper plugin</title> +<link href="styles.css" rel="stylesheet" type="text/css"> +</head> + +<body> +<h1>Configuration Helper Plugin for CKEditor</h1> + +<h2>Introduction</h2> +<p>This plugin tries to help setup <a href="http://www.ckeditor.com">CKEditor</a> by providing additional configuration options to perform some +kind of common tasks.</p> +<p>Currently if offers a "removeDialogFields" that allows to remove individual fields in the dialogs (versus removing whole tabs with +<a href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.removeDialogTabs">removeDialogTabs</a>, and "dialogFieldsDefaultValues" +defines default values for dialog fields.</p> + +<h3 id="contact">Author:</h3> +<p><a href="mailto:amla70@gmail.com">Alfonso Martínez de Lizarrondo</a></p> + +<h3>Version history: </h3> +<ol> + <li>1.0: 26-February-2012. First version.</li> + <li>1.1: 16-February-2012. Added placeholder.</li> + <li>1.2: 23-April-2012. Added hideDialogFields.</li> + <li>1.3: 1-December-2012. Compatibility with CKEditor 4.</li> + <li>1.4: 28-March-2013. Compatibility of the "placeholder" attribute with the inline mode of CKEditor 4.</li> + <li>1.5: 16-April-2013. Version 1.4 was broken in CKEditor 3.</li> + <li>1.6: 16-August-2013. Handle the setData method to update the "placeholder" status</li> + <li>1.7: 6-October-2013. <a href="https://github.com/AlfonsoML/confighelper/pull/2">Patch by bfavors</a> to fix handling placeholder on initial load of editor</li> + <li>1.8: 9-March-2014. <a href="http://ckeditor.com/comment/reply/128664/130294">Check for IE11 by Russel Ward</a><br> + Set caret into the empty paragraph correctly on first focus, <a href="https://github.com/AlfonsoML/confighelper/pull/5">patch by glanchow</a> + </li> + <li>1.8.1: 5-April-2014. <a href="https://github.com/AlfonsoML/confighelper/issues/6">Fix IE8 & IE9 problem with "inline textarea" if it's empty on start</a> + </li> + <li>1.8.2: 12-April-2014. <a href="https://github.com/AlfonsoML/confighelper/pull/8">Protect detection of empty content</a>. Thanks to tanihito. + </li> + <li>1.8.3: 30-November-2014. Force SCAYT to use the language that it's specified as the language for the contents.<br> + <a href="https://github.com/AlfonsoML/confighelper/pull/13">Listen to the contentDom event to avoid problems when calling setData in WYSIWYG mode</a>. Thanks to noam-si. + </li> +</ol> + +<h2>Installation</h2> +<h3>1. Copying the files</h3> +<p>Extract the contents of the zip in you plugins directory, so it ends up like + this<br> + <!--<img src="installation.png" alt="Screenshot of installation" width="311" height="346" longdesc="#install">--> + </p> +<pre id="--install"> +ckeditor\ + ... + images\ + lang\ + plugins\ + ... + confighelper\ + plugin.js + docs\ + install.html + ... + skins\ + themes\ +</pre> +<h3>2. Adding it to CKEditor</h3> +<p>Now add the plugin in your <em>config.js</em> or custom js configuration +file: +<code>config.extraPlugins='confighelper'; </code> +</p> + +<h3>3. Configuration</h3> +<h4>config.removeDialogFields</h4> +<p>This entry is a string, the fields are defined as dialogName + ":" + tab + ":" + field. Fields are joined with semicolons. +In order to learn the name of the parameters you can use the "Developer Tools plugin", launch that sample and open the dialog that you want to customize. +Now a little popup with appear showing the info about that field, for example: +<pre><u>Element Information</u> +Dialog window name : image +Tab name : info +Element ID : txtBorder +Element type : text +</pre> +so in order to remove the class attribute for images the config is: +<pre>config.removeDialogFields="image:info:txtBorder";</pre> +removing another field +<pre>config.removeDialogFields="image:info:txtBorder;image:info:txtHSpace";</pre> + +<h4>config.dialogFieldsDefaultValues</h4> +<p>This setting uses directly a JSON object as the configuration value, first an object that has the dialog names as properties, each property is +a new object with the name of the tabs and finally each property name maps to the field name and it's value is the default value to use for the field.</p> +<p>An example might be much better as I might have messed up something in the description:</p> +<pre>config.dialogFieldsDefaultValues = +{ + image: + { + advanced: + { + txtGenClass : 'myClass', + txtGenTitle : 'Image title' + } + } +}; +</pre> + +<h4>config.placeholder</h4> +<p>This a text that will be shown when the editor is empty following the HTML5 placeholder attribute. When the user focus the editor, the content is +cleared automatically.</p> +<p>The value can be set in the configuration or as an attribute of the replaced element</p> +<pre>config.placeholder = 'Type here...';</pre> + +<h4>config.hideDialogFields</h4> +<p>This entry uses the same sintax that the 'removeDialogFields' option. The difference is that some fields can't be removed easily as other parts of the dialog +might not be ready and might try to always use it, generating a javascript error. In other cases the layout might be broken if the field is removed instead of hidden.<br> +In those cases it's possible to hide the fields using this entry, and the preview in the image dialog is an example of such a field.</p> +<pre>config.hideDialogFields="image:info:htmlPreview";</pre> + +<!-- +<h2>Final notes</h2> +--> + +<h2>Disclaimers</h2> +<p>CKEditor is © CKSource.com</p> +</body> +</html> diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/docs/styles.css b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/docs/styles.css new file mode 100644 index 00000000000..58ae80a0d67 --- /dev/null +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/docs/styles.css @@ -0,0 +1,59 @@ +body { + font-family: Arial, Helvetica, sans-serif; + font-size: 90%; +} +h1 { + text-align:center; + font-size:180%; +} +h2 { + border-bottom:2px solid #CCC; + margin:1em 0 0.4em 0; +} +h3 { + margin-bottom:0.4em; +} +p { + margin:0 0 1em 1em; + text-align:justify; +} +ol { + margin:0 0 1.2em 1em; + padding:0; + list-style-type:none; +} +ol li { + margin:0.2em 0; +} +pre, code { + font-size:100%; + font-family:"Courier New", Courier, mono; + background-color: #CCCCCC; + border:1px solid #999; + padding:0.2em 1em; + margin: 0.4em 0; + display:block; + white-space: pre; + overflow: auto; +} +form { + margin:0 0 0 1em; +} +span.key { + color: #006600; +} +#install { + display:none +} +#languages ul { + display:inline; + list-style-type:none; + margin:0; + padding:0; +} +#languages li { + display:inline; + margin:0; + padding:0; + vertical-align:bottom; +} \ No newline at end of file diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/plugin.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/plugin.js new file mode 100644 index 00000000000..37d2d70e347 --- /dev/null +++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/lib/ckeditor/js/plugins/confighelper/plugin.js @@ -0,0 +1,389 @@ +/** + * @file Configuration helper plugin for CKEditor + * Copyright (C) 2012 Alfonso Martínez de Lizarrondo + * + */ +(function() { +"use strict"; + +// Check if the browser supports the placeholder attribute on textareas natively. +var supportsPlaceholder = ('placeholder' in document.createElement( 'textarea' ) ); + +// If the data is "empty" (BR, P) or the placeholder then return an empty string. +// Otherwise return the original data +function dataIsEmpty( data ) +{ + if ( !data) + return true; + + if ( data.length > 20 ) + return false; + + var value = data.replace( /[\n|\t]*/g, '' ).toLowerCase(); + if ( !value || value == '<br>' || value == '<p> <br></p>' || value == '<p><br></p>' || value == '<p> </p>' || value == ' ' || value == ' ' || value == ' <br>' || value == ' <br>' ) + return true; + + return false; +} + +function addPlaceholder(ev) { + var editor = ev.editor; + var root = (editor.editable ? editor.editable() : (editor.mode == 'wysiwyg' ? editor.document && editor.document.getBody() : editor.textarea ) ); + var placeholder = ev.listenerData; + if (!root) + return; + + if (editor.mode == 'wysiwyg') + { + // If the blur is due to a dialog, don't apply the placeholder + if ( CKEDITOR.dialog._.currentTop ) + return; + + if ( !root ) + return; + + if ( dataIsEmpty( root.getHtml() ) ) + { + root.setHtml( placeholder ); + root.addClass( 'placeholder' ); + } + } + + if (editor.mode == 'source') + { + if ( supportsPlaceholder ) + { + if (ev.name=='mode') + { + root.setAttribute( 'placeholder', placeholder ); + } + return; + } + + if ( dataIsEmpty( root.getValue() ) ) + { + root.setValue( placeholder ); + root.addClass( 'placeholder' ); + } + } +} + +function removePlaceholder(ev) { + var editor = ev.editor; + var root = (editor.editable ? editor.editable() : (editor.mode == 'wysiwyg' ? editor.document && editor.document.getBody() : editor.textarea ) ); + if (!root) + return; + + if (editor.mode == 'wysiwyg' ) + { + if (!root.hasClass( 'placeholder' )) + return; + + root.removeClass( 'placeholder' ); + // fill it properly + if (CKEDITOR.dtd[ root.getName() ]['p']) + { + root.setHtml( '<p><br/></p>' ); + // Set caret in position + var range = new CKEDITOR.dom.range(editor.document); + range.moveToElementEditablePosition(root.getFirst(), true); + editor.getSelection().selectRanges([range]); + } + else + { + root.setHtml(' '); + } + } + + if (editor.mode == 'source') + { + if ( !root.hasClass( 'placeholder' ) ) + return; + + root.removeClass( 'placeholder' ); + root.setValue( '' ); + } +} + + +function getLang( element ) +{ + if (!element) + return null; + + return element.getAttribute( 'lang' ) || getLang( element.getParent() ); +} + + +CKEDITOR.plugins.add( 'confighelper', +{ + getPlaceholderCss : function() + { + return '.placeholder{ color: #999; }'; + }, + + onLoad : function() + { + // v4 + if (CKEDITOR.addCss) + CKEDITOR.addCss( this.getPlaceholderCss() ); + }, + + init : function( editor ) + { + + // correct focus status after switch mode + editor.on( 'mode', function( ev ) { + // Let's update to match reality + ev.editor.focusManager.hasFocus = false; + // Now focus it: + }); + + // Placeholder - Start + // Get the placeholder from the replaced element or from the configuration + var placeholder = editor.element.getAttribute( 'placeholder' ) || editor.config.placeholder; + + if (placeholder) + { + // CSS for WYSIWYG mode + // v3 + if (editor.addCss) + editor.addCss(this.getPlaceholderCss()); + + // CSS for textarea mode + var node = CKEDITOR.document.getHead().append( 'style' ); + node.setAttribute( 'type', 'text/css' ); + var content = 'textarea.placeholder { color: #999; font-style: italic; }'; + + if ( CKEDITOR.env.ie && CKEDITOR.env.version<11) + node.$.styleSheet.cssText = content; + else + node.$.innerHTML = content; + + // Watch for the calls to getData to remove the placeholder + editor.on( 'getData', function( ev ) { + var element = (editor.editable ? editor.editable() : (editor.mode == 'wysiwyg' ? editor.document && editor.document.getBody() : editor.textarea ) ); + + if ( element && element.hasClass( 'placeholder' ) ) + ev.data.dataValue = ''; + }); + + // Watch for setData to remove placeholder class + editor.on('setData', function(ev) { + if ( CKEDITOR.dialog._.currentTop ) + return; + + if ( editor.mode =='source' && supportsPlaceholder ) + return; + + var root = (editor.editable ? editor.editable() : (editor.mode == 'wysiwyg' ? editor.document && editor.document.getBody() : editor.textarea ) ); + + if ( !root ) + return; + + if ( !dataIsEmpty( ev.data.dataValue ) ) + { + // Remove the class if new data is not empty + if ( root.hasClass( 'placeholder' ) ) + root.removeClass( 'placeholder' ); + } + else + { + // if data is empty, set it to the placeholder + addPlaceholder(ev); + } + }); + + editor.on('blur', addPlaceholder, null, placeholder); + editor.on('mode', addPlaceholder, null, placeholder); + editor.on('contentDom', addPlaceholder, null, placeholder); + + editor.on('focus', removePlaceholder); + editor.on('beforeModeUnload', removePlaceholder); + } // Placeholder - End + + + // SCAYT lang from element lang: + var lang = editor.config.contentsLanguage || getLang( editor.element ); + if ( lang && ! editor.config.scayt_sLang ) + { + // Remove the stored language + if (localStorage) + localStorage.removeItem("scayt_0_lang"); + + // Convert from HTML5 Lang to spellchecker.net values + var map = { + 'en' : 'en_US', + 'en-us': 'en_US', + 'en-gb': 'en_GB', + 'pt-br': 'pt_BR', + 'da' : 'da_DK', + 'da-dk': 'da_DK', + 'nl-nl': 'nl_NL', + 'en-ca': 'en_CA', + 'fi-fi': 'fi_FI', + 'fr' : 'fr_FR', + 'fr-fr': 'fr_FR', + 'fr-ca': 'fr_CA', + 'de' : 'de_DE', + 'de-de': 'de_DE', + 'el-gr': 'el_GR', + 'it' : 'it_IT', + 'it-it': 'it_IT', + 'nb-no': 'nb_NO', + 'pt' : 'pt_PT', + 'pt-pt': 'pt_PT', + 'es' : 'es_ES', + 'es-es': 'es_ES', + 'sv-se': 'sv_SE' + }; + editor.config.scayt_sLang = map[ lang.toLowerCase() ]; + } + + // Parse the config to turn it into a js object + // format= dialogName:tabName:fieldName + var parseDefinitionToObject = function ( value ) + { + // Allow JSON definitions + if (typeof value == 'object') + return value; + + var contents = value.split( ';' ), + tabsToProcess = {}, + i; + + for ( i = 0; i < contents.length; i++ ) + { + var parts = contents[ i ].split( ':' ); + if ( parts.length == 3 ) + { + var dialogName = parts[ 0 ], + tabName = parts[ 1 ], + fieldName = parts[ 2 ]; + + if ( !tabsToProcess[ dialogName ] ) + tabsToProcess[ dialogName ] = {}; + if ( !tabsToProcess[ dialogName ][ tabName ] ) + tabsToProcess[ dialogName ][ tabName ] = []; + + tabsToProcess[ dialogName ][ tabName ].push( fieldName ); + } + } + return tabsToProcess; + }; + + // Customize dialogs: + CKEDITOR.on( 'dialogDefinition', function( ev ) + { + if ( editor != ev.editor ) + return; + + var dialogName = ev.data.name, + dialogDefinition = ev.data.definition, + tabsToProcess, + i, name, fields, tab; + + if (dialogName=='tableProperties') + dialogName=='table'; + + // Parse the config to turn it into a js object + if ( !( 'removeDialogFields' in editor._ ) && editor.config.removeDialogFields ) + editor._.removeDialogFields = parseDefinitionToObject( editor.config.removeDialogFields ); + + // Remove fields of this dialog. + if ( editor._.removeDialogFields && ( tabsToProcess = editor._.removeDialogFields[ dialogName ] ) ) + { + for ( name in tabsToProcess ) + { + fields = tabsToProcess[ name ]; + tab = dialogDefinition.getContents( name ); + + for ( i=0; i<fields.length ; i++ ) + tab.remove( fields[ i ] ); + } + } + + + if ( !( 'hideDialogFields' in editor._ ) && editor.config.hideDialogFields ) + editor._.hideDialogFields = parseDefinitionToObject( editor.config.hideDialogFields ); + + // Remove fields of this dialog. + if ( editor._.hideDialogFields && ( tabsToProcess = editor._.hideDialogFields[ dialogName ] ) ) + { + for ( name in tabsToProcess ) + { + fields = tabsToProcess[ name ]; + tab = dialogDefinition.getContents( name ); + + for ( i=0; i<fields.length ; i++ ) + tab.get( fields[ i ] ).hidden = true; + } + } + + // Set default values. + if ( editor.config.dialogFieldsDefaultValues && ( tabsToProcess = editor.config.dialogFieldsDefaultValues[ dialogName ] ) ) + { + for ( name in tabsToProcess ) + { + fields = tabsToProcess[ name ]; + tab = dialogDefinition.getContents( name ); + + for ( var fieldName in fields ) + { + var dialogField = tab.get( fieldName ); + if ( dialogField ) + dialogField[ 'default' ] = fields[ fieldName ]; + } + } + } + + + }); + + } +} ); + +})(); + + /** + * Allows to define which dialog fiels must be removed + * @name CKEDITOR.config.removeDialogFields + * @type {String} + * @example + * editor.config.removeDialogFields = "image:info:txtBorder;image:info:txtHSpace"; + */ + + /** + * Allows to define which dialog fiels must be hidden + * @name CKEDITOR.config.hideDialogFields + * @type {String} + * @example + * editor.config.hideDialogFields = "image:info:htmlPreview"; + */ + + /** + * Allows to define default values for dialog fields + * @name CKEDITOR.config.dialogFieldsDefaultValues + * @type {Object} + * @example + config.dialogFieldsDefaultValues = + { + image: + { + advanced: + { + txtGenClass : 'myClass', + txtGenTitle : 'Image title' + } + } + }; + */ + + + /** + * Placeholder text for empty editor + * @name CKEDITOR.config.placeholder + * @type {String} + * @example + * editor.config.placeholder = "Please, type here..."; + */ -- GitLab