May 17 2008

How to write a fast catch-all RegExp

Tag: FixingAndrea Ercolino @ 18:55:36

In How to write a safe catch-all RegExp I suggested to use (?:\w|\W)* for matching any character in a regular expression. It’s certainly true and safe, and the same stands for its siblings (?:\s|\S)* and (?:\d|\D)*.

If you want to match a large text, these expressions are not the best. I’ve prepared a simple test page where the GeSHi’s engine file, which is almost 120KB, is going to be matched by the regular expression you input.

In Firefox 2 the performance is quite good, about 100 ms on my PC, but in Internet Explorer 7 it takes more than 7 minutes !!!

The best catch-all regular expression is [\w\W]*, which employs about 50 ms in FF2, and 0 ms in IE7 !!! (yes, zero milliseconds)


Nov 24 2007

WordPress Rendering Troubles

Tag: FixingAndrea Ercolino @ 23:41:59

WordPress has many helpers that allow authors to write down some text and have it nicely formatted for their readers, without having to care about HTML issues. It’s a great job, but sometimes it doesn’t do the right thing.

This bug affects content and custom fields, which means that it’s more of a conceptual bug than a coding bug. I wrote an article with a workaround for the content. Now, let’s see a simple fix for custom fields.

I’ll describe both problems I detected and give a solution based on changing some WordPress code. I know it’s not a perfect solution, but it works and it’s also relatively easy. In the snippets you’ll see the code as it’s supposed to get changed to. (with 3 lines of context before and after changed lines, each preceded by a //noteslog.com comment)

Wordpress Version: 2.3.1

Problem: HTML Entities Conversion

Custom fields that have HTML entities in their key or value are treated by WordPress weirdly. Frustration will appear soon after realizing that WordPress won’t return what you put in before.

If I write ¶ inside the visual editor of a post, WordPress should assume that I want to visualize ¶. In fact it will pretend to do the right thing the first time I save the post. All subsequent times it will show a where I put a ¶.

If I write ¶ inside the code editor of a post, WordPress should assume that I want to visualize , and it does the right thing (sort of, because I now have a inside the code too).

If I write ¶ inside a custom field’s key or value, WordPress should assume that I want to visualize for my readers, and ¶ for myself when I’m authoring the custom field. In fact Wordpress does the wrong thing here again, because it’ll immediately convert ¶ to .

Solution

This fix requires changing four lines in two files. We’ll use the PHP function htmlspecialchars in place of the WordPress function attribute_escape. After the fix, filters for “attribute_escape” won’t get applied to custom fields keys and values. (this shouldn’t be a problem)

Open: wp-admin/admin-ajax.php
Search: function wp_ajax_meta_row

add_action( 'shutdown', 'get_out_now', -1 );

function wp_ajax_meta_row( $pid, $mid, $key, $value ) {
//noteslog.com
	$value = htmlspecialchars( $value ); //attribute_escape($value);
	$key_js = addslashes(wp_specialchars($key, 'double'));
//noteslog.com
	$key = htmlspecialchars( $key ); //attribute_escape($key);
	$r .= "<tr id='meta-$mid'><td valign='top'>";
	$r .= "<input name='meta[$mid][key]' tabindex='6' onkeypress='return killSubmit(\"theList.ajaxUpdater(&#039;meta&#039;,&#039;meta-$mid&#039;);\",event);' type='text' size='20' value='$key' />";
	$r .= "</td><td><textarea name='meta[$mid][value]' tabindex='6' rows='2' cols='30'>$value</textarea></td><td align='center'>";

Open: wp-admin/includes/template.php
Search: function list_meta

}

		$key_js = js_escape( $entry['meta_key'] );
//noteslog.com
		$entry['meta_key']   = htmlspecialchars($entry['meta_key']);//attribute_escape($entry['meta_key']);
//noteslog.com
		$entry['meta_value'] = htmlspecialchars($entry['meta_value']);//attribute_escape($entry['meta_value']);
		$entry['meta_id'] = (int) $entry['meta_id'];
		$r .= "\n\t<tr id='meta-{$entry['meta_id']}' class='$style'>";
		$r .= "\n\t\t<td valign='top'><input name='meta[{$entry['meta_id']}][key]' tabindex='6' type='text' size='20' value='{$entry['meta_key']}' /></td>";

Problem: White Space Trimming

Custom fields that begin or end with white space in their key or value are trimmed. I can undestand that a key is more easily dealt with if it is trimmed before saving it into the database. But values should definitely retain all their white space AS IS.

Solution

This fix requires changing four lines in three files. We’ll add a $trim parameter to the wordpress function maybe_serialize, by default set to true. Wherever we do not want a $data value trimmed, we’ll call maybe_serialize with a false second argument.

Open: wp-includes/functions.php
Search: function maybe_serialize

return true;
}

