Deprecated: Assigning the return value of new by reference is deprecated in /homepages/32/d230485870/htdocs/jessmann/blog/wp-settings.php on line 520

Deprecated: Assigning the return value of new by reference is deprecated in /homepages/32/d230485870/htdocs/jessmann/blog/wp-settings.php on line 535

Deprecated: Assigning the return value of new by reference is deprecated in /homepages/32/d230485870/htdocs/jessmann/blog/wp-settings.php on line 542

Deprecated: Assigning the return value of new by reference is deprecated in /homepages/32/d230485870/htdocs/jessmann/blog/wp-settings.php on line 578

Deprecated: Function set_magic_quotes_runtime() is deprecated in /homepages/32/d230485870/htdocs/jessmann/blog/wp-settings.php on line 18

Strict Standards: Declaration of Walker_Page::start_lvl() should be compatible with Walker::start_lvl(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::end_lvl() should be compatible with Walker::end_lvl(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::start_el() should be compatible with Walker::start_el(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_Page::end_el() should be compatible with Walker::end_el(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1199

Strict Standards: Declaration of Walker_PageDropdown::start_el() should be compatible with Walker::start_el(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1244

Strict Standards: Declaration of Walker_Category::start_lvl() should be compatible with Walker::start_lvl(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::end_lvl() should be compatible with Walker::end_lvl(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::start_el() should be compatible with Walker::start_el(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_Category::end_el() should be compatible with Walker::end_el(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1391

Strict Standards: Declaration of Walker_CategoryDropdown::start_el() should be compatible with Walker::start_el(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/classes.php on line 1442

Strict Standards: Redefining already defined constructor for class wpdb in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/wp-db.php on line 306

Strict Standards: Redefining already defined constructor for class WP_Object_Cache in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/cache.php on line 431

Strict Standards: Declaration of Walker_Comment::start_lvl() should be compatible with Walker::start_lvl(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/comment-template.php on line 1266

Strict Standards: Declaration of Walker_Comment::end_lvl() should be compatible with Walker::end_lvl(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/comment-template.php on line 1266

Strict Standards: Declaration of Walker_Comment::start_el() should be compatible with Walker::start_el(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/comment-template.php on line 1266

Strict Standards: Declaration of Walker_Comment::end_el() should be compatible with Walker::end_el(&$output) in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/comment-template.php on line 1266

Strict Standards: Redefining already defined constructor for class WP_Dependencies in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/class.wp-dependencies.php on line 31

Strict Standards: Redefining already defined constructor for class WP_Http in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/http.php on line 61

Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method GoogleSitemapGenerator::Enable() should not be called statically in /homepages/32/d230485870/htdocs/jessmann/blog/wp-includes/plugin.php on line 339
Jess Mann » Programming -

Programming

TinyMCE wordcount with jQuery

Posted in Javascript, Programming on April 4th, 2009 by admin – 15 Comments

I was recently working on a custom content management system for a client, and I finished everything up well before our deadline. So, as I usually do, I started work on a few small additions to the software just to round off some of the functionality. One area I felt could use some improvement was the wysiwyg editor in the backend. Now, don’t get me wrong… I’ve used TinyMCE in the past, and in comparison to many other popular options such as fkceditor and wymeditor, I’ve been extraordinarily happy with it. However, the user interface looks rather plain, and there are some other simple widgets I felt could be tacked on.

One thing I was interested in adding was a “word count” area right below the editor. Looking around in the plugin repository and on google, I didn’t see any real viable solutions to this. Most involved clicking a button to check the word count, which to me, seemed a bit too clunky. I wanted something simple, where the wordcount was prominantly visible (but unobtrusive) at the bottom of the editor, and was automatically updated *every new word*.

Here’s a basic rundown of what I did (code is to follow):

First, the tricky part: We needed to add an area for the wordcount below the editor automatically. This way, when TinyMCE is instantiated for every textarea, the wordcount will drop in neatly without any extra markup. So, let’s create a function to do just that:

function addWordCount() {
$(’span.mceEditor’).after(’<div id=”‘ + tinyMCE.activeEditor.id + ‘_wordcount” class=”wordcount”>0  words, 0 characters</div>’);
return true;
}

This function simply searches for every tinyMCE instance, and appends a div (with a specific id) after the editor. Now, we’re going to call this function in TinyMCE’s “setup” function, so every time a new TinyMCE instance is created, we drop in a new “wordcount” div right below it.

Next, we need to figure out how to count the words. To do this, we need to get the editor’s contents, replace all the html so it doesn’t muddle our results, trim out any extra space, and then count the number of words (assuming a word is any alphanumeric string between spaces). This looks something like:

var text = ed.getContent().replace(/(<([^>]+)>)/g,”").replace(/\s+/g,” “);
text = $.trim(text);
var words = text.split(’ ‘).length;
var letters = text.length;

Lastly, now that we have the wordcount and have created the wordcount section, we’re going to tack on some code to change the contents of this “wordcount” div on every keystroke. We do this by adding on “onKeyUp” event listener, which retrieves the current editor contents, counts the words, and replaces the wordcount numbers. Our added code looks like this:

ed.onKeyUp.add(function(ed, e) {
$(’#’ + tinyMCE.activeEditor.id + ‘_wordcount’).html(”<span>” + words + “</span> words, <span>” + letters + “</span> characters”);
});

That’s it! Now, just for one last improvement, let’s combine all the code so that the wordcount doesn’t appear until the user has typed at least one letter (just to make things easier on the eyes), then we’re done! Here’s the final code for “setup”:

setup: function(ed) {
var text = “”;
var wordcount = false;
ed.onKeyUp.add(function(ed, e) {
if (!wordcount) {
wordcount = addWordCount();
}
text = ed.getContent().replace(/(<([^>]+)>)/g,”").replace(/\s+/g,” “);
text = $.trim(text);
$(’#’ + tinyMCE.activeEditor.id + ‘_wordcount’).html(”<span>” + text.split(’ ‘).length + “</span> words, <span>” + text.length + “</span> characters”);
});
}

PHP Benchmarking

Posted in PHP, Programming on August 11th, 2008 by admin – 1 Comment

Up to now, I’ve been under the impression that reflection in PHP, much like in other languages, is resource intensive enough to warrant being avoided unless really necessary. I remember reading an article a few years ago which stated that determining an object’s class through the use of instanceof took quite a bit of time, and back then, I didn’t feel like wasting my effort actually testing it, so it must have stuck in my mind as truth until now.

Anyway, after having a short conversation with a colleague about his extensive use of reflection in his framework, I realized I was probably considerably off-base… after all, how much extra time could something as minimal as instanceof really take up?

So now, years later, I finally got around to writing a benchmarking script, and I was actually a bit surprised at my findings.

First of all, here it is: Benchmarking Script

The script loops through a number of possible methods, from good practices to bad, to determine an object’s class, and performs that operation 500,000 times. After completion, it sleeps for 20 seconds, and then performs the benchmark again, looping 10 times. The times are then printed less an estimation of the processing time of performing each loop. The final result should be a reasonable estimate of the amount of resources for each operation, without the interference of strange server load or other oddities.

And the results:
------------------------------------------------------------------------------------
5000000 iterations in 271.190642118 seconds. Fastest in 4.02521276474 seconds.
------------------------------------------------------------------------------------
Operation         -                Total Time (Time less Loop)
Empty Loop        -     2.83129477501 seconds (0)
strcasecmp        -     8.51663279533 seconds (5.68533802032)
* instanceof        -     4.02521276474 seconds (1.19391798973)
Reflection        -     24.0526001453 seconds (21.2213053703)
Direct Comparison -     4.54614186287 seconds (1.71484708786)
Lower Comparison  -     7.83645248413 seconds (5.00515770912)
strcmp            -     7.92866182327 seconds (5.09736704826)
strcmp Lower      -     11.4372618198 seconds (8.60596704483)

Unexpectedly, instanceof comes out the winner, followed (unsurprisingly) by a direct string comparison. Strangely, I also found that strcasecmp was extremely time consuming… scaring me away from its use, probably forever.

Quite obviously, the two small uses of reflection in my script don’t fully encompass anywhere near PHP’s capabilities in that department, and as a result they are not going to be representative of the resources it would consume to use reflection for a real purpose…. But…. thus is the nature of benchmarking.