Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidTranDucVL committed Sep 15, 2020
1 parent c8bb2b1 commit 0c5ace5
Showing 1 changed file with 26 additions and 31 deletions.
57 changes: 26 additions & 31 deletions app/frontend/helpers/dynamicTextFormater.ts
Expand Up @@ -2,41 +2,35 @@ import {isBip39Word} from '../wallet/mnemonic'
import {getCaretPosition, setCaretPosition} from './caretPosition'
import matchAll from './matchAll'

const underlineNonBip39words = (element, /*component*/ content) => {
const underlineNonBip39words = (element, content) => {
const innerHTML = element.innerHTML
if (content !== innerHTML) {
const caretPosition = getCaretPosition(element)
let toFormat = innerHTML

// 1. forbid multiple divs (lines)
// console.log('========================================')
// console.log(`0. ${toFormat}`)
toFormat = toFormat.replace(/<\/{0,1}(div|br|p)[^<>]*>/g, '')
// console.log(`1. ${toFormat}`)

// 2. only non-breaking space allowed as whitespace
toFormat = toFormat.replace(/\s|&nbsp;/g, ' ')
// console.log(`2. ${toFormat}`)

// 3. wrap span around words at the start of line
// (^[^<>a-zA-Z]*) - find start of line and absence of '<' and '>'
// [a-zA-Z]+ - find word itself
// ((\s|[,;])+<span) - find next opening tag '<span'
// ^[^<>a-zA-Z]* - find start of line and absence of '<' and '>'
// [a-zA-Z]+ - find word itself
// (\s|[,;])+<span - find next opening tag '<span'
toFormat = toFormat.replace(
/(^[^<>a-zA-Z]*)([a-zA-Z]+)((\s|[,;])+<span)/g,
'$1<span>$2</span>$3'
)
// console.log(`3. ${toFormat}`)

// 4. wrap span around words in the middle of line
// (<\/span>(\s|[,;])+) - find '</span>' before word
// [a-zA-Z]+ - find word itself
// ((\s|[,;])+<span) - find '<span' after word
// <\/span>(\s|[,;])+ - find '</span>' before word
// [a-zA-Z]+ - find word itself
// (\s|[,;])+<span - find '<span' after word
toFormat = toFormat.replace(
/(<\/span>(\s|[,;])+)([a-zA-Z]+)((\s|[,;])+<span)/g,
'$1<span>$2</span>$3'
'$1<span>$3</span>$4'
)
// console.log(`4. ${toFormat}`)

// 5. wrap span around words in the end of the line
// (?<=^|\s|[,;]) - check for delimiter before word
Expand All @@ -48,7 +42,6 @@ const underlineNonBip39words = (element, /*component*/ content) => {
/(?<=^|\s|[,;])[a-zA-Z]+(?=$|\s|[,;])(?=[^<>]*$)/g,
'<span>$&</span>'
)
// console.log(`5. ${toFormat}`)

// 6. split words by whitespace or commas
// (?<!<span) - check if space before word is inside span tag,
Expand All @@ -57,27 +50,23 @@ const underlineNonBip39words = (element, /*component*/ content) => {
// (\s|[,;])+ - find whitespaces or commas
// (?!\s|[<,;]) - check for '<' symbol from next span tag
toFormat = toFormat.replace(/(?<!<span)(?<![>,;]|\s)(\s|[,;])+(?!\s|[<,;])/g, '</span>$&<span>')
// console.log(`6. ${toFormat}`)

// 7. merge words if there is no whitespace between them
toFormat = toFormat.replace(/<\/span><span[^>]*>/g, '')
// console.log(`7. ${toFormat}`)

// 8. append to wrapped word
// <span[^<>]*> - find opening tag <span class="..."> before word
// [a-zA-Z]+ - find word itself
// <\/span> - find closing tag </span> after word
// ([a-zA-Z]+) - find text to append
// [a-zA-Z]+ - find text to append
toFormat = toFormat.replace(/(<span[^<>]*>[a-zA-Z]+)(<\/span>)([a-zA-Z]+)/g, '$1$3$2')
// console.log(`8. ${toFormat}`)

// 9. preppend to wrapped word
// ([a-zA-Z]+ - find text to prepend
// [a-zA-Z]+ - find text to prepend
// <span[^<>]*> - find opening tag <span class="..."> before word
// [a-zA-Z]+ - find word itself
// <\/span> - find closing tag </span> after word
toFormat = toFormat.replace(/([a-zA-Z]+)(<span[^<>]*>)([a-zA-Z]+)(<\/span>)/g, '$2$1$3$4')
// console.log(`9. ${toFormat}`)

// 10. extract delimiters outside of spans
// <span[^<>]*> - find opening tag <span class="..."> before word
Expand All @@ -89,27 +78,33 @@ const underlineNonBip39words = (element, /*component*/ content) => {
/(<span[^<>]*>)(\s|[,;])*([a-zA-Z]+)(\s|[,;])*(<\/span>)/g,
'$2$1$3$5$4'
)
// console.log(`10. ${toFormat}`)

// 11 remove empty spans
toFormat = toFormat.replace(/<span[^>]*><\/span>/g, '')
// console.log(`11. ${toFormat}`)

// 12. translate non-breaking space back to html
// warning: this translates spaces inside span attributes as well,
// but it doesn't matter for next step
// but it doesn't matter for the next steps
toFormat = toFormat.replace(/\s/g, '&nbsp;')
// console.log(`12. ${toFormat}`)

// 13. extract raw words into array
// <span[^>]*> - find opening tag
// [^<>]* - find element content
// <\/span>) - find closing tag
const words = matchAll(/<span[^>]*>[^<>]*<\/span>/g, toFormat).map((wrappedWord) =>
wrappedWord.replace(/(<span[^>]*>)([^<>]*)(<\/span>)/g, '$2').replace(/[,;]/g, '')
wrappedWord.replace(/(<span[^>]*>)([^<>]*)(<\/span>)/g, '$2').replace(/(\s|[,;])/g, '')
)

// 14. reapply style rules to each word
const areWordsBipP39 = words.map((word) => isBip39Word(word)).reverse()
const styleReplacer = (match, p1, p2, p3, offset, string) => {
const style = areWordsBipP39.pop() ? '' : ' class="not-bip-39"'
return `<span${style}>${p2}${p3}`
}
const formattedText = toFormat.replace(/(<span[^>]*>)([^<>]*)(<\/span>)/g, styleReplacer)
const formattedText = toFormat.replace(
/(<span[^>]*>)([^<>]*)(<\/span>)/g,
(match, p1, p2, p3, offset, string) => {
const style = areWordsBipP39.pop() ? '' : ' class="not-bip-39"'
return `<span${style}>${p2}${p3}`
}
)

const rawText = words.join(' ')
element.innerHTML = `${formattedText}`
setCaretPosition(element, caretPosition)
Expand Down

0 comments on commit 0c5ace5

Please sign in to comment.