ОК, просто для справки, вот мое решение:
GREEK_CHARS = {
LOWER_ALPHA : 0x03B1
LOWER_ALPHA_ACC : 0x03AC
LOWER_EPSILON : 0x03B5
LOWER_EPSILON_ACC : 0x03AD
LOWER_ETA : 0x03B7
LOWER_ETA_ACC : 0x03AE
LOWER_IOTA : 0x03B9
LOWER_IOTA_ACC : 0x03AF
LOWER_IOTA_ACC_DIAERESIS : 0x0390
LOWER_OMICRON : 0x03BF
LOWER_OMICRON_ACC : 0x03CC
LOWER_UPSILON : 0x03C5
LOWER_UPSILON_ACC : 0x03CD
LOWER_UPSILON_ACC_DIAERESIS: 0x03B0
LOWER_OMEGA_ACC : 0x03CE
UPPER_ALPHA : 0x0391
UPPER_EPSILON : 0x0395
UPPER_ETA : 0x0397
UPPER_IOTA : 0x0399
UPPER_IOTA_DIAERESIS : 0x03AA
UPPER_OMICRON : 0x039F
UPPER_UPSILON : 0x03A5
UPPER_UPSILON_DIAERESIS : 0x03AB
UPPER_OMEGA : 0x03A9
UPPER_ALPHA_ACC : 0x0386
UPPER_EPSILON_ACC : 0x0388
UPPER_ETA_ACC : 0x0389
UPPER_IOTA_ACC : 0x038A
UPPER_OMICRON_ACC : 0x038C
UPPER_UPSILON_ACC : 0x038E
UPPER_OMEGA_ACC : 0x038F
COMBINING_ACUTE_ACCENT : 0x0301
COMBINING_DIAERESIS : 0x0308
COMBINING_ACUTE_TONE_MARK : 0x0341
COMBINING_GREEK_DIALYTIKA_TONOS : 0x0344
}
String::toUpperCaseWithoutGreek = String::toUpperCase
String::toUpperCase = ->
newStringCharCodes = []
insideTag = false
for char, idx in this
insideTag = true if char == '<'
insideTag = false if char == '>'
charCode = char.charCodeAt(0)
if insideTag
newStringCharCodes.push charCode
continue
prev = if idx > 0 then newStringCharCodes[idx-1] else GREEK_CHARS.UPPER_ALPHA
prevPrev = if idx > 1 then newStringCharCodes[idx-2] else GREEK_CHARS.UPPER_ALPHA
prevPrevPrev = if idx > 2 then newStringCharCodes[idx-3] else GREEK_CHARS.UPPER_ALPHA
switch charCode
when GREEK_CHARS.LOWER_ALPHA_ACC, GREEK_CHARS.UPPER_ALPHA_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_ALPHA
when GREEK_CHARS.LOWER_EPSILON_ACC, GREEK_CHARS.UPPER_EPSILON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_EPSILON
when GREEK_CHARS.LOWER_ETA_ACC, GREEK_CHARS.UPPER_ETA_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_ETA
when GREEK_CHARS.LOWER_IOTA_ACC, GREEK_CHARS.UPPER_IOTA_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
when GREEK_CHARS.LOWER_IOTA_ACC_DIAERESIS
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
when GREEK_CHARS.LOWER_OMICRON_ACC, GREEK_CHARS.UPPER_OMICRON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_OMICRON
when GREEK_CHARS.LOWER_UPSILON_ACC, GREEK_CHARS.UPPER_UPSILON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON
when GREEK_CHARS.LOWER_UPSILON_ACC_DIAERESIS
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON_DIAERESIS
when GREEK_CHARS.LOWER_OMEGA_ACC, GREEK_CHARS.UPPER_OMEGA_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_OMEGA
when GREEK_CHARS.LOWER_IOTA
switch prev
when GREEK_CHARS.LOWER_ALPHA_ACC, GREEK_CHARS.LOWER_EPSILON_ACC, GREEK_CHARS.LOWER_OMICRON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
when GREEK_CHARS.LOWER_UPSILON_ACC
if prevPrev == GREEK_CHARS.LOWER_OMICRON
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
else
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
when GREEK_CHARS.COMBINING_ACUTE_ACCENT, GREEK_CHARS.COMBINING_ACUTE_TONE_MARK
switch prevPrev
when GREEK_CHARS.LOWER_ALPHA, GREEK_CHARS.LOWER_EPSILON, GREEK_CHARS.LOWER_OMICRON
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
when GREEK_CHARS.LOWER_UPSILON
if prevPrevPrev == GREEK_CHARS.LOWER_OMICRON
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
else
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA_DIAERESIS
else
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
else
newStringCharCodes.push GREEK_CHARS.UPPER_IOTA
when GREEK_CHARS.LOWER_UPSILON
switch prev
when GREEK_CHARS.LOWER_ALPHA_ACC, GREEK_CHARS.LOWER_EPSILON_ACC, GREEK_CHARS.LOWER_ETA_ACC, GREEK_CHARS.LOWER_OMICRON_ACC
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON_DIAERESIS
when GREEK_CHARS.COMBINING_ACUTE_ACCENT, GREEK_CHARS.COMBINING_ACUTE_TONE_MARK
switch prevPrev
when GREEK_CHARS.LOWER_ALPHA, GREEK_CHARS.LOWER_EPSILON, GREEK_CHARS.LOWER_ETA, GREEK_CHARS.LOWER_OMICRON
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON_DIAERESIS
else
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON
else
newStringCharCodes.push GREEK_CHARS.UPPER_UPSILON
when GREEK_CHARS.COMBINING_GREEK_DIALYTIKA_TONOS
newStringCharCodes.push GREEK_CHARS.COMBINING_DIAERESIS
when GREEK_CHARS.COMBINING_ACUTE_ACCENT, GREEK_CHARS.COMBINING_ACUTE_TONE_MARK
if prev < GREEK_CHARS.LOWER_OMEGA_ACC && prev > GREEK_CHARS.UPPER_ALPHA_ACC
newStringCharCodes.push null
else
newStringCharCodes.push(String.fromCharCode(charCode).toUpperCaseWithoutGreek().charCodeAt(0))
String.fromCharCode.apply(null, newStringCharCodes)
Это адаптация кофейного сценария из патча, представленного в сообщении об ошибке выше.
Вот что я делаю после отображения вида:
# Fix greek uppercase.
[].concat($('*').get()).filter((elm) ->
window.getComputedStyle(elm).getPropertyValue('text-transform') == "uppercase";
).forEach((elm) ->
if elm.value
elm.value = elm.value.toUpperCase()
else
$elm = $(elm)
$elm.html($elm.html().toUpperCase())
)
Это не очень приятно, по любому поводу, но это работает.
Две вещи, которые я не должен здесь делать, и которые могут измениться: угнать toUpperCase()
и иметь определенные правила, чтобы не анализировать теги. Все еще открыты для лучших предложений!