Add a hook run after EditPage::attemptSave for WikiEditor
[mediawiki.git] / resources / src / jquery / jquery.expandableField.js
blob48341bc5419c52b8231b28320e03cc596367be21
1 /**
2  * This plugin provides functionality to expand a text box on focus to double it's current width
3  *
4  * Usage:
5  *
6  * Set options:
7  *              $('#textbox').expandableField( { option1: value1, option2: value2 } );
8  *              $('#textbox').expandableField( option, value );
9  * Get option:
10  *              value = $('#textbox').expandableField( option );
11  * Initialize:
12  *              $('#textbox').expandableField();
13  *
14  * Options:
15  *
16  */
17 ( function ( $ ) {
19         $.expandableField = {
20                 /**
21                  * Expand the field, make the callback
22                  */
23                 expandField: function ( e, context ) {
24                         context.config.beforeExpand.call( context.data.$field, context );
25                         context.data.$field
26                                 .animate( { 'width': context.data.expandedWidth }, 'fast', function () {
27                                         context.config.afterExpand.call( this, context );
28                                 } );
29                 },
30                 /**
31                  * Condense the field, make the callback
32                  */
33                 condenseField: function ( e, context ) {
34                         context.config.beforeCondense.call( context.data.$field, context );
35                         context.data.$field
36                                 .animate( { 'width': context.data.condensedWidth }, 'fast', function () {
37                                         context.config.afterCondense.call( this, context );
38                                 } );
39                 },
40                 /**
41                  * Sets the value of a property, and updates the widget accordingly
42                  * @param property String Name of property
43                  * @param value Mixed Value to set property with
44                  */
45                 configure: function ( context, property, value ) {
46                         // TODO: Validate creation using fallback values
47                         context.config[property] = value;
48                 }
50         };
52         $.fn.expandableField = function () {
54                 // Multi-context fields
55                 var returnValue,
56                         args = arguments;
58                 $( this ).each( function () {
59                         var key, context, timeout;
61                         /* Construction / Loading */
63                         context = $( this ).data( 'expandableField-context' );
65                         // TODO: Do we need to check both null and undefined?
66                         if ( context === undefined || context === null ) {
67                                 context = {
68                                         config: {
69                                                 // callback function for before collapse
70                                                 beforeCondense: function () {},
72                                                 // callback function for before expand
73                                                 beforeExpand: function () {},
75                                                 // callback function for after collapse
76                                                 afterCondense: function () {},
78                                                 // callback function for after expand
79                                                 afterExpand: function () {},
81                                                 // Whether the field should expand to the left or the right -- defaults to left
82                                                 expandToLeft: true
83                                         }
84                                 };
85                         }
87                         /* API */
88                         // Handle various calling styles
89                         if ( args.length > 0 ) {
90                                 if ( typeof args[0] === 'object' ) {
91                                         // Apply set of properties
92                                         for ( key in args[0] ) {
93                                                 $.expandableField.configure( context, key, args[0][key] );
94                                         }
95                                 } else if ( typeof args[0] === 'string' ) {
96                                         if ( args.length > 1 ) {
97                                                 // Set property values
98                                                 $.expandableField.configure( context, args[0], args[1] );
100                                         // TODO: Do we need to check both null and undefined?
101                                         } else if ( returnValue === null || returnValue === undefined ) {
102                                                 // Get property values, but don't give access to internal data - returns only the first
103                                                 returnValue = ( args[0] in context.config ? undefined : context.config[args[0]] );
104                                         }
105                                 }
106                         }
108                         /* Initialization */
110                         if ( context.data === undefined ) {
111                                 context.data = {
112                                         // The width of the field in it's condensed state
113                                         condensedWidth: $( this ).width(),
115                                         // The width of the field in it's expanded state
116                                         expandedWidth: $( this ).width() * 2,
118                                         // Reference to the field
119                                         $field: $( this )
120                                 };
122                                 $( this )
123                                         .addClass( 'expandableField' )
124                                         .focus( function ( e ) {
125                                                 clearTimeout( timeout );
126                                                 $.expandableField.expandField( e, context );
127                                         } )
128                                         .blur( function ( e ) {
129                                                 timeout = setTimeout( function () {
130                                                         $.expandableField.condenseField( e, context );
131                                                 }, 250 );
132                                         } );
133                         }
134                         // Store the context for next time
135                         $( this ).data( 'expandableField-context', context );
136                 } );
137                 return returnValue !== undefined ? returnValue : $( this );
138         };
140 }( jQuery ) );