Sub ZaloMSGFormat_sending()
On Error Resume Next
Dim msf As Boolean, bc As Boolean, bb As Boolean, bi As Boolean, bu As Boolean, bs As Boolean
Dim o, dict, re, ms, mt, imt%, chatInput, textFormatTools, inputv4, tHTML$, myClipboard
Dim UB%, i&, j&, n, aRGB, aSize, aIndent, tSpan$, tLi$, tUl$, tOl$, tDiv$, nID$, eID$, snID$
Dim ki$, aa, aa2, L&, vt&, vt1&, vt2&, vs1&, Lt%, idx&, idx2&, m%, nfx$, txt$, il%, ids%, nds%, si%, cl%, ib%, it%, iu%, ist%, ibl%, inr%, idv%, iid%, isi%, ico%, t&, isp&, s1, s2
Dim b As ZaloSupportArguments, c As ZaloMessageFormat
UB = UBound(Works)
Set myClipboard = New vbaClipboard
nfx = wsZaloFormat.[e3].Formula
Set dict = glbDict(1): Set re = glbRegex
aIndent = Array("", "10", "20", "30", "40", "50")
aSize = Array("15", "13", "18", "20")
aRGB = Array(" color: rgb(5, 10, 25);", " color: rgb(219, 52, 46);", " color: rgb(242, 120, 6);", " color: rgb(247, 181, 3);", " color: rgb(21, 168, 95);")
GoSub gotoMS
For i = 1 To UB
b = Works(i)
If b.fx <> nfx Then GoTo n
GoSub inputClear: GoSub formatClear
msf = b.msFormat.taked = False And b.msFormat.fIndex > 0
tHTML = "": GoSub eID
For j = 1 To b.fmIndex
c = b.messages(j): If Not c.taked Then GoTo Nx2
tSpan = ""
s2 = c.text: L = Len(s2): aa = c.formats: GoSub indexAndLen
If c.bullet > 0 Then
il = c.bullet: il = IIf(il > 6, 6, il): If ibl = 0 Or ibl <> il Then ibl = il: GoSub bullet
il = il - 1
ElseIf c.numbering > 0 Then
il = c.numbering: il = IIf(il > 6, 6, il): If inr = 0 Or inr <> il Then inr = il: GoSub numbering
il = il - 1
Else
If ibl > 0 Then tHTML = tHTML & tUl & "</ul>": tUl = "": ibl = 0
If inr > 0 Then tHTML = tHTML & tOl & "</ol>": tOl = "": inr = 0
il = c.indent: il = IIf(il < 0, 0, IIf(il > 5, 5, il)):
If iid = 0 Or iid < il Then iid = il
idv = 1
End If
For m = 1 To L
For n = 1 To UBound(aa, 2)
isp = aa(ZAIDirection, n)
If isp > 0 And aa(ZAIType, n) = 0 Then
If m = aa(ZAIIndex, n) Then
Lt = aa(ZAIIndex2, n)
t = ZFFBlack: If (t And isp) = t And cl <> 0 Then GoSub createSpan: cl = 0: ico = Lt
t = ZFFRed: If (t And isp) = t And cl <> 1 Then GoSub createSpan: cl = 1: ico = Lt
t = ZFFOrange: If (t And isp) = t And cl <> 2 Then GoSub createSpan: cl = 2: ico = Lt
t = ZFFYellow: If (t And isp) = t And cl <> 3 Then GoSub createSpan: cl = 3: ico = Lt
t = ZFfGreen: If (t And isp) = t And cl <> 4 Then GoSub createSpan: cl = 4: ico = Lt
t = ZFFSize1: If (t And isp) = t And si <> 0 Then GoSub createSpan: si = 0: isi = Lt
t = ZFFSize0: If (t And isp) = t And si <> 1 Then GoSub createSpan: si = 1: isi = Lt
t = ZFFSize2: If (t And isp) = t And si <> 2 Then GoSub createSpan: si = 2: isi = Lt
t = ZFFSize3: If (t And isp) = t And si <> 3 Then GoSub createSpan: si = 3: isi = Lt
t = ZFfBold: If (t And isp) = t And bb <> 1 Then GoSub createSpan: bb = 1: ib = Lt
t = ZFFItalic: If (t And isp) = t And bi <> 1 Then GoSub createSpan: bi = 1: it = Lt
t = ZFFUnderline: If (t And isp) = t And bu <> 1 Then GoSub createSpan: bu = 1: iu = Lt
t = ZFFStrikethrough: If (t And isp) = t And bs <> 1 Then GoSub createSpan: bs = 1: ist = Lt
aa(ZAIDirection, n) = 0
End If
End If
Next
txt = txt & Mid(s2, m, 1)
If ico > 0 And ico = m Then ico = 0: GoSub createSpan: cl = 0
If isi > 0 And isi = m Then isi = 0: GoSub createSpan: si = 0
If ib > 0 And ib = m Then ib = 0: GoSub createSpan: bb = 0
If it > 0 And it = m Then it = 0: GoSub createSpan: bi = 0
If iu > 0 And iu = m Then iu = 0: GoSub createSpan: bu = 0
If ist > 0 And ist = m Then ist = 0: GoSub createSpan: bs = 0
nx1:
Next
Nx2_1:
GoSub createSpan
If ibl > 0 Or inr > 0 Then
GoSub createLi
ElseIf idv > 0 Then
GoSub createDiv: tHTML = tHTML & tDiv: tDiv = "": idv = 0
End If
ico = 0: cl = 0
isi = 0: si = 0
ib = 0: bb = 0
it = 0: bi = 0
iu = 0: bu = 0
ist = 0: bs = 0
Nx2:
Next
If tUl <> "" Then tHTML = tHTML & tUl & "</ul>": tUl = "": ibl = 0
If tOl <> "" Then tHTML = tHTML & tOl & "</ul>": tOl = "": inr = 0
If idv > 0 Then GoSub createDiv: tHTML = tHTML & tDiv: tDiv = "": idv = 0
GoSub Paste
GoSub indent
GoSub sent
Works(i).timer = timer
Exit For
n:
Next
e:
ZaloSendEnableUDF = False
Exit Sub
Paste:
myClipboard.SetClipboardText tHTML, CTFNHTMLFormat, "1.0", "https://chat.zalo.me/"
inputv4.sendkeys SelenKeys.Control & "v"
Return
sent:
inputv4.sendkeys SelenKeys.Enter
Return
sendkeys:
inputv4.sendkeys ki
Return
gotoMS:
ZaloAppLogin
'ZaloAppGotoCloud
GoSub focused
Set chatInput = Selen.FindElementById("chatInput", 200, False)
Set textFormatTools = Selen.FindElementById("textFormatTools", 200, False)
Set inputv4 = chatInput.FindElementByXPath(".//*[contains(@class,'input-v4')]", 200, False)
Return
createDiv:
GoSub NameID
tDiv = "<div type id=""" & eID & "_" & nID & """ name=""" & nID & """ style=""white-space: pre-wrap;" & IIf(il >= 0, "", " text-indent: " & il & "0px; list-style-position: inside;") & """>" & tSpan & "</div>"
tSpan = ""
Return
createLi:
GoSub NameID
tLi = "<li type=""" & IIf(inr > 0, "1", "") & """ id=""" & eID & "_" & nID & """ name=""" & nID & """ style=""white-space: pre-wrap; " & IIf(il >= 0, "", "text-indent: " & il & "0px; list-style-position: inside;") & """>" & tSpan & "</li>"
tSpan = ""
If ibl > 0 Then tUl = tUl & tLi
If inr > 0 Then tOl = tOl & tLi
Return
createSpan: If txt = Empty Then Return
GoSub spanID
tSpan = tSpan & "<span data-text=""true"" " & _
"id=""" & eID & "_" & nID & "_" & snID & """ class="""" " & _
"name=""" & snID & """ " & _
"style=""white-space: pre-wrap;" & IIf(si <> 2, _
" font-size: " & aSize(si) & "px;", "") & IIf(bb, "" & _
" font-weight: 500;", "") & IIf(bi, "" & _
" font-style: italic;", "") & IIf(bu Or bs, " text-decoration-skip-ink: none; text-decoration: " & IIf(bu, "underline", "") & IIf(bs, " line-through", "") & ";", "") & _
IIf(cl <> 5, aRGB(cl), "") & """>" & Uni2HtmlCode(txt) & "</span>"
txt = ""
Return
bullet:
If tUl <> "" Then tHTML = tHTML & tUl & "</ul>"
tUl = "<ul>":
Return
numbering:
If tOl <> "" Then tHTML = tHTML & tOl & "</ol>"
tOl = "<ol>"
Return
indent:
Set o = inputv4.FindElementsByXPath(".//div|.//li", , 200)
For j = 1 To o.count
c = b.messages(j)
If c.taked Then
If c.bullet > 0 Then
il = c.bullet: il = il - 1
ElseIf c.numbering > 0 Then
il = c.numbering: il = il - 1
Else
il = c.indent: il = IIf(il < 0, 0, il):
End If
il = IIf(il < 0, 0, IIf(il > 5, 5, il))
While il > 0: il = il - 1
Selen.Actions.MoveToElement(o(j)).sendkeys(SelenKeys.Tab, o(j)).Perform
Wend
End If
Next
Return
focused:
Set o = Selen.FindElementByXPath(".//*[contains(@data-id,'div_RTF_Menu')]", 200, False)
If Not o.Attribute("class") Like "*focused*" Then o.click: Delay 200
Return
formatClear: textFormatTools.FindElementById("formatClear", 200, False).click: Delay 200: Return
inputClear: ki = SelenKeys.Control & "a" & SelenKeys.Backspace: GoSub sendkeys: Return
indexAndLen:
For n = 1 To UBound(aa, 2)
If aa(ZAIDirection, n) > 0 And aa(ZAIType, n) = 0 Then
idx = aa(ZAIIndex, n)
If idx > 0 And idx <= L Then
Lt = aa(ZAIlen, n)
If Lt <= 0 Then Lt = L - idx + 1 Else If Lt > L Then Lt = L
vt = idx + Lt - 1
If vt > 0 Then
aa(ZAIlen, n) = Lt
aa(ZAIIndex2, n) = vt
Else
aa(ZAIDirection, n) = 0
End If
Else
aa(ZAIDirection, n) = 0
End If
End If
Next
If msf Then
aa2 = b.msFormat.formats
For n = 1 To b.msFormat.fIndex
Select Case aa2(ZAIType, n)
Case 1: For Each s1 In aa2(ZAIIndex, n): GoSub InStr: Next
Case 2: For Each s1 In aa2(ZAIIndex, n): GoSub RegExp: Next
End Select
Next
End If
aa2 = aa
For n = 1 To c.fIndex
If aa2(ZAIDirection, n) > 0 Then
Select Case aa2(ZAIType, n)
Case 1: For Each s1 In aa2(ZAIIndex, n): GoSub InStr: Next: aa(ZAIDirection, n) = 0: aa(ZAIIndex, n) = 999
Case 2: For Each s1 In aa2(ZAIIndex, n): GoSub RegExp: Next: aa(ZAIDirection, n) = 0: aa(ZAIIndex, n) = 999
End Select
End If
Next
indexAndLen2:
idx = 0: idx = UBound(aa, 2): If idx = 0 Then Return
aa = Sort2D(aa, ZAIIndex, Horizontal:=True)
For t = 1 To idx - 1
idx2 = aa(ZAIDirection, t): isp = idx2
If isp > 0 And aa(ZAIType, t) = 0 Then
GoSub vFM: vt1 = vt
If vt1 > 0 Then
For nds = t + 1 To idx
DoEvents
isp = aa(ZAIDirection, nds):
If isp > 0 And aa(ZAIType, nds) = 0 Then
GoSub vFM
If vt > 0 Then
vt2 = vt1 And vt
Select Case True
Case aa(ZAIIndex, nds) <= aa(ZAIIndex, t) And aa(ZAIIndex2, nds) >= aa(ZAIIndex2, t): aa(ZAIDirection, t) = idx2 - vt2: GoSub rmFM
Case aa(ZAIIndex, nds) <= aa(ZAIIndex, t) And aa(ZAIIndex2, nds) < aa(ZAIIndex2, t): GoSub rmFM
aa(ZAIIndex, t) = aa(ZAIIndex2, nds) + 1: GoSub newFMLen: GoTo indexAndLen2
Case aa(ZAIIndex, nds) > aa(ZAIIndex, t) And aa(ZAIIndex, nds) <= aa(ZAIIndex2, t) And aa(ZAIIndex2, nds) >= aa(ZAIIndex2, t): GoSub rmFM
aa(ZAIIndex2, t) = aa(ZAIIndex, nds) - 1: GoSub newFMLen: GoTo indexAndLen2
Case aa(ZAIIndex, nds) > aa(ZAIIndex, t) And aa(ZAIIndex2, nds) < aa(ZAIIndex2, t): GoSub rmFM
idx = idx + 1: ReDim Preserve aa(1 To ZAILine, 1 To idx)
aa(ZAIDirection, idx) = idx2
aa(ZAIIndex, idx) = aa(ZAIIndex2, nds) + 1: aa(ZAIIndex2, idx) = aa(ZAIIndex2, t)
aa(ZAIlen, idx) = aa(ZAIIndex2, idx) - aa(ZAIIndex, idx) + 1
aa(ZAIType, idx) = 0
aa(ZAIIndex2, t) = aa(ZAIIndex, nds) - 1: GoSub newFMLen
GoTo indexAndLen2
End Select
End If
If aa(ZAIIndex, nds) = aa(ZAIIndex, t) And aa(ZAIIndex2, nds) = aa(ZAIIndex2, t) Then
aa(ZAIDirection, t) = idx2 Or isp: aa(ZAIDirection, nds) = 0
End If
End If
Next
End If
End If
Next
Return
rmFM: If vt2 > 0 Then aa(ZAIDirection, nds) = isp Or (idx2 - vt2)
Return
newFMLen: aa(ZAIlen, t) = aa(ZAIIndex2, t) - aa(ZAIIndex, t) + 1: Return
vFM: vt = (ZFFBlack + ZFFRed + ZFFOrange + ZFFYellow + ZFfGreen + ZFFSize0 + ZFFSize1 + ZFFSize2 + ZFFSize3) And isp: Return
InStr:
ids = 1: Lt = Len(s1)
Do Until ids >= L
ids = InStr(ids, s2, s1, 1): If ids = 0 Then Exit Do
idx = UBound(aa, 2) + 1: ReDim Preserve aa(1 To ZAILine, 1 To idx)
aa(ZAIDirection, idx) = aa2(ZAIDirection, n): aa(ZAIIndex, idx) = ids: aa(ZAIlen, idx) = Lt: aa(ZAIType, idx) = 0
aa(ZAIIndex2, idx) = ids + Lt - 1
ids = ids + Lt
Loop
Return
RegExp:
re.Pattern = s1: Set ms = re.Execute(s2): If ms.count = 0 Then Return
t = 0: t = UBound(aa, 2)
For isp = 1 To ms.count
Set mt = ms(isp - 1): o = mt
If mt.submatches.count Then
ids = 1
For imt = 0 To mt.submatches.count - 1
t = t + 1: ReDim Preserve aa(1 To ZAILine, 1 To t)
ids = InStr(ids, o, mt.submatches(imt), 1)
aa(ZAIIndex, t) = mt.FirstIndex + ids: aa(ZAIlen, t) = Len(mt.submatches(imt)): aa(ZAIIndex2, t) = aa(ZAIIndex, t) + aa(ZAIlen, t) - 1
aa(ZAIDirection, t) = aa2(ZAIDirection, n): aa(ZAIType, t) = 0
ids = ids + aa(ZAIlen, t)
Next
Else
t = t + 1: ReDim Preserve aa(1 To ZAILine, 1 To t)
aa(ZAIIndex, t) = mt.FirstIndex + 1: aa(ZAIlen, t) = mt.Length: aa(ZAIIndex2, t) = aa(ZAIIndex, t) + aa(ZAIlen, t) - 1
aa(ZAIDirection, t) = aa2(ZAIDirection, n): aa(ZAIType, t) = 0
End If
Next
Return
eID:
eID = Random5Key(): If dict.Exists(eID) Then GoTo eID Else dict(eID) = eID
Return
spanID:
snID = Random5Key(): If dict.Exists(snID) Then GoTo spanID Else dict(snID) = snID
Return
NameID:
nID = Random5Key(): If dict.Exists(nID) Then GoTo NameID Else dict(nID) = nID
Return
End Sub