hanzi-rails 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -2
- data/app/assets/fonts/han-space.woff +0 -0
- data/app/assets/javascripts/hanzi.js +678 -351
- data/app/assets/stylesheets/hanzi.css.erb +407 -1050
- data/lib/hanzi-rails/version.rb +2 -2
- metadata +1 -2
- data/app/assets/fonts/han.ttf +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6432afbb2c17e412416668ff9b631cf77cb2d4e
|
4
|
+
data.tar.gz: 15a05a57491228baa576a452076676a9581bd422
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92a9340628820db6d06759af2cd8bda137f09e429784c3128de8c04ee60c03ed96371fc6a9ae9c3c8f8f5df92a4347166f5e3e9f5dc098ead3322bcb76da2dce
|
7
|
+
data.tar.gz: 893ee219a9dff560f6ed8c35725c1f1fb50bde37435ec9a1dd1e312d0431aeae1481604483d1b3224f53df579235610a723c95cf2624daccff8bd1c3cf8c9d39
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
This is a rails gem which provides Sass/JavaScript typesetting framework Han.css.
|
4
4
|
|
5
|
-
You can read more about han.css at [here](https://github.com/ethantw/Han/)
|
5
|
+
You can read more about han.css at [here](https://github.com/ethantw/Han/) and read manual at [here](https://css.hanzi.co/manual/)
|
6
6
|
|
7
7
|
han.css is made by Chen Yijun (陳奕鈞,http://yijun.me/).
|
8
8
|
|
@@ -30,12 +30,22 @@ The han.css files will be added to the asset pipeline and available for you to u
|
|
30
30
|
*= require hanzi
|
31
31
|
```
|
32
32
|
|
33
|
-
If you need to use the javascript render function, Add
|
33
|
+
If you need to use the javascript render function, Add these lines to `app/assets/javascripts/application.js`:
|
34
34
|
|
35
35
|
```js
|
36
36
|
//= require hanzi
|
37
|
+
|
38
|
+
Han.init();
|
37
39
|
```
|
38
40
|
|
41
|
+
And add class `han-init` and correct lang attribute to `html` tag.
|
42
|
+
|
43
|
+
```html
|
44
|
+
<html lang="zh-Hant" class="han-init">
|
45
|
+
```
|
46
|
+
|
47
|
+
For more information, please read the [manual](https://css.hanzi.co/manual/js-api#rendering).
|
48
|
+
|
39
49
|
## Contributing
|
40
50
|
|
41
51
|
1. Fork it ( https://github.com/billy3321/hanzi-rails/fork )
|
File without changes
|
@@ -1,5 +1,5 @@
|
|
1
1
|
/*!
|
2
|
-
* 漢字標準格式 v3.
|
2
|
+
* 漢字標準格式 v3.3.0 | MIT License | css.hanzi.co
|
3
3
|
* Han.css: the CSS typography framework optimised for Hanzi
|
4
4
|
*/
|
5
5
|
|
@@ -9,7 +9,7 @@ void function( global, factory ) {
|
|
9
9
|
if ( typeof module === 'object' && typeof module.exports === 'object' ) {
|
10
10
|
module.exports = factory( global, true )
|
11
11
|
// AMD
|
12
|
-
} else if
|
12
|
+
} else if ( typeof define === 'function' && define.amd ) {
|
13
13
|
define(function() { return factory( global, true ) })
|
14
14
|
// Global namespace
|
15
15
|
} else {
|
@@ -26,7 +26,7 @@ var root = document.documentElement
|
|
26
26
|
|
27
27
|
var body = document.body
|
28
28
|
|
29
|
-
var VERSION = '3.
|
29
|
+
var VERSION = '3.3.0'
|
30
30
|
|
31
31
|
var ROUTINE = [
|
32
32
|
// Initialise the condition with feature-detecting
|
@@ -39,15 +39,15 @@ var ROUTINE = [
|
|
39
39
|
|
40
40
|
// Handle Biaodian
|
41
41
|
/* 'jinzify', */
|
42
|
-
'renderHanging',
|
43
42
|
'renderJiya',
|
43
|
+
'renderHanging',
|
44
|
+
|
45
|
+
// Address Biaodian correction
|
46
|
+
'correctBiaodian',
|
44
47
|
|
45
48
|
// Address Hanzi and Western script mixed spacing
|
46
49
|
'renderHWS',
|
47
50
|
|
48
|
-
// Address Basic Biaodian correction in Firefox
|
49
|
-
'correctBasicBD',
|
50
|
-
|
51
51
|
// Address presentational correction to combining ligatures
|
52
52
|
'substCombLigaWithPUA'
|
53
53
|
|
@@ -101,17 +101,23 @@ Han.fn = Han.prototype = {
|
|
101
101
|
// the instance or in the prototype chain.
|
102
102
|
render: function( routine ) {
|
103
103
|
var it = this
|
104
|
-
var routine = Array.isArray( routine )
|
104
|
+
var routine = Array.isArray( routine )
|
105
|
+
? routine
|
106
|
+
: this.routine
|
105
107
|
|
106
108
|
routine
|
107
109
|
.forEach(function( method ) {
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
110
|
+
if (
|
111
|
+
typeof method === 'string' &&
|
112
|
+
typeof it[ method ] === 'function'
|
113
|
+
) {
|
114
|
+
it[ method ]()
|
115
|
+
} else if (
|
116
|
+
Array.isArray( method ) &&
|
117
|
+
typeof it[ method[0] ] === 'function'
|
118
|
+
) {
|
119
|
+
it[ method.shift() ].apply( it, method )
|
120
|
+
}
|
115
121
|
})
|
116
122
|
return this
|
117
123
|
}
|
@@ -325,31 +331,31 @@ var TYPESET = (function() {
|
|
325
331
|
var rPtMid = UNICODE.punct.middle
|
326
332
|
var rPtSing = UNICODE.punct.sing
|
327
333
|
var rPt = rPtOpen + '|' + rPtEnd + '|' + rPtMid
|
328
|
-
|
329
|
-
var
|
330
|
-
var
|
331
|
-
var
|
332
|
-
var
|
333
|
-
var
|
334
|
-
var
|
335
|
-
|
334
|
+
|
335
|
+
var rBDOpen = UNICODE.biaodian.open
|
336
|
+
var rBDClose = UNICODE.biaodian.close
|
337
|
+
var rBDEnd = UNICODE.biaodian.end
|
338
|
+
var rBDMid = UNICODE.biaodian.middle
|
339
|
+
var rBDLiga = UNICODE.biaodian.liga + '{2}'
|
340
|
+
var rBD = rBDOpen + '|' + rBDEnd + '|' + rBDMid
|
341
|
+
|
336
342
|
var rKana = UNICODE.kana.base + UNICODE.kana.combine + '?'
|
337
343
|
var rKanaS = UNICODE.kana.small + UNICODE.kana.combine + '?'
|
338
344
|
var rKanaH = UNICODE.kana.half
|
339
345
|
var rEon = UNICODE.eonmun.base + '|' + UNICODE.eonmun.letter
|
340
346
|
var rEonH = UNICODE.eonmun.half
|
341
|
-
|
347
|
+
|
342
348
|
var rHan = UNICODE.hanzi.base + '|' + UNICODE.hanzi.desc + '|' + UNICODE.hanzi.radical + '|' + rKana
|
343
|
-
|
349
|
+
|
344
350
|
var rCbn = UNICODE.ellinika.combine
|
345
351
|
var rLatn = UNICODE.latin.base + rCbn + '*'
|
346
352
|
var rGk = UNICODE.ellinika.base + rCbn + '*'
|
347
|
-
|
353
|
+
|
348
354
|
var rCyCbn = UNICODE.kirillica.combine
|
349
355
|
var rCy = UNICODE.kirillica.base + rCyCbn + '*'
|
350
|
-
|
356
|
+
|
351
357
|
var rAlph = rLatn + '|' + rGk + '|' + rCy
|
352
|
-
|
358
|
+
|
353
359
|
// For words like `it's`, `Jones’s` or `'99`
|
354
360
|
var rApo = '[\u0027\u2019]'
|
355
361
|
var rChar = rHan + '|(?:' + rAlph + '|' + rApo + ')+'
|
@@ -371,29 +377,29 @@ var TYPESET = (function() {
|
|
371
377
|
},
|
372
378
|
|
373
379
|
biaodian: {
|
374
|
-
all: new RegExp( '(' +
|
375
|
-
open: new RegExp( '(' +
|
376
|
-
close: new RegExp( '(' +
|
377
|
-
end: new RegExp( '(' +
|
378
|
-
liga: new RegExp( '(' +
|
380
|
+
all: new RegExp( '(' + rBD + ')', 'g' ),
|
381
|
+
open: new RegExp( '(' + rBDOpen + ')', 'g' ),
|
382
|
+
close: new RegExp( '(' + rBDClose + ')', 'g' ),
|
383
|
+
end: new RegExp( '(' + rBDEnd + ')', 'g' ),
|
384
|
+
liga: new RegExp( '(' + rBDLiga + ')', 'g' )
|
379
385
|
},
|
380
386
|
|
381
|
-
hanzi:
|
387
|
+
hanzi: new RegExp( '(' + rHan + ')', 'g' ),
|
382
388
|
|
383
|
-
latin:
|
384
|
-
ellinika:
|
385
|
-
kirillica:
|
389
|
+
latin: new RegExp( '(' + rLatn + ')', 'ig' ),
|
390
|
+
ellinika: new RegExp( '(' + rGk + ')', 'ig' ),
|
391
|
+
kirillica: new RegExp( '(' + rCy + ')', 'ig' ),
|
386
392
|
|
387
|
-
kana:
|
388
|
-
eonmun:
|
393
|
+
kana: new RegExp( '(' + rKana + '|' + rKanaS + '|' + rKanaH + ')', 'g' ),
|
394
|
+
eonmun: new RegExp( '(' + rEon + '|' + rEonH + ')', 'g' )
|
389
395
|
},
|
390
396
|
|
391
397
|
/* Word-level selectors (詞級選擇器)
|
392
398
|
*/
|
393
399
|
group: {
|
394
400
|
biaodian: [
|
395
|
-
new RegExp( '((' +
|
396
|
-
new RegExp( '(' +
|
401
|
+
new RegExp( '((' + rBD + '){2,})', 'g' ),
|
402
|
+
new RegExp( '(' + rBDLiga + rBDOpen + ')', 'g' )
|
397
403
|
],
|
398
404
|
punct: null,
|
399
405
|
hanzi: new RegExp( '(' + rHan + ')+', 'g' ),
|
@@ -405,11 +411,11 @@ var TYPESET = (function() {
|
|
405
411
|
/* Punctuation Rules (禁則)
|
406
412
|
*/
|
407
413
|
jinze: {
|
408
|
-
hanging: new RegExp(
|
409
|
-
touwei: new RegExp( '(' +
|
410
|
-
tou: new RegExp( '(' +
|
411
|
-
wei: new RegExp( '(' + rChar + ')(' +
|
412
|
-
middle: new RegExp( '(' + rChar + ')(' +
|
414
|
+
hanging: new RegExp( rWhite + '*([、,。.])(?!' + rBDEnd + ')', 'ig' ),
|
415
|
+
touwei: new RegExp( '(' + rBDOpen + '+)(' + rChar + ')(' + rBDEnd + '+)', 'ig' ),
|
416
|
+
tou: new RegExp( '(' + rBDOpen + '+)(' + rChar + ')', 'ig' ),
|
417
|
+
wei: new RegExp( '(' + rChar + ')(' + rBDEnd + '+)', 'ig' ),
|
418
|
+
middle: new RegExp( '(' + rChar + ')(' + rBDMid + ')(' + rChar + ')', 'ig' )
|
413
419
|
},
|
414
420
|
|
415
421
|
zhuyin: {
|
@@ -507,71 +513,119 @@ Han.TYPESET.char.greek = Han.TYPESET.char.ellinika
|
|
507
513
|
Han.TYPESET.char.cyrillic = Han.TYPESET.char.kirillica
|
508
514
|
Han.TYPESET.char.hangul = Han.TYPESET.char.eonmun
|
509
515
|
|
516
|
+
Han.TYPESET.group.hangul = Han.TYPESET.group.eonmun
|
517
|
+
Han.TYPESET.group.cjk = Han.TYPESET.group.hanzi
|
518
|
+
|
510
519
|
var $ = {
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
520
|
+
/**
|
521
|
+
* Query selectors which return arrays of the resulted
|
522
|
+
* node lists.
|
523
|
+
*/
|
524
|
+
id: function( selector, $context ) {
|
525
|
+
return ( $context || document ).getElementById( selector )
|
515
526
|
},
|
516
527
|
|
517
|
-
tag: function( selector, context ) {
|
528
|
+
tag: function( selector, $context ) {
|
518
529
|
return this.makeArray(
|
519
|
-
( context || document ).getElementsByTagName( selector )
|
530
|
+
( $context || document ).getElementsByTagName( selector )
|
520
531
|
)
|
521
532
|
},
|
522
533
|
|
523
|
-
|
534
|
+
qs: function( selector, $context ) {
|
535
|
+
return ( $context || document ).querySelector( selector )
|
536
|
+
},
|
537
|
+
|
538
|
+
qsa: function( selector, $context ) {
|
524
539
|
return this.makeArray(
|
525
|
-
( context || document ).querySelectorAll( selector )
|
540
|
+
( $context || document ).querySelectorAll( selector )
|
526
541
|
)
|
527
542
|
},
|
528
543
|
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
544
|
+
parent: function( $node, selector ) {
|
545
|
+
return selector
|
546
|
+
? (function() {
|
547
|
+
if ( typeof $.matches !== 'function' ) return
|
548
|
+
|
549
|
+
while (!$.matches( $node, selector )) {
|
550
|
+
if (
|
551
|
+
!$node ||
|
552
|
+
$node === document.documentElement
|
553
|
+
) {
|
554
|
+
$node = undefined
|
555
|
+
break
|
556
|
+
}
|
557
|
+
$node = $node.parentNode
|
558
|
+
}
|
559
|
+
return $node
|
560
|
+
})()
|
561
|
+
: $node
|
562
|
+
? $node.parentNode : undefined
|
563
|
+
},
|
564
|
+
|
565
|
+
/**
|
566
|
+
* Create a document fragment, a text node with text
|
567
|
+
* or an element with/without classes.
|
568
|
+
*/
|
569
|
+
create: function( name, clazz ) {
|
570
|
+
var $elmt = '!' === name
|
571
|
+
? document.createDocumentFragment()
|
572
|
+
: '' === name
|
573
|
+
? document.createTextNode( clazz || '' )
|
574
|
+
: document.createElement( name )
|
537
575
|
|
538
576
|
try {
|
539
577
|
if ( clazz ) {
|
540
|
-
|
578
|
+
$elmt.className = clazz
|
541
579
|
}
|
542
580
|
} catch (e) {}
|
543
581
|
|
544
|
-
return
|
582
|
+
return $elmt
|
545
583
|
},
|
546
584
|
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
585
|
+
/**
|
586
|
+
* Clone a DOM node (text, element or fragment) deeply
|
587
|
+
* or childlessly.
|
588
|
+
*/
|
589
|
+
clone: function( $node, deep ) {
|
590
|
+
return $node.cloneNode(
|
591
|
+
typeof deep === 'boolean'
|
592
|
+
? deep
|
593
|
+
: true
|
594
|
+
)
|
551
595
|
},
|
552
596
|
|
553
|
-
|
554
|
-
|
555
|
-
|
597
|
+
/**
|
598
|
+
* Remove a node (text, element or fragment).
|
599
|
+
*/
|
600
|
+
remove: function( $node ) {
|
601
|
+
return $node.parentNode.removeChild( $node )
|
556
602
|
},
|
557
603
|
|
558
|
-
|
604
|
+
/**
|
605
|
+
* Set attributes all in once with an object.
|
606
|
+
*/
|
559
607
|
setAttr: function( target, attr ) {
|
560
|
-
if ( typeof attr !== 'object' )
|
608
|
+
if ( typeof attr !== 'object' ) return
|
561
609
|
var len = attr.length
|
562
610
|
|
563
|
-
// Native NamedNodeMap
|
564
|
-
if (
|
611
|
+
// Native `NamedNodeMap``:
|
612
|
+
if (
|
613
|
+
typeof attr[0] === 'object' &&
|
614
|
+
'name' in attr[0]
|
615
|
+
) {
|
565
616
|
for ( var i = 0; i < len; i++ ) {
|
566
617
|
if ( attr[ i ].value !== undefined ) {
|
567
618
|
target.setAttribute( attr[ i ].name, attr[ i ].value )
|
568
619
|
}
|
569
620
|
}
|
570
621
|
|
571
|
-
// Plain object
|
622
|
+
// Plain object:
|
572
623
|
} else {
|
573
624
|
for ( var name in attr ) {
|
574
|
-
if (
|
625
|
+
if (
|
626
|
+
attr.hasOwnProperty( name ) &&
|
627
|
+
attr[ name ] !== undefined
|
628
|
+
) {
|
575
629
|
target.setAttribute( name, attr[ name ] )
|
576
630
|
}
|
577
631
|
}
|
@@ -579,29 +633,47 @@ var $ = {
|
|
579
633
|
return target
|
580
634
|
},
|
581
635
|
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
636
|
+
/**
|
637
|
+
* Indicate whether or not the given node is an
|
638
|
+
* element.
|
639
|
+
*/
|
640
|
+
isElmt: function( $node ) {
|
641
|
+
return $node && $node.nodeType === Node.ELEMENT_NODE
|
586
642
|
},
|
587
643
|
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
644
|
+
/**
|
645
|
+
* Indicate whether or not the given node should
|
646
|
+
* be ignored (`<wbr>` or comments).
|
647
|
+
*/
|
648
|
+
isIgnorable: function( $node ) {
|
649
|
+
if ( !$node ) return false
|
650
|
+
|
651
|
+
return (
|
652
|
+
$node.nodeName === 'WBR' ||
|
653
|
+
$node.nodeType === Node.COMMENT_NODE
|
654
|
+
)
|
655
|
+
},
|
656
|
+
|
657
|
+
/**
|
658
|
+
* Convert array-like objects into real arrays.
|
659
|
+
*/
|
660
|
+
makeArray: function( object ) {
|
661
|
+
return Array.prototype.slice.call( object )
|
592
662
|
},
|
593
663
|
|
594
|
-
|
664
|
+
/**
|
665
|
+
* Extend target with an object.
|
666
|
+
*/
|
595
667
|
extend: function( target, object ) {
|
596
|
-
|
597
|
-
typeof target === '
|
668
|
+
if ((
|
669
|
+
typeof target === 'object' ||
|
670
|
+
typeof target === 'function' ) &&
|
598
671
|
typeof object === 'object'
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
target[ name ] = object[ name ]
|
672
|
+
) {
|
673
|
+
for ( var name in object ) {
|
674
|
+
if (object.hasOwnProperty( name )) {
|
675
|
+
target[ name ] = object[ name ]
|
676
|
+
}
|
605
677
|
}
|
606
678
|
}
|
607
679
|
return target
|
@@ -628,9 +700,9 @@ var document = global.document || undefined
|
|
628
700
|
function matches( node, selector, bypassNodeType39 ) {
|
629
701
|
var Efn = Element.prototype
|
630
702
|
var matches = Efn.matches || Efn.mozMatchesSelector || Efn.msMatchesSelector || Efn.webkitMatchesSelector
|
631
|
-
|
703
|
+
|
632
704
|
if ( node instanceof Element ) {
|
633
|
-
return matches.call( node, selector )
|
705
|
+
return matches.call( node, selector )
|
634
706
|
} else if ( bypassNodeType39 ) {
|
635
707
|
if ( /^[39]$/.test( node.nodeType )) return true
|
636
708
|
}
|
@@ -672,7 +744,7 @@ Fibre.fn = Fibre.prototype = {
|
|
672
744
|
}
|
673
745
|
|
674
746
|
if ( !context ) {
|
675
|
-
throw new Error( 'A context is required for Fibre to initialise.' )
|
747
|
+
throw new Error( 'A context is required for Fibre to initialise.' )
|
676
748
|
} else if ( context instanceof Node ) {
|
677
749
|
if ( context instanceof Document ) this.context = context.body || context
|
678
750
|
else this.context = context
|
@@ -748,23 +820,23 @@ Fibre.fn = Fibre.prototype = {
|
|
748
820
|
replace: function( regexp, newSubStr ) {
|
749
821
|
var it = this
|
750
822
|
it.finder.push(Finder( it.context, {
|
751
|
-
find: regexp,
|
823
|
+
find: regexp,
|
752
824
|
replace: newSubStr,
|
753
825
|
filterElements: function( currentNode ) {
|
754
826
|
return it.filterFn( currentNode )
|
755
|
-
},
|
827
|
+
},
|
756
828
|
forceContext: function( currentNode ) {
|
757
829
|
return it.boundaryFn( currentNode )
|
758
830
|
},
|
759
831
|
portionMode: it.portionMode
|
760
832
|
}))
|
761
|
-
return it
|
833
|
+
return it
|
762
834
|
},
|
763
835
|
|
764
836
|
wrap: function( regexp, strElemName ) {
|
765
837
|
var it = this
|
766
838
|
it.finder.push(Finder( it.context, {
|
767
|
-
find: regexp,
|
839
|
+
find: regexp,
|
768
840
|
wrap: strElemName,
|
769
841
|
filterElements: function( currentNode ) {
|
770
842
|
return it.filterFn( currentNode )
|
@@ -778,7 +850,7 @@ Fibre.fn = Fibre.prototype = {
|
|
778
850
|
},
|
779
851
|
|
780
852
|
revert: function( level ) {
|
781
|
-
var max = this.finder.length
|
853
|
+
var max = this.finder.length
|
782
854
|
var level = Number( level ) || ( level === 0 ? Number(0) :
|
783
855
|
( level === 'all' ? max : 1 ))
|
784
856
|
|
@@ -862,7 +934,7 @@ return Fibre
|
|
862
934
|
m.index += m[0].indexOf(cg)
|
863
935
|
m[0] = cg
|
864
936
|
}
|
865
|
-
|
937
|
+
|
866
938
|
m.endIndex = m.index + m[0].length
|
867
939
|
m.startIndex = m.index
|
868
940
|
m.index = mi
|
@@ -876,9 +948,9 @@ return Fibre
|
|
876
948
|
return true
|
877
949
|
}
|
878
950
|
|
879
|
-
/**
|
951
|
+
/**
|
880
952
|
* findAndReplaceDOMText
|
881
|
-
*
|
953
|
+
*
|
882
954
|
* Locates matches and replaces with replacementNode
|
883
955
|
*
|
884
956
|
* @param {Node} node Element or Text node to search within
|
@@ -1011,7 +1083,7 @@ return Fibre
|
|
1011
1083
|
if (!match[0]) {
|
1012
1084
|
throw new Error('findAndReplaceDOMText cannot handle zero-length matches')
|
1013
1085
|
}
|
1014
|
-
|
1086
|
+
|
1015
1087
|
match.endIndex = characterOffset + match.index + match[0].length
|
1016
1088
|
match.startIndex = characterOffset + match.index
|
1017
1089
|
match.index = matchIndex
|
@@ -1072,10 +1144,10 @@ return Fibre
|
|
1072
1144
|
} while (node = node.nextSibling)
|
1073
1145
|
return txt
|
1074
1146
|
}
|
1075
|
-
|
1147
|
+
|
1076
1148
|
},
|
1077
1149
|
|
1078
|
-
/**
|
1150
|
+
/**
|
1079
1151
|
* Steps through the target node, looking for matches, and
|
1080
1152
|
* calling replaceFn when a match is found.
|
1081
1153
|
*/
|
@@ -1141,7 +1213,7 @@ return Fibre
|
|
1141
1213
|
|
1142
1214
|
curNode = this.replaceMatch(match, startPortion, innerPortions, endPortion)
|
1143
1215
|
// processMatches has to return the node that replaced the endNode
|
1144
|
-
// and then we step back so we can continue from the end of the
|
1216
|
+
// and then we step back so we can continue from the end of the
|
1145
1217
|
// match:
|
1146
1218
|
|
1147
1219
|
atIndex -= (endPortion.node.data.length - endPortion.endIndexInNode)
|
@@ -1363,37 +1435,82 @@ return Fibre
|
|
1363
1435
|
|
1364
1436
|
);
|
1365
1437
|
|
1366
|
-
|
1367
|
-
|
1438
|
+
var isNodeNormalizeNormal = (function() {
|
1439
|
+
//// Disabled `Node.normalize()` for temp due to
|
1440
|
+
//// issue below in IE11.
|
1441
|
+
//// See: http://stackoverflow.com/questions/22337498/why-does-ie11-handle-node-normalize-incorrectly-for-the-minus-symbol
|
1442
|
+
var div = $.create( 'div' )
|
1368
1443
|
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
elem.innerHTML = portion.text
|
1373
|
-
elem.classList.add( 'portion' )
|
1444
|
+
div.appendChild($.create( '', '0-' ))
|
1445
|
+
div.appendChild($.create( '', '2' ))
|
1446
|
+
div.normalize()
|
1374
1447
|
|
1375
|
-
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1448
|
+
return div.firstChild.length !== 2
|
1449
|
+
})()
|
1450
|
+
|
1451
|
+
function getFuncOrElmt( obj ) {
|
1452
|
+
return (
|
1453
|
+
typeof obj === 'function' ||
|
1454
|
+
obj instanceof Element
|
1455
|
+
)
|
1456
|
+
? obj
|
1457
|
+
: undefined
|
1382
1458
|
}
|
1383
1459
|
|
1384
|
-
function
|
1385
|
-
var
|
1460
|
+
function createBDGroup( portion ) {
|
1461
|
+
var clazz = portion.index === 0 && portion.isEnd
|
1462
|
+
? 'biaodian cjk'
|
1463
|
+
: 'biaodian cjk portion ' + (
|
1464
|
+
portion.index === 0
|
1465
|
+
? 'is-first'
|
1466
|
+
: portion.isEnd
|
1467
|
+
? 'is-end'
|
1468
|
+
: 'is-inner'
|
1469
|
+
)
|
1470
|
+
|
1471
|
+
var $elmt = $.create( 'h-char-group', clazz )
|
1472
|
+
$elmt.innerHTML = portion.text
|
1473
|
+
return $elmt
|
1474
|
+
}
|
1475
|
+
|
1476
|
+
function createBDChar( char ) {
|
1477
|
+
var div = $.create( 'div' )
|
1386
1478
|
var unicode = char.charCodeAt( 0 ).toString( 16 )
|
1387
|
-
var clazz = 'biaodian cjk ' + ( char.match( TYPESET.char.biaodian.open ) ? 'bd-open' :
|
1388
|
-
char.match( TYPESET.char.biaodian.close ) ? 'bd-close bd-end' :
|
1389
|
-
char.match( TYPESET.char.biaodian.end ) ? 'bd-end' :
|
1390
|
-
char.match( new RegExp( '(' + UNICODE.biaodian.liga + ')' )) ? 'bd-liga' : '' )
|
1391
1479
|
|
1392
|
-
div.innerHTML =
|
1480
|
+
div.innerHTML = (
|
1481
|
+
'<h-char unicode="' + unicode +
|
1482
|
+
'" class="biaodian cjk ' + getBDType( char ) +
|
1483
|
+
'">' + char + '</h-char>'
|
1484
|
+
)
|
1393
1485
|
return div.firstChild
|
1394
1486
|
}
|
1395
1487
|
|
1488
|
+
function getBDType( char ) {
|
1489
|
+
return char.match( TYPESET.char.biaodian.open )
|
1490
|
+
? 'bd-open'
|
1491
|
+
: char.match( TYPESET.char.biaodian.close )
|
1492
|
+
? 'bd-close bd-end'
|
1493
|
+
: char.match( TYPESET.char.biaodian.end )
|
1494
|
+
? (
|
1495
|
+
/(?:\u3001|\u3002|\uff0c)/i.test( char )
|
1496
|
+
? 'bd-end bd-cop'
|
1497
|
+
: 'bd-end'
|
1498
|
+
)
|
1499
|
+
: char.match(new RegExp( UNICODE.biaodian.liga ))
|
1500
|
+
? 'bd-liga'
|
1501
|
+
: char.match(new RegExp( UNICODE.biaodian.middle ))
|
1502
|
+
? 'bd-middle'
|
1503
|
+
: ''
|
1504
|
+
}
|
1505
|
+
|
1396
1506
|
$.extend( Fibre.fn, {
|
1507
|
+
normalize: function() {
|
1508
|
+
if ( isNodeNormalizeNormal ) {
|
1509
|
+
this.context.normalize()
|
1510
|
+
}
|
1511
|
+
return this
|
1512
|
+
},
|
1513
|
+
|
1397
1514
|
// Force punctuation & biaodian typesetting rules to be applied.
|
1398
1515
|
jinzify: function( selector ) {
|
1399
1516
|
return (
|
@@ -1449,33 +1566,34 @@ $.extend( Fibre.fn, {
|
|
1449
1566
|
western: false // Includes Latin, Greek and Cyrillic
|
1450
1567
|
}, option || {})
|
1451
1568
|
|
1452
|
-
this.avoid( 'h-
|
1569
|
+
this.avoid( 'h-word, h-char-group' )
|
1453
1570
|
|
1454
1571
|
if ( option.biaodian ) {
|
1455
1572
|
this.replace(
|
1456
|
-
TYPESET.group.biaodian[
|
1573
|
+
TYPESET.group.biaodian[0], createBDGroup
|
1457
1574
|
).replace(
|
1458
|
-
TYPESET.group.biaodian[
|
1575
|
+
TYPESET.group.biaodian[1], createBDGroup
|
1459
1576
|
)
|
1460
1577
|
}
|
1578
|
+
|
1461
1579
|
if ( option.hanzi || option.cjk ) {
|
1462
1580
|
this.wrap(
|
1463
|
-
TYPESET.group.hanzi, $.clone(
|
1581
|
+
TYPESET.group.hanzi, $.clone($.create( 'h-char-group', 'hanzi cjk' ))
|
1464
1582
|
)
|
1465
1583
|
}
|
1466
1584
|
if ( option.western ) {
|
1467
1585
|
this.wrap(
|
1468
|
-
TYPESET.group.western, $.clone(
|
1586
|
+
TYPESET.group.western, $.clone($.create( 'h-word', 'western' ))
|
1469
1587
|
)
|
1470
1588
|
}
|
1471
1589
|
if ( option.kana ) {
|
1472
1590
|
this.wrap(
|
1473
|
-
TYPESET.group.kana, $.clone(
|
1591
|
+
TYPESET.group.kana, $.clone($.create( 'h-char-group', 'kana' ))
|
1474
1592
|
)
|
1475
1593
|
}
|
1476
1594
|
if ( option.eonmun || option.hangul ) {
|
1477
1595
|
this.wrap(
|
1478
|
-
TYPESET.group.eonmun, $.clone(
|
1596
|
+
TYPESET.group.eonmun, $.clone($.create( 'h-word', 'eonmun hangul' ))
|
1479
1597
|
)
|
1480
1598
|
}
|
1481
1599
|
|
@@ -1485,6 +1603,7 @@ $.extend( Fibre.fn, {
|
|
1485
1603
|
|
1486
1604
|
charify: function( option ) {
|
1487
1605
|
var option = $.extend({
|
1606
|
+
avoid: true,
|
1488
1607
|
biaodian: false,
|
1489
1608
|
punct: false,
|
1490
1609
|
hanzi: false, // Includes Kana
|
@@ -1495,50 +1614,77 @@ $.extend( Fibre.fn, {
|
|
1495
1614
|
eonmun: false
|
1496
1615
|
}, option || {})
|
1497
1616
|
|
1498
|
-
|
1617
|
+
if ( option.avoid ) {
|
1618
|
+
this.avoid( 'h-char' )
|
1619
|
+
}
|
1499
1620
|
|
1500
1621
|
if ( option.biaodian ) {
|
1501
1622
|
this.replace(
|
1502
1623
|
TYPESET.char.biaodian.all,
|
1503
|
-
|
1624
|
+
getFuncOrElmt( option.biaodian )
|
1625
|
+
||
|
1626
|
+
function( portion ) { return createBDChar( portion.text ) }
|
1504
1627
|
).replace(
|
1505
1628
|
TYPESET.char.biaodian.liga,
|
1506
|
-
|
1629
|
+
getFuncOrElmt( option.biaodian )
|
1630
|
+
||
|
1631
|
+
function( portion ) { return createBDChar( portion.text ) }
|
1507
1632
|
)
|
1508
1633
|
}
|
1509
1634
|
if ( option.hanzi || option.cjk ) {
|
1510
1635
|
this.wrap(
|
1511
|
-
TYPESET.char.hanzi,
|
1636
|
+
TYPESET.char.hanzi,
|
1637
|
+
getFuncOrElmt( option.hanzi || option.cjk )
|
1638
|
+
||
|
1639
|
+
$.clone($.create( 'h-char', 'hanzi cjk' ))
|
1512
1640
|
)
|
1513
1641
|
}
|
1514
1642
|
if ( option.punct ) {
|
1515
1643
|
this.wrap(
|
1516
|
-
TYPESET.char.punct.all,
|
1644
|
+
TYPESET.char.punct.all,
|
1645
|
+
getFuncOrElmt( option.punct )
|
1646
|
+
||
|
1647
|
+
$.clone($.create( 'h-char', 'punct' ))
|
1517
1648
|
)
|
1518
1649
|
}
|
1519
1650
|
if ( option.latin ) {
|
1520
1651
|
this.wrap(
|
1521
|
-
TYPESET.char.latin,
|
1652
|
+
TYPESET.char.latin,
|
1653
|
+
getFuncOrElmt( option.latin )
|
1654
|
+
||
|
1655
|
+
$.clone($.create( 'h-char', 'alphabet latin' ))
|
1522
1656
|
)
|
1523
1657
|
}
|
1524
1658
|
if ( option.ellinika || option.greek ) {
|
1525
1659
|
this.wrap(
|
1526
|
-
TYPESET.char.ellinika,
|
1660
|
+
TYPESET.char.ellinika,
|
1661
|
+
getFuncOrElmt( option.ellinika || option.greek )
|
1662
|
+
||
|
1663
|
+
$.clone($.create( 'h-char', 'alphabet ellinika greek' ))
|
1527
1664
|
)
|
1528
1665
|
}
|
1529
1666
|
if ( option.kirillica || option.cyrillic ) {
|
1530
1667
|
this.wrap(
|
1531
|
-
TYPESET.char.kirillica,
|
1668
|
+
TYPESET.char.kirillica,
|
1669
|
+
getFuncOrElmt( option.kirillica || option.cyrillic )
|
1670
|
+
||
|
1671
|
+
$.clone($.create( 'h-char', 'alphabet kirillica cyrillic' ))
|
1532
1672
|
)
|
1533
1673
|
}
|
1534
1674
|
if ( option.kana ) {
|
1535
1675
|
this.wrap(
|
1536
|
-
TYPESET.char.kana,
|
1676
|
+
TYPESET.char.kana,
|
1677
|
+
getFuncOrElmt( option.kana )
|
1678
|
+
||
|
1679
|
+
$.clone($.create( 'h-char', 'kana' ))
|
1537
1680
|
)
|
1538
1681
|
}
|
1539
1682
|
if ( option.eonmun || option.hangul ) {
|
1540
1683
|
this.wrap(
|
1541
|
-
TYPESET.char.eonmun,
|
1684
|
+
TYPESET.char.eonmun,
|
1685
|
+
getFuncOrElmt( option.eonmun || option.hangul )
|
1686
|
+
||
|
1687
|
+
$.clone($.create( 'h-char', 'eonmun hangul' ))
|
1542
1688
|
)
|
1543
1689
|
}
|
1544
1690
|
|
@@ -1547,7 +1693,14 @@ $.extend( Fibre.fn, {
|
|
1547
1693
|
}
|
1548
1694
|
})
|
1549
1695
|
|
1550
|
-
Han
|
1696
|
+
$.extend( Han, {
|
1697
|
+
isNodeNormalizeNormal: isNodeNormalizeNormal,
|
1698
|
+
find: Fibre,
|
1699
|
+
createBDGroup: createBDGroup,
|
1700
|
+
createBDChar: createBDChar
|
1701
|
+
})
|
1702
|
+
|
1703
|
+
$.matches = Han.find.matches
|
1551
1704
|
|
1552
1705
|
void [
|
1553
1706
|
'setMode',
|
@@ -2021,7 +2174,7 @@ function createNormalRu( $rb, $rt, attr ) {
|
|
2021
2174
|
if ( Array.isArray( $rb )) {
|
2022
2175
|
$ru.innerHTML = $rb.map(function( rb ) {
|
2023
2176
|
if ( typeof rb === 'undefined' ) return ''
|
2024
|
-
return rb.outerHTML
|
2177
|
+
return rb.outerHTML
|
2025
2178
|
}).join('') + $rt.outerHTML
|
2026
2179
|
} else {
|
2027
2180
|
$ru.appendChild( $.clone( $rb ))
|
@@ -2131,32 +2284,34 @@ $.extend( Locale, {
|
|
2131
2284
|
this.renderEm( context )
|
2132
2285
|
},
|
2133
2286
|
|
2134
|
-
|
2135
|
-
|
2136
|
-
|
2287
|
+
// Traverse all target elements and address
|
2288
|
+
// presentational corrections if any two of
|
2289
|
+
// them are adjacent to each other.
|
2137
2290
|
renderDecoLine: function( context, target ) {
|
2138
|
-
var target = target || 'u, ins'
|
2139
|
-
var
|
2140
|
-
|
2141
|
-
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2146
|
-
//
|
2147
|
-
|
2148
|
-
|
2149
|
-
|
2150
|
-
|
2151
|
-
|
2152
|
-
|
2153
|
-
|
2154
|
-
|
2155
|
-
|
2291
|
+
var $$target = $.qsa( target || 'u, ins', context )
|
2292
|
+
var i = $$target.length
|
2293
|
+
|
2294
|
+
traverse: while ( i-- ) {
|
2295
|
+
var $this = $$target[ i ]
|
2296
|
+
var $prev = null
|
2297
|
+
|
2298
|
+
// Ignore all `<wbr>` and comments in between,
|
2299
|
+
// and add class `.adjacent` once two targets
|
2300
|
+
// are next to each other.
|
2301
|
+
ignore: do {
|
2302
|
+
$prev = ( $prev || $this ).previousSibling
|
2303
|
+
|
2304
|
+
if ( !$prev ) {
|
2305
|
+
continue traverse
|
2306
|
+
} else if ( $$target[ i-1 ] === $prev ) {
|
2307
|
+
$this.classList.add( 'adjacent' )
|
2308
|
+
}
|
2309
|
+
} while ( $.isIgnorable( $prev ))
|
2310
|
+
}
|
2156
2311
|
},
|
2157
2312
|
|
2158
|
-
// Traverse target elements to render
|
2159
|
-
//
|
2313
|
+
// Traverse all target elements to render
|
2314
|
+
// emphasis marks.
|
2160
2315
|
renderEm: function( context, target ) {
|
2161
2316
|
var method = target ? 'qsa' : 'tag'
|
2162
2317
|
var target = target || 'em'
|
@@ -2168,13 +2323,13 @@ $.extend( Locale, {
|
|
2168
2323
|
|
2169
2324
|
if ( Locale.support.textemphasis ) {
|
2170
2325
|
$elem
|
2171
|
-
.avoid( 'rt, h-char
|
2326
|
+
.avoid( 'rt, h-char' )
|
2172
2327
|
.charify({ biaodian: true, punct: true })
|
2173
2328
|
} else {
|
2174
2329
|
$elem
|
2175
2330
|
.avoid( 'rt, h-char, h-char-group' )
|
2176
2331
|
.jinzify()
|
2177
|
-
.groupify({ western: true
|
2332
|
+
.groupify({ western: true })
|
2178
2333
|
.charify({
|
2179
2334
|
hanzi: true,
|
2180
2335
|
biaodian: true,
|
@@ -2229,101 +2384,160 @@ $.extend( Han.support, {
|
|
2229
2384
|
// 'fangsong-gb': Han.detectFont( '"Han Fangsong GB"' )
|
2230
2385
|
})
|
2231
2386
|
|
2232
|
-
|
2387
|
+
Han.correctBiaodian = function( context ) {
|
2388
|
+
var context = context || document
|
2389
|
+
var finder = Han.find( context )
|
2233
2390
|
|
2234
|
-
|
2235
|
-
|
2236
|
-
|
2237
|
-
var
|
2238
|
-
|
2391
|
+
finder
|
2392
|
+
.avoid( 'h-char' )
|
2393
|
+
.replace( /([‘“])/g, function( portion ) {
|
2394
|
+
var $char = Han.createBDChar( portion.text )
|
2395
|
+
$char.classList.add( 'bd-open', 'punct' )
|
2396
|
+
return $char
|
2397
|
+
})
|
2398
|
+
.replace( /([’”])/g, function( portion ) {
|
2399
|
+
var $char = Han.createBDChar( portion.text )
|
2400
|
+
$char.classList.add( 'bd-close', 'bd-end', 'punct' )
|
2401
|
+
return $char
|
2402
|
+
})
|
2239
2403
|
|
2240
|
-
|
2241
|
-
|
2242
|
-
|
2404
|
+
return Han.support.unicoderange
|
2405
|
+
? finder
|
2406
|
+
: finder.charify({ biaodian: true })
|
2407
|
+
}
|
2243
2408
|
|
2244
|
-
|
2245
|
-
|
2409
|
+
Han.correctBasicBD = Han.correctBiaodian
|
2410
|
+
Han.correctBD = Han.correctBiaodian
|
2246
2411
|
|
2247
|
-
|
2248
|
-
|
2249
|
-
hws.innerHTML = ' '
|
2412
|
+
$.extend( Han.fn, {
|
2413
|
+
biaodian: null,
|
2250
2414
|
|
2251
|
-
|
2252
|
-
|
2415
|
+
correctBiaodian: function() {
|
2416
|
+
this.biaodian = Han.correctBiaodian( this.context )
|
2417
|
+
return this
|
2418
|
+
},
|
2253
2419
|
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2420
|
+
revertCorrectedBiaodian: function() {
|
2421
|
+
try {
|
2422
|
+
this.biaodian.revert( 'all' )
|
2423
|
+
} catch (e) {}
|
2424
|
+
return this
|
2425
|
+
}
|
2426
|
+
})
|
2258
2427
|
|
2259
|
-
|
2260
|
-
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2428
|
+
// Legacy support (deprecated):
|
2429
|
+
Han.fn.correctBasicBD = Han.fn.correctBiaodian
|
2430
|
+
Han.fn.revertBasicBD = Han.fn.revertCorrectedBiaodian
|
2431
|
+
|
2432
|
+
var hws = '<<hws>>'
|
2433
|
+
|
2434
|
+
var $hws = $.create( 'h-hws' )
|
2435
|
+
$hws.setAttribute( 'hidden', '' )
|
2436
|
+
$hws.innerHTML = ' '
|
2437
|
+
|
2438
|
+
function sharingSameParent( $a, $b ) {
|
2439
|
+
return $a && $b && $a.parentNode === $b.parentNode
|
2440
|
+
}
|
2441
|
+
|
2442
|
+
function properlyPlaceHWSBehind( $node, text ) {
|
2443
|
+
var $elmt = $node
|
2444
|
+
var text = text || ''
|
2445
|
+
|
2446
|
+
if (
|
2447
|
+
$.isElmt( $node.nextSibling ) ||
|
2448
|
+
sharingSameParent( $node, $node.nextSibling )
|
2449
|
+
) {
|
2450
|
+
return text + hws
|
2451
|
+
} else {
|
2452
|
+
// One of the parental elements of the current text
|
2453
|
+
// node would definitely have a next sibling, since
|
2454
|
+
// it is of the first portion and not `isEnd`.
|
2455
|
+
while ( !$elmt.nextSibling ) {
|
2456
|
+
$elmt = $elmt.parentNode
|
2457
|
+
}
|
2458
|
+
if ( $node !== $elmt ) {
|
2459
|
+
$elmt.insertAdjacentHTML( 'afterEnd', '<h-hws hidden> </h-hws>' )
|
2265
2460
|
}
|
2461
|
+
}
|
2462
|
+
return text
|
2463
|
+
}
|
2266
2464
|
|
2267
|
-
|
2268
|
-
|
2269
|
-
|
2465
|
+
function firstStepLabel( portion, mat ) {
|
2466
|
+
return portion.isEnd && portion.index === 0
|
2467
|
+
? mat[1] + hws + mat[2]
|
2468
|
+
: portion.index === 0
|
2469
|
+
? properlyPlaceHWSBehind( portion.node, portion.text )
|
2470
|
+
: portion.text
|
2471
|
+
}
|
2270
2472
|
|
2271
|
-
|
2272
|
-
|
2473
|
+
function real$hwsElmt( portion ) {
|
2474
|
+
return portion.index === 0
|
2475
|
+
? $.clone( $hws )
|
2476
|
+
: ''
|
2477
|
+
}
|
2273
2478
|
|
2274
|
-
|
2275
|
-
// See: https://github.com/ethantw/Han/issues/59
|
2276
|
-
.replace( /<hws\/>([‘“]+)/ig, '$1' )
|
2277
|
-
.replace( /([’”]+)<hws\/>/ig, '$1' )
|
2479
|
+
var last$hwsIdx
|
2278
2480
|
|
2279
|
-
|
2280
|
-
|
2281
|
-
return $.clone( hws )
|
2282
|
-
})
|
2481
|
+
function apostrophe( portion ) {
|
2482
|
+
var $elmt = portion.node.parentNode
|
2283
2483
|
|
2284
|
-
|
2285
|
-
|
2286
|
-
|
2287
|
-
.qsa( QUERY_HWS_AS_FIRST_CHILD, context )
|
2288
|
-
.forEach(function( firstChild ) {
|
2289
|
-
var parent = firstChild.parentNode
|
2290
|
-
var target = parent.firstChild
|
2291
|
-
|
2292
|
-
// Skip all `<wbr>` and comments
|
2293
|
-
while ( $.isIgnorable( target )) {
|
2294
|
-
target = target.nextSibling
|
2295
|
-
|
2296
|
-
if ( !target ) return
|
2297
|
-
}
|
2484
|
+
if ( portion.index === 0 ) {
|
2485
|
+
last$hwsIdx = portion.endIndexInNode-2
|
2486
|
+
}
|
2298
2487
|
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2488
|
+
if (
|
2489
|
+
$elmt.nodeName.toLowerCase() === 'h-hws' && (
|
2490
|
+
portion.index === 1 || portion.indexInMatch === last$hwsIdx
|
2491
|
+
)) {
|
2492
|
+
$elmt.classList.add( 'quote-inner' )
|
2493
|
+
}
|
2494
|
+
return portion.text
|
2495
|
+
}
|
2306
2496
|
|
2307
|
-
|
2308
|
-
|
2497
|
+
function curveQuote( portion ) {
|
2498
|
+
var $elmt = portion.node.parentNode
|
2309
2499
|
|
2310
|
-
|
2311
|
-
|
2312
|
-
|
2500
|
+
if ( $elmt.nodeName.toLowerCase() === 'h-hws' ) {
|
2501
|
+
$elmt.classList.add( 'quote-outer' )
|
2502
|
+
}
|
2503
|
+
return portion.text
|
2504
|
+
}
|
2313
2505
|
|
2314
|
-
|
2315
|
-
|
2316
|
-
|
2317
|
-
|
2318
|
-
|
2319
|
-
|
2320
|
-
|
2321
|
-
})
|
2506
|
+
$.extend( Han, {
|
2507
|
+
renderHWS: function( context, strict ) {
|
2508
|
+
// Elements to be filtered according to the
|
2509
|
+
// HWS rendering mode.
|
2510
|
+
var AVOID = strict
|
2511
|
+
? 'textarea, code, kbd, samp, pre'
|
2512
|
+
: 'textarea'
|
2322
2513
|
|
2323
|
-
|
2324
|
-
|
2325
|
-
|
2326
|
-
|
2514
|
+
var mode = strict ? 'strict' : 'base'
|
2515
|
+
var context = context || document
|
2516
|
+
var finder = Han.find( context )
|
2517
|
+
|
2518
|
+
finder
|
2519
|
+
.avoid( AVOID )
|
2520
|
+
|
2521
|
+
// Basic situations:
|
2522
|
+
// - 字a => 字<hws/>a
|
2523
|
+
// - A字 => A<hws/>字
|
2524
|
+
.replace( Han.TYPESET.hws[ mode ][0], firstStepLabel )
|
2525
|
+
.replace( Han.TYPESET.hws[ mode ][1], firstStepLabel )
|
2526
|
+
|
2527
|
+
// Convert text nodes `<hws/>` into real element nodes:
|
2528
|
+
.replace( new RegExp( '(' + hws + ')+', 'g' ), real$hwsElmt )
|
2529
|
+
|
2530
|
+
// Deal with:
|
2531
|
+
// - '<hws/>字<hws/>' => '字'
|
2532
|
+
// - "<hws/>字<hws/>" => "字"
|
2533
|
+
.replace( /([\'"])\s(.+?)\s\1/g, apostrophe )
|
2534
|
+
|
2535
|
+
// Deal with:
|
2536
|
+
// - <hws/>“字”<hws/>
|
2537
|
+
// - <hws/>‘字’<hws/>
|
2538
|
+
.replace( /\s[‘“]/g, curveQuote )
|
2539
|
+
.replace( /[’”]\s/g, curveQuote )
|
2540
|
+
.normalize()
|
2327
2541
|
|
2328
2542
|
// Return the finder instance for future usage
|
2329
2543
|
return finder
|
@@ -2331,23 +2545,27 @@ $.extend( Han, {
|
|
2331
2545
|
})
|
2332
2546
|
|
2333
2547
|
$.extend( Han.fn, {
|
2334
|
-
HWS: null,
|
2335
|
-
|
2336
2548
|
renderHWS: function( strict ) {
|
2337
2549
|
Han.renderHWS( this.context, strict )
|
2338
|
-
|
2339
|
-
this.HWS = $.tag( 'h-hws', this.context )
|
2340
2550
|
return this
|
2341
2551
|
},
|
2342
2552
|
|
2343
2553
|
revertHWS: function() {
|
2344
|
-
|
2554
|
+
$.tag( 'h-hws', this.context )
|
2555
|
+
.forEach(function( hws ) {
|
2345
2556
|
$.remove( hws )
|
2346
2557
|
})
|
2558
|
+
this.HWS = []
|
2347
2559
|
return this
|
2348
2560
|
}
|
2349
2561
|
})
|
2350
2562
|
|
2563
|
+
var HANGABLE_CLASS = 'bd-hangable'
|
2564
|
+
var HANGABLE_AVOID = 'h-char.bd-hangable'
|
2565
|
+
var HANGABLE_CS_HTML = '<h-cs hidden class="jinze-outer hangable-outer"> </h-cs>'
|
2566
|
+
|
2567
|
+
var matches = Han.find.matches
|
2568
|
+
|
2351
2569
|
function detectSpaceFont() {
|
2352
2570
|
var div = $.create( 'div' )
|
2353
2571
|
var ret
|
@@ -2355,144 +2573,253 @@ function detectSpaceFont() {
|
|
2355
2573
|
div.innerHTML = '<span>a b</span><span style="font-family: \'Han Space\'">a b</span>'
|
2356
2574
|
body.appendChild( div )
|
2357
2575
|
ret = div.firstChild.offsetWidth !== div.lastChild.offsetWidth
|
2358
|
-
$.remove( div
|
2576
|
+
$.remove( div )
|
2359
2577
|
return ret
|
2360
2578
|
}
|
2361
2579
|
|
2580
|
+
function insertHangableCS( $jinze ) {
|
2581
|
+
var $cs = $jinze.nextSibling
|
2582
|
+
|
2583
|
+
if ( $cs && matches( $cs, 'h-cs.jinze-outer' )) {
|
2584
|
+
$cs.classList.add( 'hangable-outer' )
|
2585
|
+
} else {
|
2586
|
+
$jinze.insertAdjacentHTML(
|
2587
|
+
'afterend',
|
2588
|
+
HANGABLE_CS_HTML
|
2589
|
+
)
|
2590
|
+
}
|
2591
|
+
}
|
2592
|
+
|
2593
|
+
Han.support['han-space'] = detectSpaceFont()
|
2594
|
+
|
2362
2595
|
$.extend( Han, {
|
2363
2596
|
detectSpaceFont: detectSpaceFont,
|
2364
|
-
isSpaceFontLoaded: detectSpaceFont()
|
2365
|
-
})
|
2597
|
+
isSpaceFontLoaded: detectSpaceFont(),
|
2366
2598
|
|
2367
|
-
|
2599
|
+
renderHanging: function( context ) {
|
2600
|
+
var context = context || document
|
2601
|
+
var finder = Han.find( context )
|
2368
2602
|
|
2369
|
-
|
2370
|
-
|
2371
|
-
|
2603
|
+
finder
|
2604
|
+
.avoid( 'textarea, code, kbd, samp, pre' )
|
2605
|
+
.avoid( HANGABLE_AVOID )
|
2606
|
+
.replace(
|
2607
|
+
TYPESET.jinze.hanging,
|
2608
|
+
function( portion ) {
|
2609
|
+
if ( /^[\x20\t\r\n\f]+$/.test( portion.text )) {
|
2610
|
+
return ''
|
2611
|
+
}
|
2372
2612
|
|
2373
|
-
|
2374
|
-
|
2375
|
-
.replace(
|
2376
|
-
TYPESET.jinze.hanging,
|
2377
|
-
function( portion, match ) {
|
2378
|
-
var elem = $.create( 'h-hangable' )
|
2379
|
-
elem.innerHTML = match[1] + '<h-cs><h-inner hidden> </h-inner><h-char class="biaodian bd-close bd-end cjk">' + match[2] + '</h-char></h-cs>'
|
2380
|
-
return portion.index === 0 ? elem : ''
|
2381
|
-
}
|
2382
|
-
)
|
2613
|
+
var $elmt = portion.node.parentNode
|
2614
|
+
var $jinze, $new, $bd, biaodian
|
2383
2615
|
|
2384
|
-
|
2385
|
-
|
2616
|
+
if ( $jinze = $.parent( $elmt, 'h-jinze' )) {
|
2617
|
+
insertHangableCS( $jinze )
|
2618
|
+
}
|
2386
2619
|
|
2387
|
-
|
2388
|
-
hanging: null,
|
2620
|
+
biaodian = portion.text.trim()
|
2389
2621
|
|
2390
|
-
|
2391
|
-
|
2392
|
-
|
2622
|
+
$new = Han.createBDChar( biaodian )
|
2623
|
+
$new.innerHTML = '<h-inner>' + biaodian + '</h-inner>'
|
2624
|
+
$new.classList.add( HANGABLE_CLASS )
|
2625
|
+
|
2626
|
+
$bd = $.parent( $elmt, 'h-char.biaodian' )
|
2627
|
+
|
2628
|
+
return !$bd
|
2629
|
+
? $new
|
2630
|
+
: (function() {
|
2631
|
+
$bd.classList.add( HANGABLE_CLASS )
|
2632
|
+
|
2633
|
+
return matches( $elmt, 'h-inner, h-inner *' )
|
2634
|
+
? biaodian
|
2635
|
+
: $new.firstChild
|
2636
|
+
})()
|
2637
|
+
}
|
2638
|
+
)
|
2639
|
+
return finder
|
2640
|
+
}
|
2641
|
+
})
|
2393
2642
|
|
2394
|
-
|
2395
|
-
|
2396
|
-
|
2643
|
+
$.extend( Han.fn, {
|
2644
|
+
renderHanging: function() {
|
2645
|
+
var classList = this.condition.classList
|
2646
|
+
Han.isSpaceFontLoaded = detectSpaceFont()
|
2647
|
+
|
2648
|
+
if (
|
2649
|
+
Han.isSpaceFontLoaded &&
|
2650
|
+
classList.contains( 'no-han-space' )
|
2651
|
+
) {
|
2652
|
+
classList.remove( 'no-han-space' )
|
2653
|
+
classList.add( 'han-space' )
|
2397
2654
|
}
|
2398
2655
|
|
2399
|
-
|
2656
|
+
Han.renderHanging( this.context )
|
2400
2657
|
return this
|
2401
2658
|
},
|
2402
2659
|
|
2403
2660
|
revertHanging: function() {
|
2404
|
-
|
2405
|
-
|
2406
|
-
|
2661
|
+
$.qsa(
|
2662
|
+
'h-char.bd-hangable, h-cs.hangable-outer',
|
2663
|
+
this.context
|
2664
|
+
).forEach(function( $elmt ) {
|
2665
|
+
var classList = $elmt.classList
|
2666
|
+
classList.remove( 'bd-hangable' )
|
2667
|
+
classList.remove( 'hangable-outer' )
|
2668
|
+
})
|
2407
2669
|
return this
|
2408
2670
|
}
|
2409
2671
|
})
|
2410
2672
|
|
2411
|
-
|
2412
|
-
|
2413
|
-
|
2673
|
+
var JIYA_CLASS = 'bd-jiya'
|
2674
|
+
var JIYA_AVOID = 'h-char.bd-jiya'
|
2675
|
+
var CONSECUTIVE_CLASS = 'bd-consecutive'
|
2676
|
+
var JIYA_CS_HTML = '<h-cs hidden class="jinze-outer jiya-outer"> </h-cs>'
|
2414
2677
|
|
2415
|
-
|
2416
|
-
.avoid( 'textarea, code, kbd, samp, pre, h-char-group' )
|
2417
|
-
.replace(
|
2418
|
-
// This is a safeguard against hanging rendering
|
2419
|
-
new RegExp( '(' + UNICODE.biaodian.end + '+)(' + UNICODE.biaodian.open + '+)', 'g' ),
|
2420
|
-
function( portion, match ) {
|
2421
|
-
if ( portion.index === 0 ) return portion.isEnd ? match[0] : match[1]
|
2422
|
-
|
2423
|
-
var elem = $.create( 'h-char-group', 'biaodian cjk portion' )
|
2424
|
-
elem.innerHTML = match[2]
|
2425
|
-
return elem
|
2426
|
-
}
|
2427
|
-
)
|
2428
|
-
.endAvoid()
|
2678
|
+
var matches = Han.find.matches
|
2429
2679
|
|
2430
|
-
|
2431
|
-
.
|
2432
|
-
|
2433
|
-
.
|
2434
|
-
|
2435
|
-
// The reason we're doing this instead of using pseudo elements in CSS
|
2436
|
-
// is because WebKit has problem rendering pseudo elements containing only
|
2437
|
-
// space.
|
2438
|
-
$.qsa( 'h-char.biaodian.bd-open, h-char.biaodian.bd-end', context )
|
2439
|
-
.forEach(function( elem ) {
|
2440
|
-
if ( Han.find.matches( elem, 'h-cs *' )) return
|
2441
|
-
var html = '<h-inner>' + elem.innerHTML + '</h-inner>'
|
2442
|
-
var hcs = '<h-cs hidden> </h-cs>'
|
2443
|
-
var isOpen = elem.classList.contains( 'bd-open' )
|
2444
|
-
elem.innerHTML = isOpen ? hcs + html : html + hcs
|
2445
|
-
})
|
2680
|
+
function trimBDClass( clazz ) {
|
2681
|
+
return clazz.replace(
|
2682
|
+
/(biaodian|cjk|bd-jiya|bd-consecutive|bd-hangable)/gi, ''
|
2683
|
+
).trim()
|
2684
|
+
}
|
2446
2685
|
|
2447
|
-
|
2686
|
+
function charifyBiaodian( portion ) {
|
2687
|
+
var biaodian = portion.text
|
2688
|
+
var $elmt = portion.node.parentNode
|
2689
|
+
var $bd = $.parent( $elmt, 'h-char.biaodian' )
|
2690
|
+
var $new = Han.createBDChar( biaodian )
|
2691
|
+
var $jinze
|
2692
|
+
|
2693
|
+
$new.innerHTML = '<h-inner>' + biaodian + '</h-inner>'
|
2694
|
+
$new.classList.add( JIYA_CLASS )
|
2695
|
+
|
2696
|
+
if ( $jinze = $.parent( $elmt, 'h-jinze' )) {
|
2697
|
+
insertJiyaCS( $jinze )
|
2698
|
+
}
|
2699
|
+
|
2700
|
+
return !$bd
|
2701
|
+
? $new
|
2702
|
+
: (function() {
|
2703
|
+
$bd.classList.add( JIYA_CLASS )
|
2704
|
+
|
2705
|
+
return matches( $elmt, 'h-inner, h-inner *' )
|
2706
|
+
? biaodian
|
2707
|
+
: $new.firstChild
|
2708
|
+
})()
|
2448
2709
|
}
|
2449
2710
|
|
2450
|
-
|
2451
|
-
jiya: null,
|
2711
|
+
var prevBDType, $$prevCS
|
2452
2712
|
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2713
|
+
function locateConsecutiveBD( portion ) {
|
2714
|
+
var prev = prevBDType
|
2715
|
+
var $elmt = portion.node.parentNode
|
2716
|
+
var $bd = $.parent( $elmt, 'h-char.biaodian' )
|
2717
|
+
var $jinze = $.parent( $bd, 'h-jinze' )
|
2718
|
+
var classList
|
2457
2719
|
|
2458
|
-
|
2459
|
-
|
2460
|
-
|
2461
|
-
|
2462
|
-
|
2720
|
+
classList = $bd.classList
|
2721
|
+
|
2722
|
+
if ( prev ) {
|
2723
|
+
$bd.setAttribute( 'prev', prev )
|
2724
|
+
}
|
2725
|
+
|
2726
|
+
if ( $$prevCS && classList.contains( 'bd-open' )) {
|
2727
|
+
$$prevCS.pop().setAttribute( 'next', 'bd-open' )
|
2463
2728
|
}
|
2464
|
-
})
|
2465
2729
|
|
2466
|
-
|
2730
|
+
$$prevCS = undefined
|
2467
2731
|
|
2468
|
-
|
2469
|
-
|
2732
|
+
if ( portion.isEnd ) {
|
2733
|
+
prevBDType = undefined
|
2734
|
+
classList.add( CONSECUTIVE_CLASS, 'end-portion' )
|
2735
|
+
} else {
|
2736
|
+
prevBDType = trimBDClass($bd.getAttribute( 'class' ))
|
2737
|
+
classList.add( CONSECUTIVE_CLASS )
|
2738
|
+
}
|
2470
2739
|
|
2471
|
-
|
2472
|
-
|
2740
|
+
if ( $jinze ) {
|
2741
|
+
$$prevCS = locateCS( $jinze, {
|
2742
|
+
prev: prev,
|
2743
|
+
'class': trimBDClass($bd.getAttribute( 'class' ))
|
2744
|
+
})
|
2745
|
+
}
|
2746
|
+
return portion.text
|
2747
|
+
}
|
2473
2748
|
|
2474
|
-
|
2475
|
-
|
2749
|
+
function insertJiyaCS( $jinze ) {
|
2750
|
+
if (
|
2751
|
+
matches( $jinze, '.tou, .touwei' ) &&
|
2752
|
+
!matches( $jinze.previousSibling, 'h-cs.jiya-outer' )
|
2753
|
+
) {
|
2754
|
+
$jinze.insertAdjacentHTML( 'beforebegin', JIYA_CS_HTML )
|
2755
|
+
}
|
2756
|
+
if (
|
2757
|
+
matches( $jinze, '.wei, .touwei' ) &&
|
2758
|
+
!matches( $jinze.nextSibling, 'h-cs.jiya-outer' )
|
2759
|
+
) {
|
2760
|
+
$jinze.insertAdjacentHTML( 'afterend', JIYA_CS_HTML )
|
2761
|
+
}
|
2762
|
+
}
|
2763
|
+
|
2764
|
+
function locateCS( $jinze, attr ) {
|
2765
|
+
var $prev, $next
|
2766
|
+
|
2767
|
+
if (matches( $jinze, '.tou, .touwei' )) {
|
2768
|
+
$prev = $jinze.previousSibling
|
2769
|
+
|
2770
|
+
if (matches( $prev, 'h-cs' )) {
|
2771
|
+
$prev.className = 'jinze-outer jiya-outer'
|
2772
|
+
$prev.setAttribute( 'prev', attr.prev )
|
2773
|
+
}
|
2774
|
+
}
|
2775
|
+
if (matches( $jinze, '.wei, .touwei' )) {
|
2776
|
+
$next = $jinze.nextSibling
|
2777
|
+
|
2778
|
+
if (matches( $next, 'h-cs' )) {
|
2779
|
+
$next.className = 'jinze-outer jiya-outer ' + attr[ 'class' ]
|
2780
|
+
$next.removeAttribute( 'prev' )
|
2781
|
+
}
|
2782
|
+
}
|
2783
|
+
return [ $prev, $next ]
|
2784
|
+
}
|
2476
2785
|
|
2477
|
-
|
2786
|
+
Han.renderJiya = function( context ) {
|
2787
|
+
var context = context || document
|
2788
|
+
var finder = Han.find( context )
|
2478
2789
|
|
2479
2790
|
finder
|
2480
|
-
.
|
2481
|
-
|
2791
|
+
.avoid( 'textarea, code, kbd, samp, pre, h-cs' )
|
2792
|
+
|
2793
|
+
.avoid( JIYA_AVOID )
|
2794
|
+
.charify({
|
2795
|
+
avoid: false,
|
2796
|
+
biaodian: charifyBiaodian
|
2797
|
+
})
|
2798
|
+
// End avoiding `JIYA_AVOID`:
|
2799
|
+
.endAvoid()
|
2800
|
+
|
2801
|
+
.avoid( 'textarea, code, kbd, samp, pre, h-cs' )
|
2802
|
+
.replace( TYPESET.group.biaodian[0], locateConsecutiveBD )
|
2803
|
+
.replace( TYPESET.group.biaodian[1], locateConsecutiveBD )
|
2804
|
+
|
2805
|
+
return finder
|
2482
2806
|
}
|
2483
2807
|
|
2484
2808
|
$.extend( Han.fn, {
|
2485
|
-
|
2486
|
-
|
2487
|
-
correctBasicBD: function( all ) {
|
2488
|
-
this.basicBD = Han.correctBasicBD( this.context, all )
|
2809
|
+
renderJiya: function() {
|
2810
|
+
Han.renderJiya( this.context )
|
2489
2811
|
return this
|
2490
2812
|
},
|
2491
2813
|
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2814
|
+
revertJiya: function() {
|
2815
|
+
$.qsa(
|
2816
|
+
'h-char.bd-jiya, h-cs.jiya-outer',
|
2817
|
+
this.context
|
2818
|
+
).forEach(function( $elmt ) {
|
2819
|
+
var classList = $elmt.classList
|
2820
|
+
classList.remove( 'bd-jiya' )
|
2821
|
+
classList.remove( 'jiya-outer' )
|
2822
|
+
})
|
2496
2823
|
return this
|
2497
2824
|
}
|
2498
2825
|
})
|