503f08acf4cf6e4af02bd52f68ef7110d7f65766
[ckeditor.git] / skins / ckeditor / _source / plugins / placeholder / plugin.js
1 /*
2 Copyright (c) 2003-2011, 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 : [ 'en', 'he' ],
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 };