hanzi-rails 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
})
|