1 /* 2 Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * @file Forms Plugin 8 */ 9 10 CKEDITOR.plugins.add( 'forms', 11 { 12 requires : [ 'dialog' ], 13 init : function( editor ) 14 { 15 var lang = editor.lang; 16 17 editor.addCss( 18 'form' + 19 '{' + 20 'border: 1px dotted #FF0000;' + 21 'padding: 2px;' + 22 '}\n' ); 23 24 editor.addCss( 25 'img.cke_hidden' + 26 '{' + 27 'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/hiddenfield.gif' ) + ');' + 28 'background-position: center center;' + 29 'background-repeat: no-repeat;' + 30 'border: 1px solid #a9a9a9;' + 31 'width: 16px !important;' + 32 'height: 16px !important;' + 33 '}' ); 34 35 // All buttons use the same code to register. So, to avoid 36 // duplications, let's use this tool function. 37 var addButtonCommand = function( buttonName, commandName, dialogFile ) 38 { 39 editor.addCommand( commandName, new CKEDITOR.dialogCommand( commandName ) ); 40 41 editor.ui.addButton( buttonName, 42 { 43 label : lang.common[ buttonName.charAt(0).toLowerCase() + buttonName.slice(1) ], 44 command : commandName 45 }); 46 CKEDITOR.dialog.add( commandName, dialogFile ); 47 }; 48 49 var dialogPath = this.path + 'dialogs/'; 50 addButtonCommand( 'Form', 'form', dialogPath + 'form.js' ); 51 addButtonCommand( 'Checkbox', 'checkbox', dialogPath + 'checkbox.js' ); 52 addButtonCommand( 'Radio', 'radio', dialogPath + 'radio.js' ); 53 addButtonCommand( 'TextField', 'textfield', dialogPath + 'textfield.js' ); 54 addButtonCommand( 'Textarea', 'textarea', dialogPath + 'textarea.js' ); 55 addButtonCommand( 'Select', 'select', dialogPath + 'select.js' ); 56 addButtonCommand( 'Button', 'button', dialogPath + 'button.js' ); 57 addButtonCommand( 'ImageButton', 'imagebutton', CKEDITOR.plugins.getPath('image') + 'dialogs/image.js' ); 58 addButtonCommand( 'HiddenField', 'hiddenfield', dialogPath + 'hiddenfield.js' ); 59 60 // If the "menu" plugin is loaded, register the menu items. 61 if ( editor.addMenuItems ) 62 { 63 editor.addMenuItems( 64 { 65 form : 66 { 67 label : lang.form.menu, 68 command : 'form', 69 group : 'form' 70 }, 71 72 checkbox : 73 { 74 label : lang.checkboxAndRadio.checkboxTitle, 75 command : 'checkbox', 76 group : 'checkbox' 77 }, 78 79 radio : 80 { 81 label : lang.checkboxAndRadio.radioTitle, 82 command : 'radio', 83 group : 'radio' 84 }, 85 86 textfield : 87 { 88 label : lang.textfield.title, 89 command : 'textfield', 90 group : 'textfield' 91 }, 92 93 hiddenfield : 94 { 95 label : lang.hidden.title, 96 command : 'hiddenfield', 97 group : 'hiddenfield' 98 }, 99 100 imagebutton : 101 { 102 label : lang.image.titleButton, 103 command : 'imagebutton', 104 group : 'imagebutton' 105 }, 106 107 button : 108 { 109 label : lang.button.title, 110 command : 'button', 111 group : 'button' 112 }, 113 114 select : 115 { 116 label : lang.select.title, 117 command : 'select', 118 group : 'select' 119 }, 120 121 textarea : 122 { 123 label : lang.textarea.title, 124 command : 'textarea', 125 group : 'textarea' 126 } 127 }); 128 } 129 130 // If the "contextmenu" plugin is loaded, register the listeners. 131 if ( editor.contextMenu ) 132 { 133 editor.contextMenu.addListener( function( element ) 134 { 135 if ( element && element.hasAscendant( 'form', true ) && !element.isReadOnly() ) 136 return { form : CKEDITOR.TRISTATE_OFF }; 137 }); 138 139 editor.contextMenu.addListener( function( element ) 140 { 141 if ( element && !element.isReadOnly() ) 142 { 143 var name = element.getName(); 144 145 if ( name == 'select' ) 146 return { select : CKEDITOR.TRISTATE_OFF }; 147 148 if ( name == 'textarea' ) 149 return { textarea : CKEDITOR.TRISTATE_OFF }; 150 151 if ( name == 'input' ) 152 { 153 switch( element.getAttribute( 'type' ) ) 154 { 155 case 'button' : 156 case 'submit' : 157 case 'reset' : 158 return { button : CKEDITOR.TRISTATE_OFF }; 159 160 case 'checkbox' : 161 return { checkbox : CKEDITOR.TRISTATE_OFF }; 162 163 case 'radio' : 164 return { radio : CKEDITOR.TRISTATE_OFF }; 165 166 case 'image' : 167 return { imagebutton : CKEDITOR.TRISTATE_OFF }; 168 169 default : 170 return { textfield : CKEDITOR.TRISTATE_OFF }; 171 } 172 } 173 174 if ( name == 'img' && element.data( 'cke-real-element-type' ) == 'hiddenfield' ) 175 return { hiddenfield : CKEDITOR.TRISTATE_OFF }; 176 } 177 }); 178 } 179 180 editor.on( 'doubleclick', function( evt ) 181 { 182 var element = evt.data.element; 183 184 if ( element.is( 'form' ) ) 185 evt.data.dialog = 'form'; 186 else if ( element.is( 'select' ) ) 187 evt.data.dialog = 'select'; 188 else if ( element.is( 'textarea' ) ) 189 evt.data.dialog = 'textarea'; 190 else if ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'hiddenfield' ) 191 evt.data.dialog = 'hiddenfield'; 192 else if ( element.is( 'input' ) ) 193 { 194 switch ( element.getAttribute( 'type' ) ) 195 { 196 case 'button' : 197 case 'submit' : 198 case 'reset' : 199 evt.data.dialog = 'button'; 200 break; 201 case 'checkbox' : 202 evt.data.dialog = 'checkbox'; 203 break; 204 case 'radio' : 205 evt.data.dialog = 'radio'; 206 break; 207 case 'image' : 208 evt.data.dialog = 'imagebutton'; 209 break; 210 default : 211 evt.data.dialog = 'textfield'; 212 break; 213 } 214 } 215 }); 216 }, 217 218 afterInit : function( editor ) 219 { 220 var dataProcessor = editor.dataProcessor, 221 htmlFilter = dataProcessor && dataProcessor.htmlFilter, 222 dataFilter = dataProcessor && dataProcessor.dataFilter; 223 224 // Cleanup certain IE form elements default values. 225 if ( CKEDITOR.env.ie ) 226 { 227 htmlFilter && htmlFilter.addRules( 228 { 229 elements : 230 { 231 input : function( input ) 232 { 233 var attrs = input.attributes, 234 type = attrs.type; 235 // Old IEs don't provide type for Text inputs #5522 236 if ( !type ) 237 attrs.type = 'text'; 238 if ( type == 'checkbox' || type == 'radio' ) 239 attrs.value == 'on' && delete attrs.value; 240 } 241 } 242 } ); 243 } 244 245 if ( dataFilter ) 246 { 247 dataFilter.addRules( 248 { 249 elements : 250 { 251 input : function( element ) 252 { 253 if ( element.attributes.type == 'hidden' ) 254 return editor.createFakeParserElement( element, 'cke_hidden', 'hiddenfield' ); 255 } 256 } 257 } ); 258 } 259 }, 260 requires : [ 'image', 'fakeobjects' ] 261 } ); 262 263 if ( CKEDITOR.env.ie ) 264 { 265 CKEDITOR.dom.element.prototype.hasAttribute = CKEDITOR.tools.override( CKEDITOR.dom.element.prototype.hasAttribute, 266 function( original ) 267 { 268 return function( name ) 269 { 270 var $attr = this.$.attributes.getNamedItem( name ); 271 272 if ( this.getName() == 'input' ) 273 { 274 switch ( name ) 275 { 276 case 'class' : 277 return this.$.className.length > 0; 278 case 'checked' : 279 return !!this.$.checked; 280 case 'value' : 281 var type = this.getAttribute( 'type' ); 282 return type == 'checkbox' || type == 'radio' ? this.$.value != 'on' : this.$.value; 283 } 284 } 285 286 return original.apply( this, arguments ); 287 }; 288 }); 289 } 290