From 59b22c284dedc7351f44fb2a2952ae79b1cd7966 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Sat, 14 Mar 2015 23:49:00 +0000 Subject: [PATCH] Emoji: - Move the TinyMCE plugin CSS to wp-content.css. - Change the replacement images class to `wp-emoji` inside the editor. - Clean up both the plugin and wp-emoji.js, abstract and restructure a bit. See #31242. git-svn-id: https://develop.svn.wordpress.org/trunk@31779 602fd350-edb4-49c9-b593-d223f7449a82 --- .../js/tinymce/plugins/wpemoji/css/editor.css | 15 -- .../plugins/wpemoji/css/rtl/editor-rtl.css | 17 -- .../js/tinymce/plugins/wpemoji/plugin.js | 32 ++-- .../js/tinymce/skins/wordpress/wp-content.css | 12 ++ src/wp-includes/js/wp-emoji.js | 147 ++++++++---------- 5 files changed, 91 insertions(+), 132 deletions(-) delete mode 100755 src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css delete mode 100755 src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css mode change 100755 => 100644 src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js diff --git a/src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css b/src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css deleted file mode 100755 index 9d96569122..0000000000 --- a/src/wp-includes/js/tinymce/plugins/wpemoji/css/editor.css +++ /dev/null @@ -1,15 +0,0 @@ -.emoji-wrapper, -.emoji-spacer { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; -} -img.emoji { - height: 1em; - width: 1em; - margin: 0 .05em 0 .1em; - vertical-align: -0.1em; - border: none; - padding: 0; -} diff --git a/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css b/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css deleted file mode 100755 index f2a5b512ea..0000000000 --- a/src/wp-includes/js/tinymce/plugins/wpemoji/css/rtl/editor-rtl.css +++ /dev/null @@ -1,17 +0,0 @@ -/* This file was automatically generated on Nov 19 2014 05:08:11 */ - -.emoji-wrapper, -.emoji-spacer { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; -} -img.emoji { - height: 1em; - width: 1em; - margin: 0 .1em 0 .05em; - vertical-align: -0.1em; - border: none; - padding: 0; -} diff --git a/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js b/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js old mode 100755 new mode 100644 index c5e98ded48..fa172d08d6 --- a/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js +++ b/src/wp-includes/js/tinymce/plugins/wpemoji/plugin.js @@ -1,29 +1,18 @@ ( function( tinymce, wp ) { - tinymce.PluginManager.add( 'wpemoji', function( editor, url ) { + tinymce.PluginManager.add( 'wpemoji', function( editor ) { var typing, isMacWebKit = tinymce.Env.mac && tinymce.Env.webkit; - if ( ! wp.emoji.parseEmoji ) { + if ( ! wp || ! wp.emoji ) { return; } - // Loads stylesheet for custom styles within the editor - editor.on( 'init', function() { - var cssId = editor.dom.uniqueId(); - var linkElm = editor.dom.create( 'link', { - id: cssId, - rel: 'stylesheet', - href: url + '/css/editor.css' - }); - editor.getDoc().getElementsByTagName( 'head' )[0].appendChild( linkElm ); - } ); - editor.on( 'keydown keyup', function( event ) { typing = event.type === 'keydown'; } ); editor.on( 'input setcontent', function( event ) { - var selection, node, bookmark, imgs; + var selection, node, bookmark, images; if ( typing && event.type === 'input' ) { return; @@ -36,16 +25,15 @@ bookmark = selection.getBookmark(); } - wp.emoji.parse( node ); + wp.emoji.parse( node, { className: 'wp-emoji new-emoji' } ); - imgs = editor.dom.select( 'img.emoji', node ); + images = editor.dom.select( 'img.new-emoji', node ); - tinymce.each( imgs, function( elem ) { - if ( ! elem.getAttribute( 'data-wp-emoji' ) ) { - elem.setAttribute( 'data-mce-resize', 'false' ); - elem.setAttribute( 'data-mce-placeholder', '1' ); - elem.setAttribute( 'data-wp-emoji', elem.alt ); - } + tinymce.each( images, function( image ) { + image.className = 'wp-emoji'; + image.setAttribute( 'data-mce-resize', 'false' ); + image.setAttribute( 'data-mce-placeholder', '1' ); + image.setAttribute( 'data-wp-emoji', image.alt ); } ); // In IE all content in the editor is left selected aftrer wp.emoji.parse()... diff --git a/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css b/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css index f088a5e7aa..d4488d1435 100644 --- a/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css +++ b/src/wp-includes/js/tinymce/skins/wordpress/wp-content.css @@ -57,6 +57,18 @@ th { font-size: inherit; } +/* For emoji replacement images */ +img.wp-emoji { + height: 1em !important; + width: 1em !important; + margin: 0 0.07em !important; + vertical-align: -0.1em !important; + border: none !important; + padding: 0 !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; +} + /* DFW mode */ html.wp-fullscreen, html.wp-fullscreen body#tinymce { diff --git a/src/wp-includes/js/wp-emoji.js b/src/wp-includes/js/wp-emoji.js index 85ca1e4652..726f455f4e 100644 --- a/src/wp-includes/js/wp-emoji.js +++ b/src/wp-includes/js/wp-emoji.js @@ -1,9 +1,8 @@ -window.wp = window.wp || {}; -( function( window, wp, twemoji, settings ) { - var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; +( function( window, twemoji, settings ) { + function wpEmoji() { + var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver, - var emoji = { /** * Flag to determine if we should parse all emoji characters into Twemoji images. * @@ -11,7 +10,7 @@ window.wp = window.wp || {}; * * @var Boolean */ - parseAllEmoji: false, + parseAllEmoji = false, /** * Flag to determine if we should consider parsing emoji characters into Twemoji images. @@ -20,7 +19,7 @@ window.wp = window.wp || {}; * * @var Boolean */ - parseEmoji: false, + parseEmoji = false, /** * Flag to determine if we should parse flag characters into Twemoji images. @@ -29,31 +28,14 @@ window.wp = window.wp || {}; * * @var Boolean */ - parseFlags: false, - - /** - * Initialize our emoji support, and set up listeners. - * - * @since 4.2.0 - */ - init: function() { - emoji.parseAllEmoji = ! emoji.browserSupportsEmoji(); - emoji.parseFlags = ! emoji.browserSupportsFlagEmoji(); - emoji.parseEmoji = emoji.parseAllEmoji || emoji.parseFlags; - - if ( window.addEventListener ) { - window.addEventListener( 'load', emoji.load, false ); - } else if ( window.attachEvent ) { - window.attachEvent( 'onload', emoji.load ); - } - }, + parseFlags = false; /** * Runs when the document load event is fired, so we can do our first parse of the page. * * @since 4.2.0 */ - load: function() { + function load() { if ( MutationObserver ) { new MutationObserver( function( mutationRecords ) { var i = mutationRecords.length, @@ -71,7 +53,7 @@ window.wp = window.wp || {}; } if ( node && node.nodeType === 1 ) { - emoji.parse( node ); + parse( node ); } } } @@ -83,45 +65,19 @@ window.wp = window.wp || {}; } ); } - emoji.parse( document.body ); - }, + parse( document.body ); + } /** - * Detect if the browser supports rendering emoji. - * - * @since 4.2.0 - * - * @return {Boolean} True if the browser can render emoji, false if it cannot. - */ - browserSupportsEmoji: function() { - var canvas = document.createElement( 'canvas' ), - context = canvas.getContext && canvas.getContext( '2d' ); - - if ( ! context || ! context.fillText ) { - return false; - } - - /* - * Chrome on OS X added native emoji rendering in M41. Unfortunately, - * it doesn't work when the font is bolder than 500 weight. So, we - * check for bold rendering support to avoid invisible emoji in Chrome. - */ - context.textBaseline = 'top'; - context.font = '600 32px Arial'; - context.fillText( String.fromCharCode( 55357, 56835 ), 0, 0 ); - - return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0; - }, - - /** - * Detect if the browser supports rendering flag emoji. Flag emoji are a single glyph + * Detect if the browser supports rendering emoji or flag emoji. Flag emoji are a single glyph * made of two characters, so some browsers (notably, Firefox OS X) don't support them. * * @since 4.2.0 * - * @return {Boolean} True if the browser renders flag characters as a flag glyph, false if it does not. + * @param flagEmoji {Boolean} Whether to test for support of flag emoji. + * @return {Boolean} True if the browser can render emoji, false if it cannot. */ - browserSupportsFlagEmoji: function() { + function browserSupportsEmoji( type ) { var canvas = document.createElement( 'canvas' ), context = canvas.getContext && canvas.getContext( '2d' ); @@ -130,20 +86,30 @@ window.wp = window.wp || {}; } context.textBaseline = 'top'; - context.font = '32px Arial'; - context.fillText( String.fromCharCode( 55356, 56812, 55356, 56807 ), 0, 0 ); + context.font = '600 32px Arial'; - /* - * This works because the image will be one of three things: - * - Two empty squares, if the browser doen't render emoji - * - Two squares with 'G' and 'B' in them, if the browser doen't render flag emoji - * - The British flag - * - * The first two will encode to small images (1-2KB data URLs), the third will encode - * to a larger image (4-5KB data URL). - */ - return canvas.toDataURL().length > 3000; - }, + if ( type === 'flag' ) { + /* + * This works because the image will be one of three things: + * - Two empty squares, if the browser doen't render emoji + * - Two squares with 'G' and 'B' in them, if the browser doen't render flag emoji + * - The British flag + * + * The first two will encode to small images (1-2KB data URLs), the third will encode + * to a larger image (4-5KB data URL). + */ + context.fillText( String.fromCharCode( 55356, 56812, 55356, 56807 ), 0, 0 ); + return canvas.toDataURL().length > 3000; + } else { + /* + * Chrome on OS X added native emoji rendering in M41. Unfortunately, + * it doesn't work when the font is bolder than 500 weight. So, we + * check for bold rendering support to avoid invisible emoji in Chrome. + */ + context.fillText( String.fromCharCode( 55357, 56835 ), 0, 0 ); + return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0; + } + } /** * Given an element or string, parse any emoji characters into Twemoji images. @@ -152,14 +118,17 @@ window.wp = window.wp || {}; * * @param {HTMLElement|String} object The element or string to parse. */ - parse: function( object ) { - if ( ! emoji.parseEmoji ) { + function parse( object, options ) { + if ( ! parseEmoji ) { return object; } + var className = ( options && options.className ) || 'emoji'; + return twemoji.parse( object, { base: settings.baseUrl, ext: settings.ext, + className: className, callback: function( icon, options ) { // Ignore some standard characters that TinyMCE recommends in its character map. switch ( icon ) { @@ -174,7 +143,7 @@ window.wp = window.wp || {}; return false; } - if ( emoji.parseFlags && ! emoji.parseAllEmoji && + if ( parseFlags && ! parseAllEmoji && ! /^1f1(?:e[6-9a-f]|f[1-9a-f])-1f1(?:e[6-9a-f]|f[1-9a-f])$/.test( icon ) ) { return false; @@ -184,9 +153,31 @@ window.wp = window.wp || {}; } } ); } - }; - emoji.init(); + if ( ! twemoji || ! settings ) { + return; + } - wp.emoji = emoji; -} )( window, window.wp, window.twemoji, window._wpemojiSettings ); + /** + * Initialize our emoji support, and set up listeners. + */ + parseAllEmoji = ! browserSupportsEmoji(); + parseFlags = ! browserSupportsEmoji( 'flag' ); + parseEmoji = parseAllEmoji || parseFlags; + + if ( window.addEventListener ) { + window.addEventListener( 'load', load, false ); + } else if ( window.attachEvent ) { + window.attachEvent( 'onload', load ); + } + + return { + browserSupportsEmoji: browserSupportsEmoji, + parse: parse + }; + } + + window.wp = window.wp || {}; + window.wp.emoji = new wpEmoji(); + +} )( window, window.twemoji, window._wpemojiSettings );