2 Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
3 For licensing, see LICENSE.html or http://ckeditor.com/license
6 CKEDITOR.dialog.add( 'docProps', function( editor )
8 var lang = editor.lang.docprops,
9 langCommon = editor.lang.common,
12 function getDialogValue( dialogName, callback )
16 releaseHandlers( this );
17 callback( this, this._.parentDialog );
19 var releaseHandlers = function( dialog )
21 dialog.removeListener( 'ok', onOk );
22 dialog.removeListener( 'cancel', releaseHandlers );
24 var bindToDialog = function( dialog )
26 dialog.on( 'ok', onOk );
27 dialog.on( 'cancel', releaseHandlers );
29 editor.execCommand( dialogName );
30 if ( editor._.storedDialogs.colordialog )
31 bindToDialog( editor._.storedDialogs.colordialog );
34 CKEDITOR.on( 'dialogDefinition', function( e )
36 if ( e.data.name != dialogName )
39 var definition = e.data.definition;
42 definition.onLoad = CKEDITOR.tools.override( definition.onLoad, function( orginal )
47 definition.onLoad = orginal;
48 if ( typeof orginal == 'function' )
55 function handleOther()
57 var dialog = this.getDialog(),
58 other = dialog.getContentElement( 'general', this.id + 'Other' );
61 if ( this.getValue() == 'other' )
63 other.getInputElement().removeAttribute( 'readOnly' );
65 other.getElement().removeClass( 'cke_disabled' );
69 other.getInputElement().setAttribute( 'readOnly', true );
70 other.getElement().addClass( 'cke_disabled' );
73 function commitMeta( name, isHttp, value )
75 return function( doc, html, head )
78 val = typeof value != 'undefined' ? value : this.getValue();
79 if ( !val && ( name in hash ) )
80 hash[ name ].remove();
81 else if ( val && ( name in hash ) )
82 hash[ name ].setAttribute( 'content', val );
85 var meta = new CKEDITOR.dom.element( 'meta', editor.document );
86 meta.setAttribute( isHttp ? 'http-equiv' : 'name', name );
87 meta.setAttribute( 'content', val );
92 function setupMeta( name, ret )
97 result = ( name in hash ) ? hash[ name ].getAttribute( 'content' ) || '' : '';
100 this.setValue( result );
104 function commitMargin( name )
106 return function( doc, html, head, body )
108 body.removeAttribute( 'margin' + name );
109 var val = this.getValue();
111 body.setStyle( 'margin-' + name, CKEDITOR.tools.cssLength( val ) );
113 body.removeStyle( 'margin-' + name );
117 function createMetaHash( doc )
120 metas = doc.getElementsByTag( 'meta' ),
121 count = metas.count();
123 for ( var i = 0; i < count; i++ )
125 var meta = metas.getItem( i );
126 hash[ meta.getAttribute( meta.hasAttribute( 'http-equiv' ) ? 'http-equiv' : 'name' ).toLowerCase() ] = meta;
130 // We cannot just remove the style from the element, as it might be affected from non-inline stylesheets.
131 // To get the proper result, we should manually set the inline style to its default value.
132 function resetStyle( element, prop, resetVal )
134 element.removeStyle( prop );
135 if ( element.getComputedStyle( prop ) != resetVal )
136 element.setStyle( prop, resetVal );
139 // Utilty to shorten the creation of color fields in the dialog.
140 var colorField = function( id, label, fieldProps )
145 widths : [ '60%', '40%' ],
147 CKEDITOR.tools.extend( {
150 label : lang[ label ]
151 }, fieldProps || {}, 1 ),
155 label : lang.chooseColor,
156 className : 'colorChooser',
160 getDialogValue( 'colordialog', function( colorDialog )
162 var dialog = self.getDialog();
163 dialog.getContentElement( dialog._.currentTabId, id ).setValue( colorDialog.getContentElement( 'picker', 'selectedColor' ).getValue() );
170 var previewSrc = 'javascript:' +
171 'void((function(){' +
174 ( CKEDITOR.env.isCustomDomain() ? 'document.domain=\'' + document.domain + '\';' : '' ) +
175 'document.write( \'<html style="background-color: #ffffff; height: 100%"><head></head><body style="width: 100%; height: 100%; margin: 0px">' + lang.previewHtml + '</body></html>\' );' +
186 var doc = editor.document,
187 html = doc.getElementsByTag( 'html' ).getItem( 0 ),
188 head = doc.getHead(),
189 body = doc.getBody();
190 metaHash = createMetaHash( doc );
191 this.setupContent( doc, html, head, body );
199 var doc = editor.document,
200 html = doc.getElementsByTag( 'html' ).getItem( 0 ),
201 head = doc.getHead(),
202 body = doc.getBody();
203 this.commitContent( doc, html, head, body );
208 label : langCommon.generalTab,
213 label : lang.docTitle,
214 setup : function( doc )
216 this.setValue( doc.getElementsByTag( 'title' ).getItem( 0 ).data( 'cke-title' ) );
218 commit : function( doc, html, head, body, isPreview )
222 doc.getElementsByTag( 'title' ).getItem( 0 ).data( 'cke-title', this.getValue() );
231 label : langCommon.langDir,
232 style : 'width: 100%',
234 [ langCommon.notSet , '' ],
235 [ langCommon.langDirLtr, 'ltr' ],
236 [ langCommon.langDirRtl, 'rtl' ]
238 setup : function( doc, html, head, body )
240 this.setValue( body.getDirection() || '' );
242 commit : function( doc, html, head, body )
244 var val = this.getValue();
246 body.setAttribute( 'dir', val );
248 body.removeAttribute( 'dir' );
249 body.removeStyle( 'direction' );
255 label : langCommon.langCode,
256 setup : function( doc, html )
258 this.setValue( html.getAttribute( 'xml:lang' ) || html.getAttribute( 'lang' ) || '' );
260 commit : function( doc, html, head, body, isPreview )
264 var val = this.getValue();
266 html.setAttributes( { 'xml:lang' : val, lang : val } );
268 html.removeAttributes( { 'xml:lang' : 1, lang : 1 } );
279 label : lang.charset,
280 style : 'width: 100%',
282 [ langCommon.notSet, '' ],
283 [ lang.charsetASCII, 'us-ascii' ],
284 [ lang.charsetCE, 'iso-8859-2' ],
285 [ lang.charsetCT, 'big5' ],
286 [ lang.charsetCR, 'iso-8859-5' ],
287 [ lang.charsetGR, 'iso-8859-7' ],
288 [ lang.charsetJP, 'iso-2022-jp' ],
289 [ lang.charsetKR, 'iso-2022-kr' ],
290 [ lang.charsetTR, 'iso-8859-9' ],
291 [ lang.charsetUN, 'utf-8' ],
292 [ lang.charsetWE, 'iso-8859-1' ],
293 [ lang.other, 'other' ]
296 onChange : function()
298 this.getDialog().selectedCharset = this.getValue() != 'other' ? this.getValue() : '';
299 handleOther.call( this );
303 this.metaCharset = ( 'charset' in metaHash );
305 var func = setupMeta( this.metaCharset ? 'charset' : 'content-type', 1, 1 ),
306 val = func.call( this );
308 !this.metaCharset && val.match( /charset=[^=]+$/ ) && ( val = val.substring( val.indexOf( '=' ) + 1 ) );
312 this.setValue( val.toLowerCase() );
313 if ( !this.getValue() )
315 this.setValue( 'other' );
316 var other = this.getDialog().getContentElement( 'general', 'charsetOther' );
317 other && other.setValue( val );
319 this.getDialog().selectedCharset = val;
322 handleOther.call( this );
324 commit : function( doc, html, head, body, isPreview )
328 var value = this.getValue(),
329 other = this.getDialog().getContentElement( 'general', 'charsetOther' );
331 value == 'other' && ( value = other ? other.getValue() : '' );
333 value && !this.metaCharset && ( value = ( metaHash[ 'content-type' ] ? metaHash[ 'content-type' ].getAttribute( 'content' ).split( ';' )[0] : 'text/html' ) + '; charset=' + value );
335 var func = commitMeta( this.metaCharset ? 'charset' : 'content-type', 1, value );
336 func.call( this, doc, html, head );
342 label : lang.charsetOther,
343 onChange : function(){ this.getDialog().selectedCharset = this.getValue(); }
353 label : lang.docType,
354 style : 'width: 100%',
356 [ langCommon.notSet , '' ],
357 [ 'XHTML 1.1', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">' ],
358 [ 'XHTML 1.0 Transitional', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' ],
359 [ 'XHTML 1.0 Strict', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' ],
360 [ 'XHTML 1.0 Frameset', '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">' ],
361 [ 'HTML 5', '<!DOCTYPE html>' ],
362 [ 'HTML 4.01 Transitional', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' ],
363 [ 'HTML 4.01 Strict', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' ],
364 [ 'HTML 4.01 Frameset', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">' ],
365 [ 'HTML 3.2', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">' ],
366 [ 'HTML 2.0', '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">' ],
367 [ lang.other, 'other' ]
369 onChange : handleOther,
372 if ( editor.docType )
374 this.setValue( editor.docType );
375 if ( !this.getValue() )
377 this.setValue( 'other' );
378 var other = this.getDialog().getContentElement( 'general', 'docTypeOther' );
379 other && other.setValue( editor.docType );
382 handleOther.call( this );
384 commit : function( doc, html, head, body, isPreview )
388 var value = this.getValue(),
389 other = this.getDialog().getContentElement( 'general', 'docTypeOther' );
390 editor.docType = value == 'other' ? ( other ? other.getValue() : '' ) : value;
396 label : lang.docTypeOther
403 label : lang.xhtmlDec,
406 this.setValue( !!editor.xmlDeclaration );
408 commit : function( doc, html, head, body, isPreview )
412 if ( this.getValue() )
414 editor.xmlDeclaration = '<?xml version="1.0" encoding="' + ( this.getDialog().selectedCharset || 'utf-8' )+ '"?>' ;
415 html.setAttribute( 'xmlns', 'http://www.w3.org/1999/xhtml' );
419 editor.xmlDeclaration = '';
420 html.removeAttribute( 'xmlns' );
432 widths : [ '60%', '40%' ],
437 colorField( 'txtColor', 'txtColor',
439 setup : function( doc, html, head, body )
441 this.setValue( body.getComputedStyle( 'color' ) );
443 commit : function( doc, html, head, body, isPreview )
445 if ( this.isChanged() || isPreview )
447 body.removeAttribute( 'text' );
448 var val = this.getValue();
450 body.setStyle( 'color', val );
452 body.removeStyle( 'color' );
456 colorField( 'bgColor', 'bgColor', {
457 setup : function( doc, html, head, body )
459 var val = body.getComputedStyle( 'background-color' ) || '';
460 this.setValue( val == 'transparent' ? '' : val );
462 commit : function( doc, html, head, body, isPreview )
464 if ( this.isChanged() || isPreview )
466 body.removeAttribute( 'bgcolor' );
467 var val = this.getValue();
469 body.setStyle( 'background-color', val );
471 resetStyle( body, 'background-color', 'transparent' );
477 widths : [ '60%', '40%' ],
483 label : lang.bgImage,
484 setup : function( doc, html, head, body )
486 var val = body.getComputedStyle( 'background-image' ) || '';
491 val = val.replace( /url\(\s*(["']?)\s*([^\)]*)\s*\1\s*\)/i, function( match, quote, url )
496 this.setValue( val );
498 commit : function( doc, html, head, body )
500 body.removeAttribute( 'background' );
501 var val = this.getValue();
503 body.setStyle( 'background-image', 'url(' + val + ')' );
505 resetStyle( body, 'background-image', 'none' );
510 id : 'bgImageChoose',
511 label : langCommon.browseServer,
512 style : 'display:inline-block;margin-top:10px;',
514 filebrowser : 'design:bgImage'
521 label : lang.bgFixed,
522 setup : function( doc, html, head, body )
524 this.setValue( body.getComputedStyle( 'background-attachment' ) == 'fixed' );
526 commit : function( doc, html, head, body )
528 if ( this.getValue() )
529 body.setStyle( 'background-attachment', 'fixed' );
531 resetStyle( body, 'background-attachment', 'scroll' );
542 html : '<div style="text-align: center; margin: 0px auto; font-weight: bold">' + lang.margin + '</div>'
547 label : lang.marginTop,
548 style : 'width: 80px; text-align: center',
550 inputStyle : 'text-align: center',
551 setup : function( doc, html, head, body )
553 this.setValue( body.getStyle( 'margin-top' ) || body.getAttribute( 'margintop' ) || '' );
555 commit : commitMargin( 'top' )
563 label : lang.marginLeft,
564 style : 'width: 80px; text-align: center',
566 inputStyle : 'text-align: center',
567 setup : function( doc, html, head, body )
569 this.setValue( body.getStyle( 'margin-left' ) || body.getAttribute( 'marginleft' ) || '' );
571 commit : commitMargin( 'left' )
576 label : lang.marginRight,
577 style : 'width: 80px; text-align: center',
579 inputStyle : 'text-align: center',
580 setup : function( doc, html, head, body )
582 this.setValue( body.getStyle( 'margin-right' ) || body.getAttribute( 'marginright' ) || '' );
584 commit : commitMargin( 'right' )
591 label : lang.marginBottom,
592 style : 'width: 80px; text-align: center',
594 inputStyle : 'text-align: center',
595 setup : function( doc, html, head, body )
597 this.setValue( body.getStyle( 'margin-bottom' ) || body.getAttribute( 'marginbottom' ) || '' );
599 commit : commitMargin( 'bottom' )
614 label : lang.metaKeywords,
615 setup : setupMeta( 'keywords' ),
616 commit : commitMeta( 'keywords' )
620 id : 'metaDescription',
621 label : lang.metaDescription,
622 setup : setupMeta( 'description' ),
623 commit : commitMeta( 'description' )
628 label : lang.metaAuthor,
629 setup : setupMeta( 'author' ),
630 commit : commitMeta( 'author' )
634 id : 'metaCopyright',
635 label : lang.metaCopyright,
636 setup : setupMeta( 'copyright' ),
637 commit : commitMeta( 'copyright' )
643 label : langCommon.preview,
648 html : '<iframe src="' + previewSrc + '" style="width: 100%; height: 310px" hidefocus="true" frameborder="0" ' +
649 'id="cke_docProps_preview_iframe"></iframe>',
652 this.getDialog().on( 'selectPage', function( ev )
654 if ( ev.data.page == 'preview' )
657 setTimeout( function()
659 var doc = CKEDITOR.document.getById( 'cke_docProps_preview_iframe' ).getFrameDocument(),
660 html = doc.getElementsByTag( 'html' ).getItem( 0 ),
661 head = doc.getHead(),
662 body = doc.getBody();
663 self.commitContent( doc, html, head, body, 1 );
667 CKEDITOR.document.getById( 'cke_docProps_preview_iframe' ).getAscendant( 'table' ).setStyle( 'height', '100%' );