From d792f370ef4b8119d2bffb7f31f82f71eb8752d8 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Sat, 22 Oct 2016 23:59:56 +0000 Subject: [PATCH] Emoji: Load polyfill responsibly. Improve performance of Emoji tests and loading of the polyfill. Reduces the number of tests to determine browser support for emoji to those most likely to fail. Adds the defer flag to the loaded scripts for browsers lacking support. Props superpoincare for perf testing, peterwilsoncc. Fixes #37817. git-svn-id: https://develop.svn.wordpress.org/trunk@38869 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/js/bookmarklet.min.js | 2 +- src/wp-includes/js/wp-emoji-loader.js | 67 +++++++-------------------- 2 files changed, 19 insertions(+), 50 deletions(-) diff --git a/src/wp-admin/js/bookmarklet.min.js b/src/wp-admin/js/bookmarklet.min.js index 089a849516..1531806990 100644 --- a/src/wp-admin/js/bookmarklet.min.js +++ b/src/wp-admin/js/bookmarklet.min.js @@ -1 +1 @@ -(function(a,b,c,d){function e(a,c){if("undefined"!=typeof c){var d=b.createElement("input");d.name=a,d.value=c,d.type="hidden",p.appendChild(d)}}var f,g,h,i,j,k,l,m,n,o=a.encodeURIComponent,p=b.createElement("form"),q=b.getElementsByTagName("head")[0],r="_press_this_app",s=!0;if(d){if(!c.match(/^https?:/))return void(top.location.href=d);if(d+="&u="+o(c),c.match(/^https:/)&&d.match(/^http:/)&&(s=!1),a.getSelection?h=a.getSelection()+"":b.getSelection?h=b.getSelection()+"":b.selection&&(h=b.selection.createRange().text||""),d+="&buster="+(new Date).getTime(),s||(b.title&&(d+="&t="+o(b.title.substr(0,256))),h&&(d+="&s="+o(h.substr(0,512)))),f=a.outerWidth||b.documentElement.clientWidth||600,g=a.outerHeight||b.documentElement.clientHeight||700,f=800>f||f>5e3?600:.7*f,g=800>g||g>3e3?700:.9*g,!s)return void a.open(d,r,"location,resizable,scrollbars,width="+f+",height="+g);i=q.getElementsByTagName("meta")||[];for(var t=0;t200);t++){var u=i[t],v=u.getAttribute("name"),w=u.getAttribute("property"),x=u.getAttribute("content");x&&(v?e("_meta["+v+"]",x):w&&e("_meta["+w+"]",x))}j=q.getElementsByTagName("link")||[];for(var y=0;y=50);y++){var z=j[y],A=z.getAttribute("rel");"canonical"!==A&&"icon"!==A&&"shortlink"!==A||e("_links["+A+"]",z.getAttribute("href"))}b.body.getElementsByClassName&&(k=b.body.getElementsByClassName("hfeed")[0]),k=b.getElementById("content")||k||b.body,l=k.getElementsByTagName("img")||[];for(var B=0;B=100);B++)n=l[B],n.src.indexOf("avatar")>-1||n.className.indexOf("avatar")>-1||n.width&&n.width<256||n.height&&n.height<128||e("_images[]",n.src);m=b.body.getElementsByTagName("iframe")||[];for(var C=0;C=50);C++)e("_embeds[]",m[C].src);b.title&&e("t",b.title),h&&e("s",h),p.setAttribute("method","POST"),p.setAttribute("action",d),p.setAttribute("target",r),p.setAttribute("style","display: none;"),a.open("about:blank",r,"location,resizable,scrollbars,width="+f+",height="+g),b.body.appendChild(p),p.submit()}})(window,document,top.location.href,window.pt_url); \ No newline at end of file +(function(a,b,c,d){function e(a,c){if("undefined"!=typeof c){var d=b.createElement("input");d.name=a,d.value=c,d.type="hidden",p.appendChild(d)}}var f,g,h,i,j,k,l,m,n,o=a.encodeURIComponent,p=b.createElement("form"),q=b.getElementsByTagName("head")[0],r="_press_this_app",s=!0;if(d){if(!c.match(/^https?:/))return void(top.location.href=d);if(d+="&u="+o(c),c.match(/^https:/)&&d.match(/^http:/)&&(s=!1),a.getSelection?h=a.getSelection()+"":b.getSelection?h=b.getSelection()+"":b.selection&&(h=b.selection.createRange().text||""),d+="&buster="+(new Date).getTime(),s||(b.title&&(d+="&t="+o(b.title.substr(0,256))),h&&(d+="&s="+o(h.substr(0,512)))),f=a.outerWidth||b.documentElement.clientWidth||600,g=a.outerHeight||b.documentElement.clientHeight||700,f=f<800||f>5e3?600:.7*f,g=g<800||g>3e3?700:.9*g,!s)return void a.open(d,r,"location,resizable,scrollbars,width="+f+",height="+g);i=q.getElementsByTagName("meta")||[];for(var t=0;t200);t++){var u=i[t],v=u.getAttribute("name"),w=u.getAttribute("property"),x=u.getAttribute("content");x&&(v?e("_meta["+v+"]",x):w&&e("_meta["+w+"]",x))}j=q.getElementsByTagName("link")||[];for(var y=0;y=50);y++){var z=j[y],A=z.getAttribute("rel");"canonical"!==A&&"icon"!==A&&"shortlink"!==A||e("_links["+A+"]",z.getAttribute("href"))}b.body.getElementsByClassName&&(k=b.body.getElementsByClassName("hfeed")[0]),k=b.getElementById("content")||k||b.body,l=k.getElementsByTagName("img")||[];for(var B=0;B=100);B++)n=l[B],n.src.indexOf("avatar")>-1||n.className.indexOf("avatar")>-1||n.width&&n.width<256||n.height&&n.height<128||e("_images[]",n.src);m=b.body.getElementsByTagName("iframe")||[];for(var C=0;C=50);C++)e("_embeds[]",m[C].src);b.title&&e("t",b.title),h&&e("s",h),p.setAttribute("method","POST"),p.setAttribute("action",d),p.setAttribute("target",r),p.setAttribute("style","display: none;"),a.open("about:blank",r,"location,resizable,scrollbars,width="+f+",height="+g),b.body.appendChild(p),p.submit()}})(window,document,top.location.href,window.pt_url); \ No newline at end of file diff --git a/src/wp-includes/js/wp-emoji-loader.js b/src/wp-includes/js/wp-emoji-loader.js index 5ddea9fbac..0b474f83ff 100644 --- a/src/wp-includes/js/wp-emoji-loader.js +++ b/src/wp-includes/js/wp-emoji-loader.js @@ -1,25 +1,33 @@ ( function( window, document, settings ) { var src, ready, ii, tests; + /* + * Create a canvas element for testing native browser support + * of emoji. + */ + var canvas = document.createElement( 'canvas' ); + var context = canvas.getContext && canvas.getContext( '2d' ); + /** * 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 * - * @param type {String} Whether to test for support of "simple", "flag", "diversity" or "unicode8" emoji. + * @param type {String} Whether to test for support of "flag" or "emoji4" emoji. * @return {Boolean} True if the browser can render emoji, false if it cannot. */ function browserSupportsEmoji( type ) { - var canvas = document.createElement( 'canvas' ), - context = canvas.getContext && canvas.getContext( '2d' ), - stringFromCharCode = String.fromCharCode, - flag, flag2, tonedata, tone, tone2, technologist, technologist2; + var stringFromCharCode = String.fromCharCode, + flag, flag2, technologist, technologist2; if ( ! context || ! context.fillText ) { return false; } + // Cleanup from previous test. + context.clearRect( 0, 0, canvas.width, canvas.height ); + /* * 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 @@ -33,13 +41,13 @@ /* * This works because the image will be one of three things: * - Two empty squares, if the browser doesn't render emoji - * - Two squares with 'A' and 'U' in them, if the browser doesn't render flag emoji - * - The Australian flag + * - Two squares with 'U' and 'N' in them, if the browser doesn't render flag emoji + * - The United Nations 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( stringFromCharCode( 55356, 56806, 55356, 56826 ), 0, 0 ); + context.fillText( stringFromCharCode( 55356, 56826, 55356, 56819 ), 0, 0 ); if ( canvas.toDataURL().length < 3000 ) { return false; } @@ -63,45 +71,6 @@ flag2 = canvas.toDataURL(); return flag !== flag2; - case 'diversity': - /* - * This tests if the browser supports the Emoji Diversity specification, by rendering an - * emoji with no skin tone specified (in this case, Santa). It then adds a skin tone, and - * compares if the emoji rendering has changed. - */ - context.fillText( stringFromCharCode( 55356, 57221 ), 0, 0 ); - tonedata = context.getImageData( 16, 16, 1, 1 ).data; - tone = tonedata[0] + ',' + tonedata[1] + ',' + tonedata[2] + ',' + tonedata[3]; - - context.fillText( stringFromCharCode( 55356, 57221, 55356, 57343 ), 0, 0 ); - // Chrome has issues comparing arrays, and Safari has issues converting arrays to strings. - // So, we create our own string and compare that, instead. - tonedata = context.getImageData( 16, 16, 1, 1 ).data; - tone2 = tonedata[0] + ',' + tonedata[1] + ',' + tonedata[2] + ',' + tonedata[3]; - - return tone !== tone2; - case 'simple': - /* - * This creates a smiling emoji, and checks to see if there is any image data in the - * center pixel. In browsers that don't support emoji, the character will be rendered - * as an empty square, so the center pixel will be blank. - */ - context.fillText( stringFromCharCode( 55357, 56835 ), 0, 0 ); - return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0; - case 'unicode8': - /* - * To check for Unicode 8 support, let's try rendering the most important advancement - * that the Unicode Consortium have made in years: the burrito. - */ - context.fillText( stringFromCharCode( 55356, 57135 ), 0, 0 ); - return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0; - case 'unicode9': - /* - * Do Unicode 9 emoji render? - * ¯\_(ツ)_/¯ - */ - context.fillText( stringFromCharCode( 55358, 56631 ), 0, 0 ); - return context.getImageData( 16, 16, 1, 1 ).data[0] !== 0; case 'emoji4': /* * Emoji 4 has the best technologists. So does WordPress! @@ -128,11 +97,11 @@ var script = document.createElement( 'script' ); script.src = src; - script.type = 'text/javascript'; + script.defer = script.type = 'text/javascript'; document.getElementsByTagName( 'head' )[0].appendChild( script ); } - tests = Array( 'simple', 'flag', 'unicode8', 'diversity', 'unicode9', 'emoji4' ); + tests = Array( 'flag', 'emoji4' ); settings.supports = { everything: true,