d4ebce58c109a90d425da1ad40006c9166ebeeb1
[ckeditor.git] / skins / ckeditor / _source / plugins / fakeobjects / 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 (function()
7 {
8 var cssStyle = CKEDITOR.htmlParser.cssStyle,
9 cssLength = CKEDITOR.tools.cssLength;
10
11 var cssLengthRegex = /^((?:\d*(?:\.\d+))|(?:\d+))(.*)?$/i;
12
13 /*
14 * Replacing the former CSS length value with the later one, with
15 * adjustment to the length unit.
16 */
17 function replaceCssLength( length1, length2 )
18 {
19 var parts1 = cssLengthRegex.exec( length1 ),
20 parts2 = cssLengthRegex.exec( length2 );
21
22 // Omit pixel length unit when necessary,
23 // e.g. replaceCssLength( 10, '20px' ) -> 20
24 if ( parts1 )
25 {
26 if ( !parts1[ 2 ] && parts2[ 2 ] == 'px' )
27 return parts2[ 1 ];
28 if ( parts1[ 2 ] == 'px' && !parts2[ 2 ] )
29 return parts2[ 1 ] + 'px';
30 }
31
32 return length2;
33 }
34
35 var htmlFilterRules =
36 {
37 elements :
38 {
39 $ : function( element )
40 {
41 var attributes = element.attributes,
42 realHtml = attributes && attributes[ 'data-cke-realelement' ],
43 realFragment = realHtml && new CKEDITOR.htmlParser.fragment.fromHtml( decodeURIComponent( realHtml ) ),
44 realElement = realFragment && realFragment.children[ 0 ];
45
46 // Width/height in the fake object are subjected to clone into the real element.
47 if ( realElement && element.attributes[ 'data-cke-resizable' ] )
48 {
49 var styles = new cssStyle( element ).rules,
50 realAttrs = realElement.attributes,
51 width = styles.width,
52 height = styles.height;
53
54 width && ( realAttrs.width = replaceCssLength( realAttrs.width, width ) );
55 height && ( realAttrs.height = replaceCssLength( realAttrs.height, height ) );
56 }
57
58 return realElement;
59 }
60 }
61 };
62
63 CKEDITOR.plugins.add( 'fakeobjects',
64 {
65 requires : [ 'htmlwriter' ],
66
67 afterInit : function( editor )
68 {
69 var dataProcessor = editor.dataProcessor,
70 htmlFilter = dataProcessor && dataProcessor.htmlFilter;
71
72 if ( htmlFilter )
73 htmlFilter.addRules( htmlFilterRules );
74 }
75 });
76
77 CKEDITOR.editor.prototype.createFakeElement = function( realElement, className, realElementType, isResizable )
78 {
79 var lang = this.lang.fakeobjects,
80 label = lang[ realElementType ] || lang.unknown;
81
82 var attributes =
83 {
84 'class' : className,
85 src : CKEDITOR.getUrl( 'images/spacer.gif' ),
86 'data-cke-realelement' : encodeURIComponent( realElement.getOuterHtml() ),
87 'data-cke-real-node-type' : realElement.type,
88 alt : label,
89 title : label,
90 align : realElement.getAttribute( 'align' ) || ''
91 };
92
93 if ( realElementType )
94 attributes[ 'data-cke-real-element-type' ] = realElementType;
95
96 if ( isResizable )
97 {
98 attributes[ 'data-cke-resizable' ] = isResizable;
99
100 var fakeStyle = new cssStyle();
101
102 var width = realElement.getAttribute( 'width' ),
103 height = realElement.getAttribute( 'height' );
104
105 width && ( fakeStyle.rules.width = cssLength( width ) );
106 height && ( fakeStyle.rules.height = cssLength( height ) );
107 fakeStyle.populate( attributes );
108 }
109
110 return this.document.createElement( 'img', { attributes : attributes } );
111 };
112
113 CKEDITOR.editor.prototype.createFakeParserElement = function( realElement, className, realElementType, isResizable )
114 {
115 var lang = this.lang.fakeobjects,
116 label = lang[ realElementType ] || lang.unknown,
117 html;
118
119 var writer = new CKEDITOR.htmlParser.basicWriter();
120 realElement.writeHtml( writer );
121 html = writer.getHtml();
122
123 var attributes =
124 {
125 'class' : className,
126 src : CKEDITOR.getUrl( 'images/spacer.gif' ),
127 'data-cke-realelement' : encodeURIComponent( html ),
128 'data-cke-real-node-type' : realElement.type,
129 alt : label,
130 title : label,
131 align : realElement.attributes.align || ''
132 };
133
134 if ( realElementType )
135 attributes[ 'data-cke-real-element-type' ] = realElementType;
136
137 if ( isResizable )
138 {
139 attributes[ 'data-cke-resizable' ] = isResizable;
140 var realAttrs = realElement.attributes,
141 fakeStyle = new cssStyle();
142
143 var width = realAttrs.width,
144 height = realAttrs.height;
145
146 width != undefined && ( fakeStyle.rules.width = cssLength( width ) );
147 height != undefined && ( fakeStyle.rules.height = cssLength ( height ) );
148 fakeStyle.populate( attributes );
149 }
150
151 return new CKEDITOR.htmlParser.element( 'img', attributes );
152 };
153
154 CKEDITOR.editor.prototype.restoreRealElement = function( fakeElement )
155 {
156 if ( fakeElement.data( 'cke-real-node-type' ) != CKEDITOR.NODE_ELEMENT )
157 return null;
158
159 var element = CKEDITOR.dom.element.createFromHtml(
160 decodeURIComponent( fakeElement.data( 'cke-realelement' ) ),
161 this.document );
162
163 if ( fakeElement.data( 'cke-resizable') )
164 {
165 var width = fakeElement.getStyle( 'width' ),
166 height = fakeElement.getStyle( 'height' );
167
168 width && element.setAttribute( 'width', replaceCssLength( element.getAttribute( 'width' ), width ) );
169 height && element.setAttribute( 'height', replaceCssLength( element.getAttribute( 'height' ), height ) );
170 }
171
172 return element;
173 };
174
175 })();