From 5164e396ca93938b5c44af2a207439b7ca67b88a Mon Sep 17 00:00:00 2001 From: Syoichi Tsuyuhara Date: Sun, 22 Sep 2013 20:38:25 +0900 Subject: [PATCH] Revise prototype.js #12 * Change coding style * Change indent from 1 tab to 2 spaces * Use wrapper function * Use Strict Mode * Use Object.defineProperties() instead of update() * Add extendBuiltInObject() * Custom methods should be non-enumerable * Gruntfile.js: Uncomment prototype.js --- Gruntfile.js | 2 +- test/prototype_test_patch.js | 75 ++++ xpi/chrome/content/library/prototype.js | 573 ++++++++++++++++-------- 3 files changed, 450 insertions(+), 200 deletions(-) create mode 100644 test/prototype_test_patch.js diff --git a/Gruntfile.js b/Gruntfile.js index c369c624..9e409648 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -9,7 +9,7 @@ module.exports = function (grunt) { // 'xpi/components/tombfix.js', // 'xpi/chrome/content/library/third_party/MochiKit.js', // 'xpi/chrome/content/library/component.js', - // 'xpi/chrome/content/library/prototype.js' + 'xpi/chrome/content/library/prototype.js' // 'xpi/chrome/content/library/utility.js', // 'xpi/chrome/content/library/database.js', // 'xpi/chrome/content/library/progress.js', diff --git a/test/prototype_test_patch.js b/test/prototype_test_patch.js new file mode 100644 index 00000000..f953d985 --- /dev/null +++ b/test/prototype_test_patch.js @@ -0,0 +1,75 @@ +log(Date.TIME_SECOND === 1000); +log(Date.TIME_MINUTE === 60000); +log(Date.TIME_HOUR === 3600000); +log(Date.TIME_DAY === 86400000); +log((10).pad(10) === '0000000010'); +log((10).pad(10, 'a') === 'aaaaaaaa10'); +// log((10).pad(0) === '10'); +log((100).toHexString() === '64'); +log(['a', 'b', 'c'].split(1).length === 3); +log(['a', 'b', 'c'].split(1).join(', ') === 'a, b, c'); +log(['a', 'b', 'c'].split(1).every(function (val, idx) { return val[0] === this[idx][0]; }, [['a'], ['b'], ['c']])); +log(['a', 'b', 'c'].split(2).length === 2); +log(['a', 'b', 'c'].split(2).join(', ') === 'a,b, c'); +log(['a', 'b', 'c'].split(2).every(function (val, idx) { return val[0] === this[idx][0]; }, [['a', 'b'], ['c']])); +log(['a', 'b', 'c'].split(3).length === 1); +log(['a', 'b', 'c'].split(3).join(', ') === 'a,b,c'); +log(['a', 'b', 'c'].split(3).every(function (val, idx) { return val[0] === this[idx][0]; }, [['a', 'b', 'c']])); +log(['a', 'b', 'c'].split(100).length === 1); +log(['a', 'b', 'c'].split(100).join(', ') === 'a,b,c'); +log(['a', 'b', 'c'].split(100).every(function (val, idx) { return val[0] === this[idx][0]; }, [['a', 'b', 'c']])); +/*log(['a', 'b', 'c'].split(0).length === 3); +log(['a', 'b', 'c'].split(0).join(', ') === 'a, b, c'); +log(['a', 'b', 'c'].split(0).every(function (val, idx) { return val[0] === this[idx][0]; }, ['a', 'b', 'c']));*/ +log(typeof String.katakana === 'object'); +log('a'.pad(2) === ' a'); +log('a'.pad(2, '0') === '0a'); +// log('a'.pad(0) === 'a'); +log('a'.indent(2) === ' a'); +log('a'.indent(2, ' ') === ' a'); +log('a\na'.indent(2) === ' a\n a'); +log('a'.indent(0) === 'a'); +log('a'.wrap('t') === 'tat'); +log('a'.wrap('t', 's') === 'tas'); +log('e'.wrap(9) === '9e9'); +log('test'.extract(/^(t)e(st)$/) === 't'); +log('test'.extract(/^(t)e(st)$/, 2) === 'st'); +log('TEST'.decapitalize() === 'tEST'); +log('test'.capitalize() === 'Test'); +log('a'.toByteArray()[0] === 97); +log('a'.toByteArray().join(', ') === '97'); +log('テスト'.toByteArray('utf8').join(', ') === '227, 131, 134, 227, 130, 185, 227, 131, 136'); +log('テスト'.toByteArray('Shift_JIS').join(', ') === '131, 101, 131, 88, 131, 103'); +log('a'.md5() === '0cc175b9c0f1b6a831c399e269772661'); +log('テスト'.md5('utf8') === 'b0f1c5a480f416234a803b35d9932c57'); +log('テスト'.md5('Shift_JIS') === '3f0326f4e56c3f4b54feede9071cafbf'); +log('a'.sha1() === 'hvfkN/qlp/zhXR3cuerq6jd2Z7g='); +log('テスト'.sha1('utf8') === 'Y7Vg24hJ4IeXYktYM1JA4NBigr0='); +log('テスト'.sha1('Shift_JIS') === 'phP4bmL7OC/qjrV8YiycASIQQiE='); +log('テスト'.convertToUnicode() === 'ƹ'); +log('テスト'.convertToUnicode('Shift_JIS') === 'ニケネ'); +log('テスト'.convertToUnicode('EUC-JP') === '胴'); +log('テスト'.convertToUnicode('iso-2022-jp') === '���'); +log('テスト'.convertFromUnicode() === 'テスト'); +log('テスト'.convertFromUnicode('Shift_JIS') === 'ƒeƒXƒg'); +log('テスト'.convertFromUnicode('EUC-JP') === '¥Æ¥¹¥È'); +log('テスト'.convertFromUnicode('iso-2022-jp') === '$B%F%9%H'); +log('aa'.trimTag() === 'aa'); +log('
a
'.trimTag() === 'a'); +log('
a

