Ticket #32425: 32425.patch
File 32425.patch, 45.6 KB (added by , 6 years ago) |
---|
-
src/wp-admin/js/editor.js
1 /* global tinymce, tinyMCEPreInit, QTags, setUserSetting */2 1 3 window.switchEditors = { 2 ( function( $ ) { 3 function switchEditors() { 4 var tinymce, mce$, exports; 4 5 5 switchto: function( el ) { 6 var aid = el.id, 7 l = aid.length, 8 id = aid.substr( 0, l - 5 ), 9 mode = aid.substr( l - 4 ); 6 function init() { 7 if ( ! tinymce && window.tinymce ) { 8 tinymce = window.tinymce; 9 mce$ = tinymce.$; 10 10 11 this.go( id, mode );12 },11 mce$( document ).on( 'click', function( event ) { 12 var id, mode, target = mce$( event.target ); 13 13 14 // mode can be 'html', 'tmce', or 'toggle'; 'html' is used for the 'Text' editor tab. 15 go: function( id, mode ) { 16 var t = this, ed, wrap_id, txtarea_el, iframe, editorHeight, toolbarHeight, 17 DOM = tinymce.DOM; //DOMUtils outside the editor iframe 18 19 id = id || 'content'; 20 mode = mode || 'toggle'; 21 22 ed = tinymce.get( id ); 23 wrap_id = 'wp-' + id + '-wrap'; 24 txtarea_el = DOM.get( id ); 25 26 if ( 'toggle' === mode ) { 27 if ( ed && ! ed.isHidden() ) { 28 mode = 'html'; 29 } else { 30 mode = 'tmce'; 14 if ( target.hasClass( 'wp-switch-editor' ) ) { 15 id = target.attr( 'data-wp-editor-id' ); 16 mode = target.hasClass( 'switch-tmce' ) ? 'tmce' : 'html'; 17 switchEditor( id, mode ); 18 } 19 }); 31 20 } 32 21 } 33 22 34 function getToolbarHeight( ) {35 var node = DOM.select( '.mce-toolbar-grp', ed.getContainer() )[0],23 function getToolbarHeight( editor ) { 24 var node = mce$( '.mce-toolbar-grp', editor.getContainer() )[0], 36 25 height = node && node.clientHeight; 37 26 38 27 if ( height && height > 10 && height < 200 ) { … … 42 31 return 30; 43 32 } 44 33 45 if ( 'tmce' === mode || 'tinymce' === mode ) { 46 if ( ed && ! ed.isHidden() ) { 47 return false; 48 } 34 function switchEditor( id, mode ) { 35 id = id || 'content'; 36 mode = mode || 'toggle'; 49 37 50 if ( typeof( QTags ) !== 'undefined' ) { 51 QTags.closeAllTags( id ); 38 var editorHeight, toolbarHeight, iframe, 39 editor = tinymce.get( id ), 40 wrap = mce$( '#wp-' + id + '-wrap' ), 41 $textarea = mce$( '#' + id ), 42 textarea = $textarea[0]; 43 44 if ( 'toggle' === mode ) { 45 if ( editor && ! editor.isHidden() ) { 46 mode = 'html'; 47 } else { 48 mode = 'tmce'; 49 } 52 50 } 53 51 54 editorHeight = txtarea_el ? parseInt( txtarea_el.style.height, 10 ) : 0; 52 if ( 'tmce' === mode || 'tinymce' === mode ) { 53 if ( editor && ! editor.isHidden() ) { 54 return false; 55 } 55 56 56 if ( tinyMCEPreInit.mceInit[ id ] && tinyMCEPreInit.mceInit[ id ].wpautop) {57 txtarea_el.value = t.wpautop( txtarea_el.value);58 }57 if ( typeof( window.QTags ) !== 'undefined' ) { 58 window.QTags.closeAllTags( id ); 59 } 59 60 60 if ( ed ) { 61 ed.show(); 61 editorHeight = parseInt( textarea.style.height, 10 ) || 0; 62 62 63 // No point resizing the iframe in iOS 64 if ( ! tinymce.Env.iOS && editorHeight ) { 65 toolbarHeight = getToolbarHeight(); 66 editorHeight = editorHeight - toolbarHeight + 14; 63 if ( editor ) { 64 editor.show(); 67 65 68 // height cannot be under 50 or over 5000 69 if ( editorHeight > 50 && editorHeight < 5000 ) { 70 ed.theme.resizeTo( null, editorHeight ); 66 // No point resizing the iframe in iOS 67 if ( ! tinymce.Env.iOS && editorHeight ) { 68 toolbarHeight = getToolbarHeight( editor ); 69 editorHeight = editorHeight - toolbarHeight + 14; 70 71 // height cannot be under 50 or over 5000 72 if ( editorHeight > 50 && editorHeight < 5000 ) { 73 editor.theme.resizeTo( null, editorHeight ); 74 } 71 75 } 76 } else { 77 tinymce.init( window.tinyMCEPreInit.mceInit[id] ); 72 78 } 73 } else {74 tinymce.init( tinyMCEPreInit.mceInit[id] );75 }76 79 77 DOM.removeClass( wrap_id, 'html-active' ); 78 DOM.addClass( wrap_id, 'tmce-active' ); 79 DOM.setAttrib( txtarea_el, 'aria-hidden', true ); 80 setUserSetting( 'editor', 'tinymce' ); 80 wrap.removeClass( 'html-active' ).addClass( 'tmce-active' ); 81 $textarea.attr( 'aria-hidden', true ); 82 window.setUserSetting( 'editor', 'tinymce' ); 81 83 82 } else if ( 'html' === mode ) { 84 } else if ( 'html' === mode ) { 85 if ( editor && editor.isHidden() ) { 86 return false; 87 } 83 88 84 if ( ed && ed.isHidden() ) { 85 return false; 86 } 89 if ( editor ) { 90 if ( ! tinymce.Env.iOS ) { 91 iframe = editor.iframeElement; 92 editorHeight = iframe ? parseInt( iframe.style.height, 10 ) : 0; 87 93 88 if ( ed ) { 89 if ( ! tinymce.Env.iOS ) { 90 iframe = DOM.get( id + '_ifr' ); 91 editorHeight = iframe ? parseInt( iframe.style.height, 10 ) : 0; 94 if ( editorHeight ) { 95 toolbarHeight = getToolbarHeight( editor ); 96 editorHeight = editorHeight + toolbarHeight - 14; 92 97 93 if ( editorHeight ) { 94 toolbarHeight = getToolbarHeight(); 95 editorHeight = editorHeight + toolbarHeight - 14; 96 97 // height cannot be under 50 or over 5000 98 if ( editorHeight > 50 && editorHeight < 5000 ) { 99 txtarea_el.style.height = editorHeight + 'px'; 98 // height cannot be under 50 or over 5000 99 if ( editorHeight > 50 && editorHeight < 5000 ) { 100 textarea.style.height = editorHeight + 'px'; 101 } 100 102 } 101 103 } 102 }103 104 104 ed.hide(); 105 } else { 106 // The TinyMCE instance doesn't exist, run the content through 'pre_wpautop()' and show the textarea 107 if ( tinyMCEPreInit.mceInit[ id ] && tinyMCEPreInit.mceInit[ id ].wpautop ) { 108 txtarea_el.value = t.pre_wpautop( txtarea_el.value ); 105 editor.hide(); 106 } else { 107 // The TinyMCE instance doesn't exist, show the textarea 108 $textarea.css({ 'display': '', 'visibility': '' }); 109 109 } 110 110 111 DOM.setStyles( txtarea_el, {'display': '', 'visibility': ''} ); 111 wrap.removeClass( 'tmce-active' ).addClass( 'html-active' ); 112 $textarea.attr( 'aria-hidden', false ); 113 window.setUserSetting( 'editor', 'html' ); 112 114 } 113 114 DOM.removeClass( wrap_id, 'tmce-active' );115 DOM.addClass( wrap_id, 'html-active' );116 DOM.setAttrib( txtarea_el, 'aria-hidden', false );117 setUserSetting( 'editor', 'html' );118 115 } 119 return false;120 },121 116 122 _wp_Nop: function( content ) {123 var blocklist1, blocklist2,124 preserve_linebreaks = false,125 preserve_br = false;117 function _preWpautop( content ) { 118 var blocklist1, blocklist2, 119 preserve_linebreaks = false, 120 preserve_br = false; 126 121 127 // Protect pre|script tags128 if ( content.indexOf( '<pre' ) !== -1 || content.indexOf( '<script' ) !== -1 ) {129 preserve_linebreaks = true;130 content = content.replace( /<(pre|script)[^>]*>[\s\S]+?<\/\1>/g, function( a ) {131 a = a.replace( /<br ?\/?>(\r\n|\n)?/g, '<wp-line-break>' );132 a = a.replace( /<\/?p( [^>]*)?>(\r\n|\n)?/g, '<wp-line-break>' );133 return a.replace( /\r?\n/g, '<wp-line-break>' );134 });135 }122 // Protect pre|script tags 123 if ( content.indexOf( '<pre' ) !== -1 || content.indexOf( '<script' ) !== -1 ) { 124 preserve_linebreaks = true; 125 content = content.replace( /<(pre|script)[^>]*>[\s\S]+?<\/\1>/g, function( a ) { 126 a = a.replace( /<br ?\/?>(\r\n|\n)?/g, '<wp-line-break>' ); 127 a = a.replace( /<\/?p( [^>]*)?>(\r\n|\n)?/g, '<wp-line-break>' ); 128 return a.replace( /\r?\n/g, '<wp-line-break>' ); 129 }); 130 } 136 131 137 // keep <br> tags inside captions and remove line breaks138 if ( content.indexOf( '[caption' ) !== -1 ) {139 preserve_br = true;140 content = content.replace( /\[caption[\s\S]+?\[\/caption\]/g, function( a ) {141 return a.replace( /<br([^>]*)>/g, '<wp-temp-br$1>' ).replace( /[\r\n\t]+/, '' );142 });143 }132 // keep <br> tags inside captions and remove line breaks 133 if ( content.indexOf( '[caption' ) !== -1 ) { 134 preserve_br = true; 135 content = content.replace( /\[caption[\s\S]+?\[\/caption\]/g, function( a ) { 136 return a.replace( /<br([^>]*)>/g, '<wp-temp-br$1>' ).replace( /[\r\n\t]+/, '' ); 137 }); 138 } 144 139 145 // Pretty it up for the source editor146 blocklist1 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|div|h[1-6]|p|fieldset';147 content = content.replace( new RegExp( '\\s*</(' + blocklist1 + ')>\\s*', 'g' ), '</$1>\n' );148 content = content.replace( new RegExp( '\\s*<((?:' + blocklist1 + ')(?: [^>]*)?)>', 'g' ), '\n<$1>' );140 // Pretty it up for the source editor 141 blocklist1 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|div|h[1-6]|p|fieldset'; 142 content = content.replace( new RegExp( '\\s*</(' + blocklist1 + ')>\\s*', 'g' ), '</$1>\n' ); 143 content = content.replace( new RegExp( '\\s*<((?:' + blocklist1 + ')(?: [^>]*)?)>', 'g' ), '\n<$1>' ); 149 144 150 // Mark </p> if it has any attributes.151 content = content.replace( /(<p [^>]+>.*?)<\/p>/g, '$1</p#>' );145 // Mark </p> if it has any attributes. 146 content = content.replace( /(<p [^>]+>.*?)<\/p>/g, '$1</p#>' ); 152 147 153 // Separate <div> containing <p>154 content = content.replace( /<div( [^>]*)?>\s*<p>/gi, '<div$1>\n\n' );148 // Separate <div> containing <p> 149 content = content.replace( /<div( [^>]*)?>\s*<p>/gi, '<div$1>\n\n' ); 155 150 156 // Remove <p> and <br />157 content = content.replace( /\s*<p>/gi, '' );158 content = content.replace( /\s*<\/p>\s*/gi, '\n\n' );159 content = content.replace( /\n[\s\u00a0]+\n/g, '\n\n' );160 content = content.replace( /\s*<br ?\/?>\s*/gi, '\n' );151 // Remove <p> and <br /> 152 content = content.replace( /\s*<p>/gi, '' ); 153 content = content.replace( /\s*<\/p>\s*/gi, '\n\n' ); 154 content = content.replace( /\n[\s\u00a0]+\n/g, '\n\n' ); 155 content = content.replace( /\s*<br ?\/?>\s*/gi, '\n' ); 161 156 162 // Fix some block element newline issues163 content = content.replace( /\s*<div/g, '\n<div' );164 content = content.replace( /<\/div>\s*/g, '</div>\n' );165 content = content.replace( /\s*\[caption([^\[]+)\[\/caption\]\s*/gi, '\n\n[caption$1[/caption]\n\n' );166 content = content.replace( /caption\]\n\n+\[caption/g, 'caption]\n\n[caption' );157 // Fix some block element newline issues 158 content = content.replace( /\s*<div/g, '\n<div' ); 159 content = content.replace( /<\/div>\s*/g, '</div>\n' ); 160 content = content.replace( /\s*\[caption([^\[]+)\[\/caption\]\s*/gi, '\n\n[caption$1[/caption]\n\n' ); 161 content = content.replace( /caption\]\n\n+\[caption/g, 'caption]\n\n[caption' ); 167 162 168 blocklist2 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|h[1-6]|pre|fieldset';169 content = content.replace( new RegExp('\\s*<((?:' + blocklist2 + ')(?: [^>]*)?)\\s*>', 'g' ), '\n<$1>' );170 content = content.replace( new RegExp('\\s*</(' + blocklist2 + ')>\\s*', 'g' ), '</$1>\n' );171 content = content.replace( /<li([^>]*)>/g, '\t<li$1>' );163 blocklist2 = 'blockquote|ul|ol|li|table|thead|tbody|tfoot|tr|th|td|h[1-6]|pre|fieldset'; 164 content = content.replace( new RegExp('\\s*<((?:' + blocklist2 + ')(?: [^>]*)?)\\s*>', 'g' ), '\n<$1>' ); 165 content = content.replace( new RegExp('\\s*</(' + blocklist2 + ')>\\s*', 'g' ), '</$1>\n' ); 166 content = content.replace( /<li([^>]*)>/g, '\t<li$1>' ); 172 167 173 if ( content.indexOf( '<option' ) !== -1 ) {174 content = content.replace( /\s*<option/g, '\n<option' );175 content = content.replace( /\s*<\/select>/g, '\n</select>' );176 }168 if ( content.indexOf( '<option' ) !== -1 ) { 169 content = content.replace( /\s*<option/g, '\n<option' ); 170 content = content.replace( /\s*<\/select>/g, '\n</select>' ); 171 } 177 172 178 if ( content.indexOf( '<hr' ) !== -1 ) {179 content = content.replace( /\s*<hr( [^>]*)?>\s*/g, '\n\n<hr$1>\n\n' );180 }173 if ( content.indexOf( '<hr' ) !== -1 ) { 174 content = content.replace( /\s*<hr( [^>]*)?>\s*/g, '\n\n<hr$1>\n\n' ); 175 } 181 176 182 if ( content.indexOf( '<object' ) !== -1 ) {183 content = content.replace( /<object[\s\S]+?<\/object>/g, function( a ) {184 return a.replace( /[\r\n]+/g, '' );185 });186 }177 if ( content.indexOf( '<object' ) !== -1 ) { 178 content = content.replace( /<object[\s\S]+?<\/object>/g, function( a ) { 179 return a.replace( /[\r\n]+/g, '' ); 180 }); 181 } 187 182 188 // Unmark special paragraph closing tags189 content = content.replace( /<\/p#>/g, '</p>\n' );190 content = content.replace( /\s*(<p [^>]+>[\s\S]*?<\/p>)/g, '\n$1' );183 // Unmark special paragraph closing tags 184 content = content.replace( /<\/p#>/g, '</p>\n' ); 185 content = content.replace( /\s*(<p [^>]+>[\s\S]*?<\/p>)/g, '\n$1' ); 191 186 192 // Trim whitespace193 content = content.replace( /^\s+/, '' );194 content = content.replace( /[\s\u00a0]+$/, '' );187 // Trim whitespace 188 content = content.replace( /^\s+/, '' ); 189 content = content.replace( /[\s\u00a0]+$/, '' ); 195 190 196 // put back the line breaks in pre|script197 if ( preserve_linebreaks ) {198 content = content.replace( /<wp-line-break>/g, '\n' );199 }191 // put back the line breaks in pre|script 192 if ( preserve_linebreaks ) { 193 content = content.replace( /<wp-line-break>/g, '\n' ); 194 } 200 195 201 // and the <br> tags in captions 202 if ( preserve_br ) { 203 content = content.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' ); 196 // and the <br> tags in captions 197 if ( preserve_br ) { 198 content = content.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' ); 199 } 200 201 return content; 204 202 } 205 203 206 return content; 207 }, 204 function _wpautop( pee ) { 205 var preserve_linebreaks = false, 206 preserve_br = false, 207 blocklist = 'table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre' + 208 '|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section' + 209 '|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary'; 208 210 209 _wp_Autop: function(pee) { 210 var preserve_linebreaks = false, 211 preserve_br = false, 212 blocklist = 'table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre' + 213 '|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section' + 214 '|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary'; 211 if ( pee.indexOf( '<object' ) !== -1 ) { 212 pee = pee.replace( /<object[\s\S]+?<\/object>/g, function( a ) { 213 return a.replace( /[\r\n]+/g, '' ); 214 }); 215 } 215 216 216 if ( pee.indexOf( '<object' ) !== -1 ) { 217 pee = pee.replace( /<object[\s\S]+?<\/object>/g, function( a ) { 218 return a.replace( /[\r\n]+/g, '' ); 217 pee = pee.replace( /<[^<>]+>/g, function( a ){ 218 return a.replace( /[\r\n]+/g, ' ' ); 219 219 }); 220 }221 220 222 pee = pee.replace( /<[^<>]+>/g, function( a ){ 223 return a.replace( /[\r\n]+/g, ' ' ); 224 }); 221 // Protect pre|script tags 222 if ( pee.indexOf( '<pre' ) !== -1 || pee.indexOf( '<script' ) !== -1 ) { 223 preserve_linebreaks = true; 224 pee = pee.replace( /<(pre|script)[^>]*>[\s\S]+?<\/\1>/g, function( a ) { 225 return a.replace( /(\r\n|\n)/g, '<wp-line-break>' ); 226 }); 227 } 225 228 226 // Protect pre|script tags 227 if ( pee.indexOf( '<pre' ) !== -1 || pee.indexOf( '<script' ) !== -1 ) { 228 preserve_linebreaks = true; 229 pee = pee.replace( /<(pre|script)[^>]*>[\s\S]+?<\/\1>/g, function( a ) { 230 return a.replace( /(\r\n|\n)/g, '<wp-line-break>' ); 231 }); 232 } 229 // keep <br> tags inside captions and convert line breaks 230 if ( pee.indexOf( '[caption' ) !== -1 ) { 231 preserve_br = true; 232 pee = pee.replace( /\[caption[\s\S]+?\[\/caption\]/g, function( a ) { 233 // keep existing <br> 234 a = a.replace( /<br([^>]*)>/g, '<wp-temp-br$1>' ); 235 // no line breaks inside HTML tags 236 a = a.replace( /<[a-zA-Z0-9]+( [^<>]+)?>/g, function( b ) { 237 return b.replace( /[\r\n\t]+/, ' ' ); 238 }); 239 // convert remaining line breaks to <br> 240 return a.replace( /\s*\n\s*/g, '<wp-temp-br />' ); 241 }); 242 } 233 243 234 // keep <br> tags inside captions and convert line breaks 235 if ( pee.indexOf( '[caption' ) !== -1 ) { 236 preserve_br = true; 237 pee = pee.replace( /\[caption[\s\S]+?\[\/caption\]/g, function( a ) { 238 // keep existing <br> 239 a = a.replace( /<br([^>]*)>/g, '<wp-temp-br$1>' ); 240 // no line breaks inside HTML tags 241 a = a.replace( /<[a-zA-Z0-9]+( [^<>]+)?>/g, function( b ) { 242 return b.replace( /[\r\n\t]+/, ' ' ); 243 }); 244 // convert remaining line breaks to <br> 245 return a.replace( /\s*\n\s*/g, '<wp-temp-br />' ); 244 pee = pee + '\n\n'; 245 pee = pee.replace( /<br \/>\s*<br \/>/gi, '\n\n' ); 246 pee = pee.replace( new RegExp( '(<(?:' + blocklist + ')(?: [^>]*)?>)', 'gi' ), '\n$1' ); 247 pee = pee.replace( new RegExp( '(</(?:' + blocklist + ')>)', 'gi' ), '$1\n\n' ); 248 pee = pee.replace( /<hr( [^>]*)?>/gi, '<hr$1>\n\n' ); // hr is self closing block element 249 pee = pee.replace( /\s*<option/gi, '<option' ); // No <p> or <br> around <option> 250 pee = pee.replace( /<\/option>\s*/gi, '</option>' ); 251 pee = pee.replace( /\r\n|\r/g, '\n' ); 252 pee = pee.replace( /\n\s*\n+/g, '\n\n' ); 253 pee = pee.replace( /([\s\S]+?)\n\n/g, '<p>$1</p>\n' ); 254 pee = pee.replace( /<p>\s*?<\/p>/gi, ''); 255 pee = pee.replace( new RegExp( '<p>\\s*(</?(?:' + blocklist + ')(?: [^>]*)?>)\\s*</p>', 'gi' ), '$1' ); 256 pee = pee.replace( /<p>(<li.+?)<\/p>/gi, '$1'); 257 pee = pee.replace( /<p>\s*<blockquote([^>]*)>/gi, '<blockquote$1><p>'); 258 pee = pee.replace( /<\/blockquote>\s*<\/p>/gi, '</p></blockquote>'); 259 pee = pee.replace( new RegExp( '<p>\\s*(</?(?:' + blocklist + ')(?: [^>]*)?>)', 'gi' ), '$1' ); 260 pee = pee.replace( new RegExp( '(</?(?:' + blocklist + ')(?: [^>]*)?>)\\s*</p>', 'gi' ), '$1' ); 261 pee = pee.replace( /\s*\n/gi, '<br />\n'); 262 pee = pee.replace( new RegExp( '(</?(?:' + blocklist + ')[^>]*>)\\s*<br />', 'gi' ), '$1' ); 263 pee = pee.replace( /<br \/>(\s*<\/?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)/gi, '$1' ); 264 pee = pee.replace( /(?:<p>|<br ?\/?>)*\s*\[caption([^\[]+)\[\/caption\]\s*(?:<\/p>|<br ?\/?>)*/gi, '[caption$1[/caption]' ); 265 266 pee = pee.replace( /(<(?:div|th|td|form|fieldset|dd)[^>]*>)(.*?)<\/p>/g, function( a, b, c ) { 267 if ( c.match( /<p( [^>]*)?>/ ) ) { 268 return a; 269 } 270 271 return b + '<p>' + c + '</p>'; 246 272 }); 247 }248 273 249 pee = pee + '\n\n'; 250 pee = pee.replace( /<br \/>\s*<br \/>/gi, '\n\n' ); 251 pee = pee.replace( new RegExp( '(<(?:' + blocklist + ')(?: [^>]*)?>)', 'gi' ), '\n$1' ); 252 pee = pee.replace( new RegExp( '(</(?:' + blocklist + ')>)', 'gi' ), '$1\n\n' ); 253 pee = pee.replace( /<hr( [^>]*)?>/gi, '<hr$1>\n\n' ); // hr is self closing block element 254 pee = pee.replace( /\s*<option/gi, '<option' ); // No <p> or <br> around <option> 255 pee = pee.replace( /<\/option>\s*/gi, '</option>' ); 256 pee = pee.replace( /\r\n|\r/g, '\n' ); 257 pee = pee.replace( /\n\s*\n+/g, '\n\n' ); 258 pee = pee.replace( /([\s\S]+?)\n\n/g, '<p>$1</p>\n' ); 259 pee = pee.replace( /<p>\s*?<\/p>/gi, ''); 260 pee = pee.replace( new RegExp( '<p>\\s*(</?(?:' + blocklist + ')(?: [^>]*)?>)\\s*</p>', 'gi' ), '$1' ); 261 pee = pee.replace( /<p>(<li.+?)<\/p>/gi, '$1'); 262 pee = pee.replace( /<p>\s*<blockquote([^>]*)>/gi, '<blockquote$1><p>'); 263 pee = pee.replace( /<\/blockquote>\s*<\/p>/gi, '</p></blockquote>'); 264 pee = pee.replace( new RegExp( '<p>\\s*(</?(?:' + blocklist + ')(?: [^>]*)?>)', 'gi' ), '$1' ); 265 pee = pee.replace( new RegExp( '(</?(?:' + blocklist + ')(?: [^>]*)?>)\\s*</p>', 'gi' ), '$1' ); 266 pee = pee.replace( /\s*\n/gi, '<br />\n'); 267 pee = pee.replace( new RegExp( '(</?(?:' + blocklist + ')[^>]*>)\\s*<br />', 'gi' ), '$1' ); 268 pee = pee.replace( /<br \/>(\s*<\/?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)>)/gi, '$1' ); 269 pee = pee.replace( /(?:<p>|<br ?\/?>)*\s*\[caption([^\[]+)\[\/caption\]\s*(?:<\/p>|<br ?\/?>)*/gi, '[caption$1[/caption]' ); 274 // put back the line breaks in pre|script 275 if ( preserve_linebreaks ) { 276 pee = pee.replace( /<wp-line-break>/g, '\n' ); 277 } 270 278 271 pee = pee.replace( /(<(?:div|th|td|form|fieldset|dd)[^>]*>)(.*?)<\/p>/g, function( a, b, c ) { 272 if ( c.match( /<p( [^>]*)?>/ ) ) { 273 return a; 279 if ( preserve_br ) { 280 pee = pee.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' ); 274 281 } 275 282 276 return b + '<p>' + c + '</p>'; 277 }); 278 279 // put back the line breaks in pre|script 280 if ( preserve_linebreaks ) { 281 pee = pee.replace( /<wp-line-break>/g, '\n' ); 283 return pee; 282 284 } 283 285 284 if ( preserve_br ) { 285 pee = pee.replace( /<wp-temp-br([^>]*)>/g, '<br$1>' ); 286 } 286 function preWpautop( content ) { 287 var obj = { o: exports, data: content, unfiltered: content }; 287 288 288 return pee; 289 }, 289 if ( $ ) { 290 $( 'body' ).trigger( 'beforePreWpautop', [ obj ] ); 291 } 290 292 291 pre_wpautop: function( content ) { 292 var t = this, o = { o: t, data: content, unfiltered: content }, 293 q = typeof( jQuery ) !== 'undefined'; 293 obj.data = _preWpautop( obj.data ); 294 294 295 if ( q ) { 296 jQuery( 'body' ).trigger( 'beforePreWpautop', [ o ] ); 295 if ( $ ) { 296 $( 'body' ).trigger( 'afterPreWpautop', [ obj ] ); 297 } 298 299 return obj.data; 297 300 } 298 301 299 o.data = t._wp_Nop( o.data ); 302 function wpautop( content ) { 303 var obj = { o: exports, data: content, unfiltered: content }; 300 304 301 if ( q) {302 jQuery('body').trigger('afterPreWpautop', [ o] );303 }305 if ( $ ) { 306 $( 'body' ).trigger( 'beforeWpautop', [ obj ] ); 307 } 304 308 305 return o.data; 306 }, 309 obj.data = _wpautop( obj.data ); 307 310 308 wpautop: function( pee) {309 var t = this, o = { o: t, data: pee, unfiltered: pee },310 q = typeof( jQuery ) !== 'undefined';311 if ( $ ) { 312 $( 'body' ).trigger( 'afterWpautop', [ obj ] ); 313 } 311 314 312 if ( q ) { 313 jQuery( 'body' ).trigger('beforeWpautop', [ o ] ); 315 return obj.data; 314 316 } 315 317 316 o.data = t._wp_Autop( o.data ); 317 318 if ( q ) { 319 jQuery( 'body' ).trigger('afterWpautop', [ o ] ); 318 if ( $ ) { 319 $( document ).ready( init ); 320 } else if ( document.addEventListener ) { 321 document.addEventListener( 'DOMContentLoaded', init, false ); 322 window.addEventListener( 'load', init, false ); 323 } else if ( window.attachEvent ) { 324 window.attachEvent( 'onload', init ); 325 document.attachEvent( 'onreadystatechange', function() { 326 if ( 'complete' === document.readyState ) { 327 init(); 328 } 329 } ); 320 330 } 321 331 322 return o.data; 332 exports = { 333 wpautop: wpautop, 334 preWpautop: preWpautop, 335 336 // Back-compat 337 go: switchEditor, 338 pre_wpautop: preWpautop, 339 _wp_Autop: _wpautop, 340 _wp_Nop: _preWpautop 341 }; 342 343 return exports; 323 344 } 324 }; 345 346 window.switchEditors = new switchEditors(); 347 }( window.jQuery )); -
src/wp-includes/class-wp-editor.php
137 137 * @param array $settings See the _parse_settings() method for description. 138 138 */ 139 139 public static function editor( $content, $editor_id, $settings = array() ) { 140 141 140 $set = self::parse_settings( $editor_id, $settings ); 142 $editor_class = ' class="' . trim( $set['editor_class'] . ' wp-editor-area' ) . '"';141 $editor_class = ' class="' . esc_attr( trim( $set['editor_class'] ) ) . ' wp-editor-area"'; 143 142 $tabindex = $set['tabindex'] ? ' tabindex="' . (int) $set['tabindex'] . '"' : ''; 144 143 $switch_class = 'html-active'; 145 144 $toolbar = $buttons = $autocomplete = ''; 145 $default_editor = null; 146 $editor_id_attr = esc_attr( $editor_id ); 146 147 147 148 if ( $set['drag_drop_upload'] ) { 148 149 self::$drag_drop_upload = true; 149 150 } 150 151 151 if ( ! empty( $set['editor_height'] ) ) 152 $height = ' style="height: ' . $set['editor_height'] . 'px"'; 153 else 154 $height = ' rows="' . $set['textarea_rows'] . '"'; 152 if ( ! empty( $set['editor_height'] ) ) { 153 $height = ' style="height: ' . (int) $set['editor_height'] . 'px"'; 154 } else { 155 $height = ' rows="' . (int) $set['textarea_rows'] . '"'; 156 } 155 157 156 if ( ! current_user_can( 'upload_files' ) )158 if ( ! current_user_can( 'upload_files' ) ) { 157 159 $set['media_buttons'] = false; 160 } 158 161 159 if ( ! self::$this_quicktags && self::$this_tinymce ) { 160 $switch_class = 'tmce-active'; 162 if ( self::$this_tinymce ) { 161 163 $autocomplete = ' autocomplete="off"'; 162 } elseif ( self::$this_quicktags && self::$this_tinymce ) {163 164 $default_editor = $set['default_editor'] ? $set['default_editor'] : wp_default_editor(); 164 $autocomplete = ' autocomplete="off"';165 165 166 // 'html' is used for the "Text" editor tab. 167 if ( 'html' === $default_editor ) { 168 add_filter('the_editor_content', 'wp_htmledit_pre'); 169 $switch_class = 'html-active'; 166 if ( self::$this_quicktags ) { 167 // 'html' is used for the "Text" editor tab. 168 if ( 'html' !== $default_editor ) { 169 $switch_class = 'tmce-active'; 170 } 171 172 $buttons .= '<button type="button" id="' . $editor_id_attr . '-tmce" class="wp-switch-editor switch-tmce"' . 173 ' data-wp-editor-id="' . $editor_id_attr . '">' . __('Visual') . "</button>\n"; 174 $buttons .= '<button type="button" id="' . $editor_id_attr . '-html" class="wp-switch-editor switch-html"' . 175 ' data-wp-editor-id="' . $editor_id_attr . '">' . _x( 'Text', 'Name for the Text editor tab (formerly HTML)' ) . "</button>\n"; 170 176 } else { 171 add_filter('the_editor_content', 'wp_richedit_pre');172 177 $switch_class = 'tmce-active'; 173 178 } 174 175 $buttons .= '<button type="button" id="' . $editor_id . '-tmce" class="wp-switch-editor switch-tmce" onclick="switchEditors.switchto(this);">' . __('Visual') . "</button>\n";176 $buttons .= '<button type="button" id="' . $editor_id . '-html" class="wp-switch-editor switch-html" onclick="switchEditors.switchto(this);">' . _x( 'Text', 'Name for the Text editor tab (formerly HTML)' ) . "</button>\n";177 179 } 178 180 179 181 $wrap_class = 'wp-core-ui wp-editor-wrap ' . $switch_class; … … 182 184 $wrap_class .= ' has-dfw'; 183 185 } 184 186 185 echo '<div id="wp-' . $editor_id . '-wrap" class="' . $wrap_class . '">';187 echo '<div id="wp-' . $editor_id_attr . '-wrap" class="' . $wrap_class . '">'; 186 188 187 189 if ( self::$editor_buttons_css ) { 188 wp_print_styles( 'editor-buttons');190 wp_print_styles( 'editor-buttons' ); 189 191 self::$editor_buttons_css = false; 190 192 } 191 193 192 if ( ! empty($set['editor_css']) )194 if ( ! empty( $set['editor_css'] ) ) { 193 195 echo $set['editor_css'] . "\n"; 196 } 194 197 195 if ( ! empty($buttons) || $set['media_buttons'] ) {196 echo '<div id="wp-' . $editor_id . '-editor-tools" class="wp-editor-tools hide-if-no-js">';198 if ( ! empty( $buttons ) || $set['media_buttons'] ) { 199 echo '<div id="wp-' . $editor_id_attr . '-editor-tools" class="wp-editor-tools hide-if-no-js">'; 197 200 198 201 if ( $set['media_buttons'] ) { 199 202 self::$has_medialib = true; 200 203 201 if ( ! function_exists('media_buttons') )202 include( ABSPATH . 'wp-admin/includes/media.php');204 if ( ! function_exists( 'media_buttons' ) ) 205 include( ABSPATH . 'wp-admin/includes/media.php' ); 203 206 204 echo '<div id="wp-' . $editor_id . '-media-buttons" class="wp-media-buttons">';207 echo '<div id="wp-' . $editor_id_attr . '-media-buttons" class="wp-media-buttons">'; 205 208 206 209 /** 207 210 * Fires after the default media button(s) are displayed. … … 218 221 echo "</div>\n"; 219 222 } 220 223 224 $quicktags_toolbar = ''; 225 226 if ( self::$this_quicktags ) { 227 if ( 'content' === $editor_id && ! empty( $GLOBALS['current_screen'] ) && $GLOBALS['current_screen']->base === 'post' ) { 228 $toolbar_id = 'ed_toolbar'; 229 } else { 230 $toolbar_id = 'qt_' . $editor_id_attr . '_toolbar'; 231 } 232 233 $quicktags_toolbar = '<div id="' . $toolbar_id . '" class="quicktags-toolbar"></div>'; 234 } 235 221 236 /** 222 237 * Filter the HTML markup output that displays the editor. 223 238 * … … 225 240 * 226 241 * @param string $output Editor's HTML markup. 227 242 */ 228 $the_editor = apply_filters( 'the_editor', '<div id="wp-' . $editor_id . '-editor-container" class="wp-editor-container">' . 229 '<textarea' . $editor_class . $height . $tabindex . $autocomplete . ' cols="40" name="' . $set['textarea_name'] . '" ' . 230 'id="' . $editor_id . '">%s</textarea></div>' ); 243 $the_editor = apply_filters( 'the_editor', '<div id="wp-' . $editor_id_attr . '-editor-container" class="wp-editor-container">' . 244 $quicktags_toolbar . 245 '<textarea' . $editor_class . $height . $tabindex . $autocomplete . ' cols="40" name="' . esc_attr( $set['textarea_name'] ) . '" ' . 246 'id="' . $editor_id_attr . '">%s</textarea></div>' ); 231 247 232 248 /** 233 249 * Filter the default editor content. … … 238 254 */ 239 255 $content = apply_filters( 'the_editor_content', $content ); 240 256 257 // Back-compat for the `htmledit_pre` and `richedit_pre` filters 258 if ( 'html' === $default_editor && has_filter( 'htmledit_pre' ) ) { 259 // TODO: needs _deprecated_filter(), use _deprecated_function() as substitute for now 260 _deprecated_function( 'add_filter( htmledit_pre )', '4.3.0', 'add_filter( format_for_editor )' ); 261 $content = apply_filters( 'htmledit_pre', $content ); 262 } elseif ( null !== $default_editor && has_filter( 'richedit_pre' ) ) { 263 _deprecated_function( 'add_filter( richedit_pre )', '4.3.0', 'add_filter( format_for_editor )' ); 264 $content = apply_filters( 'richedit_pre', $content ); 265 } 266 241 267 printf( $the_editor, $content ); 242 268 echo "\n</div>\n\n"; 243 269 … … 470 496 'theme' => 'modern', 471 497 'skin' => 'lightgray', 472 498 'language' => self::$mce_locale, 473 'formats' => "{474 alignleft: [475 {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'left'}},476 {selector: 'img,table,dl.wp-caption', classes: 'alignleft'}477 ],478 aligncenter: [479 {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'center'}},480 {selector: 'img,table,dl.wp-caption', classes: 'aligncenter'}481 ],482 alignright: [483 {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles: {textAlign:'right'}},484 {selector: 'img,table,dl.wp-caption', classes: 'alignright'}485 ],486 strikethrough: {inline: 'del'}487 }",499 'formats' => '{' . 500 'alignleft: [' . 501 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"left"}},' . 502 '{selector: "img,table,dl.wp-caption", classes: "alignleft"}' . 503 '],' . 504 'aligncenter: [' . 505 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"center"}},' . 506 '{selector: "img,table,dl.wp-caption", classes: "aligncenter"}' . 507 '],' . 508 'alignright: [' . 509 '{selector: "p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li", styles: {textAlign:"right"}},' . 510 '{selector: "img,table,dl.wp-caption", classes: "alignright"}' . 511 '],' . 512 'strikethrough: {inline: "del"}' . 513 '}', 488 514 'relative_urls' => false, 489 515 'remove_script_host' => false, 490 516 'convert_urls' => false, … … 654 680 'body_class' => $body_class 655 681 ); 656 682 657 if ( $first_run )658 683 // Merge with the first part of the init array 684 $mceInit = array_merge( self::$first_init, $mceInit ); 659 685 660 686 if ( is_array( $set['tinymce'] ) ) 661 687 $mceInit = array_merge( $mceInit, $set['tinymce'] ); … … 666 692 * before tinyMCE.init. Setting "valid_elements", "invalid_elements" 667 693 * and "extended_valid_elements" can be done through this filter. Best 668 694 * is to use the default cleanup by not specifying valid_elements, 669 * as TinyMCE c ontains full set of XHTML 1.0.695 * as TinyMCE checks against the full set of HTML 5.0 elements and attributes. 670 696 */ 671 697 if ( $set['teeny'] ) { 672 698 … … 1166 1192 ?> 1167 1193 1168 1194 ( function() { 1169 var init, edId, qtId, firstInit, wrapper;1195 var init, id; 1170 1196 1171 1197 if ( typeof tinymce !== 'undefined' ) { 1172 for ( edId in tinyMCEPreInit.mceInit ) { 1173 if ( firstInit ) { 1174 init = tinyMCEPreInit.mceInit[edId] = tinymce.extend( {}, firstInit, tinyMCEPreInit.mceInit[edId] ); 1175 } else { 1176 init = firstInit = tinyMCEPreInit.mceInit[edId]; 1177 } 1198 for ( id in tinyMCEPreInit.mceInit ) { 1199 init = tinyMCEPreInit.mceInit[id]; 1178 1200 1179 wrapper = tinymce.DOM.select( '#wp-' + edId + '-wrap' )[0]; 1201 if ( ! init.wp_skip_init ) { 1202 tinymce.init( init ); 1180 1203 1181 if ( ( tinymce.DOM.hasClass( wrapper, 'tmce-active' ) || ! tinyMCEPreInit.qtInit.hasOwnProperty( edId ) ) && 1182 ! init.wp_skip_init ) { 1183 1184 try { 1185 tinymce.init( init ); 1186 1187 if ( ! window.wpActiveEditor ) { 1188 window.wpActiveEditor = edId; 1189 } 1190 } catch(e){} 1204 if ( ! window.wpActiveEditor ) { 1205 window.wpActiveEditor = id; 1206 } 1191 1207 } 1192 1208 } 1193 1209 } 1194 1210 1195 1211 if ( typeof quicktags !== 'undefined' ) { 1196 for ( qtId in tinyMCEPreInit.qtInit ) { 1197 try { 1198 quicktags( tinyMCEPreInit.qtInit[qtId] ); 1212 for ( id in tinyMCEPreInit.qtInit ) { 1213 quicktags( tinyMCEPreInit.qtInit[id] ); 1199 1214 1200 if ( ! window.wpActiveEditor ) { 1201 window.wpActiveEditor = qtId; 1202 } 1203 } catch(e){}; 1204 } 1205 } 1206 1207 if ( typeof jQuery !== 'undefined' ) { 1208 jQuery('.wp-editor-wrap').on( 'click.wp-editor', function() { 1209 if ( this.id ) { 1210 window.wpActiveEditor = this.id.slice( 3, -5 ); 1215 if ( ! window.wpActiveEditor ) { 1216 window.wpActiveEditor = id; 1211 1217 } 1212 });1213 } else {1214 for ( qtId in tinyMCEPreInit.qtInit ) {1215 document.getElementById( 'wp-' + qtId + '-wrap' ).onclick = function() {1216 window.wpActiveEditor = this.id.slice( 3, -5 );1217 }1218 1218 } 1219 1219 } 1220 1220 }()); -
src/wp-includes/css/editor.css
286 286 .mce-path-item, 287 287 .mce-path .mce-divider { 288 288 font-size: 12px; 289 line-height: 18px;290 289 } 291 290 292 291 .mce-toolbar .mce-btn, … … 1066 1065 position: relative; 1067 1066 border-bottom: 1px solid #dedede; 1068 1067 background: #f5f5f5; 1068 min-height: 30px; 1069 1069 } 1070 1070 1071 1071 .has-dfw .quicktags-toolbar { -
src/wp-includes/default-filters.php
346 346 add_action( 'before_delete_post', '_reset_front_page_settings_for_post' ); 347 347 add_action( 'wp_trash_post', '_reset_front_page_settings_for_post' ); 348 348 349 // Prepare the content for both Visual and Text editors 350 add_filter( 'the_editor_content', 'format_for_editor' ); 351 349 352 // Post Formats 350 353 add_filter( 'request', '_post_format_request' ); 351 354 add_filter( 'term_link', '_post_format_link', 10, 3 ); -
src/wp-includes/deprecated.php
3491 3491 3492 3492 return false; 3493 3493 } 3494 3495 /** 3496 * Formats text for the rich text editor. 3497 * 3498 * The filter 'richedit_pre' is applied here. If $text is empty the filter will 3499 * be applied to an empty string. 3500 * 3501 * @since 2.0.0 3502 * @deprecated 4.3.0 3503 * 3504 * @param string $text The text to be formatted. 3505 * @return string The formatted text after filter is applied. 3506 */ 3507 function wp_richedit_pre($text) { 3508 _deprecated_function( __FUNCTION__, '4.3', 'format_for_editor()' ); 3509 3510 if ( empty( $text ) ) { 3511 /** 3512 * Filter text returned for the rich text editor. 3513 * 3514 * This filter is first evaluated, and the value returned, if an empty string 3515 * is passed to wp_richedit_pre(). If an empty string is passed, it results 3516 * in a break tag and line feed. 3517 * 3518 * If a non-empty string is passed, the filter is evaluated on the wp_richedit_pre() 3519 * return after being formatted. 3520 * 3521 * @since 2.0.0 3522 * @deprecated 4.3.0 3523 * 3524 * @param string $output Text for the rich text editor. 3525 */ 3526 return apply_filters( 'richedit_pre', '' ); 3527 } 3528 3529 $output = convert_chars($text); 3530 $output = wpautop($output); 3531 $output = htmlspecialchars($output, ENT_NOQUOTES, get_option( 'blog_charset' ) ); 3532 3533 /** This filter is documented in wp-includes/deprecated.php */ 3534 return apply_filters( 'richedit_pre', $output ); 3535 } 3536 3537 /** 3538 * Formats text for the HTML editor. 3539 * 3540 * Unless $output is empty it will pass through htmlspecialchars before the 3541 * 'htmledit_pre' filter is applied. 3542 * 3543 * @since 2.5.0 3544 * @deprecated 4.3.0 3545 * 3546 * @param string $output The text to be formatted. 3547 * @return string Formatted text after filter applied. 3548 */ 3549 function wp_htmledit_pre($output) { 3550 _deprecated_function( __FUNCTION__, '4.3', 'format_for_editor()' ); 3551 3552 if ( !empty($output) ) 3553 $output = htmlspecialchars($output, ENT_NOQUOTES, get_option( 'blog_charset' ) ); // convert only < > & 3554 3555 /** 3556 * Filter the text before it is formatted for the HTML editor. 3557 * 3558 * @since 2.5.0 3559 * @deprecated 4.3.0 3560 * 3561 * @param string $output The HTML-formatted text. 3562 */ 3563 return apply_filters( 'htmledit_pre', $output ); 3564 } 3565 -
src/wp-includes/formatting.php
2980 2980 } 2981 2981 2982 2982 /** 2983 * Formats text for the rich texteditor.2983 * Formats text for the editor. 2984 2984 * 2985 * The filter ' richedit_pre' is applied here. If $text is empty the filter will2985 * The filter 'format_for_editor' is applied here. If $text is empty the filter will 2986 2986 * be applied to an empty string. 2987 2987 * 2988 * @since 2.0.02988 * @since 4.3.0 2989 2989 * 2990 2990 * @param string $text The text to be formatted. 2991 2991 * @return string The formatted text after filter is applied. 2992 2992 */ 2993 function wp_richedit_pre($text) { 2994 if ( empty( $text ) ) { 2995 /** 2996 * Filter text returned for the rich text editor. 2997 * 2998 * This filter is first evaluated, and the value returned, if an empty string 2999 * is passed to wp_richedit_pre(). If an empty string is passed, it results 3000 * in a break tag and line feed. 3001 * 3002 * If a non-empty string is passed, the filter is evaluated on the wp_richedit_pre() 3003 * return after being formatted. 3004 * 3005 * @since 2.0.0 3006 * 3007 * @param string $output Text for the rich text editor. 3008 */ 3009 return apply_filters( 'richedit_pre', '' ); 2993 function format_for_editor( $text ) { 2994 if ( ! empty( $text ) ) { 2995 $text = htmlspecialchars( $text, ENT_NOQUOTES, get_option( 'blog_charset' ) ); // convert only < > & 3010 2996 } 3011 2997 3012 $output = convert_chars($text);3013 $output = wpautop($output);3014 $output = htmlspecialchars($output, ENT_NOQUOTES, get_option( 'blog_charset' ) );3015 3016 /** This filter is documented in wp-includes/formatting.php */3017 return apply_filters( 'richedit_pre', $output );3018 }3019 3020 /**3021 * Formats text for the HTML editor.3022 *3023 * Unless $output is empty it will pass through htmlspecialchars before the3024 * 'htmledit_pre' filter is applied.3025 *3026 * @since 2.5.03027 *3028 * @param string $output The text to be formatted.3029 * @return string Formatted text after filter applied.3030 */3031 function wp_htmledit_pre($output) {3032 if ( !empty($output) )3033 $output = htmlspecialchars($output, ENT_NOQUOTES, get_option( 'blog_charset' ) ); // convert only < > &3034 3035 2998 /** 3036 * Filter the text before it is formatted for the HTMLeditor.2999 * Filter the text after it is formatted for the editor. 3037 3000 * 3038 * @since 2.5.03001 * @since 4.3.0 3039 3002 * 3040 * @param string $ output The HTML-formatted text.3003 * @param string $text The formatted text. 3041 3004 */ 3042 return apply_filters( ' htmledit_pre', $output );3005 return apply_filters( 'format_for_editor', $text ); 3043 3006 } 3044 3007 3045 3008 /** -
src/wp-includes/js/quicktags.js
163 163 id = settings.id, 164 164 canvas = document.getElementById(id), 165 165 name = 'qt_' + id, 166 tb, onclick, toolbar_id ;166 tb, onclick, toolbar_id, wrap, setActiveEditor; 167 167 168 168 if ( !id || !canvas ) { 169 169 return false; … … 182 182 toolbar_id = name + '_toolbar'; 183 183 } 184 184 185 tb = document.createElement('div'); 186 tb.id = toolbar_id; 187 tb.className = 'quicktags-toolbar'; 188 tb.onclick = function() { 189 window.wpActiveEditor = id; 190 }; 185 tb = document.getElementById( toolbar_id ); 191 186 187 if ( ! tb ) { 188 tb = document.createElement('div'); 189 tb.id = toolbar_id; 190 tb.className = 'quicktags-toolbar'; 191 } 192 192 193 canvas.parentNode.insertBefore(tb, canvas); 193 194 t.toolbar = tb; 194 195 … … 214 215 } 215 216 }; 216 217 218 setActiveEditor = function() { 219 window.wpActiveEditor = id; 220 }; 221 222 wrap = document.getElementById( 'wp-' + id + '-wrap' ); 223 217 224 if ( tb.addEventListener ) { 218 tb.addEventListener('click', onclick, false); 225 tb.addEventListener( 'click', onclick, false ); 226 227 if ( wrap ) { 228 wrap.addEventListener( 'click', setActiveEditor, false ); 229 } 219 230 } else if ( tb.attachEvent ) { 220 tb.attachEvent('onclick', onclick); 231 tb.attachEvent( 'onclick', onclick ); 232 233 if ( wrap ) { 234 wrap.attachEvent( 'onclick', setActiveEditor ); 235 } 221 236 } 222 237 223 238 t.getButton = function(id) { -
src/wp-includes/js/tinymce/plugins/wordpress/plugin.js
8 8 each = tinymce.each, 9 9 __ = editor.editorManager.i18n.translate, 10 10 wpAdvButton, style, 11 hasWpautop = ( editor.getParam( 'wpautop', true ) && typeof window.switchEditors !== 'undefined' ), 12 jq = window.jQuery, 11 13 last = 0; 12 14 13 if ( typeof window.jQuery !== 'undefined') {14 window.jQuery( document ).triggerHandler( 'tinymce-editor-setup', [ editor ] );15 if ( jq ) { 16 jq( document ).triggerHandler( 'tinymce-editor-setup', [ editor ] ); 15 17 } 16 18 17 19 function toggleToolbars( state ) { … … 89 91 }); 90 92 91 93 // Replace Read More/Next Page tags with images 92 editor.on( 'BeforeSetContent', function( e ) { 93 var title; 94 editor.on( 'BeforeSetContent', function( event ) { 95 var title, 96 paragraph = tinymce.Env.webkit ? '<p><br /></p>' : '<p></p>'; 94 97 95 if ( e .content ) {96 if ( e .content.indexOf( '<!--more' ) !== -1 ) {98 if ( event.content ) { 99 if ( event.content.indexOf( '<!--more' ) !== -1 ) { 97 100 title = __( 'Read more...' ); 98 101 99 e .content = e.content.replace( /<!--more(.*?)-->/g, function( match, moretext ) {102 event.content = event.content.replace( /<!--more(.*?)-->/g, function( match, moretext ) { 100 103 return '<img src="' + tinymce.Env.transparentSrc + '" data-wp-more="more" data-wp-more-text="' + moretext + '" ' + 101 104 'class="wp-more-tag mce-wp-more" title="' + title + '" data-mce-resize="false" data-mce-placeholder="1" />'; 102 105 }); 103 106 } 104 107 105 if ( e .content.indexOf( '<!--nextpage-->' ) !== -1 ) {108 if ( event.content.indexOf( '<!--nextpage-->' ) !== -1 ) { 106 109 title = __( 'Page break' ); 107 110 108 e .content = e.content.replace( /<!--nextpage-->/g,111 event.content = event.content.replace( /<!--nextpage-->/g, 109 112 '<img src="' + tinymce.Env.transparentSrc + '" data-wp-more="nextpage" class="wp-more-tag mce-wp-nextpage" ' + 110 113 'title="' + title + '" data-mce-resize="false" data-mce-placeholder="1" />' ); 111 114 } 115 116 // Remove spaces from empty paragraphs. 117 event.content = event.content.replace( /<p>(?: |\u00a0|\uFEFF|\s)+<\/p>/gi, paragraph ); 118 119 if ( event.load && event.format !== 'raw' && hasWpautop ) { 120 event.content = window.switchEditors.wpautop( event.content ); 121 } 112 122 } 113 123 }); 114 124 … … 289 299 doc = editor.getDoc(), 290 300 dom = editor.dom; 291 301 292 if ( tinymce.Env.iOS ) {302 if ( env.iOS ) { 293 303 dom.addClass( doc.documentElement, 'ios' ); 294 304 } 295 305 … … 318 328 } 319 329 }); 320 330 331 // Start hidden when the Text editor is set to load first. 332 if ( tinymce.$( '#wp-' + editor.id + '-wrap' ).hasClass( 'html-active' ) ) { 333 editor.hide(); 334 } 335 321 336 // Remove invalid parent paragraphs when inserting HTML 322 // TODO: still needed? 323 editor.on( 'BeforeSetContent', function( e ) { 324 if ( e.content ) { 325 e.content = e.content.replace(/<p>\s*<(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)( [^>]*)?>/gi, '<$1$2>'); 326 e.content = e.content.replace(/<\/(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre|address)>\s*<\/p>/gi, '</$1>'); 337 editor.on( 'BeforeSetContent', function( event ) { 338 if ( event.content ) { 339 event.content = event.content.replace( /<p>\s*<(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre)( [^>]*)?>/gi, '<$1$2>' ) 340 .replace( /<\/(p|div|ul|ol|dl|table|blockquote|h[1-6]|fieldset|pre)>\s*<\/p>/gi, '</$1>' ); 327 341 } 328 342 }); 329 343 330 if ( typeof window.jQuery !== 'undefined') {331 window.jQuery( document ).triggerHandler( 'tinymce-editor-init', [editor] );344 if ( jq ) { 345 jq( document ).triggerHandler( 'tinymce-editor-init', [editor] ); 332 346 } 333 347 334 348 if ( window.tinyMCEPreInit && window.tinyMCEPreInit.dragDropUpload ) { 335 349 dom.bind( doc, 'dragstart dragend dragover drop', function( event ) { 336 if ( typeof window.jQuery !== 'undefined') {350 if ( jq ) { 337 351 // Trigger the jQuery handlers. 338 window.jQuery( document ).trigger( new window.jQuery.Event( event ) );352 jq( document ).trigger( new jq.Event( event ) ); 339 353 } 340 354 }); 341 355 } … … 364 378 }); 365 379 366 380 // Word count 367 if ( typeof window.jQuery !== 'undefined') {381 if ( jq ) { 368 382 editor.on( 'keyup', function( e ) { 369 383 var key = e.keyCode || e.charCode; 370 384 … … 373 387 } 374 388 375 389 if ( 13 === key || 8 === last || 46 === last ) { 376 window.jQuery( document ).triggerHandler( 'wpcountwords', [ editor.getContent({ format : 'raw' }) ] );390 jq( document ).triggerHandler( 'wpcountwords', [ editor.getContent({ format : 'raw' }) ] ); 377 391 } 378 392 379 393 last = key; … … 390 404 // Keep empty paragraphs :( 391 405 e.content = e.content.replace( /<p>(?:<br ?\/?>|\u00a0|\uFEFF| )*<\/p>/g, '<p> </p>' ); 392 406 393 if ( editor.getParam( 'wpautop', true ) && typeof window.switchEditors !== 'undefined') {407 if ( hasWpautop ) { 394 408 e.content = window.switchEditors.pre_wpautop( e.content ); 395 409 } 396 410 }); 397 411 398 // Remove spaces from empty paragraphs.399 editor.on( 'BeforeSetContent', function( event ) {400 var paragraph = tinymce.Env.webkit ? '<p><br /></p>' : '<p></p>';401 402 if ( event.content ) {403 event.content = event.content.replace( /<p>(?: |\u00a0|\uFEFF|\s)+<\/p>/gi, paragraph );404 }405 });406 407 412 editor.on( 'preInit', function() { 408 413 // Don't replace <i> with <em> and <b> with <strong> and don't remove them when empty 409 414 editor.schema.addValidElements( '@[id|accesskey|class|dir|lang|style|tabindex|title|contenteditable|draggable|dropzone|hidden|spellcheck|translate],i,b' );