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 @@ +