diff --git a/src/wp-admin/js/post.js b/src/wp-admin/js/post.js
index ae0c094bd5..d265b520f7 100644
--- a/src/wp-admin/js/post.js
+++ b/src/wp-admin/js/post.js
@@ -203,7 +203,6 @@ $(document).on( 'heartbeat-send.refresh-lock', function( e, data ) {
jQuery(document).ready( function($) {
var stamp, visibility, $submitButtons, updateVisibility, updateText,
sticky = '',
- last = 0,
$textarea = $('#content'),
$document = $(document),
$editSlugWrap = $('#edit-slug-box'),
@@ -788,24 +787,6 @@ jQuery(document).ready( function($) {
});
}
- // word count
- if ( typeof(wpWordCount) != 'undefined' ) {
- $document.triggerHandler('wpcountwords', [ $textarea.val() ]);
-
- $textarea.keyup( function(e) {
- var k = e.keyCode || e.charCode;
-
- if ( k == last )
- return true;
-
- if ( 13 == k || 8 == last || 46 == last )
- $document.triggerHandler('wpcountwords', [ $textarea.val() ]);
-
- last = k;
- return true;
- });
- }
-
wptitlehint = function(id) {
id = id || 'title';
@@ -935,3 +916,44 @@ jQuery(document).ready( function($) {
}
});
});
+
+( function( $, counter ) {
+ $( function() {
+ var $content = $( '#content' ),
+ $count = $( '#wp-word-count' ).find( '.word-count' ),
+ prevCount = 0,
+ contentEditor;
+
+ function update() {
+ var text, count;
+
+ if ( ! contentEditor || contentEditor.isHidden() ) {
+ text = $content.val();
+ } else {
+ text = contentEditor.getContent( { format: 'raw' } );
+ }
+
+ count = counter.count( text );
+
+ if ( count !== prevCount ) {
+ $count.text( count );
+ }
+
+ prevCount = count;
+ }
+
+ $( document ).on( 'tinymce-editor-init', function( event, editor ) {
+ if ( editor.id !== 'content' ) {
+ return;
+ }
+
+ contentEditor = editor;
+
+ editor.on( 'nodechange keyup', _.debounce( update, 2000 ) );
+ } );
+
+ $content.on( 'input keyup', _.debounce( update, 2000 ) );
+
+ update();
+ } );
+} )( jQuery, new wp.utils.WordCounter() );
diff --git a/src/wp-admin/js/word-count.js b/src/wp-admin/js/word-count.js
index 0c537ba179..c1902c39bc 100644
--- a/src/wp-admin/js/word-count.js
+++ b/src/wp-admin/js/word-count.js
@@ -1,44 +1,48 @@
-/* global wordCountL10n */
-var wpWordCount;
-(function($,undefined) {
- wpWordCount = {
+( function() {
+ function WordCounter( settings ) {
+ var key;
- settings : {
- strip : /<[a-zA-Z\/][^<>]*>/g, // strip HTML tags
- clean : /[0-9.(),;:!?%#$¿'"_+=\\/-]+/g, // regexp to remove punctuation, etc.
- w : /\S\s+/g, // word-counting regexp
- c : /\S/g // char-counting regexp for asian languages
- },
-
- block : 0,
-
- wc : function(tx, type) {
- var t = this, w = $('.word-count'), tc = 0;
-
- if ( type === undefined )
- type = wordCountL10n.type;
- if ( type !== 'w' && type !== 'c' )
- type = 'w';
-
- if ( t.block )
- return;
-
- t.block = 1;
-
- setTimeout( function() {
- if ( tx ) {
- tx = tx.replace( t.settings.strip, ' ' ).replace( / | /gi, ' ' );
- tx = tx.replace( t.settings.clean, '' );
- tx.replace( t.settings[type], function(){tc++;} );
+ if ( settings ) {
+ for ( key in settings ) {
+ if ( settings.hasOwnProperty( key ) ) {
+ this.settings[ key ] = settings[ key ];
}
- w.html(tc.toString());
-
- setTimeout( function() { t.block = 0; }, 2000 );
- }, 1 );
+ }
}
+ }
+
+ WordCounter.prototype.settings = {
+ HTMLRegExp: /<\/?[a-z][^>]*?>/gi,
+ spaceRegExp: / | /gi,
+ removeRegExp: /[0-9.(),;:!?%#$¿'"_+=\\\/-]+/g,
+ wordsRegExp: /\S\s+/g,
+ charactersRegExp: /\S/g,
+ l10n: window.wordCountL10n || {}
};
- $(document).bind( 'wpcountwords', function(e, txt) {
- wpWordCount.wc(txt);
- });
-}(jQuery));
+ WordCounter.prototype.count = function( text, type ) {
+ var count = 0;
+
+ type = type || this.settings.l10n.type || 'words';
+
+ if ( text ) {
+ text = ' ' + text + ' ';
+
+ text = text.replace( this.settings.HTMLRegExp, ' ' );
+ text = text.replace( this.settings.spaceRegExp, ' ' );
+ text = text.replace( this.settings.removeRegExp, '' );
+
+ text = text.match( this.settings[ type + 'RegExp' ] );
+
+ if ( text ) {
+ count = text.length;
+ }
+ }
+
+ return count;
+ };
+
+ window.wp = window.wp || {};
+ window.wp.utils = window.wp.utils || {};
+ window.wp.utils.WordCounter = WordCounter;
+} )();
diff --git a/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js b/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js
index 0006d66969..73075e6f89 100644
--- a/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js
+++ b/src/wp-includes/js/tinymce/plugins/wordpress/plugin.js
@@ -7,8 +7,7 @@ tinymce.PluginManager.add( 'wordpress', function( editor ) {
var DOM = tinymce.DOM,
each = tinymce.each,
__ = editor.editorManager.i18n.translate,
- wpAdvButton, style,
- last = 0;
+ wpAdvButton, style;
if ( typeof window.jQuery !== 'undefined' ) {
window.jQuery( document ).triggerHandler( 'tinymce-editor-setup', [ editor ] );
@@ -363,23 +362,6 @@ tinymce.PluginManager.add( 'wordpress', function( editor ) {
}
});
- // Word count
- if ( typeof window.jQuery !== 'undefined' ) {
- editor.on( 'keyup', function( e ) {
- var key = e.keyCode || e.charCode;
-
- if ( key === last ) {
- return;
- }
-
- if ( 13 === key || 8 === last || 46 === last ) {
- window.jQuery( document ).triggerHandler( 'wpcountwords', [ editor.getContent({ format : 'raw' }) ] );
- }
-
- last = key;
- });
- }
-
editor.on( 'SaveContent', function( e ) {
// If editor is hidden, we just want the textarea's value to be saved
if ( ! editor.inline && editor.isHidden() ) {
diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php
index 71e07f5500..0bf838d501 100644
--- a/src/wp-includes/script-loader.php
+++ b/src/wp-includes/script-loader.php
@@ -371,11 +371,11 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'wpdialogs', "/wp-includes/js/wpdialog$suffix.js", array( 'jquery-ui-dialog' ), false, 1 );
- $scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array( 'jquery' ), false, 1 );
+ $scripts->add( 'word-count', "/wp-admin/js/word-count$suffix.js", array(), false, 1 );
did_action( 'init' ) && $scripts->localize( 'word-count', 'wordCountL10n', array(
/* translators: If your word count is based on single characters (East Asian characters),
enter 'characters'. Otherwise, enter 'words'. Do not translate into your own language. */
- 'type' => 'characters' == _x( 'words', 'word count: words or characters?' ) ? 'c' : 'w',
+ 'type' => _x( 'words', 'word count: words or characters?' )
) );
$scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox', 'shortcode' ), false, 1 );
@@ -451,7 +451,7 @@ function wp_default_scripts( &$scripts ) {
'tagDelimiter' => _x( ',', 'tag delimiter' ),
) );
- $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box' ), false, 1 );
+ $scripts->add( 'post', "/wp-admin/js/post$suffix.js", array( 'suggest', 'wp-lists', 'postbox', 'tags-box', 'underscore', 'word-count' ), false, 1 );
did_action( 'init' ) && $scripts->localize( 'post', 'postL10n', array(
'ok' => __('OK'),
'cancel' => __('Cancel'),
diff --git a/tests/qunit/index.html b/tests/qunit/index.html
index 6f11295bb3..347d8abf2a 100644
--- a/tests/qunit/index.html
+++ b/tests/qunit/index.html
@@ -32,6 +32,7 @@
+
@@ -40,6 +41,7 @@
+