wp-admin/js/editor.js を改造する場合の、テキスト→ビジュアル切り替え用 JavaScript コードです。
コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
// content reform for visual editor // text to visual function hk_editor_html2tmce( content ) { var pre_tags1, pre_tags2, line_break, code_names, code_types; // 1st common reform content = hk_editor_reform_1st( content ); // empty content if ( content.length == 0 ) { return '<p> </p>'; } // escape PRE tag pre_tags1 = new Array(); pre_tags2 = new Array(); line_break = false; content = hk_editor_escape_pre( content, pre_tags1, pre_tags2, line_break ); // remove \n content = content.replace( /\n/g, '' ); // short code check code_names = new Array(); code_types = new Array(); content = hk_short_code_check( content, code_names, code_types ); // 2nd common reform content = hk_editor_reform_2nd( content, code_names, code_types ); // insert input area around table content = content.replace( /^<table( [^>]*>|>)/i, '<p> </p><table$1' ); content = content.replace( /<\/table><table( [^>]*>|>)/ig, '</table><p> </p><table$1' ); content = content.replace( /<\/table>$/ig, '</table><p> </p>' ); // put back PRE tag content = hk_editor_put_back_pre( content, pre_tags1, pre_tags2 ); // trim content = content.trim(); if ( content.length == 0 ) { content = '<p> </p>'; } return content; } // 1st Common Reform function hk_editor_reform_1st( content ) { // remove tab content = content.replace( /\t/g, '' ); // change characters content = content.replace( /\u00A0/g, ' ' ); content = content.replace( /\r\n|\r/g, '\n' ); // remove unnecessary space: before and after tag content = content.replace( / *(<[^>]*>) */g, '$1' ); // remove unnecessary p-tag content = content.replace( /<p> <\/p>/ig, '' ); content = content.replace( /<p><\/p>/ig, '' ); content = content.replace( /<p>\n<\/p>/ig, '' ); // trim content = content.trim(); return content; } // 2nd Common Reform function hk_editor_reform_2nd( content, code_names, code_types ) { var allblocks, pattern_b, re_str_b, blocks, i, pattern00, pattern3, re_str3, j_max, j, sub_blocks, sub_max, content_parts, pattern, re_str; allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|form|map|area|blockquote|address|math|style|p|h[1-6]|hr|fieldset|legend|section|article|aside|hgroup|header|footer|nav|figure|figcaption|details|menu|summary)'; // if top character is not '<', p-tag wrap. if ( content.indexOf( '<' ) != 0 ) { // split by block tag pattern_b = '(<' + allblocks + '(?: [^>]*>|>))'; re_str_b = new RegExp( pattern_b, 'ig' ); blocks = content.split( re_str_b ); // blocks[0] <block-tag> // wrap blocks[0] with p-tag blocks[0] = '<p>' + blocks[0] + '</p>'; content = blocks.join( '' ); } // shortcode_unautop if ( code_names.length != 0 ) { for ( i in code_names ) { code_name = code_names[i]; code_type = code_types[code_name]; pattern00 = hk_short_code_pattern( code_name, code_type ); // split by short code pattern3 = '(' + pattern00 + ')(?!\\])'; re_str3 = new RegExp( pattern3, 'ig' ); blocks = content.split( re_str3 ); j_max = blocks.length - 2; for ( j=0; j<j_max; j+=2 ) { // blocks[j] [shortcode] blocks[j+2] // split blocks[j] by block-tag pattern_b = '(<' + allblocks + '(?: [^>]*>|>))'; re_str_b = new RegExp( pattern_b, 'ig' ); sub_blocks = blocks[ j ].split( re_str_b ); sub_max = sub_blocks.length; // if no block tag, 'continue'. if ( sub_max == 1 ) { continue; } // <block-tag> sub_blocks[sub_max-1] [shortcode] // if block-tag is not p-tag, 'continue'. if ( sub_blocks[ sub_max-2 ].match( /<p( [^>]*>|>)/i ) == null ) { continue; } // <p> sub_blocks[sub_max-1] [shortcode] // if </p> exists in sub_blocks[sub_max-1], 'continue'. if ( sub_blocks[ sub_max-1 ].indexOf( '</p>' ) != -1 ) { continue; } // <p> xxxxx [shortcode] yyyyy </p> // insert </p> and <p> // -> <p> xxxxx </p> [shortcode] <p> yyyyy </p> blocks[ j ] += '</p>'; blocks[ j+2 ] = '<p>' + blocks[ j+2 ]; } content = blocks.join( '' ); // delete <p></p> content = content.replace( /<p(?: [^>]*>|>)((?:<br [^>]*>)+)<\/p>/ig, '$1' ); content = content.replace( /<p( [^>]*>|>)<\/p>/ig, '' ); } } // delete p-tag inside table if ( content.indexOf( '</td>' ) != -1 ) { // split by </td> content_parts = content.split( '</td>' ); content = ''; for ( i in content_parts ) { // split by <td pattern = '(<td(?: [^>]*>|>))'; re_str = new RegExp( pattern, 'ig' ); blocks = content_parts[ i ].split( re_str ); // if no td tag, 'continue'. if ( blocks.length == 1 ) { content += content_parts[ i ]; continue; } // string after td-tag // delete p-tag blocks[ 2 ] = blocks[ 2 ].replace( /<p(?: [^>]*>|>)/ig, '' ); // delete </p> at the end of string blocks[ 2 ] = blocks[ 2 ].replace( /<\/p>$/i, '' ); // replace </p> with <br /> blocks[ 2 ] = blocks[ 2 ].replace( /<\/p>/ig, '<br />' ); // add string content += blocks[ 0 ] + blocks[ 1 ] + blocks[ 2 ] + '</td>'; } } // p-tag indent ( \u3000 : ZENKAKU space ) content = content.replace( /<p>\u3000/ig, '<p>' ); content = content.replace( /<p>/ig, '<p>\u3000' ); content = content.replace( /<p>\u3000</ig, '<p><' ); content = content.replace( /<p><\/p>/ig, '' ); return content; } // escape PRE tag function hk_editor_escape_pre( content, pre_tags1, pre_tags2, line_break ) { var content_parts, pre_i, i, pattern, re_str, blocks, pre_block, pre_name; // </pre> check if ( content.indexOf( '</pre>' ) == -1 ) { return content; } // split by </pre> content_parts = content.split( '</pre>' ); // initialize content = ''; pre_i = 0; for ( i in content_parts ) { // split by <pre pattern = '(<pre(?: [^>]*>|>))'; re_str = new RegExp( pattern, 'ig' ); blocks = content_parts[ i ].split( re_str ); // if no pre tag, 'continue'. if ( blocks.length == 1 ) { content += content_parts[ i ]; continue; } // blocks[0] <pre> blocks[2] // string : before <pre> content += blocks[ 0 ]; // string : after <pre> // trim \n blocks[ 2 ] = blocks[ 2 ].replace( /^\n+/, '' ); blocks[ 2 ] = blocks[ 2 ].replace( /\n+$/, '' ); // string : <pre> and after if ( line_break ) { pre_block = blocks[ 1 ] + '\n' + blocks[ 2 ] + '\n</pre>'; } else { pre_block = blocks[ 1 ] + blocks[ 2 ] + '</pre>'; } // data save pre_name = '<pre hk-pre-tag-' + pre_i + '></pre>'; pre_tags1[ pre_i ] = pre_name; pre_tags2[ pre_i ] = pre_block; content += pre_name; pre_i++; } return content; } // put back PRE tag function hk_editor_put_back_pre( content, pre_tags1, pre_tags2 ) { var pre_i, i; pre_i = pre_tags1.length; if ( pre_i != 0 ) { for ( i=0; i<pre_i; i++ ) { content = content.replace( pre_tags1[ i ], pre_tags2[ i ] ); } } return content; } // Short Code Check function hk_short_code_check( content, code_names, code_types ) { var i, code_name, self, re_str1, encl, re_str2, type, pattern00, pattern01, re_str01, pattern02, re_str02, pattern03, re_str03, pattern04, re_str04; for ( i in hk_short_codes ) { code_name = hk_short_codes[i]; self = hk_short_code_pattern( code_name, 'self' ); re_str1 = new RegExp( self, 'i' ); // if shortcode does not exist, 'continue'. if ( content.match( re_str1 ) == null ) { continue; } encl = hk_short_code_pattern( code_name, 'encl' ); re_str2 = new RegExp( encl, 'i' ); // enclosing shortcodes if ( content.match( re_str2 ) ) { type = 'encl'; pattern00 = encl; } // self-closing shortcodes else { type = 'self'; pattern00 = self; } // correct pseudo-shortcode pattern01 = '(\\[' + pattern00 + ')(?!\\])'; re_str01 = new RegExp( pattern01, 'ig' ); content = content.replace( re_str01, '$1\]' ); pattern02 = '(' + pattern00 + '\\])'; re_str02 = new RegExp( pattern02, 'ig' ); content = content.replace( re_str02, '\[$1' ); pattern03 = '\\[(\\[' + pattern00 + '\\])'; re_str03 = new RegExp( pattern03, 'ig' ); content = content.replace( re_str03, '$1' ); // register shortcode pattern04 = '(?:[^\\[]|^)' + pattern00 + '(?:[^\\]]|$)'; re_str04 = new RegExp( pattern04, 'i' ); if ( content.match( re_str04 ) ) { code_names.push( code_name ); code_types[ code_name ] = type; } } return content; } // Short Code pattern function hk_short_code_pattern( code_name, code_type ) { var self, encl; self = '\\[' + code_name + '[^\\]]*\\]'; encl = self + '[^\\[]*[\\[]+\\/' + code_name + '\\]'; if ( code_type == 'self' ) { return self; } return encl; }
説明
9行目:コンテンツが空の場合の初期値です。文頭の字下げ用です。
15行目:PREタグを退避。Script も必要があれば退避した方が良いでしょう。
17行目:改行を削除。ビジュアルエディターで改行が空白に変わるため削除します。
21行目:shortcode の有無をチェックします。
24~27行目:表の周りに文字入力スペースを作ります。
29行目:PREタグ復元。
43行目:u00A0 はユニコードの空白文字コードの一つ。
61~71行目:先頭がタグでない場合、pタグでラップします。
72~115行目:ショートコードのpタグラップ解除。
116~141行目:表内部のpタグ削除。
142~146行目:字下げ。u3000 はユニコードの全角スペースです。
150~194行目:PREタグ退避。
196~206行目:PREタグ復元。
208~251行目:ショートコードの有無をチェック。
253~262行目:ショートコード用正規表現パターン作成。
このプログラムをお使いになる場合は、お使いになる方の自己責任でお願いします。