Skip to content

Instantly share code, notes, and snippets.

@upsuper
Last active August 29, 2015 14:14
Show Gist options
  • Save upsuper/c3263166affa82a8d0be to your computer and use it in GitHub Desktop.
Save upsuper/c3263166affa82a8d0be to your computer and use it in GitHub Desktop.
Tone mark positioning polyfill
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<title>Polyfill demo for tone mark positioning</title>
<style>
body {
-webkit-writing-mode: vertical-rl;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
line-height: 5;
font-size: 52px;
}
rt {
font-size: 30%;
line-height: 1;
text-align: center;
}
</style>
</head>
<body>
<ruby>認<rt>ㄖㄣˋ</rt>得<rt>ㄉㄜˊ</rt>幾<rt>ㄐㄧˇ</rt>個<rt>ㄍㄜˋ</rt>字<rt>ㄗˋ</rt></ruby>
<script>
function iterateTextNodes(node, callback) {
var childList = node.childNodes;
for (var i = 0; i < childList.length; i++) {
var child = childList[i];
if (child.nodeType == Node.ELEMENT_NODE) {
iterateTextNodes(child, callback);
} else if (child.nodeType == Node.TEXT_NODE) {
callback(child);
}
}
}
function $c(tag) { return document.createElement(tag); }
function $t(text) { return document.createTextNode(text); }
function positionToneMark(textNode) {
var text = textNode.textContent;
var pieces = text.split(/([\u02c9\u02ca\u02c7\u02cb])/);
if (pieces.length <= 1) {
return;
}
var outer = $c('span');
for (var i = 0; i < pieces.length - 1; i += 2) {
var toneMarkElem;
if (!pieces[i]) {
outer.appendChild($t(pieces[i + 1]));
} else {
outer.appendChild($t(pieces[i].slice(0, -1)));
var wrapper = $c('span');
wrapper.appendChild($t(pieces[i].slice(-1)));
wrapper.style.webkitWritingMode = 'horizontal-tb';
wrapper.style.writingMode = 'lr-tb';
wrapper.style.writingMode = 'horizontal-tb';
wrapper.style.position = 'relative';
var mark = $c('span');
mark.appendChild($t(pieces[i + 1]));
mark.style.position = 'absolute';
wrapper.appendChild(mark);
outer.appendChild(wrapper);
}
}
outer.appendChild($t(pieces.pop()));
textNode.parentNode.replaceChild(outer, textNode);
}
var rtList = document.getElementsByTagName('rt');
for (var i = 0; i < rtList.length; i++) {
iterateTextNodes(rtList[i], function (textNode) {
positionToneMark(textNode);
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment