1 /* 2 Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * @fileOverview The "placeholder" plugin. 8 * 9 */ 10 11 (function() 12 { 13 var placeholderReplaceRegex = /\[\[[^\]]+\]\]/g; 14 CKEDITOR.plugins.add( 'placeholder', 15 { 16 requires : [ 'dialog' ], 17 lang : [ 'bg', 'cs', 'cy', 'da', 'de', 'el', 'en', 'eo', 'et', 'fa', 'fi', 'fr', 'he', 'hr', 'it', 'ku', 'nb', 'nl', 'no', 'pl', 'pt-br', 'sk', 'tr', 'ug', 'uk', 'vi', 'zh-cn' ], 18 init : function( editor ) 19 { 20 var lang = editor.lang.placeholder; 21 22 editor.addCommand( 'createplaceholder', new CKEDITOR.dialogCommand( 'createplaceholder' ) ); 23 editor.addCommand( 'editplaceholder', new CKEDITOR.dialogCommand( 'editplaceholder' ) ); 24 25 editor.ui.addButton( 'CreatePlaceholder', 26 { 27 label : lang.toolbar, 28 command :'createplaceholder', 29 icon : this.path + 'placeholder.gif' 30 }); 31 32 if ( editor.addMenuItems ) 33 { 34 editor.addMenuGroup( 'placeholder', 20 ); 35 editor.addMenuItems( 36 { 37 editplaceholder : 38 { 39 label : lang.edit, 40 command : 'editplaceholder', 41 group : 'placeholder', 42 order : 1, 43 icon : this.path + 'placeholder.gif' 44 } 45 } ); 46 47 if ( editor.contextMenu ) 48 { 49 editor.contextMenu.addListener( function( element, selection ) 50 { 51 if ( !element || !element.data( 'cke-placeholder' ) ) 52 return null; 53 54 return { editplaceholder : CKEDITOR.TRISTATE_OFF }; 55 } ); 56 } 57 } 58 59 editor.on( 'doubleclick', function( evt ) 60 { 61 if ( CKEDITOR.plugins.placeholder.getSelectedPlaceHoder( editor ) ) 62 evt.data.dialog = 'editplaceholder'; 63 }); 64 65 editor.addCss( 66 '.cke_placeholder' + 67 '{' + 68 'background-color: #ffff00;' + 69 ( CKEDITOR.env.gecko ? 'cursor: default;' : '' ) + 70 '}' 71 ); 72 73 editor.on( 'contentDom', function() 74 { 75 editor.document.getBody().on( 'resizestart', function( evt ) 76 { 77 if ( editor.getSelection().getSelectedElement().data( 'cke-placeholder' ) ) 78 evt.data.preventDefault(); 79 }); 80 }); 81 82 CKEDITOR.dialog.add( 'createplaceholder', this.path + 'dialogs/placeholder.js' ); 83 CKEDITOR.dialog.add( 'editplaceholder', this.path + 'dialogs/placeholder.js' ); 84 }, 85 afterInit : function( editor ) 86 { 87 var dataProcessor = editor.dataProcessor, 88 dataFilter = dataProcessor && dataProcessor.dataFilter, 89 htmlFilter = dataProcessor && dataProcessor.htmlFilter; 90 91 if ( dataFilter ) 92 { 93 dataFilter.addRules( 94 { 95 text : function( text ) 96 { 97 return text.replace( placeholderReplaceRegex, function( match ) 98 { 99 return CKEDITOR.plugins.placeholder.createPlaceholder( editor, null, match, 1 ); 100 }); 101 } 102 }); 103 } 104 105 if ( htmlFilter ) 106 { 107 htmlFilter.addRules( 108 { 109 elements : 110 { 111 'span' : function( element ) 112 { 113 if ( element.attributes && element.attributes[ 'data-cke-placeholder' ] ) 114 delete element.name; 115 } 116 } 117 }); 118 } 119 } 120 }); 121 })(); 122 123 CKEDITOR.plugins.placeholder = 124 { 125 createPlaceholder : function( editor, oldElement, text, isGet ) 126 { 127 var element = new CKEDITOR.dom.element( 'span', editor.document ); 128 element.setAttributes( 129 { 130 contentEditable : 'false', 131 'data-cke-placeholder' : 1, 132 'class' : 'cke_placeholder' 133 } 134 ); 135 136 text && element.setText( text ); 137 138 if ( isGet ) 139 return element.getOuterHtml(); 140 141 if ( oldElement ) 142 { 143 if ( CKEDITOR.env.ie ) 144 { 145 element.insertAfter( oldElement ); 146 // Some time is required for IE before the element is removed. 147 setTimeout( function() 148 { 149 oldElement.remove(); 150 element.focus(); 151 }, 10 ); 152 } 153 else 154 element.replace( oldElement ); 155 } 156 else 157 editor.insertElement( element ); 158 159 return null; 160 }, 161 162 getSelectedPlaceHoder : function( editor ) 163 { 164 var range = editor.getSelection().getRanges()[ 0 ]; 165 range.shrink( CKEDITOR.SHRINK_TEXT ); 166 var node = range.startContainer; 167 while( node && !( node.type == CKEDITOR.NODE_ELEMENT && node.data( 'cke-placeholder' ) ) ) 168 node = node.getParent(); 169 return node; 170 } 171 }; 172