1( function( $, editorSettings ) { 2 3 HappyForms.parts = HappyForms.parts || {}; 4 5 window._wpLink = {}; 6 7 var defaultOnPostRender = function( editor, settings, e ) { 8 e.target.$el.html( $( '#' + settings.icon ).html() ); 9 }; 10 11 var GetButton = function( editor, settings ) { 12 var onPostRender = settings.onPostRender || defaultOnPostRender; 13 14 var button = Object.assign( {}, settings, { 15 onClick: settings.onClick.bind( this, editor ), 16 onPostRender: onPostRender.bind( this, editor, settings ), 17 } ); 18 19 return button; 20 }; 21 22 var buttons = { 23 hfbold: { 24 icon: 'happyforms-rich-text-icon-bold', 25 stateSelector: 'strong', 26 27 onClick: function ( editor ) { 28 editor.execCommand( 'mceToggleFormat', false, 'bold' ); 29 }, 30 }, 31 hfitalic: { 32 icon: 'happyforms-rich-text-icon-italic', 33 stateSelector: 'em', 34 35 onClick: function ( editor ) { 36 editor.execCommand( 'mceToggleFormat', false, 'italic' ); 37 }, 38 }, 39 hful: { 40 icon: 'happyforms-rich-text-icon-ul', 41 stateSelector: 'ul', 42 43 onClick: function ( editor ) { 44 editor.execCommand( 'InsertUnorderedList' ); 45 }, 46 }, 47 hfol: { 48 icon: 'happyforms-rich-text-icon-ol', 49 stateSelector: 'ol', 50 51 onClick: function ( editor ) { 52 editor.execCommand( 'InsertOrderedList' ); 53 }, 54 }, 55 hfquote: { 56 icon: 'happyforms-rich-text-icon-quote', 57 stateSelector: 'blockquote', 58 59 onClick: function ( editor ) { 60 editor.execCommand( 'mceToggleFormat', false, 'blockquote' ); 61 }, 62 }, 63 hfcode: { 64 icon: 'happyforms-rich-text-icon-code', 65 stateSelector: 'pre', 66 67 onClick: function ( editor ) { 68 editor.execCommand( 'mceToggleFormat', false, 'pre' ); 69 }, 70 }, 71 hfstrike: { 72 icon: 'happyforms-rich-text-icon-strike', 73 stateSelector: 'del', 74 75 onClick: function ( editor ) { 76 editor.execCommand( 'mceToggleFormat', false, 'strikethrough' ); 77 }, 78 }, 79 hfunderline: { 80 icon: 'happyforms-rich-text-icon-underline', 81 82 onClick: function ( editor ) { 83 editor.execCommand( 'mceToggleFormat', false, 'underline' ); 84 }, 85 86 onPostRender: function( editor, settings, e ) { 87 defaultOnPostRender.apply( this, arguments ); 88 89 var self = e.target; 90 91 editor.on( 'NodeChange', function( e ) { 92 self.active( 'underline' === e.element.style.textDecoration ); 93 } ); 94 }, 95 }, 96 hfhr: { 97 icon: 'happyforms-rich-text-icon-hr', 98 99 onClick: function ( editor ) { 100 editor.execCommand( 'InsertHorizontalRule' ); 101 }, 102 }, 103 }; 104 105 HappyForms.parts.multi_line_text = { 106 init: function( options ) { 107 this.$form = options.form; 108 this.rich = this.$el.hasClass( 'happyforms-part--rich_text' ); 109 this.type = this.$el.data( 'happyforms-type' ); 110 this.$input = $( 'textarea', this.$el ); 111 this.$counter = $( '.happyforms-part__char-counter span.counter', this.$el ); 112 113 if ( ! this.rich ) { 114 this.$input.on( 'blur', this.onBlur.bind( this ) ); 115 this.$input.on( 'keyup', this.triggerChange.bind( this ) ); 116 this.$input.on( 'change', this.triggerChange.bind( this ) ); 117 this.$el.on( 'keyup', this.refreshCounter.bind( this ) ); 118 this.refreshCounter(); 119 $( '.happyforms-part__char-counter' ).show(); 120 } else { 121 this.editorId = this.$input.attr( 'id' ); 122 this.editor = null; 123 124 this.$el.on( 'happyforms.attach', this.editorCreate.bind( this ) ); 125 this.$el.on( 'happyforms.detach', this.editorDestroy.bind( this ) ); 126 this.$el.on( 'happyforms.formclass', this.onFormClassChange.bind( this ) ); 127 this.$el.on( 'happyforms.cssvar', this.onCSSVarChange.bind( this ) ); 128 129 this.editorCreate(); 130 } 131 this.initTooltip(); 132 }, 133 134 getValueLength: function() { 135 var mode = this.$input.attr( 'data-length-mode' ); 136 var value = this.$input.val(); 137 138 if ( this.rich ) { 139 value = this.editor.getContent( { format: 'text' } ); 140 value = value.replace( /[\r\n]+/gm, ' ' ); 141 value = value.replace(/\s+/g,' '); 142 value = value.trim(); 143 } 144 145 var length = value.length; 146 147 if ( 'word' === mode ) { 148 var matches = value.match( /\w+/g ); 149 length = matches ? matches.length : 0; 150 } else { 151 if ( this.rich && '\n' === value ) { 152 length --; 153 } 154 } 155 156 return length; 157 }, 158 159 refreshCounter: function() { 160 var hasLength = parseInt( this.$input.attr( 'data-length' ), 10 ); 161 162 if ( hasLength < 1 ) { 163 return; 164 } 165 166 var length = this.getValueLength(); 167 this.$counter.text( length ); 168 }, 169 170 editorCreate: function() { 171 var self = this; 172 173 tinymce.init( { 174 selector: '#' + this.editorId, 175 branding: false, 176 menubar: false, 177 toolbar1: 'hfbold,hfitalic,hful,hfol,hfquote,link,unlink,hfcode,hfstrike,hfunderline,hfhr', 178 statusbar: true, 179 resize: true, 180 plugins: 'hr,paste', 181 content_css: editorSettings.contentCSS,
182 valid_elements: editorSettings.validElements, 183 paste_as_text: true, 184 inline_styles: false, 185 min_height: 50, 186 formats: { 187 underline: { inline: 'u', exact : true }, 188 strikethrough: { inline: 'del', exact : true }, 189 }, 190 191 setup: function( editor ) { 192 var wpAddButton = editor.addButton; 193 194 // Remove tooltips 195 editor.addButton = function( id, options ) { 196 switch ( id ) { 197 case 'link': 198 case 'unlink': 199 case 'wp_link_apply': 200 case 'wp_link_edit': 201 case 'wp_link_remove': 202 delete options.tooltip; 203 break; 204 default: 205 break; 206 } 207 208 return wpAddButton.apply( this, arguments ); 209 } 210 211 // Add custom buttons 212 for ( var button in buttons ) { 213 editor.addButton( button, GetButton( editor, buttons[button] ) ); 214 } 215 216 // Inherit form class, fonts and css-vars 217 editor.on( 'init', function() { 218 self.editor = editor; 219 220 self.inheritFormClass(); 221 self.inheritFonts(); 222 223 var target = self.editor.dom.doc.querySelector( 'body' ); 224 self.inheritCSSVars( editorSettings.cssVars, target ); 225 self.refreshCounter(); 226 $( '.happyforms-part__char-counter' ).show(); 227 } ); 228 229 // Custom main toolbar icons 230 editor.on( 'postrender', function() { 231 var $el = $( editor.container ); 232 233 $( 'i.mce-i-link', $el ).replaceWith( 234 $( '#happyforms-rich-text-icon-link' ).html() 235 ); 236 237 $( 'i.mce-i-unlink', $el ).replaceWith( 238 $( '#happyforms-rich-text-icon-unlink' ).html() 239 ); 240 241 self.editor = editor; 242 243 var target = self.editor.dom.doc.querySelector( 'body' ); 244 target.style.color = $( 'body' ).css( 'color' ); 245 } ); 246 247 editor.on( 'change', self.onEditorChange.bind( self ) ); 248 editor.on( 'focus', self.onFocus.bind( self ) ); 249 editor.on( 'blur', self.onBlur.bind( self ) ); 250 editor.on( 'keyup', self.refreshCounter.bind( self ) ); 251 }, 252 } ); 253 }, 254 255 editorDestroy: function() { 256 var editor = tinymce.get( this.editorId ); 257 258 if ( editor ) { 259 editor.remove(); 260 } 261 262 self.editor = null; 263 }, 264 265 onEditorChange: function() { 266 this.triggerChange(); 267 }, 268 269 onFocus: function() { 270 this.$el.addClass( 'focus' ); 271 }, 272 273 onBlur: function() { 274 this.$el.removeClass( 'focus' ); 275 }, 276 277 inheritFormClass: function() { 278 this.editor.dom.doc.documentElement.className = this.$form.attr( 'class' ); 279 }, 280 281 inheritCSSVars: function( vars, target ) { 282 var styles = getComputedStyle( this.$form[0] ); 283 284 if ( 'object' !== typeof vars ) { 285 return; 286 } 287 288 vars.forEach( function( variable ) { 289 var value = styles.getPropertyValue( variable ); 290 target.style.setProperty( variable, value ); 291 } ); 292 }, 293 294 inheritFonts: function() { 295 var formStyle = getComputedStyle( this.$form[0] ); 296 var stylesheets = [].slice.call( document.styleSheets ); 297 var editorDocument = this.editor.dom.doc; 298 299 // Append parent stylesheets to editor 300 stylesheets 301 .map( function( stylesheet ) { 302 if ( ! stylesheet.ownerNode ) { 303 return null; 304 } 305 306 return stylesheet.ownerNode.cloneNode(); 307 } ) 308 .forEach( function( node ) { 309 if ( node ) { 310 editorDocument.head.insertBefore( node, editorDocument.head.firstChild ); 311 } 312 } ); 313 314 // Apply font-family 315 editorDocument.body.style.setProperty( 'font-family', formStyle.getPropertyValue( 'font-family' ) ); 316 }, 317 318 onFormClassChange: function( e, classes ) { 319 if ( this.editor ) { 320 this.editor.dom.doc.documentElement.className = classes; 321 } 322 }, 323 324 onCSSVarChange: function( e, variable ) { 325 if ( this.editor ) { 326 this.editor.dom.doc.querySelector( 'body' ).style.setProperty( variable.name, variable.value ); 327 328 $( '.happyforms-editor-toolbar-link' ).each( function() { 329 this.style.setProperty( variable.name, variable.value ); 330 } ); 331 } 332 }, 333 334 isFilled: function() { 335 if ( this.rich ) { 336 var content = tinymce.get( this.editorId ).getContent(); 337 return '' !== content; 338 } 339 340 return '' !== this.$input.val(); 341 }, 342 343 serialize: function() { 344 var serialized = HappyForms.parts.base.serialize.apply( this, arguments ); 345 346 if ( this.rich ) { 347 serialized = [ { 348 name: this.$input.attr( 'name' ), 349 value: tinymce.get( this.editorId ).getContent(), 350 } ]; 351 } 352 353 return serialized; 354 } 355 }; 356 357} )( jQuery, _happyFormsRichTextSettings );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.