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 (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 'data-cke-realelement' : encodeURIComponent( realElement.getOuterHtml() ), 86 'data-cke-real-node-type' : realElement.type, 87 alt : label, 88 title : label, 89 align : realElement.getAttribute( 'align' ) || '' 90 }; 91 92 // Do not set "src" on high-contrast so the alt text is displayed. (#8945) 93 if ( !CKEDITOR.env.hc ) 94 attributes.src = CKEDITOR.getUrl( 'images/spacer.gif' ); 95 96 if ( realElementType ) 97 attributes[ 'data-cke-real-element-type' ] = realElementType; 98 99 if ( isResizable ) 100 { 101 attributes[ 'data-cke-resizable' ] = isResizable; 102 103 var fakeStyle = new cssStyle(); 104 105 var width = realElement.getAttribute( 'width' ), 106 height = realElement.getAttribute( 'height' ); 107 108 width && ( fakeStyle.rules.width = cssLength( width ) ); 109 height && ( fakeStyle.rules.height = cssLength( height ) ); 110 fakeStyle.populate( attributes ); 111 } 112 113 return this.document.createElement( 'img', { attributes : attributes } ); 114 }; 115 116 CKEDITOR.editor.prototype.createFakeParserElement = function( realElement, className, realElementType, isResizable ) 117 { 118 var lang = this.lang.fakeobjects, 119 label = lang[ realElementType ] || lang.unknown, 120 html; 121 122 var writer = new CKEDITOR.htmlParser.basicWriter(); 123 realElement.writeHtml( writer ); 124 html = writer.getHtml(); 125 126 var attributes = 127 { 128 'class' : className, 129 'data-cke-realelement' : encodeURIComponent( html ), 130 'data-cke-real-node-type' : realElement.type, 131 alt : label, 132 title : label, 133 align : realElement.attributes.align || '' 134 }; 135 136 // Do not set "src" on high-contrast so the alt text is displayed. (#8945) 137 if ( !CKEDITOR.env.hc ) 138 attributes.src = CKEDITOR.getUrl( 'images/spacer.gif' ); 139 140 if ( realElementType ) 141 attributes[ 'data-cke-real-element-type' ] = realElementType; 142 143 if ( isResizable ) 144 { 145 attributes[ 'data-cke-resizable' ] = isResizable; 146 var realAttrs = realElement.attributes, 147 fakeStyle = new cssStyle(); 148 149 var width = realAttrs.width, 150 height = realAttrs.height; 151 152 width != undefined && ( fakeStyle.rules.width = cssLength( width ) ); 153 height != undefined && ( fakeStyle.rules.height = cssLength ( height ) ); 154 fakeStyle.populate( attributes ); 155 } 156 157 return new CKEDITOR.htmlParser.element( 'img', attributes ); 158 }; 159 160 CKEDITOR.editor.prototype.restoreRealElement = function( fakeElement ) 161 { 162 if ( fakeElement.data( 'cke-real-node-type' ) != CKEDITOR.NODE_ELEMENT ) 163 return null; 164 165 var element = CKEDITOR.dom.element.createFromHtml( 166 decodeURIComponent( fakeElement.data( 'cke-realelement' ) ), 167 this.document ); 168 169 if ( fakeElement.data( 'cke-resizable') ) 170 { 171 var width = fakeElement.getStyle( 'width' ), 172 height = fakeElement.getStyle( 'height' ); 173 174 width && element.setAttribute( 'width', replaceCssLength( element.getAttribute( 'width' ), width ) ); 175 height && element.setAttribute( 'height', replaceCssLength( element.getAttribute( 'height' ), height ) ); 176 } 177 178 return element; 179 }; 180 181 })(); 182