plugin.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /**
  2. * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or http://ckeditor.com/license
  4. */
  5. ( function() {
  6. var cssStyle = CKEDITOR.htmlParser.cssStyle,
  7. cssLength = CKEDITOR.tools.cssLength;
  8. var cssLengthRegex = /^((?:\d*(?:\.\d+))|(?:\d+))(.*)?$/i;
  9. // Replacing the former CSS length value with the later one, with
  10. // adjustment to the length unit.
  11. function replaceCssLength( length1, length2 ) {
  12. var parts1 = cssLengthRegex.exec( length1 ),
  13. parts2 = cssLengthRegex.exec( length2 );
  14. // Omit pixel length unit when necessary,
  15. // e.g. replaceCssLength( 10, '20px' ) -> 20
  16. if ( parts1 ) {
  17. if ( !parts1[ 2 ] && parts2[ 2 ] == 'px' )
  18. return parts2[ 1 ];
  19. if ( parts1[ 2 ] == 'px' && !parts2[ 2 ] )
  20. return parts2[ 1 ] + 'px';
  21. }
  22. return length2;
  23. }
  24. var htmlFilterRules = {
  25. elements: {
  26. $: function( element ) {
  27. var attributes = element.attributes,
  28. realHtml = attributes && attributes[ 'data-cke-realelement' ],
  29. realFragment = realHtml && new CKEDITOR.htmlParser.fragment.fromHtml( decodeURIComponent( realHtml ) ),
  30. realElement = realFragment && realFragment.children[ 0 ];
  31. // Width/height in the fake object are subjected to clone into the real element.
  32. if ( realElement && element.attributes[ 'data-cke-resizable' ] ) {
  33. var styles = new cssStyle( element ).rules,
  34. realAttrs = realElement.attributes,
  35. width = styles.width,
  36. height = styles.height;
  37. width && ( realAttrs.width = replaceCssLength( realAttrs.width, width ) );
  38. height && ( realAttrs.height = replaceCssLength( realAttrs.height, height ) );
  39. }
  40. return realElement;
  41. }
  42. }
  43. };
  44. CKEDITOR.plugins.add( 'fakeobjects', {
  45. // jscs:disable maximumLineLength
  46. lang: 'af,ar,bg,bn,bs,ca,cs,cy,da,de,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%
  47. // jscs:enable maximumLineLength
  48. init: function( editor ) {
  49. // Allow image with all styles and classes plus src, alt and title attributes.
  50. // We need them when fakeobject is pasted.
  51. editor.filter.allow( 'img[!data-cke-realelement,src,alt,title](*){*}', 'fakeobjects' );
  52. },
  53. afterInit: function( editor ) {
  54. var dataProcessor = editor.dataProcessor,
  55. htmlFilter = dataProcessor && dataProcessor.htmlFilter;
  56. if ( htmlFilter ) {
  57. htmlFilter.addRules( htmlFilterRules, {
  58. applyToAll: true
  59. } );
  60. }
  61. }
  62. } );
  63. /**
  64. * @member CKEDITOR.editor
  65. * @todo
  66. */
  67. CKEDITOR.editor.prototype.createFakeElement = function( realElement, className, realElementType, isResizable ) {
  68. var lang = this.lang.fakeobjects,
  69. label = lang[ realElementType ] || lang.unknown;
  70. var attributes = {
  71. 'class': className,
  72. 'data-cke-realelement': encodeURIComponent( realElement.getOuterHtml() ),
  73. 'data-cke-real-node-type': realElement.type,
  74. alt: label,
  75. title: label,
  76. align: realElement.getAttribute( 'align' ) || ''
  77. };
  78. // Do not set "src" on high-contrast so the alt text is displayed. (#8945)
  79. if ( !CKEDITOR.env.hc )
  80. attributes.src = CKEDITOR.tools.transparentImageData;
  81. if ( realElementType )
  82. attributes[ 'data-cke-real-element-type' ] = realElementType;
  83. if ( isResizable ) {
  84. attributes[ 'data-cke-resizable' ] = isResizable;
  85. var fakeStyle = new cssStyle();
  86. var width = realElement.getAttribute( 'width' ),
  87. height = realElement.getAttribute( 'height' );
  88. width && ( fakeStyle.rules.width = cssLength( width ) );
  89. height && ( fakeStyle.rules.height = cssLength( height ) );
  90. fakeStyle.populate( attributes );
  91. }
  92. return this.document.createElement( 'img', { attributes: attributes } );
  93. };
  94. /**
  95. * @member CKEDITOR.editor
  96. * @todo
  97. */
  98. CKEDITOR.editor.prototype.createFakeParserElement = function( realElement, className, realElementType, isResizable ) {
  99. var lang = this.lang.fakeobjects,
  100. label = lang[ realElementType ] || lang.unknown,
  101. html;
  102. var writer = new CKEDITOR.htmlParser.basicWriter();
  103. realElement.writeHtml( writer );
  104. html = writer.getHtml();
  105. var attributes = {
  106. 'class': className,
  107. 'data-cke-realelement': encodeURIComponent( html ),
  108. 'data-cke-real-node-type': realElement.type,
  109. alt: label,
  110. title: label,
  111. align: realElement.attributes.align || ''
  112. };
  113. // Do not set "src" on high-contrast so the alt text is displayed. (#8945)
  114. if ( !CKEDITOR.env.hc )
  115. attributes.src = CKEDITOR.tools.transparentImageData;
  116. if ( realElementType )
  117. attributes[ 'data-cke-real-element-type' ] = realElementType;
  118. if ( isResizable ) {
  119. attributes[ 'data-cke-resizable' ] = isResizable;
  120. var realAttrs = realElement.attributes,
  121. fakeStyle = new cssStyle();
  122. var width = realAttrs.width,
  123. height = realAttrs.height;
  124. width !== undefined && ( fakeStyle.rules.width = cssLength( width ) );
  125. height !== undefined && ( fakeStyle.rules.height = cssLength( height ) );
  126. fakeStyle.populate( attributes );
  127. }
  128. return new CKEDITOR.htmlParser.element( 'img', attributes );
  129. };
  130. /**
  131. * @member CKEDITOR.editor
  132. * @todo
  133. */
  134. CKEDITOR.editor.prototype.restoreRealElement = function( fakeElement ) {
  135. if ( fakeElement.data( 'cke-real-node-type' ) != CKEDITOR.NODE_ELEMENT )
  136. return null;
  137. var element = CKEDITOR.dom.element.createFromHtml( decodeURIComponent( fakeElement.data( 'cke-realelement' ) ), this.document );
  138. if ( fakeElement.data( 'cke-resizable' ) ) {
  139. var width = fakeElement.getStyle( 'width' ),
  140. height = fakeElement.getStyle( 'height' );
  141. width && element.setAttribute( 'width', replaceCssLength( element.getAttribute( 'width' ), width ) );
  142. height && element.setAttribute( 'height', replaceCssLength( element.getAttribute( 'height' ), height ) );
  143. }
  144. return element;
  145. };
  146. } )();