a

'.trimTag() === 'aa'); +log('
a
'.trimTag() === 'a'); +log('\n
a
'.trimTag() === '\na'); +log('a'.includesFullwidth() === false); +log('テスト'.includesFullwidth()); +log('abあcd'.includesFullwidth()); +log('aiueo'.toHiragana() === 'aiueo'); +log('アイウエオ'.toHiragana() === 'あいうえお'); +log('カキクケコ'.toHiragana() === 'かきくけこ'); +log('aiueo'.toKatakana() === 'aiueo'); +log('あいうえお'.toKatakana() === 'アイウエオ'); +log('かきくけこ'.toKatakana() === 'カキクケコ'); +log('aiueo'.toRoma() === 'aiueo'); +log('あいうえお'.toRoma() === 'aiueo'); +log('かきくけこ'.toRoma() === 'kakikukeko'); +log('アイウエオ'.toRoma() === 'aiueo'); +log('カキクケコ'.toRoma() === 'kakikukeko'); diff --git a/xpi/chrome/content/library/prototype.js b/xpi/chrome/content/library/prototype.js index 7291d280..b17c541d 100755 --- a/xpi/chrome/content/library/prototype.js +++ b/xpi/chrome/content/library/prototype.js @@ -1,199 +1,374 @@ -update(Date, { - TIME_SECOND : 1000, - TIME_MINUTE : 1000 * 60, - TIME_HOUR : 1000 * 60 * 60, - TIME_DAY : 1000 * 60 * 60 * 24, -}) - -if(typeof(update)=='undefined'){ - function update(t, s){ - for(var p in s) - t[p] = s[p]; - return t; - } -} - -update(Number.prototype, { - pad : function(len, ch){ - return ('' + this).pad(len, ch || '0'); - }, - toHexString : function(){ - return ('0' + this.toString(16)).slice(-2); - }, -}); - -update(Array.prototype, { - split : function(step){ - var res = []; - for(var i=0,len=this.length ; i/gm, '').replace(/<[\s\S]+?>/gm, ''); - }, - - includesFullwidth : function(){ - return (/[^ -~。-゚]/).test(this); - }, - - // http://code.google.com/p/kanaxs/ - toHiragana : function(){ - var c, i = this.length, a = []; - - while(i--){ - c = this.charCodeAt(i); - a[i] = (0x30A1 <= c && c <= 0x30F6) ? c - 0x0060 : c; - }; - - return String.fromCharCode.apply(null, a); - }, - - toKatakana : function(){ - var c, i = this.length, a = []; - - while(i--){ - c = this.charCodeAt(i); - a[i] = (0x3041 <= c && c <= 0x3096) ? c + 0x0060 : c; - }; - - return String.fromCharCode.apply(null, a); - }, - - toRoma : function(){ - var res = ''; - var s = this.toKatakana(); - for(var i = 0, kana, table = String.katakana ; i < s.length ; i += kana.length){ - kana = s.substr(i, 2); - roma = table[kana]; - - if(!roma){ - kana = s.substr(i, 1); - roma = table[kana]; - } - - if(!roma){ - roma = kana; - } - - res += roma; - } - res = res.replace(/ltu(.)/g, '$1$1'); - - return res; - }, -}); +/* global UnicodeConverter, CryptoHash */ + +(function executePrototype() { + 'use strict'; + + function extendBuiltInObject(builtInObject, obj) { + var props = {}; + + Object.keys(obj).forEach(function setDescriptor(key) { + props[key] = { + value : obj[key], + enumerable : false, + writable : true, + configurable : true + }; + }); + + return Object.defineProperties(builtInObject, props); + } + + extendBuiltInObject(Date, { + TIME_SECOND : 1000, + TIME_MINUTE : 1000 * 60, + TIME_HOUR : 1000 * 60 * 60, + TIME_DAY : 1000 * 60 * 60 * 24 + }); + + extendBuiltInObject(Number.prototype, { + pad : function pad(len, ch) { + return this.toString().pad(len, ch || '0'); + }, + toHexString : function toHexString() { + return ('0' + this.toString(16)).slice(-2); + } + }); + + extendBuiltInObject(Array.prototype, { + split : function split(step) { + var res = [], i = 0, len = this.length; + + while (i < len) { + res.push(this.slice(i, i += step)); + } + + return res; + } + }); + + extendBuiltInObject(String, { + katakana: { + 'ウァ' : 'wha', + 'ウィ' : 'wi', + 'ウェ' : 'we', + 'ウォ' : 'who', + 'キャ' : 'kya', + 'キィ' : 'kyi', + 'キュ' : 'kyu', + 'キェ' : 'kye', + 'キョ' : 'kyo', + 'クャ' : 'qya', + 'クュ' : 'qyu', + 'クァ' : 'qwa', + 'クィ' : 'qwi', + 'クゥ' : 'qwu', + 'クェ' : 'qwe', + 'クォ' : 'qwo', + 'ギャ' : 'gya', + 'ギィ' : 'gyi', + 'ギュ' : 'gyu', + 'ギェ' : 'gye', + 'ギョ' : 'gyo', + 'グァ' : 'gwa', + 'グィ' : 'gwi', + 'グゥ' : 'gwu', + 'グェ' : 'gwe', + 'グォ' : 'gwo', + 'シャ' : 'sha', + 'シィ' : 'syi', + 'シュ' : 'shu', + 'シェ' : 'sye', + 'ショ' : 'sho', + 'スァ' : 'swa', + 'スィ' : 'swi', + 'スゥ' : 'swu', + 'スェ' : 'swe', + 'スォ' : 'swo', + 'ジャ' : 'ja', + 'ジィ' : 'jyi', + 'ジュ' : 'ju', + 'ジェ' : 'jye', + 'ジョ' : 'jo', + 'チャ' : 'cha', + 'チィ' : 'tyi', + 'チュ' : 'chu', + 'チェ' : 'tye', + 'チョ' : 'cho', + 'ツァ' : 'tsa', + 'ツィ' : 'tsi', + 'ツェ' : 'tse', + 'ツォ' : 'tso', + 'テャ' : 'tha', + 'ティ' : 'thi', + 'テュ' : 'thu', + 'テェ' : 'the', + 'テョ' : 'tho', + 'トァ' : 'twa', + 'トィ' : 'twi', + 'トゥ' : 'twu', + 'トェ' : 'twe', + 'トォ' : 'two', + 'ヂャ' : 'dya', + 'ヂィ' : 'dyi', + 'ヂュ' : 'dyu', + 'ヂェ' : 'dye', + 'ヂョ' : 'dyo', + 'デャ' : 'dha', + 'ディ' : 'dhi', + 'デュ' : 'dhu', + 'デェ' : 'dhe', + 'デョ' : 'dho', + 'ドァ' : 'dwa', + 'ドィ' : 'dwi', + 'ドゥ' : 'dwu', + 'ドェ' : 'dwe', + 'ドォ' : 'dwo', + 'ニャ' : 'nya', + 'ニィ' : 'nyi', + 'ニュ' : 'nyu', + 'ニェ' : 'nye', + 'ニョ' : 'nyo', + 'ヒャ' : 'hya', + 'ヒィ' : 'hyi', + 'ヒュ' : 'hyu', + 'ヒェ' : 'hye', + 'ヒョ' : 'hyo', + 'フャ' : 'fya', + 'フュ' : 'fyu', + 'フョ' : 'fyo', + 'ファ' : 'fa', + 'フィ' : 'fi', + 'フゥ' : 'fwu', + 'フェ' : 'fe', + 'フォ' : 'fo', + 'ビャ' : 'bya', + 'ビィ' : 'byi', + 'ビュ' : 'byu', + 'ビェ' : 'bye', + 'ビョ' : 'byo', + 'ヴァ' : 'va', + 'ヴィ' : 'vi', + 'ヴ' : 'vu', + 'ヴェ' : 've', + 'ヴォ' : 'vo', + 'ヴャ' : 'vya', + 'ヴュ' : 'vyu', + 'ヴョ' : 'vyo', + 'ピャ' : 'pya', + 'ピィ' : 'pyi', + 'ピュ' : 'pyu', + 'ピェ' : 'pye', + 'ピョ' : 'pyo', + 'ミャ' : 'mya', + 'ミィ' : 'myi', + 'ミュ' : 'myu', + 'ミェ' : 'mye', + 'ミョ' : 'myo', + 'リャ' : 'rya', + 'リィ' : 'ryi', + 'リュ' : 'ryu', + 'リェ' : 'rye', + 'リョ' : 'ryo', + + 'ア' : 'a', + 'イ' : 'i', + 'ウ' : 'u', + 'エ' : 'e', + 'オ' : 'o', + 'カ' : 'ka', + 'キ' : 'ki', + 'ク' : 'ku', + 'ケ' : 'ke', + 'コ' : 'ko', + 'サ' : 'sa', + 'シ' : 'shi', + 'ス' : 'su', + 'セ' : 'se', + 'ソ' : 'so', + 'タ' : 'ta', + 'チ' : 'chi', + 'ツ' : 'tsu', + 'テ' : 'te', + 'ト' : 'to', + 'ナ' : 'na', + 'ニ' : 'ni', + 'ヌ' : 'nu', + 'ネ' : 'ne', + 'ノ' : 'no', + 'ハ' : 'ha', + 'ヒ' : 'hi', + 'フ' : 'fu', + 'ヘ' : 'he', + 'ホ' : 'ho', + 'マ' : 'ma', + 'ミ' : 'mi', + 'ム' : 'mu', + 'メ' : 'me', + 'モ' : 'mo', + 'ヤ' : 'ya', + 'ユ' : 'yu', + 'ヨ' : 'yo', + 'ラ' : 'ra', + 'リ' : 'ri', + 'ル' : 'ru', + 'レ' : 're', + 'ロ' : 'ro', + 'ワ' : 'wa', + 'ヲ' : 'wo', + 'ン' : 'nn', + 'ガ' : 'ga', + 'ギ' : 'gi', + 'グ' : 'gu', + 'ゲ' : 'ge', + 'ゴ' : 'go', + 'ザ' : 'za', + 'ジ' : 'zi', + 'ズ' : 'zu', + 'ゼ' : 'ze', + 'ゾ' : 'zo', + 'ダ' : 'da', + 'ヂ' : 'di', + 'ヅ' : 'du', + 'デ' : 'de', + 'ド' : 'do', + 'バ' : 'ba', + 'ビ' : 'bi', + 'ブ' : 'bu', + 'ベ' : 'be', + 'ボ' : 'bo', + 'パ' : 'pa', + 'ピ' : 'pi', + 'プ' : 'pu', + 'ペ' : 'pe', + 'ポ' : 'po', + + 'ァ' : 'la', + 'ィ' : 'li', + 'ゥ' : 'lu', + 'ェ' : 'le', + 'ォ' : 'lo', + 'ヵ' : 'lka', + 'ヶ' : 'lke', + 'ッ' : 'ltu', + 'ャ' : 'lya', + 'ュ' : 'lyu', + 'ョ' : 'lyo', + 'ヮ' : 'lwa', + '。' : '.', + '、' : ', ', + 'ー' : '-' + } + }); + + extendBuiltInObject(String.prototype, { + pad : function pad(len, ch) { + len = len - this.length; + + if (len <= 0) { + return this; + } + + return (ch || ' ').repeat(len) + this; + }, + indent : function indent(num, c) { + c = c || ' '; + + return this.replace(/^/mg, c.repeat(num)); + }, + wrap : function wrap(prefix, suffix) { + suffix = suffix || prefix; + + return prefix + this + suffix; + }, + extract : function extract(re, group) { + var res = this.match(re); + group = group == null ? 1 : group; + + return res ? res[group] : ''; + }, + decapitalize : function decapitalize() { + return this.substr(0, 1).toLowerCase() + this.substr(1); + }, + capitalize : function capitalize() { + return this.substr(0, 1).toUpperCase() + this.substr(1); + }, + toByteArray : function toByteArray(charset) { + return new UnicodeConverter(charset).convertToByteArray(this, {}); + }, + md5 : function md5(charset) { + var crypto = new CryptoHash(CryptoHash.MD5), + data = this.toByteArray(charset); + + crypto.update(data, data.length); + + return crypto.finish(false).split('').map(function getHexString(char) { + return char.charCodeAt().toHexString(); + }).join(''); + }, + sha1 : function sha1(charset) { + var crypto = new CryptoHash(CryptoHash.SHA1), + data = this.toByteArray(charset); + + crypto.update(data, data.length); + + return crypto.finish(true); + }, + convertToUnicode : function convertToUnicode(charset) { + return new UnicodeConverter(charset).ConvertToUnicode(this); + }, + convertFromUnicode : function convertFromUnicode(charset) { + return new UnicodeConverter(charset).ConvertFromUnicode(this); + }, + trimTag : function trimTag() { + return this.replace(//gm, '').replace(/<[\s\S]+?>/gm, ''); + }, + includesFullwidth : function includesFullwidth() { + return (/[^ -~。-゚]/).test(this); + }, + // https://code.google.com/p/kanaxs/ + toHiragana : function toHiragana() { + var c, i = this.length, ary = []; + + while (i--) { + c = this.charCodeAt(i); + ary[i] = (0x30A1 <= c && c <= 0x30F6) ? c - 0x0060 : c; + } + + return String.fromCharCode.apply(null, ary); + }, + toKatakana : function toKatakana() { + var c, i = this.length, ary = []; + + while (i--) { + c = this.charCodeAt(i); + ary[i] = (0x3041 <= c && c <= 0x3096) ? c + 0x0060 : c; + } + + return String.fromCharCode.apply(null, ary); + }, + toRoma : function toRoma() { + var res = '', + str = this.toKatakana(), + len = str.length, + table = String.katakana; + + for (let i = 0, kana, roma; i < len; i += kana.length) { + kana = str.substr(i, 2); + roma = table[kana]; + + if (!roma) { + kana = str.substr(i, 1); + roma = table[kana]; + } + + if (!roma) { + roma = kana; + } + + res += roma; + } + + return res.replace(/ltu(.)/g, '$1$1'); + } + }); +}());