@@ -36,12 +36,44 @@ const CROWDIN_INLINE_ELEMENT_SELECTOR = [
3636 'var' ,
3737] . join ( ',' ) ;
3838
39+ /**
40+ * Returns a sibling when it is an inline element whose boundary Crowdin may rewrite.
41+ * @param {Node|null } sibling Candidate sibling.
42+ * @returns {Element|null } Matching inline element.
43+ */
44+ function _getCrowdinInlineSibling ( sibling ) {
45+ if ( ! ( sibling instanceof globalThis . Element ) ) return null ;
46+ return sibling . matches ( CROWDIN_INLINE_ELEMENT_SELECTOR ) ? sibling : null ;
47+ }
48+
49+ /**
50+ * Returns the exact whitespace at the start of a string.
51+ * @param {string } text Text to inspect.
52+ * @returns {string } Leading whitespace.
53+ */
54+ function _getLeadingWhitespace ( text ) {
55+ const trimmedText = text . trimStart ( ) ;
56+ return text . slice ( 0 , text . length - trimmedText . length ) ;
57+ }
58+
59+ /**
60+ * Returns the exact whitespace at the end of a string.
61+ * @param {string } text Text to inspect.
62+ * @returns {string } Trailing whitespace.
63+ */
64+ function _getTrailingWhitespace ( text ) {
65+ const trimmedText = text . trimEnd ( ) ;
66+ return text . slice ( trimmedText . length ) ;
67+ }
68+
3969/**
4070 * Records whitespace that separates text from inline elements before Crowdin translates the page.
4171 * @returns {Array<{
4272 * node: Text,
4373 * leading: boolean,
74+ * leadingWhitespace: string,
4475 * trailing: boolean,
76+ * trailingWhitespace: string,
4577 * previousInline: Element|null,
4678 * nextInline: Element|null,
4779 * whitespaceOnly: boolean
@@ -53,21 +85,23 @@ function _captureCrowdinWhitespaceBoundaries() {
5385 let node = walker . nextNode ( ) ;
5486
5587 while ( node !== null ) {
56- const previousIsInline = node . previousSibling instanceof globalThis . Element &&
57- node . previousSibling . matches ( CROWDIN_INLINE_ELEMENT_SELECTOR ) ;
58- const nextIsInline = node . nextSibling instanceof globalThis . Element &&
59- node . nextSibling . matches ( CROWDIN_INLINE_ELEMENT_SELECTOR ) ;
60- const leading = previousIsInline && / ^ \s / . test ( node . data ) ;
61- const trailing = nextIsInline && / \s $ / . test ( node . data ) ;
88+ const previousInline = _getCrowdinInlineSibling ( node . previousSibling ) ;
89+ const nextInline = _getCrowdinInlineSibling ( node . nextSibling ) ;
90+ const leadingWhitespace = previousInline === null ? '' : _getLeadingWhitespace ( node . data ) ;
91+ const trailingWhitespace = nextInline === null ? '' : _getTrailingWhitespace ( node . data ) ;
92+ const leading = leadingWhitespace !== '' ;
93+ const trailing = trailingWhitespace !== '' ;
6294
6395 if ( leading || trailing ) {
6496 boundaries . push ( {
6597 node,
6698 leading,
99+ leadingWhitespace,
67100 trailing,
68- previousInline : previousIsInline ? node . previousSibling : null ,
69- nextInline : nextIsInline ? node . nextSibling : null ,
70- whitespaceOnly : / ^ \s * $ / . test ( node . data ) ,
101+ trailingWhitespace,
102+ previousInline,
103+ nextInline,
104+ whitespaceOnly : node . data . trim ( ) === '' ,
71105 } ) ;
72106 }
73107
@@ -119,11 +153,14 @@ function _restoreCrowdinWhitespaceBoundaries(boundaries) {
119153 const node = _resolveCrowdinWhitespaceNode ( boundary ) ;
120154 if ( node === null ) return ;
121155
122- if ( boundary . leading && ! / ^ \s / . test ( node . data ) ) {
123- node . data = ' ' + node . data ;
156+ const currentLeadingWhitespace = _getLeadingWhitespace ( node . data ) ;
157+ if ( boundary . leading && currentLeadingWhitespace !== boundary . leadingWhitespace ) {
158+ node . data = boundary . leadingWhitespace + node . data . slice ( currentLeadingWhitespace . length ) ;
124159 }
125- if ( boundary . trailing && ! / \s $ / . test ( node . data ) ) {
126- node . data += ' ' ;
160+ const currentTrailingWhitespace = _getTrailingWhitespace ( node . data ) ;
161+ if ( boundary . trailing && currentTrailingWhitespace !== boundary . trailingWhitespace ) {
162+ const translatedTextEnd = node . data . length - currentTrailingWhitespace . length ;
163+ node . data = node . data . slice ( 0 , translatedTextEnd ) + boundary . trailingWhitespace ;
127164 }
128165 } ) ;
129166}
0 commit comments