//noteslog.com
function maybe_serialize($data, $trim=true) { //($data)
//noteslog.com
	if ( $trim && is_string($data) ) //( is_string($data) )
		$data = trim($data);
	elseif ( is_array($data) || is_object($data) )
		return serialize($data);

Open: wp-admin/includes/post.php
Search: function add_meta

$metakeyselect = $wpdb->escape( stripslashes( trim( $_POST['metakeyselect'] ) ) );
	$metakeyinput = $wpdb->escape( stripslashes( trim( $_POST['metakeyinput'] ) ) );
//noteslog.com
	$metavalue = maybe_serialize( stripslashes( ( $_POST['metavalue'] ) ), false ); //( stripslashes( trim( $_POST['metavalue'] ) ) );
	$metavalue = $wpdb->escape( $metavalue );

	if ( ('0' === $metavalue || !empty ( $metavalue ) ) && ((('#NONE#' != $metakeyselect) && !empty ( $metakeyselect) ) || !empty ( $metakeyinput) ) ) {
		// We have a key/value pair. If both the select and the

Open: wp-admin/includes/post.php
Search: function update_meta

if ( in_array($mkey, $protected) )
		return false;

//noteslog.com
	$mvalue = maybe_serialize( stripslashes( $mvalue ), false ); //( stripslashes( $mvalue ) );
	$mvalue = $wpdb->escape( $mvalue );
	$mid = (int) $mid;
	return $wpdb->query( "UPDATE $wpdb->postmeta SET meta_key = '$mkey', meta_value = '$mvalue' WHERE meta_id = '$mid'" );


Sep 23 2007

How to fix the resize event in IE

Tag: FixingAndrea Ercolino @ 22:45:46

In IE the window resize event is fired multiple times per actual resize: it is a well known issue for IE6 and IE7, but they misbehave along different patterns. Actually it seems that IE6 is worse than IE7.

After quite a long session of R&D, I’ve got to a pretty good solution, in the form of a jQuery plugin: jquery.wresize.js

/*  
===============================================================================
WResize is the jQuery plugin for fixing the IE window resize bug
...............................................................................
                                               Copyright 2007 / Andrea Ercolino
-------------------------------------------------------------------------------
LICENSE: http://www.opensource.org/licenses/mit-license.php
WEBSITE: http://noteslog.com/
===============================================================================
*/

( function( $ ) 
{
	$.fn.wresize = function( f ) 
	{
		version = '1.1';
		wresize = {fired: false, width: 0};

		function resizeOnce() 
		{
			if ( $.browser.msie )
			{
				if ( ! wresize.fired )
				{
					wresize.fired = true;
				}
				else 
				{
					var version = parseInt( $.browser.version, 10 );
					wresize.fired = false;
					if ( version < 7 )
					{
						return false;
					}
					else if ( version == 7 )
					{
						//a vertical resize is fired once, an horizontal resize twice
						var width = $( window ).width();
						if ( width != wresize.width )
						{
							wresize.width = width;
							return false;
						}
					}
				}
			}

			return true;
		}

		function handleWResize( e ) 
		{
			if ( resizeOnce() )
			{
				return f.apply(this, [e]);
			}
		}

		this.each( function() 
		{
			if ( this == window )
			{
				$( this ).resize( handleWResize );
			}
			else
			{
				$( this ).resize( f );
			}
		} );

		return this;
	};

} ) ( jQuery );

If you want to try it, here is a test page, where a div is automatically resized when the window is resized.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" style="overflow:hidden;">
 <head>
  <title> test window resize </title>

<script type="text/javascript" src="http://jquery.com/src/jquery-latest.pack.js"></script>
<script type="text/javascript" src="jquery.wresize.js"></script>


<script type="text/javascript">
jQuery( function( $ ) 
{
	function content_resize() 
	{
		var w = $( window );
		var H = w.height();
		var W = w.width();
		$( '#content' ).css( {width: W-20, height: H-20} );
	}

	$( window ).wresize( content_resize );

	content_resize();
} );
</script>

 </head>

 <body>
 
<div id="content" style="border: 1px dashed silver; position:absolute; overflow:auto;">
test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test 
</div>

 </body>
</html>

References:

http://dev.jquery.com
http://snook.ca
http://ecmascript.stchur.com


Next Page »