Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save syoichi/2943717 to your computer and use it in GitHub Desktop.
Save syoichi/2943717 to your computer and use it in GitHub Desktop.
エラーの発生、インジケーターの表示がずれるのを修正した。また、arguments.calleeとsetInterval、getBoundingClientRectを使わないようにし、アニメーションはCSS Transitionsで行うようにした。さらに、原稿用紙への切り替えはインジケーターのクリックでできるように変更した。そして、文字数のカウントをサロゲートペアに対応させた。
// ==UserScript==
// @id textarea character count
// @name textarea character count
// @namespace http://tokyoenvious.net/
// @author motemen
// @version 0.0.1
// @update 2012-06-17T15:44:53.818Z(GMT+09:00)
// @description テキストエリアの文字数をカウントする。
// @include http://*
// @include https://*
// @run-at document-end
// @priority 0
// @compatibility Firefox 13.0.1(Scriptish 0.1.7), Chrome 19.0.1084.56, Safari 5.1.7(NinjaKit 0.9.1), Opera 12.00 on Windows 7 Home Premium SP1 64bit
// @charset UTF-8
// ==/UserScript==
/*jslint browser: true, maxlen: 80*/
// Edition 2012-05-09
(function executeTextareaCharacterCount(win, doc) {
'use strict';
var enableGenko, getStringLength, getGenko, setIndicator, changeGenko;
doc.head.appendChild(doc.createElement('style')).textContent = [
'textarea + .indicator {',
' background-color: #333 !important;',
' color: white !important;',
' font-family: Verdana !important;',
' font-size: 9pt !important;',
' padding: 0.1em 0.5em !important;',
' border-radius: 0.2em !important;',
' position: absolute !important;',
' opacity: 0 !important;',
' -webkit-user-select: none !important;',
' -moz-user-select: none !important;',
' -ms-user-select: none !important;',
' -o-user-select: none !important;',
' user-select: none !important;',
' cursor: pointer !important;',
' -webkit-transition: opacity linear 0.3s !important;',
' -moz-transition: opacity linear 0.3s !important;',
' -ms-transition: opacity linear 0.3s !important;',
' -o-transition: opacity linear 0.3s !important;',
' transition: opacity linear 0.3s !important;',
'}',
'textarea:hover + .indicator,',
'textarea + .indicator:hover {',
' opacity: 1 !important;',
'}'
].join('\n');
enableGenko = false;
getStringLength = function getStringLength(str) {
return str.replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, '1').length;
};
getGenko = function getGenko(text) {
var lineCount, lines, linesLen, line, lineTextLen, idx, pageCount,
genko;
lineCount = 0;
lines = text.replace(/\n+$/, '').split('\n');
linesLen = lines.length;
while (linesLen) {
line = lines[linesLen -= 1];
lineTextLen = getStringLength(line);
idx = 0;
while (idx < lineTextLen) {
lineCount += 1;
idx += 20;
if (/[っ。、」』]/.test(line[idx])) {
idx += 1;
if (idx >= lineTextLen) {
break;
}
}
}
}
pageCount = Math.floor(lineCount / 20);
lineCount = lineCount % 20;
genko = '原稿用紙 ';
if (pageCount) {
genko += pageCount + ' 枚';
if (lineCount) {
genko += ' + ';
}
}
if (!pageCount || lineCount) {
genko += lineCount + ' 行';
}
return genko;
};
setIndicator = function setIndicator(evt) {
var target, targetNextElement, indicator, indicatorStyle, oTop, oLeft;
target = evt.target;
if (target.tagName !== 'TEXTAREA') {
return;
}
targetNextElement = target.nextElementSibling;
if (targetNextElement && targetNextElement.className === 'indicator') {
indicator = targetNextElement;
} else {
indicator = doc.createElement('span');
target.parentNode.insertBefore(
indicator,
target.nextSibling
).className = 'indicator';
}
indicator.textContent = enableGenko
? getGenko(target.value)
: getStringLength(target.value);
indicatorStyle = indicator.style;
oTop = target.offsetTop;
oLeft = target.offsetLeft;
indicatorStyle.top =
(oTop + target.clientHeight - 25) + 'px';
indicatorStyle.right =
(win.innerWidth - oLeft - target.clientWidth - 10) + 'px';
};
changeGenko = function changeGenko(evt) {
var target, prevNode;
target = evt.target;
prevNode = target.previousSibling;
if (
!(
prevNode &&
prevNode.tagName === 'TEXTAREA' &&
target.tagName === 'SPAN' &&
target.className === 'indicator' &&
target.getAttribute('style')
)
) {
return;
}
enableGenko = !enableGenko;
setIndicator({target: prevNode});
};
doc.addEventListener('input', setIndicator);
doc.addEventListener('click', changeGenko);
}(window, document));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment