hanzi-rails 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3bf6279622dcf65dd2d529e27c7d97d09bd6e8ad
4
- data.tar.gz: 39e9a0e9e5973225b15f03371ce6adfec0c27aa6
3
+ metadata.gz: d376de721042532c4f7c2f99f146461b0cef6899
4
+ data.tar.gz: 3bcb98fa871757975ad994c6cf79bf9a91a951df
5
5
  SHA512:
6
- metadata.gz: 2ea058b6c801b4deba45dccb145f0f0709e342206b60d7802af8daac09c9bc3fc64019ce642bf15d04651d5c5c0c9d93b78e0c70ae6e96cca8396065dc2f30d8
7
- data.tar.gz: f8222df3a6c61f516c641322e7695dc24bcb4aad7227ec7d56a057d0a08d6de9e9942eafa373d5164ee5d218e883be949d80e3c7015254ef5900222e0adaf47b
6
+ metadata.gz: eb7000d1153a2c853951ca9ff8e12ae67faea07b4054001f73ec4e92d6001e619620e9ef6acf1f99cb186e5ba4d076ad4589dd5d3c2f6b8de660240cf1ba4d89
7
+ data.tar.gz: 910609e466d5bad1468a21b281f9fd843996cf52c93ce47198e3a652c08b50b1c4937273e20be683ba08d00024f6b459d7154af1813cde688bc5a24111812f8f
Binary file
Binary file
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * 漢字標準格式 v3.1.0 | MIT License | css.hanzi.co
2
+ * 漢字標準格式 v3.2.0 | MIT License | css.hanzi.co
3
3
  * Han.css: the CSS typography framework optimised for Hanzi
4
4
  */
5
5
 
@@ -22,7 +22,7 @@ var root = document.documentElement
22
22
 
23
23
  var body = document.body
24
24
 
25
- var VERSION = '3.1.0'
25
+ var VERSION = '3.2.0'
26
26
 
