OSDN Git Service

Version 0.6.146, fix XHR.send, add RegExp free encodeURIComponent, fix X.Object.deepCopy.
[pettanr/clientJs.git] / 0.6.x / js / 01_core / 00_builtin.js
1 /**\r
2  * @preserve Copyright 2012-2014 pettanR team.\r
3  * https://sourceforge.jp/projects/pettanr/\r
4  * BSD 3-Clause License\r
5  */\r
6 \r
7 /* \r
8  * ビルトインオブジェクトに拡張したい10のメソッド\r
9  * http://d.hatena.ne.jp/ofk/20080922/1222047483\r
10  */\r
11 \r
12 Function.prototype.apply || (Function.prototype.apply = function (x, y) {\r
13         var apply = '__apply',\r
14                 a, i, r, j;\r
15 \r
16         x = x || window;\r
17         y = y || [];\r
18         \r
19         // apply 内で apply を呼んだ場合に備える\r
20         if( x === window ){\r
21                 x[ apply ] = void 0;\r
22         } else {\r
23                 if( x.constructor && x.constructor.prototype[ apply ] ){\r
24                         delete x.constructor.prototype[ apply ];\r
25                 } else\r
26                 if( x[ apply ] ) delete x[ apply ];\r
27         };\r
28         \r
29         x[ apply ] = this;\r
30         if (!x[ apply ]) x.constructor.prototype[ apply ] = this;\r
31         j = y.length;\r
32         switch (j) {\r
33                 case 0: r = x[ apply ](); break;\r
34                 case 1: r = x[ apply ](y[0]); break;\r
35                 case 2: r = x[ apply ](y[0], y[1]); break;\r
36                 case 3: r = x[ apply ](y[0], y[1], y[2]); break;\r
37                 case 4: r = x[ apply ](y[0], y[1], y[2], y[3]); break;\r
38                 case 5: r = x[ apply ](y[0], y[1], y[2], y[3], y[4]); break;\r
39                 case 6: r = x[ apply ](y[0], y[1], y[2], y[3], y[4], y[5]); break;\r
40                 case 7: r = x[ apply ](y[0], y[1], y[2], y[3], y[4], y[5], y[6]); break;\r
41                 case 8: r = x[ apply ](y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7]); break;\r
42                 case 9: r = x[ apply ](y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7], y[8]); break;\r
43                 default:\r
44                         a = [];\r
45                         for (i = 0; i < j; ++i)\r
46                                 a[i] = 'y[' + i + ']';\r
47                         //r = eval('x.__apply(' + a.join(',') + ')');\r
48                         // closuer compiler 対策\r
49                         r = (new Function( 'x,y', 'return x.__apply(' + a.join(',') + ')' ))( x, y );\r
50                         break;\r
51         };\r
52         // ie5\r
53         if( x === window ){\r
54                 x[ apply ] = void 0;\r
55         } else {\r
56                 //alert( typeof x );\r
57                 if( x.constructor && x.constructor.prototype[ apply ] ){\r
58                         delete x.constructor.prototype[ apply ];\r
59                 } else\r
60                 if( x[ apply ] ) delete x[ apply ];\r
61         };\r
62         return r;\r
63 });\r
64 Function.prototype.call || (Function.prototype.call = function () {\r
65         var a = arguments, x = a[0], y = [], i = 1, j = a.length;\r
66         for (; i < j; ++i)\r
67                 y[i - 1] = a[i];\r
68         return this.apply(x, y);\r
69 });\r
70 \r
71 Array.prototype.pop || (Array.prototype.pop = function () {\r
72         var r = this[this.length - 1];\r
73         --this.length;\r
74         return r;\r
75 });\r
76 Array.prototype.push || (Array.prototype.push = function () {\r
77         var a = arguments, i = 0, j = a.length, l = this.length;\r
78         for (; i < j; ++i)\r
79                 this[l + i] = a[i];\r
80         return this.length;\r
81 });\r
82 Array.prototype.shift || (Array.prototype.shift = function () {\r
83         var r = this[0], i = 1, j = this.length;\r
84         for( ; i < j; ++i)\r
85                 this[i - 1] = this[i];\r
86         --this.length;\r
87         return r;\r
88 });\r
89 Array.prototype.unshift || (Array.prototype.unshift = function () {\r
90         var a = arguments, l = a.length, j = this.length += l - 1, i = j;\r
91         for (; i >= l; --i)\r
92                 this[i] = this[i - l];\r
93         for (i = 0; i < l; ++i)\r
94                 this[i] = a[i];\r
95         return j;\r
96 });\r
97 Array.prototype.splice || (Array.prototype.splice = function (x, y) {\r
98         var a = arguments, s = a.length - 2 - y, r = this.slice(x, x + y),i,j;\r
99         if (s > 0) {\r
100                 for (i = this.length - 1, j = x + y; i >= j; --i)\r
101                         this[i + s] = this[i];\r
102         }\r
103         else if (s < 0) {\r
104                 for (i = x + y, j = this.length; i < j; ++i)\r
105                         this[i + s] = this[i];\r
106                 this.length += s;\r
107         }\r
108         for (i = 2, j = a.length; i < j; ++i)\r
109                 this[i - 2 + x] = a[i];\r
110         return r;\r
111 });\r
112 \r
113 /*\r
114  * original\r
115  * JavaScript 1.6, Array.indexOfを下位互換実装する\r
116  * http://www.inazumatv.com/contents/archives/7965\r
117  */\r
118 \r
119 Array.prototype.indexOf || (Array.prototype.indexOf = function( searchElement, fromIndex ){\r
120         var l = this.length >>> 0, i;\r
121         \r
122         if( l === 0 ) return -1;\r
123         \r
124         if( fromIndex ){\r
125             i = fromIndex || 0;\r
126             i = i === -Infinity ? 0 : ( i < 0 ? -i : i ) | 0; // Math.floor\r
127             if( l <= i ) return -1;\r
128         };\r
129 \r
130         for( i = 0 <= i ? i : 0 < l + i ? l + i : 0; i < l; ++i ){\r
131             if( this[ i ] === searchElement ) return i;\r
132         };\r
133         return -1;\r
134         });\r
135 \r
136 \r
137 /*\r
138  * JavaScript split Bugs: Fixed!\r
139  * http://blog.stevenlevithan.com/archives/cross-browser-split\r
140  */\r
141 \r
142 /*\r
143  * original:\r
144  * by https://web.archive.org/web/20100413085309/http://nurucom-archives.hp.infoseek.co.jp/digital/trans-uri.html\r
145  */\r
146 var _builtin_skipEncodeURI = (function(){\r
147         var encodeURIComponentTarget = '!\'()*-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~',\r
148                 encodeURITarget = '#$&+,-/:;=?@',\r
149                 obj = {}, i;\r
150         for( i = encodeURIComponentTarget.length; i; ){\r
151                 obj[ encodeURIComponentTarget.charCodeAt( --i ) ] = 2;\r
152         };\r
153         for( i = encodeURITarget.length; i; ){\r
154                 obj[ encodeURITarget.charCodeAt( --i ) ] = 1;\r
155         };\r
156         return obj;\r
157 })();\r
158 \r
159 // /[^!#$&-;=?-Z_a-z~]/g\r
160 window.encodeURI || (window.encodeURI = function( x ){ return _builtin_encodeURI( x, 0 ); });\r
161 // /[^!'-*.0-9A-Z_a-z~-]/g\r
162 window.encodeURIComponent || (window.encodeURIComponent = function( x ){ return _builtin_encodeURI( x, 1 ); });\r
163 \r
164 function _builtin_encodeURI( x, kind ){\r
165         var result = [],\r
166                 skip   = _builtin_skipEncodeURI,\r
167                 p      = '%',\r
168                 i = 0, l, chr, c;\r
169         \r
170         x += '';\r
171         \r
172         for( l = x.length; i < l; ++i ){\r
173                 if( !( kind < skip[ c = x.charCodeAt( i ) ] ) ){\r
174                         chr = (\r
175                                 c < 16 ? '%0' + c.toString(16) :\r
176                                 c < 128 ? p + c.toString(16) :\r
177                                 c < 2048 ? p + (c >> 6 | 192).toString(16) + p + (c & 63 | 128).toString(16) :\r
178                                 p + (c >> 12 | 224).toString(16) + p + (c >> 6 & 63 | 128).toString(16) + p + (c & 63 | 128).toString(16)\r
179                         ).toUpperCase();\r
180                 } else {\r
181                         chr = x.charAt( i );\r
182                 };\r
183                 result[ i ] = chr;\r
184         };\r
185         \r
186         return result.join( '' );\r
187 };\r
188 \r
189 \r
190 function _builtin_decodeURI( x ){\r
191         var result    = [],\r
192                 toInt     = parseInt,\r
193                 toChrCode = String.fromCharCode,\r
194                 n = -1, i = 0, l, chr, decode, code, memory;\r
195         \r
196         x += '';\r
197         \r
198         for( l = x.length; i < l; ++i ){\r
199                 if( decode ){\r
200                         code = toInt( x.substr( i, 2 ), 16 );\r
201                         ++i;                                    \r
202                         if( 127 < code ){\r
203                                 if( 223 < code ){\r
204                                         memory = ( code & 15 ) << 12;\r
205                                         code = toInt( x.substr( i + 2, 2 ), 16 ) & 63; // 00%00%00\r
206                                         i += 3;\r
207                                         memory += code << 6;                                                    \r
208                                 } else {\r
209                                         memory = ( code & 63 ) << 6;\r
210                                 };\r
211                                 code = toInt( x.substr( i + 2, 2 ), 16 ) & 63;\r
212                                 i += 3;\r
213                                 code += memory;\r
214                         };\r
215                         // if( code !== code ) error\r
216                         //console.log( code );\r
217                         result[ ++n ] = toChrCode( code );\r
218                         decode = false;\r
219                 } else {\r
220                         chr = x.charAt( i );\r
221                         if( !( decode = chr === '%' ) ){\r
222                                 result[ ++n ] = chr;                    \r
223                         };\r
224                 };\r
225         };\r
226         return result.join( '' );\r
227 };\r
228 \r
229 window.decodeURI || (window.decodeURI = _builtin_decodeURI);\r
230 window.decodeURIComponent || (window.decodeURIComponent = window.decodeURI);\r
231 \r
232 \r
233 /*\r
234  * String\r
235  */\r
236 \r
237 // replace(RegExp, Function)対応\r
238 /*\r
239 if (window.ActiveXObject ? !Number.prototype.toFixed : (!navigator.taintEnabled && !document.createElement("input").setSelectionRange))\r
240         (function () {\r
241                 var g = String.prototype.replace;\r
242                 String.prototype.replace = function (x, y) {\r
243                         var s = this, z = y;\r
244                         // 第二引数が関数\r
245                         if (y instanceof Function) {\r
246                                 // 第一引数が正規表現\r
247                                 if (x instanceof RegExp) {\r
248                                         // その上、グローバルマッチ\r
249                                         if (x.global || /^\/.*g$/.test(x)) {\r
250                                                 var r = [], m;\r
251                                                 while ((m = x.exec(s)) != null) {\r
252                                                         var i = m.index;\r
253                                                         r[r.length] = s.slice(0, i);\r
254                                                         s = s.slice(i + m[0].length);\r
255                                                         r[r.length] = y.apply(null, m.concat(i, this));\r
256                                                 }\r
257                                                 r[r.length] = s;\r
258                                                 return r.join("");\r
259                                         }\r
260                                         var m = x.exec(s);\r
261                                         if (!m)\r
262                                                 return s;\r
263                                         z = y.apply(null, m.concat(m.index, s));\r
264                                 }\r
265                                 else {\r
266                                         var i = s.indexOf(x);\r
267                                         if (i < 0)\r
268                                                 return s;\r
269                                         z = y(x, i, s);\r
270                                 }\r
271                         }\r
272                         return g.call(s, x, z);\r
273                 };\r
274         })(); */\r
275         \r
276 /*\r
277  * Safari の JavaScript の不備 \r
278  * http://nanto.asablo.jp/blog/2006/01/13/209495\r
279  * \r
280  * web.paulownia.jp - JavaScriptとクロージャ\r
281  * https://web.archive.org/web/20070526063400/http://web.paulownia.jp/script/oop/closure.html\r
282  * MacOSX 10.3のsafariにはhasOwnPropertyが実装されていないので、独自に追加する必要があります。\r
283  * \r
284  * prototype汚染問題でhasOwnPropertyを使わないクロスブラウザな方法\r
285  * http://os0x.hatenablog.com/entry/20080901/1220272509\r
286  */\r
287 /*\r
288 Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
289                 var proto = this.constructor && this.constructor.prototype,\r
290                         __p__ = proto && proto.__proto__,\r
291                         v     = this[ p ],\r
292                         r     = false;\r
293                 \r
294                 if( __p__ ) proto.__proto__ = null;\r
295                 \r
296                 if( p in this ){\r
297                         if( v !== v ){\r
298                                 if( proto && ( p in proto ) && proto[ p ] !== proto[ p ] ){ // proto[ p ] is NaN\r
299                                         proto[ p ] = 0; // different value\r
300                                         r = this[ p ] !== this[ p ]; // isNaN?\r
301                                         proto[ p ] = v; // set NaN\r
302                                 } else {\r
303                                         r = true;\r
304                                 };\r
305                         } else\r
306                         if( proto && p in proto && proto[ p ] === v ){\r
307                                 // this と proto に同名で同値が書かれている可能性あり\r
308                                 proto[ p ] = v + ' '; // different value\r
309                                 r = v === this[ p ];\r
310                                 proto[ p ] = v;\r
311                         } else {\r
312                                 r = true;\r
313                         };\r
314                 };\r
315                 \r
316                 if( __p__ ) proto.__proto__ = __p__;\r
317                 \r
318                 return r;\r
319   }); */\r
320 /*\r
321 Object.prototype.hasOwnProperty || (Object.prototype.hasOwnProperty = function( p ){\r
322                 var proto = this.constructor && this.constructor.prototype,\r
323                         __p__ = proto && proto.__proto__,\r
324                         r     = false,//!!( __p__ && ( proto.__proto__ = null ) )\r
325                         _pro_, v, isNaN;\r
326                 \r
327                 if( __p__ ) proto.__proto__ = null;\r
328                 if( this.__proto__ ){\r
329                         _pro_ = this.__proto__;\r
330                         this.__proto__ = null;\r
331                 };\r
332                 \r
333                 if( p === '__proto__' ){\r
334                         r = !!_pro_;\r
335                 } else {\r
336                         v     = this[ p ];\r
337                         isNaN = v !== v;                \r
338                         \r
339                         if( p in this ){\r
340                                 if( proto && p in proto && ( proto[ p ] === v ) ^ isNaN ){ //true + false, false + true\r
341                                         // this と proto に同名で同値が書かれている可能性あり\r
342                                         proto[ p ] = v + ' '; // different value\r
343                                         r = ( v === this[ p ] ) ^ isNaN; // true + false, false + true\r
344                                         proto[ p ] = v;\r
345                                 } else {\r
346                                         r = true;\r
347                                 };\r
348                         };                      \r
349                 };\r
350 \r
351                 if( __p__ ) proto.__proto__ = __p__;\r
352                 if( _p_ ) this.__proto__ = _pro_;\r
353                 return r;\r
354   }); */