X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fplugins%2Fdialog%2Fplugin.js;h=434a55bea948d683114c6d53d517eb32e8c0edf7;hb=3fe9cac293e090ea459a3ee10d78cbe9e1dd0e03;hp=b0b125cdce3bc45d7aec32a364f6d061f81f0a01;hpb=1056598c95187351dc58f4991d331e2258d038b5;p=ckeditor.git diff --git a/_source/plugins/dialog/plugin.js b/_source/plugins/dialog/plugin.js index b0b125c..434a55b 100644 --- a/_source/plugins/dialog/plugin.js +++ b/_source/plugins/dialog/plugin.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ @@ -93,6 +93,36 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; } } + // Handle dialog element validation state UI changes. + function handleFieldValidated( isValid, msg ) + { + var input = this.getInputElement(); + if ( input ) + { + isValid ? input.removeAttribute( 'aria-invalid' ) + : input.setAttribute( 'aria-invalid', true ); + } + + if ( !isValid ) + { + if ( this.select ) + this.select(); + else + this.focus(); + } + + msg && alert( msg ); + + this.fire( 'validated', { valid : isValid, msg : msg } ); + } + + function resetField() + { + var input = this.getInputElement(); + input && input.removeAttribute( 'aria-invalid' ); + } + + /** * This is the base class for runtime dialog objects. An instance of this * class represents a single named dialog for a single editor instance. @@ -108,7 +138,10 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; var definition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ], defaultDefinition = CKEDITOR.tools.clone( defaultDialogDefinition ), buttonsOrder = editor.config.dialog_buttonsOrder || 'OS', - dir = editor.lang.dir; + dir = editor.lang.dir, + tabsToRemove = {}, + i, + processed, stopPropagation; if ( ( buttonsOrder == 'OS' && CKEDITOR.env.mac ) || // The buttons in MacOS Apps are in reverse order (#4750) ( buttonsOrder == 'rtl' && dir == 'ltr' ) || @@ -189,7 +222,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; } , editor ).definition; - var tabsToRemove = {}; // Cache tabs that should be removed. if ( !( 'removeDialogTabs' in editor._ ) && editor.config.removeDialogTabs ) { @@ -273,25 +305,17 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; { if ( item.validate ) { - var isValid = item.validate( this ); + var retval = item.validate( this ), + invalid = typeof ( retval ) == 'string' || retval === false; - if ( typeof isValid == 'string' ) + if ( invalid ) { - alert( isValid ); - isValid = false; - } - - if ( isValid === false ) - { - if ( item.select ) - item.select(); - else - item.focus(); - evt.data.hide = false; evt.stop(); - return true; } + + handleFieldValidated.call( item, !invalid, typeof retval == 'string' ? retval : undefined ); + return invalid; } }); }, this, null, 0 ); @@ -336,10 +360,11 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; focusList[ i ].focusIndex = i; } - function changeFocus( forward ) + function changeFocus( offset ) { - var focusList = me._.focusList, - offset = forward ? 1 : -1; + var focusList = me._.focusList; + offset = offset || 0; + if ( focusList.length < 1 ) return; @@ -355,12 +380,13 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; var startIndex = ( current + offset + focusList.length ) % focusList.length, currentIndex = startIndex; - while ( !focusList[ currentIndex ].isFocusable() ) + while ( offset && !focusList[ currentIndex ].isFocusable() ) { currentIndex = ( currentIndex + offset + focusList.length ) % focusList.length; if ( currentIndex == startIndex ) break; } + focusList[ currentIndex ].focus(); // Select whole field content. @@ -370,18 +396,19 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; this.changeFocus = changeFocus; - var processed; - function focusKeydownHandler( evt ) + function keydownHandler( evt ) { // If I'm not the top dialog, ignore. if ( me != CKEDITOR.dialog._.currentTop ) return; var keystroke = evt.data.getKeystroke(), - rtl = editor.lang.dir == 'rtl'; + rtl = editor.lang.dir == 'rtl', + button; + + processed = stopPropagation = 0; - processed = 0; if ( keystroke == 9 || keystroke == CKEDITOR.SHIFT + 9 ) { var shiftPressed = ( keystroke == CKEDITOR.SHIFT + 9 ); @@ -397,7 +424,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; else { // Change the focus of inputs. - changeFocus( !shiftPressed ); + changeFocus( shiftPressed ? -1 : 1 ); } processed = 1; @@ -422,43 +449,75 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; this.selectPage( this._.currentTabId ); this._.tabBarMode = false; this._.currentFocusIndex = -1; - changeFocus( true ); + changeFocus( 1 ); processed = 1; } - - if ( processed ) + // If user presses enter key in a text box, it implies clicking OK for the dialog. + else if ( keystroke == 13 /*ENTER*/ ) { - evt.stop(); - evt.data.preventDefault(); + // Don't do that for a target that handles ENTER. + var target = evt.data.getTarget(); + if ( !target.is( 'a', 'button', 'select', 'textarea' ) && ( !target.is( 'input' ) || target.$.type != 'button' ) ) + { + button = this.getButton( 'ok' ); + button && CKEDITOR.tools.setTimeout( button.click, 0, button ); + processed = 1; + } + stopPropagation = 1; // Always block the propagation (#4269) } + else if ( keystroke == 27 /*ESC*/ ) + { + button = this.getButton( 'cancel' ); + + // If there's a Cancel button, click it, else just fire the cancel event and hide the dialog. + if ( button ) + CKEDITOR.tools.setTimeout( button.click, 0, button ); + else + { + if ( this.fire( 'cancel', { hide : true } ).hide !== false ) + this.hide(); + } + stopPropagation = 1; // Always block the propagation (#4269) + } + else + return; + + keypressHandler( evt ); } - function focusKeyPressHandler( evt ) + function keypressHandler( evt ) { - processed && evt.data.preventDefault(); + if ( processed ) + evt.data.preventDefault(1); + else if ( stopPropagation ) + evt.data.stopPropagation(); } var dialogElement = this._.element; // Add the dialog keyboard handlers. this.on( 'show', function() { - dialogElement.on( 'keydown', focusKeydownHandler, this, null, 0 ); + dialogElement.on( 'keydown', keydownHandler, this ); + // Some browsers instead, don't cancel key events in the keydown, but in the - // keypress. So we must do a longer trip in those cases. (#4531) - if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) ) - dialogElement.on( 'keypress', focusKeyPressHandler, this ); + // keypress. So we must do a longer trip in those cases. (#4531,#8985) + if ( CKEDITOR.env.opera || CKEDITOR.env.gecko ) + dialogElement.on( 'keypress', keypressHandler, this ); } ); this.on( 'hide', function() { - dialogElement.removeListener( 'keydown', focusKeydownHandler ); - if ( CKEDITOR.env.opera || ( CKEDITOR.env.gecko && CKEDITOR.env.mac ) ) - dialogElement.removeListener( 'keypress', focusKeyPressHandler ); + dialogElement.removeListener( 'keydown', keydownHandler ); + if ( CKEDITOR.env.opera || CKEDITOR.env.gecko ) + dialogElement.removeListener( 'keypress', keypressHandler ); + + // Reset fields state when closing dialog. + iterContents( function( item ) { resetField.apply( item ); } ); } ); this.on( 'iframeAdded', function( evt ) { var doc = new CKEDITOR.dom.document( evt.data.iframe.$.contentWindow.document ); - doc.on( 'keydown', focusKeydownHandler, this, null, 0 ); + doc.on( 'keydown', keydownHandler, this, null, 0 ); } ); // Auto-focus logic in dialog. @@ -487,7 +546,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; } // Focus the first field in layout order. else - changeFocus( true ); + changeFocus( 1 ); /* * IE BUG: If the initial focus went into a non-text element (e.g. button), @@ -533,7 +592,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; ( new CKEDITOR.dom.text( definition.title, CKEDITOR.document ) ).appendTo( this.parts.title ); // Insert the tabs and contents. - for ( var i = 0 ; i < definition.contents.length ; i++ ) + for ( i = 0 ; i < definition.contents.length ; i++ ) { var page = definition.contents[i]; page && this.addPage( page ); @@ -553,7 +612,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; { this._.tabBarMode = false; this._.currentFocusIndex = -1; - changeFocus( true ); + changeFocus( 1 ); } evt.data.preventDefault(); } @@ -606,6 +665,15 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; } ); } + // Re-layout the dialog on window resize. + function resizeWithWindow( dialog ) + { + var win = CKEDITOR.document.getWindow(); + function resizeHandler() { dialog.layout(); } + win.on( 'resize', resizeHandler ); + dialog.on( 'hide', function() { win.removeListener( 'resize', resizeHandler ); } ); + } + CKEDITOR.dialog.prototype = { destroy : function() @@ -674,49 +742,54 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; * @example * dialogObj.move( 10, 40 ); */ - move : (function() - { - var isFixed; - return function( x, y, save ) - { - // The dialog may be fixed positioned or absolute positioned. Ask the - // browser what is the current situation first. - var element = this._.element.getFirst(), - rtl = this._.editor.lang.dir == 'rtl'; - - if ( isFixed === undefined ) - isFixed = element.getComputedStyle( 'position' ) == 'fixed'; - - if ( isFixed && this._.position && this._.position.x == x && this._.position.y == y ) - return; + move : function( x, y, save ) + { + // The dialog may be fixed positioned or absolute positioned. Ask the + // browser what is the current situation first. + var element = this._.element.getFirst(), + rtl = this._.editor.lang.dir == 'rtl'; + + var isFixed = element.getComputedStyle( 'position' ) == 'fixed'; + + // (#8888) In some cases of a very small viewport, dialog is incorrectly + // positioned in IE7. It also happens that it remains sticky and user cannot + // scroll down/up to reveal dialog's content below/above the viewport; this is + // cumbersome. + // The only way to fix this is to move mouse out of the browser and + // go back to see that dialog position is automagically fixed. No events, + // no style change - pure magic. This is a IE7 rendering issue, which can be + // fixed with dummy style redraw on each move. + element.setStyle( 'zoom', '100%' ); + + if ( isFixed && this._.position && this._.position.x == x && this._.position.y == y ) + return; - // Save the current position. - this._.position = { x : x, y : y }; + // Save the current position. + this._.position = { x : x, y : y }; - // If not fixed positioned, add scroll position to the coordinates. - if ( !isFixed ) - { - var scrollPosition = CKEDITOR.document.getWindow().getScrollPosition(); - x += scrollPosition.x; - y += scrollPosition.y; - } + // If not fixed positioned, add scroll position to the coordinates. + if ( !isFixed ) + { + var scrollPosition = CKEDITOR.document.getWindow().getScrollPosition(); + x += scrollPosition.x; + y += scrollPosition.y; + } - // Translate coordinate for RTL. - if ( rtl ) - { - var dialogSize = this.getSize(), - viewPaneSize = CKEDITOR.document.getWindow().getViewPaneSize(); - x = viewPaneSize.width - dialogSize.width - x; - } + // Translate coordinate for RTL. + if ( rtl ) + { + var dialogSize = this.getSize(), + viewPaneSize = CKEDITOR.document.getWindow().getViewPaneSize(); + x = viewPaneSize.width - dialogSize.width - x; + } - var styles = { 'top' : ( y > 0 ? y : 0 ) + 'px' }; - styles[ rtl ? 'right' : 'left' ] = ( x > 0 ? x : 0 ) + 'px'; + var styles = { 'top' : ( y > 0 ? y : 0 ) + 'px' }; + styles[ rtl ? 'right' : 'left' ] = ( x > 0 ? x : 0 ) + 'px'; - element.setStyles( styles ); + element.setStyles( styles ); - save && ( this._.moved = 1 ); - }; - })(), + save && ( this._.moved = 1 ); + }, /** * Gets the dialog's position in the window. @@ -769,19 +842,12 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; this._.element.getFirst().setStyle( 'z-index', CKEDITOR.dialog._.currentZIndex += 10 ); // Maintain the dialog ordering and dialog cover. - // Also register key handlers if first dialog. if ( CKEDITOR.dialog._.currentTop === null ) { CKEDITOR.dialog._.currentTop = this; this._.parentDialog = null; showCover( this._.editor ); - element.on( 'keydown', accessKeyDownHandler ); - element.on( CKEDITOR.env.opera ? 'keypress' : 'keyup', accessKeyUpHandler ); - - // Prevent some keys from bubbling up. (#4269) - for ( var event in { keyup :1, keydown :1, keypress :1 } ) - element.on( event, preventKeyBubbling ); } else { @@ -791,11 +857,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; CKEDITOR.dialog._.currentTop = this; } - // Register the Esc hotkeys. - registerAccessKey( this, this, '\x1b', null, function() - { - this.getButton( 'cancel' ) && this.getButton( 'cancel' ).click(); - } ); + element.on( 'keydown', accessKeyDownHandler ); + element.on( CKEDITOR.env.opera ? 'keypress' : 'keyup', accessKeyUpHandler ); // Reset the hasFocus state. this._.hasFocus = false; @@ -803,6 +866,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; CKEDITOR.tools.setTimeout( function() { this.layout(); + resizeWithWindow( this ); + this.parts.dialog.setStyle( 'visibility', '' ); // Execute onLoad for the first show. @@ -825,11 +890,26 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; */ layout : function() { - var viewSize = CKEDITOR.document.getWindow().getViewPaneSize(), - dialogSize = this.getSize(); + var el = this.parts.dialog; + var dialogSize = this.getSize(); + var win = CKEDITOR.document.getWindow(), + viewSize = win.getViewPaneSize(); + + var posX = ( viewSize.width - dialogSize.width ) / 2, + posY = ( viewSize.height - dialogSize.height ) / 2; + + // Switch to absolute position when viewport is smaller than dialog size. + if ( !CKEDITOR.env.ie6Compat ) + { + if ( dialogSize.height + ( posY > 0 ? posY : 0 ) > viewSize.height || + dialogSize.width + ( posX > 0 ? posX : 0 ) > viewSize.width ) + el.setStyle( 'position', 'absolute' ); + else + el.setStyle( 'position', 'fixed' ); + } - this.move( this._.moved ? this._.position.x : ( viewSize.width - dialogSize.width ) / 2, - this._.moved ? this._.position.y : ( viewSize.height - dialogSize.height ) / 2 ); + this.move( this._.moved ? this._.position.x : posX, + this._.moved ? this._.position.y : posY ); }, /** @@ -842,7 +922,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; for ( var i in this._.contents ) { for ( var j in this._.contents[i] ) - fn( this._.contents[i][j] ); + fn.call( this, this._.contents[i][j] ); } return this; }, @@ -893,6 +973,10 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; var args = arguments; this.foreach( function( widget ) { + // Make sure IE triggers "change" event on last focused input before closing the dialog. (#7915) + if ( CKEDITOR.env.ie && this._.currentFocusIndex == widget.focusIndex ) + widget.getInputElement().$.blur(); + if ( widget.commit ) widget.commit.apply( widget, args ); }); @@ -910,6 +994,8 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; this.fire( 'hide', {} ); this._.editor.fire( 'dialogHide', this ); + // Reset the tab page. + this.selectPage( this._.tabIdList[ 0 ] ); var element = this._.element; element.setStyle( 'display', 'none' ); this.parts.dialog.setStyle( 'visibility', 'hidden' ); @@ -939,10 +1025,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; element.removeListener( 'keydown', accessKeyDownHandler ); element.removeListener( CKEDITOR.env.opera ? 'keypress' : 'keyup', accessKeyUpHandler ); - // Remove bubbling-prevention handler. (#4269) - for ( var event in { keyup :1, keydown :1, keypress :1 } ) - element.removeListener( event, preventKeyBubbling ); - var editor = this._.editor; editor.focus(); @@ -2159,14 +2241,6 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; { }; - // ESC, ENTER - var preventKeyBubblingKeys = { 27 :1, 13 :1 }; - var preventKeyBubbling = function( e ) - { - if ( e.data.getKeystroke() in preventKeyBubblingKeys ) - e.data.stopPropagation(); - }; - (function() { CKEDITOR.ui.dialog = @@ -2241,6 +2315,9 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; classes[ 'cke_dialog_ui_' + elementDefinition.type ] = 1; if ( elementDefinition.className ) classes[ elementDefinition.className ] = 1; + if ( elementDefinition.disabled ) + classes[ 'cke_disabled' ] = 1; + var attributeClasses = ( attributes['class'] && attributes['class'].split ) ? attributes['class'].split( ' ' ) : []; for ( i = 0 ; i < attributeClasses.length ; i++ ) { @@ -2258,6 +2335,15 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; // Write the inline CSS styles. var styleStr = ( elementDefinition.style || '' ).split( ';' ); + + // Element alignment support. + if ( elementDefinition.align ) + { + var align = elementDefinition.align; + styles[ 'margin-left' ] = align == 'left' ? 0 : 'auto'; + styles[ 'margin-right' ] = align == 'right' ? 0 : 'auto'; + } + for ( i in styles ) styleStr.push( i + ':' + styles[i] ); if ( elementDefinition.hidden ) @@ -2288,6 +2374,23 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; if ( typeof( elementDefinition.isChanged ) == 'function' ) this.isChanged = elementDefinition.isChanged; + // Overload 'get(set)Value' on definition. + if ( typeof( elementDefinition.setValue ) == 'function' ) + { + this.setValue = CKEDITOR.tools.override( this.setValue, function( org ) + { + return function( val ){ org.call( this, elementDefinition.setValue.call( this, val ) ); }; + } ); + } + + if ( typeof( elementDefinition.getValue ) == 'function' ) + { + this.getValue = CKEDITOR.tools.override( this.getValue, function( org ) + { + return function(){ return elementDefinition.getValue.call( this, org.call( this ) ); }; + } ); + } + // Add events. CKEDITOR.event.implementOn( this ); @@ -2298,14 +2401,24 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; var me = this; dialog.on( 'load', function() { - if ( me.getInputElement() ) + var input = me.getInputElement(); + if ( input ) { - me.getInputElement().on( 'focus', function() + var focusClass = me.type in { 'checkbox' : 1, 'ratio' : 1 } && CKEDITOR.env.ie && CKEDITOR.env.version < 8 ? 'cke_dialog_ui_focused' : ''; + input.on( 'focus', function() { dialog._.tabBarMode = false; dialog._.hasFocus = true; me.fire( 'focus' ); - }, me ); + focusClass && this.addClass( focusClass ); + + }); + + input.on( 'blur', function() + { + me.fire( 'blur' ); + focusClass && this.removeClass( focusClass ); + }); } } ); @@ -2388,6 +2501,9 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; styles.push( 'height:' + cssLength( height ) ); if ( elementDefinition && elementDefinition.padding != undefined ) styles.push( 'padding:' + cssLength( elementDefinition.padding ) ); + // In IE Quirks alignment has to be done on table cells. (#7324) + if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && children[ i ].align ) + styles.push( 'text-align:' + children[ i ].align ); if ( styles.length > 0 ) html.push( 'style="' + styles.join('; ') + '" ' ); html.push( '>', childHtmlList[i], '' ); @@ -2473,6 +2589,9 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; styles.push( 'height:' + Math.floor( 100 / childHtmlList.length ) + '%' ); if ( elementDefinition && elementDefinition.padding != undefined ) styles.push( 'padding:' + cssLength( elementDefinition.padding ) ); + // In IE Quirks alignment has to be done on table cells. (#7324) + if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && children[ i ].align ) + styles.push( 'text-align:' + children[ i ].align ); if ( styles.length > 0 ) html.push( 'style="', styles.join( '; ' ), '" ' ); html.push( ' class="cke_dialog_ui_vbox_child">', childHtmlList[i], '' ); @@ -2725,8 +2844,9 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; */ disable : function() { - var element = this.getInputElement(); - element.setAttribute( 'disabled', 'true' ); + var element = this.getElement(), + input = this.getInputElement(); + input.setAttribute( 'disabled', 'true' ); element.addClass( 'cke_disabled' ); }, @@ -2736,8 +2856,9 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; */ enable : function() { - var element = this.getInputElement(); - element.removeAttribute( 'disabled' ); + var element = this.getElement(), + input = this.getInputElement(); + input.removeAttribute( 'disabled' ); element.removeClass( 'cke_disabled' ); }, @@ -2748,7 +2869,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; */ isEnabled : function() { - return !this.getInputElement().getAttribute( 'disabled' ); + return !this.getElement().hasClass( 'cke_disabled' ); }, /** @@ -2857,7 +2978,10 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; /** @ignore */ exec : function( editor ) { - editor.openDialog( this.dialogName ); + // Special treatment for Opera. (#8031) + CKEDITOR.env.opera ? + CKEDITOR.tools.setTimeout( function() { editor.openDialog( this.dialogName ); }, 0, this ) + : editor.openDialog( this.dialogName ); }, // Dialog commands just open a dialog ui, thus require no undo logic, @@ -2871,7 +2995,10 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; { var notEmptyRegex = /^([a]|[^a])+$/, integerRegex = /^\d*$/, - numberRegex = /^\d*(?:\.\d+)?$/; + numberRegex = /^\d*(?:\.\d+)?$/, + htmlLengthRegex = /^(((\d*(\.\d+))|(\d*))(px|\%)?)?$/, + cssLengthRegex = /^(((\d*(\.\d+))|(\d*))(px|em|ex|in|cm|mm|pt|pc|\%)?)?$/i, + inlineStyleRegex = /^(\s*[\w-]+\s*:\s*[^:;]+(?:;|$))*$/; CKEDITOR.VALIDATE_OR = 1; CKEDITOR.VALIDATE_AND = 2; @@ -2880,6 +3007,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; { functions : function() { + var args = arguments; return function() { /** @@ -2888,28 +3016,28 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; * combine validate functions together to make more sophisticated * validators. */ - var value = this && this.getValue ? this.getValue() : arguments[0]; + var value = this && this.getValue ? this.getValue() : args[ 0 ]; var msg = undefined, relation = CKEDITOR.VALIDATE_AND, functions = [], i; - for ( i = 0 ; i < arguments.length ; i++ ) + for ( i = 0 ; i < args.length ; i++ ) { - if ( typeof( arguments[i] ) == 'function' ) - functions.push( arguments[i] ); + if ( typeof( args[i] ) == 'function' ) + functions.push( args[i] ); else break; } - if ( i < arguments.length && typeof( arguments[i] ) == 'string' ) + if ( i < args.length && typeof( args[i] ) == 'string' ) { - msg = arguments[i]; + msg = args[i]; i++; } - if ( i < arguments.length && typeof( arguments[i]) == 'number' ) - relation = arguments[i]; + if ( i < args.length && typeof( args[i]) == 'number' ) + relation = args[i]; var passed = ( relation == CKEDITOR.VALIDATE_AND ? true : false ); for ( i = 0 ; i < functions.length ; i++ ) @@ -2920,16 +3048,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; passed = passed || functions[i]( value ); } - if ( !passed ) - { - if ( msg !== undefined ) - alert( msg ); - if ( this && ( this.select || this.focus ) ) - ( this.select || this.focus )(); - return false; - } - - return true; + return !passed ? msg : true; }; }, @@ -2942,20 +3061,7 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; return function() { var value = this && this.getValue ? this.getValue() : arguments[0]; - if ( !regex.test( value ) ) - { - if ( msg !== undefined ) - alert( msg ); - if ( this && ( this.select || this.focus ) ) - { - if ( this.select ) - this.select(); - else - this.focus(); - } - return false; - } - return true; + return !regex.test( value ) ? msg : true; }; }, @@ -2974,6 +3080,21 @@ CKEDITOR.DIALOG_RESIZE_BOTH = 3; return this.regex( numberRegex, msg ); }, + 'cssLength' : function( msg ) + { + return this.functions( function( val ){ return cssLengthRegex.test( CKEDITOR.tools.trim( val ) ); }, msg ); + }, + + 'htmlLength' : function( msg ) + { + return this.functions( function( val ){ return htmlLengthRegex.test( CKEDITOR.tools.trim( val ) ); }, msg ); + }, + + 'inlineStyle' : function( msg ) + { + return this.functions( function( val ){ return inlineStyleRegex.test( CKEDITOR.tools.trim( val ) ); }, msg ); + }, + equals : function( value, msg ) { return this.functions( function( val ){ return val == value; }, msg );