WordPress.org

Plugin Directory

Changeset 457449


Ignore:
Timestamp:
10/30/11 21:06:20 (2 years ago)
Author:
MarcusPope
Message:

updated source to use more compatible function calling mech. supports < php5.3

Location:
preserved-html-editor-markup/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • preserved-html-editor-markup/trunk/readme.txt

    r456532 r457449  
    11=== Preserved HTML Editor Markup === 
    22Contributors: marcuspope 
    3 Donate link: http://www.springbox.com/contact/ 
     3Donate link: http://www.marcuspope.com/ 
    44Tags: wpautop, editor, markup, html, white space, HTML5, WYSIWYG, visual, developer 
    55Requires at least: 3.2.1 
     
    2323  1. Orphaned text content will not be wrapped in any tag - so you will want to make sure your theme inherently wraps the post content in a div tag (or some other block element) for valid HTML markup. 
    2424 
    25   1. White space is preserved; newlines, spaces and tabs will remain in your markup for the most part.  For performance reasons, it will only preserve spaces if 4 spaces are used consecutively - i.e. an expanded tab in developer terms.  It will not preserve intra-tag white space like &lt;p&nbsp;&nbsp;&nbsp;&nbsp;&gt;.  
     25  1. White space is preserved; newlines, spaces and tabs will remain in your markup for the most part.  For performance reasons, it will only preserve spaces if 4 spaces are used consecutively - i.e. an expanded tab in developer terms.  It will not preserve intra-tag white space like &lt;p&nbsp;&nbsp;&nbsp;&nbsp;&gt;. 
    2626 
    27 There are a couple of bugs in the parsing logic that I'm aware of and I will work to iron them out over the coming weeks.   
     27There are a couple of bugs in the parsing logic that I'm aware of and I will work to iron them out over the coming weeks. 
    2828 
    2929Known issues: 
     
    5959== Changelog == 
    6060 
     61= 1.1 = 
     62* Refactored for support of < php5.3 by replacing function references with static function array refs 
    6163= 1.0 = 
    6264* Initial creation of plugin 
  • preserved-html-editor-markup/trunk/sb_preserved_markup.php

    r456532 r457449  
    33/* 
    44Plugin Name: Preserved HTML Editor Markup 
    5 Plugin URI: http://www.springbox.com/wordpress/ 
     5Plugin URI: http://www.marcuspope.com/wordpress/ 
    66Description: A Wordpress Plugin that preserves HTML markup in the TinyMCE editor, especially when switching between 
    77html and visual tabs.  Also adds support for HTML5 Block Anchors. 
    8 Author: Marcus E. Pope, Springbox.com, marcuspope 
     8Author: Marcus E. Pope, marcuspope 
    99Author URI: http://www.marcuspope.com 
    1010Version: 1.0 
    1111 
    12 Copyright 2011 Marcus E. Pope (email : marcus.pope@springbox.com) 
     12Copyright 2011 Marcus E. Pope (email : me@marcuspope.com) 
    1313 
    1414This program is free software; you can redistribute it and/or modify 
     
    2727*/ 
    2828 
    29 add_action('plugins_loaded', array('SB_WP_Preserved_Markup', 'init'), 1); 
     29add_action('plugins_loaded', array('MP_WP_Preserved_Markup', 'init'), 1); 
    3030 
    31 class SB_WP_Preserved_Markup { 
     31class MP_WP_Preserved_Markup { 
     32 
     33    public static function remove_evil() { 
     34        //remove evil: wpautop will break html5 markup! 
     35        remove_filter('the_content', 'wpautop'); 
     36    } 
     37 
     38    public static function init_tiny_mce($init) { 
     39        //Setup tinymce editor with necessary settings for better general editing 
     40        $tags = "pre[*],iframe[*],object[*],param[*]"; //add pre and iframe to allowable tags for 
     41        if (isset($init['extended_valid_elements'])) { 
     42            $tags = $init['extended_valid_elements'] . "," . $tags; 
     43        } 
     44        $init['extended_valid_elements'] = $tags; 
     45        $init['forced_root_block'] = false; //prevent tinymce from wrapping a root block level element (typically a <p> tag) 
     46        $init['force_p_newlines'] = false; 
     47        $init['remove_linebreaks'] = false; 
     48        $init['force_br_newlines'] = true; 
     49        $init['remove_trailing_nbsp'] = false; 
     50        $init['relative_urls'] = true; 
     51        $init['convert_urls'] = false; 
     52        $init['remove_linebreaks'] = false; 
     53        $init['doctype'] = '<!DOCTYPE html>'; 
     54        $init['apply_source_formatting'] = false; 
     55        $init['convert_newlines_to_brs'] = false; 
     56        $init['fix_list_elements'] = false; 
     57        $init['fix_table_elements'] = false; 
     58        $init['verify_html'] = false; 
     59 
     60        /* 
     61           Allow for html5 anchor tags 
     62           http://dev.w3.org/html5/markup/a.html 
     63           http://dev.w3.org/html5/markup/common-models.html#common.elem.phrasing 
     64           http://www.tinymce.com/wiki.php/Configuration:valid_children 
     65        */ 
     66        $init['valid_children'] = "+a[em|strong|small|mark|abbr|dfn|i|b|s|u|code|var|samp|kbd|sup|sub|q|cite|span|bdo|bdi|br|wbr|ins|del|img|embed|object|iframe|map|area|script|noscript|ruby|video|audio|input|textarea|select|button|label|output|datalist|keygen|progress|command|canvas|time|meter|p|hr|pre|ul|ol|dl|div|h1|h2|h3|h4|h5|h6|hgroup|address|blockquote|section|nav|article|aside|header|footer|figure|table|f|m|fieldset|menu|details]"; 
     67 
     68        return $init; 
     69    } 
     70 
     71    public static function fix_editor_content($html) { 
     72        remove_filter('the_editor_content', "wp_richedit_pre"); 
     73        return $html; 
     74    } 
     75 
     76    public static function content_replace_callback($a) { 
     77        $s = $a[0]; 
     78        $s = preg_replace("/(\r\n|\n)/m", '<mep-preserve-nl>', $s); 
     79        $s = preg_replace("/\t/m", '<mep-preserve-tab>', $s); 
     80        $s = preg_replace("/\s/m", '<mep-preserve-space>', $s); 
     81        return $s; 
     82    } 
     83 
     84    public static function fix_wysiwyg_content($c) { 
     85        //If the page is rendered with the WYSIWYG editor selected by default, content is processed in PHP land 
     86        //instead of using the JS land "equivalent" logic (I quote equivalent because there are sooooo many 
     87        //discrepancies between what JS wpautop and PHP wpautop functions do it's laughable. 
     88        if (wp_default_editor() == "tinymce") { 
     89            //First we inject temporary whitespace markers in pre and code elements because they won't 
     90            //be corrupted when the user switches to html mode.*   (actually IE9 will remove the first 
     91            //newline from a pre tag if there are no non-whitespace characters before the newline.) 
     92            $c = preg_replace_callback( 
     93                '/<(pre|code)[^>]*>[\s\S]+?<\/\\1>/m', 
     94                array( 
     95                    'MP_WP_Preserved_Markup', 
     96                    'content_replace_callback' 
     97                ), 
     98                $c); 
     99 
     100            //Now let's preserve whitespace with html comments so that they can be converted back when switching to 
     101            //the html mode.  FIXME: assuming four spaces is bad mmkay, what if I like only two spaces for a tab? 
     102            //and this could produce bad markup if a user had <p    class="test">hello</p> in their markup.  So 
     103            //work on a more flexible /\s/g approach when \s is inside or outside a tag definition 
     104            $c = preg_replace("/(\r\n|\n)/", "<!--mep-nl-->", $c); //preserve new lines 
     105            $c = preg_replace("/(\t|\s\s\s\s)/", "<!--mep-tab-->", $c); //preserve indents 
     106 
     107            //Now we can restore all whitespace originally escaped in pre & code tags 
     108            $c = preg_replace("/<mep-preserve-nl>/m", "\n", $c); 
     109            $c = preg_replace("/<mep-preserve-tab>/m", "\t", $c); 
     110            $c = preg_replace("/<mep-preserve-space>/m", " ", $c); 
     111 
     112            //finish up with functions that WP normally calls on the_editor_content 
     113            $c = convert_chars($c); 
     114            $c = htmlspecialchars($c, ENT_NOQUOTES); 
     115        } 
     116 
     117        return $c; 
     118    } 
     119 
     120    public static function fix_post_content($post) { 
     121        //If the user clicks save while in the Visual (WYSIWYG) tab, we'll need to strip the whitespace placeholders 
     122        //before inserting the data into the database to prevent duplication of whitespace 
     123        //WTF: ok so I ran into a problem of duplicating newlines when saving from the Visual tab, so I added this 
     124        //     code to strip what I thought was my whitespace markers not being converted back in JS land before being 
     125        //     sent to the server.  (in the same way that if you load the page on the Visual tab, the parsing logic 
     126        //     occurs on the server instead of the client!)  But after add this code I couldn't reproduce the issue 
     127        //     the post_content never contained any mep-xxx comments.  I'm leaving this code in here, because it's 
     128        //     the probable explanation for duplicated newlines, but I'm also not sure how the Visual content is 
     129        //     transfered from the iframe to the textarea. 
     130        if (isset($post['post_content'])) { 
     131            $post['post_content'] = preg_replace('/<\!--mep-nl-->/m', "\r\n", $post['post_content']); 
     132            $post['post_content'] = preg_replace('/<\!--mep-tab-->/m', "    ", $post['post_content']); 
     133        } 
     134        return $post; 
     135    } 
     136 
     137    public static function admin_init() { 
     138        //Add full attribute support for special tags 
     139        add_filter( 'tiny_mce_before_init', array( 
     140            'MP_WP_Preserved_Markup', 
     141            'init_tiny_mce' 
     142        )); 
     143 
     144        /* fix WP html editor on client side */ 
     145        wp_enqueue_script('admin-js', WP_PLUGIN_URL.'/'.str_replace(basename( __FILE__),"",plugin_basename(__FILE__))."admin.js"); 
     146 
     147        add_filter('the_editor', array( 
     148            'MP_WP_Preserved_Markup', 
     149            'fix_editor_content' 
     150        ), 1); 
     151 
     152        add_filter('the_editor_content', array( 
     153            'MP_WP_Preserved_Markup', 
     154            'fix_wysiwyg_content' 
     155        ), 1); 
     156 
     157        add_filter('wp_insert_post_data', array( 
     158            'MP_WP_Preserved_Markup', 
     159            'fix_post_content' 
     160        ), 1); 
     161    } 
    32162 
    33163    public static function init() { 
     164        add_action('init', array( 
     165            'MP_WP_Preserved_Markup', 
     166            'remove_evil' 
     167        )); 
    34168 
    35         add_action('init', function() { 
    36             //remove evil: wpautop will break html5 markup! 
    37             remove_filter('the_content', 'wpautop'); 
    38         }); 
    39  
    40         add_action('admin_init', function() { 
    41  
    42             //Add full attribute support for special tags 
    43             add_filter( 'tiny_mce_before_init', function($init) { 
    44                 $tags = "pre[*],iframe[*],object[*],param[*]"; //add pre and iframe to allowable tags for 
    45                 if (isset($init['extended_valid_elements'])) { 
    46                     $tags = $init['extended_valid_elements'] . "," . $tags; 
    47                 } 
    48                 $init['extended_valid_elements'] = $tags; 
    49                 $init['forced_root_block'] = false; //prevent tinymce from wrapping a root block level element (typically a <p> tag) 
    50                 $init['force_p_newlines'] = false; 
    51                 $init['remove_linebreaks'] = false; 
    52                 $init['force_br_newlines'] = true; 
    53                 $init['remove_trailing_nbsp'] = false; 
    54                 $init['relative_urls'] = true; 
    55                 $init['convert_urls'] = false; 
    56                 $init['remove_linebreaks'] = false; 
    57                 $init['doctype'] = '<!DOCTYPE html>'; 
    58                 $init['apply_source_formatting'] = false; 
    59                 $init['convert_newlines_to_brs'] = false; 
    60                 $init['fix_list_elements'] = false; 
    61                 $init['fix_table_elements'] = false; 
    62                 $init['verify_html'] = false; 
    63  
    64                 /* 
    65                    Allow for html5 anchor tags 
    66                    http://dev.w3.org/html5/markup/a.html 
    67                    http://dev.w3.org/html5/markup/common-models.html#common.elem.phrasing 
    68                    http://www.tinymce.com/wiki.php/Configuration:valid_children 
    69                 */ 
    70                 $init['valid_children'] = "+a[em|strong|small|mark|abbr|dfn|i|b|s|u|code|var|samp|kbd|sup|sub|q|cite|span|bdo|bdi|br|wbr|ins|del|img|embed|object|iframe|map|area|script|noscript|ruby|video|audio|input|textarea|select|button|label|output|datalist|keygen|progress|command|canvas|time|meter|p|hr|pre|ul|ol|dl|div|h1|h2|h3|h4|h5|h6|hgroup|address|blockquote|section|nav|article|aside|header|footer|figure|table|f|m|fieldset|menu|details]"; 
    71  
    72                 return $init; 
    73             }); 
    74  
    75             /* fix WP html editor */ 
    76             wp_enqueue_script('admin-js', WP_PLUGIN_URL.'/'.str_replace(basename( __FILE__),"",plugin_basename(__FILE__))."admin.js"); 
    77  
    78             add_filter('the_editor', function($html) { 
    79                 remove_filter('the_editor_content', "wp_richedit_pre"); 
    80                 return $html; 
    81             }, 1); 
    82  
    83             add_filter('the_editor_content', function($c) { 
    84                 //If the page is rendered with the WYSIWYG editor selected by default, content is processed in PHP land 
    85                 //instead of using the JS land "equivalent" logic (I quote equivalent because there are sooooo many 
    86                 //discrepancies between what JS wpautop and PHP wpautop functions do it's laughable. 
    87                 if (wp_default_editor() == "tinymce") { 
    88                     //First we inject temporary whitespace markers in pre and code elements because they won't 
    89                     //be corrupted when the user switches to html mode.*   (actually IE9 will remove the first 
    90                     //newline from a pre tag if there are no non-whitespace characters before the newline.) 
    91                     $c = preg_replace_callback('/<(pre|code)[^>]*>[\s\S]+?<\/\\1>/m', function($a) { 
    92                         $s = $a[0]; 
    93                         $s = preg_replace("/(\r\n|\n)/m", '<mep-preserve-nl>', $s); 
    94                         $s = preg_replace("/\t/m", '<mep-preserve-tab>', $s); 
    95                         $s = preg_replace("/\s/m", '<mep-preserve-space>', $s); 
    96                         return $s; 
    97                     }, $c); 
    98  
    99                     //Now let's preserve whitespace with html comments so that they can be converted back when switching to 
    100                     //the html mode.  FIXME: assuming four spaces is bad mmkay, what if I like only two spaces for a tab? 
    101                     //and this could produce bad markup if a user had <p    class="test">hello</p> in their markup.  So 
    102                     //work on a more flexible /\s/g approach when \s is inside or outside a tag definition 
    103                     $c = preg_replace("/(\r\n|\n)/", "<!--mep-nl-->", $c); //preserve new lines 
    104                     $c = preg_replace("/(\t|\s\s\s\s)/", "<!--mep-tab-->", $c); //preserve indents 
    105  
    106                     //Now we can restore all whitespace originally escaped in pre & code tags 
    107                     $c = preg_replace("/<mep-preserve-nl>/m", "\n", $c); 
    108                     $c = preg_replace("/<mep-preserve-tab>/m", "\t", $c); 
    109                     $c = preg_replace("/<mep-preserve-space>/m", " ", $c); 
    110  
    111                     //finish up with functions that WP normally calls on the_editor_content 
    112                     $c = convert_chars($c); 
    113                     $c = htmlspecialchars($c, ENT_NOQUOTES); 
    114                 } 
    115  
    116                 return $c; 
    117             }, 1); 
    118  
    119             add_filter('wp_insert_post_data', function($post) { 
    120                 //If the user clicks save while in the Visual (WYSIWYG) tab, we'll need to strip the whitespace placeholders 
    121                 //before inserting the data into the database to prevent duplication of whitespace 
    122                 //WTF: ok so I ran into a problem of duplicating newlines when saving from the Visual tab, so I added this 
    123                 //     code to strip what I thought was my whitespace markers not being converted back in JS land before being 
    124                 //     sent to the server.  (in the same way that if you load the page on the Visual tab, the parsing logic 
    125                 //     occurs on the server instead of the client!)  But after add this code I couldn't reproduce the issue 
    126                 //     the post_content never contained any mep-xxx comments.  I'm leaving this code in here, because it's 
    127                 //     the probable explanation for duplicated newlines, but I'm also not sure how the Visual content is 
    128                 //     transfered from the iframe to the textarea. 
    129                 if (isset($post['post_content'])) { 
    130                     $post['post_content'] = preg_replace('/<\!--mep-nl-->/m', "\r\n", $post['post_content']); 
    131                     $post['post_content'] = preg_replace('/<\!--mep-tab-->/m', "    ", $post['post_content']); 
    132                 } 
    133                 return $post; 
    134             }, 1); 
    135         }); 
     169        add_action('admin_init', array( 
     170            'MP_WP_Preserved_Markup', 
     171            'admin_init' 
     172        )); 
    136173    } 
    137174} 
Note: See TracChangeset for help on using the changeset viewer.