UNPKG

han-css

Version:

The CSS typography framework optimised for Hanzi

128 lines (101 loc) 3.33 kB
define([ '../core', '../method', '../regex' ], function( Han, $ ) { var QUERY_HWS_AS_FIRST_CHILD = '* > h-hws:first-child, * > wbr:first-child + h-hws, wbr:first-child + wbr + h-hws' //// Disabled `Node.normalize()` for temp due to //// issue below in IE11. //// See: http://stackoverflow.com/questions/22337498/why-does-ie11-handle-node-normalize-incorrectly-for-the-minus-symbol var isNodeNormalizeNormal = (function() { var div = $.create( 'div' ) div.appendChild( $.create( '', '0-' )) div.appendChild( $.create( '', '2' )) div.normalize() return div.firstChild.length !== 2 })() var hws = $.create( 'h-hws' ) hws.setAttribute( 'hidden', '' ) hws.innerHTML = ' ' $.extend( Han, { isNodeNormalizeNormal: isNodeNormalizeNormal, renderHWS: function( context, strict ) { var context = context || document var mode = strict ? 'strict' : 'base' var finder = Han.find( context ) // Elements to be filtered according to the // HWS rendering mode if ( strict ) { finder.avoid( 'textarea, code, kbd, samp, pre' ) } else { finder.avoid( 'textarea' ) } finder .replace( Han.TYPESET.hws[ mode ][0], '$1<hws/>$2' ) .replace( Han.TYPESET.hws[ mode ][1], '$1<hws/>$2' ) // Deal with [' 字'], [" 字"] => ['字'], ["字"] .replace( /(['"]+)<hws\/>(.+?)<hws\/>\1/ig, '$1$2$1' ) // Remove all `<hws/>` pre/post [“字”] and [‘字’] // See: https://github.com/ethantw/Han/issues/59 .replace( /<hws\/>([‘“]+)/ig, '$1' ) .replace( /([’”]+)<hws\/>/ig, '$1' ) // Convert text nodes `<hws/>` into real element nodes .replace( '<hws/>', function() { return $.clone( hws ) }) // Deal with: // `漢<u><hws/>zi</u>` => `漢<hws/><u>zi</u>` $ .qsa( QUERY_HWS_AS_FIRST_CHILD, context ) .forEach(function( firstChild ) { var parent = firstChild.parentNode var target = parent.firstChild // Skip all `<wbr>` and comments while ( $.isIgnorable( target )) { target = target.nextSibling if ( !target ) return } // The ‘first-child’ of DOM is different from // the ones of QSA, could be either an element // or a text fragment, but the latter one is // not what we want. We don't want comments, // either. while ( target.nodeName === 'H-HWS' ) { $.remove( target, parent ) target = parent.parentNode.insertBefore( $.clone( hws ), parent ) parent = parent.parentNode if ( isNodeNormalizeNormal ) { parent.normalize() } // This is for extreme circumstances, i.e., // `漢<a><b><c><h-hws/>zi</c></b></a>` => // `漢<h-hws/><a><b><c>zi</c></b></a>` if ( target !== parent.firstChild ) { break } } }) // Normalise nodes we messed up with if ( isNodeNormalizeNormal ) { context.normalize() } // Return the finder instance for future usage return finder } }) $.extend( Han.fn, { HWS: null, renderHWS: function( strict ) { Han.renderHWS( this.context, strict ) this.HWS = $.tag( 'h-hws', this.context ) return this }, revertHWS: function() { this.HWS.forEach(function( hws ) { $.remove( hws ) }) return this } }) return Han })