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