@@ -23,61 +23,99 @@ extension _RenderingContext {
2323// I do not know why this function does not work in embedded, but currently it crashes the compiler
2424#if !hasFeature(Embedded)
2525extension [ UInt8 ] {
26+ @inline ( __always)
2627 mutating func appendToken( _ token: consuming _HTMLRenderToken ) {
2728 // avoid strings and append each component directly
2829 switch token {
2930 case let . startTag( tagName, attributes: attributes, isUnpaired: _, type: _) :
3031 append ( 60 ) // <
31- append ( contentsOf: tagName. utf8)
32- for attribute in attributes {
33- append ( 32 ) // space
34- append ( contentsOf: attribute. name. utf8)
35- if let value = attribute. value {
36- append ( contentsOf: [ 61 , 34 ] ) // ="
37- appendEscapedAttributeValue ( value)
38- append ( 34 ) // "
32+ appendString ( tagName)
33+ if !attributes. isEmpty {
34+ for attribute in attributes {
35+ append ( 32 ) // space
36+ appendString ( attribute. name)
37+ if let value = attribute. value {
38+ append ( contentsOf: [ 61 , 34 ] ) // ="
39+ appendEscapedAttributeValue ( value)
40+ append ( 34 ) // "
41+ }
3942 }
4043 }
4144 append ( 62 ) // >
4245 case let . endTag( tagName, _) :
4346 append ( contentsOf: [ 60 , 47 ] ) // </
44- append ( contentsOf : tagName. utf8 )
47+ appendString ( tagName)
4548 append ( 62 ) // >
4649 case let . text( text) :
4750 appendEscapedText ( text)
4851 case let . raw( raw) :
49- append ( contentsOf : raw. utf8 )
52+ appendString ( raw)
5053 case let . comment( comment) :
51- append ( contentsOf : " <!-- " . utf8 )
54+ appendString ( " <!-- " )
5255 appendEscapedText ( comment)
53- append ( contentsOf: " --> " . utf8)
56+ appendString ( " --> " )
57+ }
58+ }
59+
60+ @inline ( __always)
61+ mutating func appendString( _ string: consuming String ) {
62+ string. withUTF8 { utf8 in
63+ append ( contentsOf: utf8)
5464 }
5565 }
5666
67+ @inline ( __always)
5768 mutating func appendEscapedAttributeValue( _ value: consuming String ) {
58- for byte in value. utf8 {
59- switch byte {
60- case 38 : // &
61- append ( contentsOf: " & " . utf8)
62- case 34 : // "
63- append ( contentsOf: " " " . utf8)
64- default :
65- append ( byte)
69+ value. withUTF8 { utf8 in
70+ var start = utf8. startIndex
71+
72+ for current in utf8. indices {
73+ switch utf8 [ current] {
74+ case 38 : // &
75+ append ( contentsOf: utf8 [ start ..< current] )
76+ appendString ( " & " )
77+ start = utf8. index ( after: current)
78+ case 34 : // "
79+ append ( contentsOf: utf8 [ start ..< current] )
80+ appendString ( " " " )
81+ start = utf8. index ( after: current)
82+ default :
83+ ( )
84+ }
85+ }
86+
87+ if start < utf8. endIndex {
88+ append ( contentsOf: utf8 [ start ..< utf8. endIndex] )
6689 }
6790 }
6891 }
6992
93+ @inline ( __always)
7094 mutating func appendEscapedText( _ value: consuming String ) {
71- for byte in value. utf8 {
72- switch byte {
73- case 38 : // &
74- append ( contentsOf: " & " . utf8)
75- case 60 : // <
76- append ( contentsOf: " < " . utf8)
77- case 62 : // >
78- append ( contentsOf: " > " . utf8)
79- default :
80- append ( byte)
95+ value. withUTF8 { utf8 in
96+ var start = utf8. startIndex
97+
98+ for current in utf8. indices {
99+ switch utf8 [ current] {
100+ case 38 : // &
101+ append ( contentsOf: utf8 [ start ..< current] )
102+ appendString ( " & " )
103+ start = utf8. index ( after: current)
104+ case 60 : // <
105+ append ( contentsOf: utf8 [ start ..< current] )
106+ appendString ( " < " )
107+ start = utf8. index ( after: current)
108+ case 62 : // >
109+ append ( contentsOf: utf8 [ start ..< current] )
110+ appendString ( " > " )
111+ start = utf8. index ( after: current)
112+ default :
113+ ( )
114+ }
115+ }
116+
117+ if start < utf8. endIndex {
118+ append ( contentsOf: utf8 [ start ..< utf8. endIndex] )
81119 }
82120 }
83121 }
0 commit comments