27
27
  var ROUTINE = [
28
28
  // Initialise the condition with feature-detecting
@@ -33,6 +33,7 @@ var ROUTINE = [
33
33
  'renderElem',
34
34
  // Handle Biaodian
35
35
  //'jinzify',
36
+ 'renderHanging',
36
37
  'renderJiya',
37
38
  // Address Hanzi and Western script mixed spacing
38
39
  'renderHWS',
@@ -147,7 +148,7 @@ var UNICODE = {
147
148
  /**
148
149
  * CJK-related blocks (CJK相關字符區段)
149
150
  *
150
- * 1. 中日韓統一表意文字:[\u4E00-\u9FFF]
151
+ * 1. 中日韓統一意音文字:[\u4E00-\u9FFF]
151
152
  Basic CJK unified ideographs
152
153
  * 2. 擴展-A區:[\u3400-\u4DB5]
153
154
  Extended-A
@@ -163,9 +164,9 @@ var UNICODE = {
163
164
  Extended-F (not supported yet)
164
165
  * 8. 筆畫區:[\u31C0-\u31E3]
165
166
  Strokes
166
- * 9. 表意數字「〇」:[\u3007]
167
+ * 9. 意音數字「〇」:[\u3007]
167
168
  Ideographic number zero
168
- * 10. 相容表意文字及補充:[\uF900-\uFAFF][\u2F800-\u2FA1D](不使用)
169
+ * 10. 相容意音文字及補充:[\uF900-\uFAFF][\u2F800-\u2FA1D](不使用)
169
170
  Compatibility ideograph and supplement (not supported)
170
171
 
171
172
  12 exceptions:
@@ -175,7 +176,7 @@ var UNICODE = {
175
176
 
176
177
  * 11. 康熙字典及簡化字部首:[\u2F00-\u2FD5\u2E80-\u2EF3]
177
178
  Kangxi and supplement radicals
178
- * 12. 表意文字描述字元:[\u2FF0-\u2FFA]
179
+ * 12. 意音文字描述字元:[\u2FF0-\u2FFA]
179
180
  Ideographic description characters
180
181
  */
181
182
  hanzi: {
@@ -343,7 +344,7 @@ var TYPESET = (function() {
343
344
 
344
345
  // For words like `it's`, `Jones’s` or `'99`
345
346
  var rApo = '[\u0027\u2019]'
346
- var rChar = rHan + '|(' + rAlph + '|' + rApo + ')+'
347
+ var rChar = rHan + '|(?:' + rAlph + '|' + rApo + ')+'
347
348
 
348
349
  var rZyS = UNICODE.zhuyin.initial
349
350
  var rZyJ = UNICODE.zhuyin.medial
@@ -366,35 +367,37 @@ var TYPESET = (function() {
366
367
  open: new RegExp( '(' + rBdOpen + ')', 'g' ),
367
368
  close: new RegExp( '(' + rBdClose + ')', 'g' ),
368
369
  end: new RegExp( '(' + rBdEnd + ')', 'g' ),
369
- liga: new RegExp( '(' + rBdLiga + ')', 'g' ),
370
-
371
- group: [
372
- new RegExp( '(' + rBdOpen + '|' + rBdMid + '|' + rBdEnd + '){2,}', 'g' ),
373
- new RegExp( '(' + rBdLiga + rBdOpen + ')', 'g' )
374
- ]
370
+ liga: new RegExp( '(' + rBdLiga + ')', 'g' )
375
371
  },
376
372
 
377
- hanzi: {
378
- individual: new RegExp( '(' + rHan + ')', 'g' ),
379
- group: new RegExp( '(' + rHan + ')+', 'g' )
380
- },
373
+ hanzi: new RegExp( '(' + rHan + ')', 'g' ),
381
374
 
382
- word: new RegExp( '(' + rLatn + '|' + rGk + '|' + rCy + '|' + rPt + ')+', 'ig' ),
375
+ latin: new RegExp( '(' + rLatn + ')', 'ig' ),
376
+ ellinika: new RegExp( '(' + rGk + ')', 'ig' ),
377
+ kirillica: new RegExp( '(' + rCy + ')', 'ig' ),
383
378
 
384
- alphabet: {
385
- latin: new RegExp( '(' + rLatn + ')', 'ig' ),
386
- ellinika: new RegExp( '(' + rGk + ')', 'ig' ),
387
- kirillica: new RegExp( '(' + rCy + ')', 'ig' ),
388
- kana: new RegExp( '(' + rKana + ')', 'g' ),
389
- smallkana: new RegExp( '(' + rKanaS + ')', 'g' ),
390
- eonmun: new RegExp( '(' + rEon + ')', 'g' ),
391
- halfeonmun: new RegExp( '(' + rEonH + ')', 'g' )
392
- }
379
+ kana: new RegExp( '(' + rKana + '|' + rKanaS + '|' + rKanaH + ')', 'g' ),
380
+ eonmun: new RegExp( '(' + rEon + '|' + rEonH + ')', 'g' )
381
+ },
382
+
383
+ /* Word-level selectors (詞級選擇器)
384
+ */
385
+ group: {
386
+ biaodian: [
387
+ new RegExp( '(' + rBd + '){2,}', 'g' ),
388
+ new RegExp( '(' + rBdLiga + rBdOpen + ')', 'g' )
389
+ ],
390
+ punct: null,
391
+ hanzi: new RegExp( '(' + rHan + ')+', 'g' ),
392
+ western: new RegExp( '(' + rLatn + '|' + rGk + '|' + rCy + '|' + rPt + ')+', 'ig' ),
393
+ kana: new RegExp( '(' + rKana + '|' + rKanaS + '|' + rKanaH + ')+', 'g' ),
394
+ eonmun: new RegExp( '(' + rEon + '|' + rEonH + ')+', 'g' )
393
395
  },
394
396
 
395
397
  /* Punctuation Rules (禁則)
396
398
  */
397
399
  jinze: {
400
+ hanging: new RegExp( '(' + rWhite + '*)(' + rBdClose + '*|[…⋯]*)([、,。.])(?!' + rBdEnd + ')', 'ig' ),
398
401
  touwei: new RegExp( '(' + rBdOpen + '+)(' + rChar + ')(' + rBdEnd + '+)', 'ig' ),
399
402
  tou: new RegExp( '(' + rBdOpen + '+)(' + rChar + ')', 'ig' ),
400
403
  wei: new RegExp( '(' + rChar + ')(' + rBdEnd + '+)', 'ig' ),
@@ -475,10 +478,10 @@ Han.UNICODE.greek = Han.UNICODE.ellinika
475
478
  Han.UNICODE.cyrillic = Han.UNICODE.kirillica
476
479
  Han.UNICODE.hangul = Han.UNICODE.eonmun
477
480
 
478
- Han.TYPESET.char.cjk = Han.TYPESET.char.hanzi
479
- Han.TYPESET.char.alphabet.greek = Han.TYPESET.char.alphabet.ellinika
480
- Han.TYPESET.char.alphabet.cyrillic = Han.TYPESET.char.alphabet.kirillica
481
- Han.TYPESET.char.alphabet.hangul = Han.TYPESET.char.alphabet.eonmun
481
+ Han.TYPESET.char.cjk = Han.TYPESET.char.hanzi
482
+ Han.TYPESET.char.greek = Han.TYPESET.char.ellinika
483
+ Han.TYPESET.char.cyrillic = Han.TYPESET.char.kirillica
484
+ Han.TYPESET.char.hangul = Han.TYPESET.char.eonmun
482
485
 
483
486
  var $ = {
484
487
  // Simplified query selectors which return the node list
@@ -1196,60 +1199,56 @@ return Fibre
1196
1199
  }())
1197
1200
  );
1198
1201
 
1202
+ function createBdChar( char ) {
1203
+ var div = $.create( 'div' )
1204
+ var unicode = char.charCodeAt( 0 ).toString( 16 )
1205
+ var clazz = 'biaodian cjk ' + ( char.match( TYPESET.char.biaodian.open ) ? 'open' :
1206
+ char.match( TYPESET.char.biaodian.close ) ? 'close end' :
1207
+ char.match( TYPESET.char.biaodian.end ) ? 'end' :
1208
+ char.match( new RegExp( '(' + UNICODE.biaodian.liga + ')' )) ? 'liga' : '' )
1209
+
1210
+ div.innerHTML = '<h-char unicode="' + unicode + '" class="' + clazz + '">' + char + '</h-char>'
1211
+ return div.firstChild
1212
+ }
1213
+
1199
1214
  $.extend( Fibre.fn, {
1200
1215
  // Force punctuation & biaodian typesetting rules to be applied.
1201
1216
  jinzify: function() {
1202
- var origFilterOutSelector= this.filterOutSelector
1203
-
1204
- this.filterOutSelector += ', jinze'
1217
+ var origFilterOutSelector = this.filterOutSelector
1218
+ this.filterOutSelector += ', h-jinze'
1205
1219
 
1206
1220
  this
1207
1221
  .replace(
1208
1222
  TYPESET.jinze.touwei,
1209
1223
  function( portion, match ) {
1210
- var mat = match[0]
1211
- var text = $.create( '', mat )
1212
- var elem = $.create( 'jinze', 'touwei' )
1213
-
1214
- elem.appendChild( text )
1215
- return (
1216
- ( portion.index === 0 && portion.isEnd ) || portion.index === 1
1217
- ) ? elem : ''
1224
+ var elem = $.create( 'h-jinze', 'touwei' )
1225
+ elem.innerHTML = match[0]
1226
+ return (( portion.index === 0 && portion.isEnd ) || portion.index === 1 )
1227
+ ? elem : ''
1218
1228
  }
1219
1229
  )
1220
1230
  .replace(
1221
1231
  TYPESET.jinze.wei,
1222
1232
  function( portion, match ) {
1223
- var mat = match[0]
1224
- var text = $.create( '', mat )
1225
- var elem = $.create( 'jinze', 'wei' )
1226
-
1227
- elem.appendChild( text )
1233
+ var elem = $.create( 'h-jinze', 'wei' )
1234
+ elem.innerHTML = match[0]
1228
1235
  return portion.index === 0 ? elem : ''
1229
1236
  }
1230
1237
  )
1231
1238
  .replace(
1232
1239
  TYPESET.jinze.tou,
1233
1240
  function( portion, match ) {
1234
- var mat = match[0]
1235
- var text = $.create( '', mat )
1236
- var elem = $.create( 'jinze', 'tou' )
1237
-
1238
- elem.appendChild( text )
1239
- return (
1240
- ( portion.index === 0 && portion.isEnd ) ||
1241
- portion.index === 1
1242
- ) ? elem : ''
1241
+ var elem = $.create( 'h-jinze', 'tou' )
1242
+ elem.innerHTML = match[0]
1243
+ return (( portion.index === 0 && portion.isEnd ) || portion.index === 1 )
1244
+ ? elem : ''
1243
1245
  }
1244
1246
  )
1245
1247
  .replace(
1246
1248
  TYPESET.jinze.middle,
1247
1249
  function( portion, match ) {
1248
- var mat = match[0]
1249
- var text = $.create( '', mat )
1250
- var elem = $.create( 'jinze', 'middle' )
1251
-
1252
- elem.appendChild( text )
1250
+ var elem = $.create( 'h-jinze', 'middle' )
1251
+ elem.innerHTML = match[0]
1253
1252
  return (( portion.index === 0 && portion.isEnd ) || portion.index === 1 )
1254
1253
  ? elem : ''
1255
1254
  }
@@ -1259,108 +1258,114 @@ $.extend( Fibre.fn, {
1259
1258
  return this
1260
1259
  },
1261
1260
 
1262
- groupify: function() {
1263
- this
1264
- .wrap(
1265
- TYPESET.char.biaodian.group[ 0 ],
1266
- $.clone( $.create( 'char_group', 'biaodian cjk' ))
1267
- )
1268
- .wrap(
1269
- TYPESET.char.biaodian.group[ 1 ],
1270
- $.clone( $.create( 'char_group', 'biaodian cjk' ))
1271
- )
1261
+ groupify: function( option ) {
1262
+ var origFilterOutSelector = this.filterOutSelector
1263
+ var option = $.extend({
1264
+ biaodian: false,
1265
+ //punct: false,
1266
+ hanzi: false, // Includes Kana
1267
+ kana: false,
1268
+ eonmun: false,
1269
+ western: false // Includes Latin, Greek and Cyrillic
1270
+ }, option || {})
1271
+
1272
+ this.filterOutSelector += ', h-hangable, h-char-group'
1273
+
1274
+ if ( option.biaodian ) {
1275
+ this.wrap(
1276
+ TYPESET.group.biaodian[ 0 ], $.clone( $.create( 'h-char-group', 'biaodian cjk' ))
1277
+ ).wrap(
1278
+ TYPESET.group.biaodian[ 1 ], $.clone( $.create( 'h-char-group', 'biaodian cjk' ))
1279
+ )
1280
+ }
1281
+ if ( option.hanzi ) {
1282
+ this.wrap(
1283
+ TYPESET.group.hanzi, $.clone( $.create( 'h-char-group', 'hanzi cjk' ))
1284
+ )
1285
+ }
1286
+ if ( option.western ) {
1287
+ this.wrap(
1288
+ TYPESET.group.western, $.clone( $.create( 'h-word', 'western' ))
1289
+ )
1290
+ }
1291
+ if ( option.kana ) {
1292
+ this.wrap(
1293
+ TYPESET.group.kana, $.clone( $.create( 'h-char-group', 'kana' ))
1294
+ )
1295
+ }
1296
+ if ( option.eonmun ) {
1297
+ this.wrap(
1298
+ TYPESET.group.eonmun, $.clone( $.create( 'h-word', 'eonmun hangul' ))
1299
+ )
1300
+ }
1301
+
1302
+ this.filterOutSelector = origFilterOutSelector
1272
1303
  return this
1273
1304
  },
1274
1305
 
1275
1306
  // Implementation of character-level selector
1276
1307
  // (字元級選擇器)
1277
1308
  charify: function( option ) {
1309
+ var origFilterOutSelector = this.filterOutSelector
1278
1310
  var option = $.extend({
1279
- hanzi: 'individual',
1280
- // individual || group || biaodian || none
1281
- liga: 'liga',
1282
- // liga || none
1283
- word: 'group',
1284
- // group || punctuation || none
1285
-
1286
- latin: 'group',
1287
- ellinika: 'group',
1288
- kirillica: 'group',
1289
- kana: 'none',
1290
- eonmun: 'none'
1291
- // group || individual || none
1311
+ biaodian: false,
1312
+ punct: false,
1313
+ hanzi: false, // Includes Kana
1314
+ latin: false,
1315
+ ellinika: false,
1316
+ kirillica: false,
1317
+ kana: false,
1318
+ eonmun: false
1292
1319
  }, option || {})
1293
1320
 
1294
- // CJK and biaodian
1295
- if ( option.hanzi === 'group' ) {
1296
- this.wrap( TYPESET.char.hanzi.group, $.clone( $.create( 'char_group', 'hanzi cjk' )))
1297
- }
1298
- if ( option.hanzi === 'individual' ) {
1299
- this.wrap( TYPESET.char.hanzi.individual, $.clone( $.create( 'char', 'hanzi cjk' )))
1300
- }
1301
-
1302
- if ( option.hanzi === 'individual' ||
1303
- option.hanzi === 'biaodian' ||
1304
- option.liga === 'liga'
1305
- ) {
1306
- if ( option.hanzi !== 'none' ) {
1307
- this.replace(
1308
- TYPESET.char.biaodian.all,
1309
- function( portion, match ) {
1310
- var mat = match[0]
1311
- var text = $.create( '', mat )
1312
- var clazz = 'biaodian cjk ' + (
1313
- mat.match( TYPESET.char.biaodian.open ) ? 'open' :
1314
- mat.match( TYPESET.char.biaodian.close ) ? 'close end' :
1315
- mat.match( TYPESET.char.biaodian.end ) ? 'end' : ''
1316
- )
1317
- var elem = $.create( 'char', clazz )
1318
- var unicode = mat.charCodeAt( 0 ).toString( 16 )
1319
-
1320
- elem.setAttribute( 'unicode', unicode )
1321
- elem.appendChild( text )
1322
- return elem
1323
- }
1324
- )
1325
- }
1321
+ this.filterOutSelector += ', h-char'
1326
1322
 
1323
+ if ( option.biaodian ) {
1327
1324
  this.replace(
1328
- option.liga === 'liga' ? TYPESET.char.biaodian.liga :
1329
- new RegExp( '(' + UNICODE.biaodian.liga + ')', 'g' ),
1330
- function( portion, match ) {
1331
- var mat = match[0]
1332
- var text = $.create( '', mat )
1333
- var elem = $.create( 'char', 'biaodian liga cjk' )
1334
- var unicode = mat.charCodeAt( 0 ).toString( 16 )
1335
-
1336
- elem.setAttribute( 'unicode', unicode )
1337
- elem.appendChild( text )
1338
- return elem
1339
- }
1325
+ TYPESET.char.biaodian.all,
1326
+ function( portion, match ) { return createBdChar( match[0] ) }
1327
+ ).replace(
1328
+ TYPESET.char.biaodian.liga,
1329
+ function( portion, match ) { return createBdChar( match[0] ) }
1340
1330
  )
1341
1331
  }
1342
-
1343
- // Western languages (word-level)
1344
- if ( option.word !== 'none' ) {
1345
- this.wrap( TYPESET.char.word, $.clone( $.create( 'word' )))
1332
+ if ( option.hanzi ) {
1333
+ this.wrap(
1334
+ TYPESET.char.hanzi, $.clone( $.create( 'h-char', 'hanzi cjk' ))
1335
+ )
1346
1336
  }
1347
-
1348
- // Western languages (alphabet-level)
1349
- if ( option.latin !== 'none' ||
1350
- option.ellinika !== 'none' ||
1351
- option.kirillica !== 'none'
1352
- ) {
1353
- this.wrap( TYPESET.char.punct.all, $.clone( $.create( 'char', 'punct' )))
1337
+ if ( option.punct ) {
1338
+ this.wrap(
1339
+ TYPESET.char.punct.all, $.clone( $.create( 'h-char', 'punct' ))
1340
+ )
1354
1341
  }
1355
- if ( option.latin === 'individual' ) {
1356
- this.wrap( TYPESET.char.alphabet.latin, $.clone( $.create( 'char', 'alphabet latin' )))
1342
+ if ( option.latin ) {
1343
+ this.wrap(
1344
+ TYPESET.char.latin, $.clone( $.create( 'h-char', 'alphabet latin' ))
1345
+ )
1357
1346
  }
1358
- if ( option.ellinika === 'individual' ) {
1359
- this.wrap( TYPESET.char.alphabet.ellinika, $.clone( $.create( 'char', 'alphabet ellinika greek' )))
1347
+ if ( option.ellinika ) {
1348
+ this.wrap(
1349
+ TYPESET.char.ellinika, $.clone( $.create( 'h-char', 'alphabet ellinika greek' ))
1350
+ )
1360
1351
  }
1361
- if ( option.kirillica === 'individual' ) {
1362
- this.wrap( TYPESET.char.alphabet.kirillica, $.clone( $.create( 'char', 'alphabet kirillica cyrillic' )))
1352
+ if ( option.kirillica ) {
1353
+ this.wrap(
1354
+ TYPESET.char.kirillica, $.clone( $.create( 'h-char', 'alphabet kirillica cyrillic' ))
1355
+ )
1356
+ }
1357
+ if ( option.kana ) {
1358
+ this.wrap(
1359
+ TYPESET.char.kana, $.clone( $.create( 'h-char', 'kana' ))
1360
+ )
1363
1361
  }
1362
+ if ( option.eonmun ) {
1363
+ this.wrap(
1364
+ TYPESET.char.eonmun, $.clone( $.create( 'h-char', 'eonmun hangul' ))
1365
+ )
1366
+ }
1367
+
1368
+ this.filterOutSelector = origFilterOutSelector
1364
1369
  return this
1365
1370
  }
1366
1371
  })
@@ -1372,6 +1377,7 @@ void [
1372
1377
  'wrap',
1373
1378
  'revert',
1374
1379
  'jinzify',
1380
+ 'groupify',
1375
1381
  'charify'
1376
1382
  ].forEach(function( method ) {
1377
1383
  Han.fn[ method ] = function() {
@@ -1385,9 +1391,7 @@ void [
1385
1391
  }
1386
1392
  })
1387
1393
 
1388
- var Hyu = {
1389
- JS_RENDERED_CLASS: 'hyu-js-rendered'
1390
- }
1394
+ var Locale = {}
1391
1395
 
1392
1396
  function writeOnCanvas( text, font ) {
1393
1397
  var canvas = $.create( 'canvas' )
@@ -1406,58 +1410,73 @@ function writeOnCanvas( text, font ) {
1406
1410
  context.strokeStyle = 'black'
1407
1411
  context.fillText( text, 0, 0 )
1408
1412
 
1409
- return [ canvas, context ]
1413
+ return {
1414
+ node: canvas,
1415
+ context: context,
1416
+ remove: function() {
1417
+ $.remove( canvas, body )
1418
+ }
1419
+ }
1410
1420
  }
1411
1421
 
1412
- function detectFont( treat, control, text ) {
1413
- var treat = treat
1414
- var control = control
1415
- var text = text || '辭Q'
1422
+ function compareCanvases( treat, control ) {
1416
1423
  var ret
1424
+ var a = treat.context
1425
+ var b = control.context
1417
1426
 
1418
1427
  try {
1419
- control = writeOnCanvas( text, control || 'sans-serif' )
1420
- treat = writeOnCanvas( text, treat )
1421
-
1422
1428
  for ( var j = 1; j <= 20; j++ ) {
1423
1429
  for ( var i = 1; i <= 50; i++ ) {
1424
1430
  if (
1425
- ret !== 'undefined' &&
1426
- treat[1].getImageData(i, j, 1, 1).data[3] !== control[1].getImageData(i, j, 1, 1).data[3]
1431
+ typeof ret === 'undefined' &&
1432
+ a.getImageData(i, j, 1, 1).data[3] !== b.getImageData(i, j, 1, 1).data[3]
1427
1433
  ) {
1428
- ret = true
1434
+ ret = false
1429
1435
  break
1430
- } else if ( ret ) {
1436
+ } else if ( typeof ret === 'boolean' ) {
1431
1437
  break
1432
1438
  }
1433
1439
 
1434
- if ( i === 50 && j === 20 && !ret ) {
1435
- ret = false
1440
+ if ( i === 50 && j === 20 && typeof ret === 'undefined' ) {
1441
+ ret = true
1436
1442
  }
1437
1443
  }
1438
1444
  }
1439
1445
 
1440
1446
  // Remove and clean from memory
1441
- $.remove( control[0] )
1442
- $.remove( treat[0] )
1443
- control = null
1447
+ treat.remove()
1448
+ control.remove()
1444
1449
  treat = null
1450
+ control = null
1445
1451
 
1446
1452
  return ret
1447
- } catch ( e ) {
1448
- return false
1449
- }
1453
+ } catch (e) {}
1454
+ return false
1455
+ }
1456
+
1457
+ function detectFont( treat, control, text ) {
1458
+ var treat = treat
1459
+ var control = control || 'sans-serif'
1460
+ var text = text || '辭Q'
1461
+ var ret
1462
+
1463
+ control = writeOnCanvas( text, control )
1464
+ treat = writeOnCanvas( text, treat )
1465
+
1466
+ return !compareCanvases( treat, control )
1450
1467
  }
1451
1468
 
1452
- Hyu.detectFont = detectFont
1469
+ Locale.writeOnCanvas = writeOnCanvas
1470
+ Locale.compareCanvases = compareCanvases
1471
+ Locale.detectFont = detectFont
1453
1472
 
1454
- Hyu.support = (function() {
1473
+ Locale.support = (function() {
1455
1474
 
1456
1475
  var PREFIX = 'Webkit Moz ms'.split(' ')
1457
1476
 
1458
1477
  // Create an element for feature detecting
1459
1478
  // (in `testCSSProp`)
1460
- var elem = $.create( '_' )
1479
+ var elem = $.create( 'h-test' )
1461
1480
  var exposed = {}
1462
1481
 
1463
1482
  function testCSSProp( prop ) {
@@ -1576,7 +1595,7 @@ Hyu.support = (function() {
1576
1595
  injectElementWithStyle(
1577
1596
  '@font-face{font-family:test-for-unicode-range;src:local(Arial),local("Droid Sans")}@font-face{font-family:test-for-unicode-range;src:local("Times New Roman"),local(Times),local("Droid Serif");unicode-range:U+270C}',
1578
1597
  function() {
1579
- ret = !Hyu.detectFont(
1598
+ ret = !Locale.detectFont(
1580
1599
  'test-for-unicode-range', // treatment group
1581
1600
  'Arial, "Droid Sans"', // control group
1582
1601
  'Q' // ASCII characters only
@@ -1594,15 +1613,18 @@ Hyu.support = (function() {
1594
1613
  }
1595
1614
  })()
1596
1615
 
1597
- Hyu.initCond = function( target ) {
1616
+ var UA = window.navigator.userAgent || null
1617
+ var isIE = /Trident/i.test( UA )
1618
+
1619
+ Locale.support['pseudo-element-clipboard'] = isIE ? true : false
1620
+
1621
+ Locale.initCond = function( target ) {
1598
1622
  var target = target || root
1599
1623
  var ret = ''
1600
1624
  var clazz
1601
1625
 
1602
- target.classList.add( Hyu.JS_RENDERED_CLASS )
1603
-
1604
- for ( var feature in Hyu.support ) {
1605
- clazz = ( Hyu.support[ feature ] ? '' : 'no-' ) + feature
1626
+ for ( var feature in Locale.support ) {
1627
+ clazz = ( Locale.support[ feature ] ? '' : 'no-' ) + feature
1606
1628
 
1607
1629
  target.classList.add( clazz )
1608
1630
  ret += clazz + ' '
@@ -1611,25 +1633,25 @@ Hyu.initCond = function( target ) {
1611
1633
  }
1612
1634
 
1613
1635
  /**
1614
- * Create and return a new `<ru>` element
1636
+ * Create and return a new `<h-ru>` element
1615
1637
  * according to the given contents
1616
1638
  */
1617
1639
  function createNormalRu( $rb, $rt, attr ) {
1618
- var $ru = $.create( 'ru' )
1640
+ var $ru = $.create( 'h-ru' )
1619
1641
  var $rt = $.clone( $rt )
1620
1642
  var attr = attr || {}
1643
+ attr.annotation = $rt.textContent
1621
1644
 
1622
1645
  if ( Array.isArray( $rb )) {
1623
1646
  $ru.innerHTML = $rb.map(function( rb ) {
1624
- if (typeof rb == 'undefined') { return '' }
1647
+ if ( typeof rb === 'undefined' ) return ''
1625
1648
  return rb.outerHTML
1626
- }).join('')
1649
+ }).join('') + $rt.outerHTML
1627
1650
  } else {
1628
1651
  $ru.appendChild( $.clone( $rb ))
1652
+ $ru.appendChild( $rt )
1629
1653
  }
1630
1654
 
1631
- $ru.appendChild( $rt )
1632
- attr.annotation = $rt.textContent
1633
1655
  $.setAttr( $ru, attr )
1634
1656
  return $ru
1635
1657
  }
@@ -1642,10 +1664,7 @@ function createZhuyinRu( $rb, $rt ) {
1642
1664
  var $rb = $.clone( $rb )
1643
1665
 
1644
1666
  // Create an element to return
1645
- var $ru = $.create( 'ru' )
1646
- var $zhuyin = $.create( 'zhuyin' )
1647
- var $yin = $.create( 'yin' )
1648
- var $diao = $.create( 'diao' )
1667
+ var $ru = $.create( 'h-ru' )
1649
1668
 
1650
1669
  // #### Explanation ####
1651
1670
  // * `zhuyin`: the entire phonetic annotation
@@ -1670,20 +1689,15 @@ function createZhuyinRu( $rb, $rt ) {
1670
1689
  y ? 'Y' : null
1671
1690
  ].join('')
1672
1691
  })
1673
- // - <ru>
1692
+ // - <h-ru>
1674
1693
  // - <rb><rb/>
1675
- // - <zhuyin>
1676
- // - <yin></yin>
1677
- // - <diao></diao>
1678
- // - </zhuyin>
1679
- // - </ru>
1680
- $diao.innerHTML = diao
1681
- $yin.innerHTML = yin
1682
- $zhuyin.appendChild( $yin )
1683
- $zhuyin.appendChild( $diao )
1684
-
1694
+ // - <h-zhuyin>
1695
+ // - <h-yin></h-yin>
1696
+ // - <h-diao></h-diao>
1697
+ // - </h-zhuyin>
1698
+ // - </h-ru>
1685
1699
  $ru.appendChild( $rb )
1686
- $ru.appendChild( $zhuyin )
1700
+ $ru.innerHTML += '<h-zhuyin><h-yin>' + yin + '</h-yin><h-diao>' + diao + '</h-diao></h-zhuyin>'
1687
1701
 
1688
1702
  // Finally, set up the necessary attribute
1689
1703
  // and return the new `<ru>`
@@ -1699,11 +1713,11 @@ function createZhuyinRu( $rb, $rt ) {
1699
1713
  /**
1700
1714
  * Normalisation rendering mechanism
1701
1715
  */
1702
- $.extend( Hyu, {
1716
+ $.extend( Locale, {
1703
1717
 
1704
1718
  // Render and normalise the given context by routine:
1705
1719
  //
1706
- // > ruby > u, ins > s, del > em
1720
+ // ruby -> u, ins -> s, del -> em
1707
1721
  //
1708
1722
  renderElem: function( context ) {
1709
1723
  this.renderRuby( context )
@@ -1712,8 +1726,8 @@ $.extend( Hyu, {
1712
1726
  this.renderEm( context )
1713
1727
  },
1714
1728
 
1715
- // Traverse target elements (those with text-decoration
1716
- // -line) to see if we should address spacing in
1729
+ // Traverse target elements (those with text-decoration-
1730
+ // line) to see if we should address spacing in
1717
1731
  // between for semantic presentation.
1718
1732
  renderDecoLine: function( context, target ) {
1719
1733
  var target = target || 'u, ins'
@@ -1745,21 +1759,26 @@ $.extend( Hyu, {
1745
1759
 
1746
1760
  $target
1747
1761
  .forEach(function( elem ) {
1748
- var $elem = Fibre( elem )
1762
+ var $elem = Han( elem )
1749
1763
 
1750
- if ( !Hyu.support.textemphasis ) {
1751
- $elem.jinzify()
1764
+ if ( !Locale.support.textemphasis ) {
1765
+ $elem
1766
+ .jinzify()
1767
+ .groupify({ western: true })
1752
1768
  }
1753
1769
 
1754
1770
  $elem
1755
- .groupify()
1756
- .charify( Hyu.support.textemphasis ? {
1757
- hanzi: 'biaodian',
1758
- word: 'punctuation'
1771
+ .groupify({ biaodian: true })
1772
+ .charify( Locale.support.textemphasis ? {
1773
+ biaodian: true,
1774
+ punct: true
1759
1775
  } : {
1760
- latin: 'individual',
1761
- ellinika: 'individual',
1762
- kirillica: 'individual'
1776
+ hanzi: true,
1777
+ biaodian: true,
1778
+ punct: true,
1779
+ latin: true,
1780
+ ellinika: true,
1781
+ kirillica: true
1763
1782
  })
1764
1783
  })
1765
1784
  },
@@ -1794,7 +1813,7 @@ $.extend( Hyu, {
1794
1813
  var clazz = ruby.classList
1795
1814
 
1796
1815
  var condition = (
1797
- !Hyu.support.ruby ||
1816
+ !Locale.support.ruby ||
1798
1817
  clazz.contains( 'zhuyin') ||
1799
1818
  clazz.contains( 'complex' ) ||
1800
1819
  clazz.contains( 'rightangle' )
@@ -1811,8 +1830,8 @@ $.extend( Hyu, {
1811
1830
  $cloned = $.qsa( target, frag )[0]
1812
1831
 
1813
1832
  // 1. Simple ruby polyfill for, um, Firefox;
1814
- // 2. Zhuyin polyfill for all.
1815
- if ( !Hyu.support.ruby || clazz.contains( 'zhuyin' )) {
1833
+ // 2. Zhuyin polyfill for all browsers.
1834
+ if ( !Locale.support.ruby || clazz.contains( 'zhuyin' )) {
1816
1835
 
1817
1836
  $
1818
1837
  .tag( 'rt', $cloned )
@@ -1826,16 +1845,16 @@ $.extend( Hyu, {
1826
1845
  do {
1827
1846
  irb = ( irb || rt ).previousSibling
1828
1847
 
1829
- if ( !irb || irb.nodeName.match( /(r[ubt])/i )) break
1848
+ if ( !irb || irb.nodeName.match( /(r\-?[ubt])/i )) break
1830
1849
 
1831
1850
  $rb.insertBefore( $.clone( irb ), $rb.firstChild )
1832
1851
  airb.push( irb )
1833
- } while ( !irb.nodeName.match( /(r[ubt])/i ))
1834
- // Create a real `<ru>` to append.
1852
+ } while ( !irb.nodeName.match( /(r\-?[ubt])/i ))
1853
+ // Create a real `<h-ru>` to append.
1835
1854
  $ru = clazz.contains( 'zhuyin' ) ?
1836
1855
  createZhuyinRu( $rb, rt ) : createNormalRu( $rb, rt )
1837
1856
 
1838
- // Replace the ruby text with the new `<ru>`,
1857
+ // Replace the ruby text with the new `<h-ru>`,
1839
1858
  // and remove the original implied ruby base(s)
1840
1859
  try {
1841
1860
  rt.parentNode.replaceChild( $ru, rt )
@@ -1860,7 +1879,7 @@ $.extend( Hyu, {
1860
1879
  //
1861
1880
  // Note that we only support one single Zhuyin
1862
1881
  // container in each complex ruby
1863
- !function( rtc ) {
1882
+ void function( rtc ) {
1864
1883
  if ( !rtc ) return
1865
1884
 
1866
1885
  $ru = $
@@ -1902,7 +1921,8 @@ $.extend( Hyu, {
1902
1921
  rb = $ru.shift()
1903
1922
  aRb.push( rb )
1904
1923
  } catch (e) {}
1905
- if (typeof rb == 'undefined') { break }
1924
+
1925
+ if ( typeof rb === 'undefined' ) break
1906
1926
  span += Number( rb.getAttribute( 'span' ) || 1 )
1907
1927
  } while ( rbspan > span )
1908
1928
 
@@ -1911,7 +1931,7 @@ $.extend( Hyu, {
1911
1931
  console.error( 'An impossible `rbspan` value detected.', ruby )
1912
1932
  return
1913
1933
  }
1914
- aRb = $.tag( 'rb', aRb[0] )
1934
+ aRb = $.tag( 'h-rb', aRb[0] )
1915
1935
  $ru = aRb.slice( rbspan ).concat( $ru )
1916
1936
  aRb = aRb.slice( 0, rbspan )
1917
1937
  span = rbspan
@@ -1937,12 +1957,10 @@ $.extend( Hyu, {
1937
1957
  $.remove( rtc )
1938
1958
  })
1939
1959
  }
1940
- // Create a new fake `<hruby>` element so the
1960
+ // Create a new fake `<h-ruby>` element so the
1941
1961
  // style sheets will render it as a polyfill,
1942
1962
  // which also helps to avoid the UA style.
1943
- //
1944
- // (The ‘H’ stands for ‘Han’, by the way)
1945
- hruby = $.create( 'hruby' )
1963
+ hruby = $.create( 'h-ruby' )
1946
1964
  hruby.innerHTML = frag.firstChild.innerHTML
1947
1965
 
1948
1966
  // Copy all attributes onto it
@@ -1960,18 +1978,10 @@ $.extend( Hyu, {
1960
1978
  // * Better error-tolerance
1961
1979
  })
1962
1980
 
1963
- /*!
1964
- * Hyu
1965
- * css.hanzi.co/hyu
1966
- *
1967
- * This module is a subset project of Han,
1968
- * which aims to provide HTML5-ready and
1969
- * Hanzi-optimised style normalisation.
1970
- */
1971
-
1972
- Han.normalize = Hyu
1973
- Han.support = Hyu.support
1974
- Han.detectFont = Hyu.detectFont
1981
+ Han.normalize = Locale
1982
+ Han.localize = Locale
1983
+ Han.support = Locale.support
1984
+ Han.detectFont = Locale.detectFont
1975
1985
 
1976
1986
  Han.fn.initCond = function() {
1977
1987
  this.condition.classList.add( 'han-js-rendered' )
@@ -2009,24 +2019,23 @@ $.extend( Han.support, {
2009
2019
  // 'fangsong-gb': Han.detectFont( '"Han Fangsong GB"' )
2010
2020
  })
2011
2021
 
2012
- var QUERY_HWS_AS_FIRST_CHILD = '* > hws:first-child, * > wbr:first-child + hws, wbr:first-child + wbr + hws'
2022
+ var QUERY_HWS_AS_FIRST_CHILD = '* > h-hws:first-child, * > wbr:first-child + h-hws, wbr:first-child + wbr + h-hws'
2013
2023
 
2014
2024
  //// Disabled `Node.normalize()` for temp due to
2015
2025
  //// issue below in IE11.
2016
2026
  //// See: http://stackoverflow.com/questions/22337498/why-does-ie11-handle-node-normalize-incorrectly-for-the-minus-symbol
2017
2027
  var isNodeNormalizeNormal = (function() {
2018
- var div = $.create( 'div' )
2019
-
2020
- div.appendChild( $.create( '', '0-' ))
2021
- div.appendChild( $.create( '', '2' ))
2022
- div.normalize()
2028
+ var div = $.create( 'div' )
2023
2029
 
2024
- return div.firstChild.length !== 2
2025
- })(),
2030
+ div.appendChild( $.create( '', '0-' ))
2031
+ div.appendChild( $.create( '', '2' ))
2032
+ div.normalize()
2026
2033
 
2027
- hws
2034
+ return div.firstChild.length !== 2
2035
+ })()
2028
2036
 
2029
- hws = $.create( 'hws' )
2037
+ var hws = $.create( 'h-hws' )
2038
+ hws.setAttribute( 'hidden', '' )
2030
2039
  hws.innerHTML = ' '
2031
2040
 
2032
2041
  $.extend( Han, {
@@ -2049,9 +2058,14 @@ $.extend( Han, {
2049
2058
  .replace( Han.TYPESET.hws[ mode ][0], '$1<hws/>$2' )
2050
2059
  .replace( Han.TYPESET.hws[ mode ][1], '$1<hws/>$2' )
2051
2060
 
2052
- // Deal with `' 字'`, `" 字"` => `'字'`, `"字"`
2061
+ // Deal with [' 字'], [" 字"] => ['字'], ["字"]
2053
2062
  .replace( /(['"]+)<hws\/>(.+?)<hws\/>\1/ig, '$1$2$1' )
2054
2063
 
2064
+ // Remove all `<hws/>` pre/post [“字”] and [‘字’]
2065
+ // See: https://github.com/ethantw/Han/issues/59
2066
+ .replace( /<hws\/>([‘“]+)/ig, '$1' )
2067
+ .replace( /([’”]+)<hws\/>/ig, '$1' )
2068
+
2055
2069
  // Convert text nodes `<hws/>` into real element nodes
2056
2070
  .replace( '<hws/>', function() {
2057
2071
  return $.clone( hws )
@@ -2077,7 +2091,7 @@ $.extend( Han, {
2077
2091
  // or a text fragment, but the latter one is
2078
2092
  // not what we want. We don't want comments,
2079
2093
  // either.
2080
- while ( target.nodeName === 'HWS' ) {
2094
+ while ( target.nodeName === 'H-HWS' ) {
2081
2095
  $.remove( target, parent )
2082
2096
 
2083
2097
  target = parent.parentNode.insertBefore( $.clone( hws ), parent )
@@ -2088,8 +2102,8 @@ $.extend( Han, {
2088
2102
  }
2089
2103
 
2090
2104
  // This is for extreme circumstances, i.e.,
2091
- // `漢<a><b><c><hws/>zi</c></b></a>` =>
2092
- // `漢<hws/><a><b><c>zi</c></b></a>`
2105
+ // `漢<a><b><c><h-hws/>zi</c></b></a>` =>
2106
+ // `漢<h-hws/><a><b><c>zi</c></b></a>`
2093
2107
  if ( target !== parent.firstChild ) {
2094
2108
  break
2095
2109
  }
@@ -2112,7 +2126,7 @@ $.extend( Han.fn, {
2112
2126
  renderHWS: function( strict ) {
2113
2127
  Han.renderHWS( this.context, strict )
2114
2128
 
2115
- this.HWS = $.tag( 'hws', this.context )
2129
+ this.HWS = $.tag( 'h-hws', this.context )
2116
2130
  return this
2117
2131
  },
2118
2132
 
@@ -2124,28 +2138,75 @@ $.extend( Han.fn, {
2124
2138
  }
2125
2139
  })
2126
2140
 
2127
- Han.renderJiya = function( context ) {
2141
+ Han.isSpaceFontLoaded = (function() {
2142
+ var div = $.create( 'div' )
2143
+ var ret
2144
+
2145
+ div.innerHTML = '<span>a b</span><span style="font-family: \'Han Space\'">a b</span>'
2146
+ body.appendChild( div )
2147
+ ret = div.firstChild.offsetWidth !== div.lastChild.offsetWidth
2148
+ $.remove( div, body )
2149
+ return ret
2150
+ })()
2151
+
2152
+ Han.support['han-space'] = Han.isSpaceFontLoaded
2153
+
2154
+ Han.renderHanging = function( context ) {
2128
2155
  var context = context || document
2129
- var finder = [ Han.find( context ) ]
2156
+ var finder = Han.find( context )
2130
2157
 
2131
- finder[ 0 ].filterOut( 'textarea, code, kbd, samp, pre, jinze, em', true )
2132
- finder[ 0 ].groupify()
2158
+ finder
2159
+ .filterOut( 'textarea, code, kbd, samp, pre, hangable', true )
2160
+ .replace(
2161
+ TYPESET.jinze.hanging,
2162
+ function( portion, match ) {
2163
+ var elem = $.create( 'h-hangable' )
2164
+ var unicode = match[3].charCodeAt( 0 ).toString( 16 )
2165
+
2166
+ elem.innerHTML = match[2] + '<h-cs biaodian="' + match[3] + '"><h-inner hidden> </h-inner></h-cs><h-char class="biaodian cjk end" unicode="' + unicode + '">' + match[3] + '</h-char>'
2167
+ return portion.index === 0 ? elem : ''
2168
+ }
2169
+ )
2170
+
2171
+ return finder
2172
+ }
2173
+
2174
+ $.extend( Han.fn, {
2175
+ hanging: null,
2176
+
2177
+ renderHanging: function() {
2178
+ this.hanging = Han.renderHanging( this.context )
2179
+ return this
2180
+ },
2133
2181
 
2134
- $
2135
- .qsa( 'char_group.biaodian', context )
2182
+ revertHanging: function() {
2183
+ try {
2184
+ this.hanging.revert( 'all' )
2185
+ } catch ( e ) {}
2186
+ return this
2187
+ }
2188
+ })
2189
+
2190
+ Han.renderJiya = function( context ) {
2191
+ var context = context || document
2192
+ var finder = Han.find( context )
2193
+
2194
+ finder
2195
+ .filterOut( 'textarea, code, kbd, samp, pre', true )
2196
+ .groupify({ biaodian: true })
2197
+ .charify({ biaodian: true })
2198
+
2199
+ // The reason we're doing this instead of using pseudo elements in CSS
2200
+ // is because WebKit has problem rendering pseudo elements containing only
2201
+ // space.
2202
+ $.qsa( 'h-char.biaodian.open, h-char.biaodian.end', context )
2136
2203
  .forEach(function( elem ) {
2137
- finder.push(
2138
- Han( elem )
2139
- .charify({
2140
- hanzi: 'biaodian',
2141
- liga: 'liga',
2142
- word: 'none',
2143
- latin: 'none',
2144
- ellinika: 'none',
2145
- kirillica: 'none'
2146
- })
2147
- )
2204
+ var html = '<h-inner>' + elem.innerHTML + '</h-inner>'
2205
+ var hcs = '<h-cs hidden> </h-cs>'
2206
+ var isOpen = elem.classList.contains( 'open' )
2207
+ elem.innerHTML = isOpen ? hcs + html : html + hcs
2148
2208
  })
2209
+
2149
2210
  return finder
2150
2211
  }
2151
2212
 
@@ -2167,7 +2228,7 @@ $.extend( Han.fn, {
2167
2228
 
2168
2229
  var mdot
2169
2230
 
2170
- mdot = $.create( 'char', 'biaodian cjk middle' )
2231
+ mdot = $.create( 'h-char', 'biaodian cjk middle' )
2171
2232
  mdot.setAttribute( 'unicode', 'b7' )
2172
2233
 
2173
2234
  Han.correctBasicBD = function( context, all ) {
@@ -2180,14 +2241,7 @@ Han.correctBasicBD = function( context, all ) {
2180
2241
 
2181
2242
  finder
2182
2243
  .wrap( /\u00B7/g, $.clone( mdot ))
2183
- .charify({
2184
- liga: 'liga',
2185
- hanzi: 'none',
2186
- word: 'none',
2187
- latin: 'none',
2188
- ellinika: 'none',
2189
- kirillica: 'none'
2190
- })
2244
+ .charify({ biaodian: true })
2191
2245
  }
2192
2246
 
2193
2247
  $.extend( Han.fn, {
@@ -2206,51 +2260,20 @@ $.extend( Han.fn, {
2206
2260
  }
2207
2261
  })
2208
2262
 
2209
- var QUERY_RU_W_ANNO = 'ru[annotation]'
2263
+ var QUERY_RU_W_ANNO = 'h-ru[annotation]'
2210
2264
  var SELECTOR_TO_IGNORE = 'textarea, code, kbd, samp, pre'
2211
2265
 
2212
2266
  var isCombLigaNormal = (function() {
2213
- var fakeBody = body || $.create( 'body' )
2214
- var div = $.create( 'div' )
2215
- var control = $.create( 'span' )
2216
- var container = body ? div : fakeBody
2217
- var treat, docOverflow, ret
2267
+ var treat = Han.localize.writeOnCanvas( '\u0069\u030D', '"Romanization Sans"' )
2268
+ var control = Han.localize.writeOnCanvas( '\uDB80\uDC69', '"Romanization Sans"' )
2218
2269
 
2219
- if ( !body ) {
2220
- fakeBody.style.background = ''
2221
- fakeBody.style.overflow = 'hidden'
2222
- docOverflow = root.style.overflow
2223
-
2224
- root.style.overflow = 'hidden'
2225
- root.appendChild( fakeBody )
2226
- } else {
2227
- body.appendChild( container )
2228
- }
2229
-
2230
- control.innerHTML = '&#x0069;&#x030D;'
2231
- control.style.fontFamily = 'sans-serif'
2232
- control.style.display = 'inline-block'
2233
-
2234
- treat = $.clone( control )
2235
- treat.style.fontFamily = '"Romanization Sans"'
2236
-
2237
- container.appendChild( control )
2238
- container.appendChild( treat )
2239
-
2240
- ret = control.clientWidth !== treat.clientWidth
2241
- $.remove( container )
2242
-
2243
- if ( !body ) {
2244
- root.style.overflow = docOverflow
2245
- }
2246
- return ret
2270
+ return Han.localize.compareCanvases( treat, control )
2247
2271
  })()
2248
2272
 
2249
2273
  var aCombLiga = Han.TYPESET[ 'display-as' ][ 'comb-liga-pua' ]
2250
2274
  var aInaccurateChar = Han.TYPESET[ 'inaccurate-char' ]
2251
2275
 
2252
- var charCombLiga = $.create( 'char', 'comb-liga' )
2253
- var charCombLigaInner = $.create( 'inner' )
2276
+ var charCombLiga = $.create( 'h-char', 'comb-liga' )
2254
2277
 
2255
2278
  $.extend( Han, {
2256
2279
  isCombLigaNormal: isCombLigaNormal,
@@ -2270,12 +2293,10 @@ $.extend( Han, {
2270
2293
  new RegExp( pattern[ 0 ], 'ig' ),
2271
2294
  function( portion, match ) {
2272
2295
  var ret = $.clone( charCombLiga )
2273
- var inner = $.clone( charCombLigaInner )
2274
2296
 
2275
2297
  // Put the original content in an inner container
2276
2298
  // for better presentational effect of hidden text
2277
- inner.innerHTML = match[ 0 ]
2278
- ret.appendChild( inner )
2299
+ ret.innerHTML = '<h-inner>' + match[0] + '</h-inner>'
2279
2300
  ret.setAttribute( 'display-as', pattern[ 1 ] )
2280
2301
  return portion.index === 0 ? ret : ''
2281
2302
  }