OSDN Git Service

Version 0.6.5
[pettanr/clientJs.git] / 0.6.x / js / core / 19_XQuery.js
1 var X = X || {};\r
2 \r
3 ;(function( window, document, undefined ){\r
4 \r
5 var $LIST     = [];\r
6 var HIDE_LIST = [];\r
7 \r
8 var Util = {\r
9         extend : function( target, override ){\r
10                 for( var k in override ){\r
11                         target[ k ] = override[ k ];\r
12                 };\r
13         },\r
14         copyArray : function( ary ){\r
15                 var ret = [],\r
16                         i   = ary.length;\r
17                 for( ; i; ){\r
18                         ret[ --i ] = ary[ i ];\r
19                 };\r
20                 return ret;\r
21         },\r
22         find$ : function( v ){\r
23                 var list = HIDE_LIST,\r
24                         i    = list.length;\r
25                 for( ; i; ){\r
26                         if( list[ --i ].elm  === v || list[ i ].elms === v ) return $LIST[ i ];\r
27                 };\r
28         },\r
29         getPrivate : function( $ ){\r
30                 var i = $LIST.indexOf( $ );\r
31                 if( i === -1 ){\r
32                         return HIDE_LIST[ HIDE_LIST.length ] = {};\r
33                 };\r
34                 return HIDE_LIST[ i ];\r
35         },\r
36         each : function( $, funcName, args ){\r
37                 var data = Util.getPrivate( $ ),\r
38                         elms = data.elms,\r
39                         _$;\r
40                 for( var i = 0, l = elms.length; i < l; ++i ){\r
41                         _$ = new X.$( elms[ i ] );\r
42                         _$[ funcName ].apply( _$, args );\r
43                 };\r
44         },\r
45         is$ : function( v ){\r
46                 return $LIST.indexOf(v) !== -1;\r
47         },\r
48         isHTMLList : function( v ){\r
49                 var type = X.Type;\r
50                 if( !type.isArray( v ) ) return false;\r
51                 for( var i = v.length; i; ){\r
52                         if( !type.isHTMLElement( v[ --i ] ) ) return false;\r
53                 };\r
54                 return true;\r
55         },\r
56         isHTMLString : function(v){\r
57                 if( typeof v === 'string' && v.charAt(0) === '<' && v.charAt(v.length - 1) === '>' ){\r
58                         return true;\r
59                 };\r
60                 return false;\r
61         },\r
62         isSelectorString : function(v){\r
63                 return typeof v === 'string';\r
64         },\r
65         getKind : function(v){\r
66                 return Util.is$(v)               ? 0 :\r
67                                 Util.isHTMLList(v)       ? 5 :\r
68                                 X.Type.isHTMLElement(v)  ? 1 :\r
69                                 Util.isHTMLString(v)     ? 2 :\r
70                                 Util.isSelectorString(v) ? 3 : 4;\r
71         }\r
72 };\r
73 \r
74 if( !document.getElementById && document.all ){\r
75         Util.ie4remove = function( parent, target, html, save ){\r
76                 var children = X.Dom.getChildNodes( parent ),\r
77                         l = children.length,\r
78                         i = 0, child, $, data;\r
79                 for( ; i < l; ++i ){\r
80                         child = children[ i ];\r
81                         if( child === target ){\r
82                                 $ = Util.find$( child );\r
83                                 if( $ ){\r
84                                         data = Util.getPrivate( $ );\r
85                                         data.htmlText = child.outerHTML;\r
86                                         delete data.elm;\r
87                                 };\r
88                         } else\r
89                         if( typeof child !== 'string' ){\r
90                                 /*\r
91                                  * 要素の書き換え前に UID を記入して要素を復帰できるようにする\r
92                                  */\r
93                                 $ = Util.find$( child );\r
94                                 if( $ ){\r
95                                         $.UID = '' + save.length;\r
96                                         child.setAttribute( 'UID', $.UID );\r
97                                         save[ save.length ] = $;\r
98                                 };\r
99                                 Util.ie4remove( child, null, null, save );\r
100                                 if( html ) html[ html.length ] = child.outerHTML;\r
101                         } else\r
102                         if( html ) html[ html.length ] = child;\r
103                 };\r
104         };\r
105 };\r
106 \r
107 \r
108 X.$ = function( v ){\r
109         if( !this || this.append !== X.$.prototype.append ) return new X.$( v );\r
110         \r
111         var elm, elms, htmlText, $, data;\r
112 \r
113         switch( Util.getKind(v) ){\r
114                 case 0 :\r
115                         return v;\r
116                 case 1 :\r
117                         elm  = v;\r
118                         $    = Util.find$( v );\r
119                         if( $ ) return $;                       \r
120                         break;\r
121                 case 2 :\r
122                         htmlText = v;\r
123                         break;\r
124                 case 3 :\r
125                         return this.find( v );\r
126                 case 5 :\r
127                         elms = v;\r
128                         break;\r
129         };\r
130         \r
131         data = Util.getPrivate( this );\r
132         $LIST[ $LIST.length ] = this;\r
133         if( elm )      data.elm      = elm;\r
134         if( elms )     data.elms     = elms;\r
135         if( htmlText ) data.htmlText = htmlText;\r
136 };\r
137 \r
138 Util.extend(\r
139         X.$.prototype,\r
140         {\r
141                 append :\r
142                         document.getElementById ?\r
143                                 (function( v ){\r
144                                         var data = Util.getPrivate( this );\r
145                                         if( data.elm ){\r
146                                                 switch( Util.getKind(v) ){\r
147                                                         case 0 :\r
148                                                                 data.elm.appendChild( Util.getPrivate( v ).elm );\r
149                                                                 return this;\r
150                                                         case 1 :\r
151                                                                 data.elm.appendChild( v );\r
152                                                                 return this;\r
153                                                         case 2 :\r
154                                                                 // data.elm.appendChild(  );\r
155                                                                 return this;\r
156                                                 };                                              \r
157                                         } else {\r
158                                                 if( !data.children ) data.children = [];\r
159                                                 data.children[ data.children.length ] = v;\r
160                                         };\r
161                                         return this;\r
162                                 }) :\r
163                         document.all ?\r
164                                 (function( v ){\r
165                                         var data = Util.getPrivate( this ),\r
166                                                 elm  = data.elm,\r
167                                                 _data, html;\r
168                                         if( elm ){\r
169                                                 switch( Util.getKind( v ) ){\r
170                                                         case 0 :\r
171                                                                 _data = Util.getPrivate( v );\r
172                                                                 elm.insertAdjacentHTML( 'BeforeEnd', _data.htmlText || elm && elm.outerHTML );\r
173                                                                 _data.elm = elm.children[ elm.children.length - 1 ];\r
174                                                                 return this;\r
175                                                         case 1 :\r
176                                                                 data.elm.insertAdjacentHTML( 'BeforeEnd', v.outerHTML );\r
177                                                                 return this;\r
178                                                         case 2 :\r
179                                                                 data.elm.insertAdjacentHTML( 'BeforeEnd', v );\r
180                                                                 return this;\r
181                                                 };              \r
182                                         } else {\r
183                                                 if( !data.children ){\r
184                                                         data.children = [ v ];\r
185                                                 } else {\r
186                                                         data.children[ data.children.length ] = v;\r
187                                                 };\r
188                                         };\r
189                                         return this;\r
190                                 }) :\r
191                                 (function(){}),\r
192                 appendTo :\r
193                         document.getElementById ?\r
194                                 (function( v ){\r
195                                         var data = Util.getPrivate( this );\r
196                                         switch( Util.getKind(v) ){\r
197                                                 case 0 :\r
198                                                         v.append( this );\r
199                                                         return this;\r
200                                                 case 1 :\r
201                                                         v.appendChild( data.elm );\r
202                                                         return this;\r
203                                                 case 2 :\r
204                                                         X.$(v).append(this)\r
205                                                         return this;\r
206                                         };\r
207                                         return this;\r
208                                 }) :\r
209                         document.all ?\r
210                                 (function( v ){\r
211                                         var data = Util.getPrivate( this ),\r
212                                                 html, i, children;\r
213                                         switch( Util.getKind( v ) ){\r
214                                                 case 0 :\r
215                                                         v.append( this );\r
216                                                         return this;\r
217                                                 case 1 :\r
218                                                         if( data.elm ){\r
219                                                                 html = data.elm.outerHTML;\r
220                                                                 this.remove();\r
221                                                         } else {\r
222                                                                 html = data.htmlText;\r
223                                                         };\r
224                                                         if( html ){\r
225                                                                 v.insertAdjacentHTML( 'BeforeEnd', html ); // elm の場合と string の場合がある\r
226                                                                 if( data.htmlText ){\r
227                                                                         delete data.htmlText;\r
228                                                                 };\r
229                                                                 data.elm = v.children[ v.children.length - 1 ];\r
230                                                         };\r
231                                                         return this;\r
232                                                 case 2 :\r
233                                                         X.$( v ).append( this );\r
234                                                         return this;\r
235                                         };\r
236 \r
237                                         return this;\r
238                                 }) :\r
239                                 (function(){}),\r
240                 remove :\r
241                         document.getElementById ?\r
242                                 (function(){\r
243                                         var data = Util.getPrivate( this );\r
244                                         data.elm.parentNode && data.elm.parentNode.removeChild( data.elm );\r
245                                         data.htmlText = data.elm.outerHTML;\r
246                                         delete data.elm;\r
247                                         return this;\r
248                                 }) :\r
249                         document.all ?\r
250                                 (function(){\r
251                                         var data = Util.getPrivate( this ),\r
252                                                 elm  = data.elm, \r
253                                                 parent, i, j,\r
254                                                 html, save, all, uid;\r
255                                         if( !elm ) return;\r
256                                         \r
257                                         Util.ie4remove( parent = elm.parentElement, elm, html = [], save = [] );\r
258                                         parent.innerHTML = html.join( '' );\r
259                                         all = Util.copyArray( parent.all );\r
260                         \r
261                                         for( i = save.length; i; ){\r
262                                                 $   = save[ --i ];\r
263                                                 uid = $.UID;\r
264                                                 for( j = all.length; j; ){\r
265                                                         elm = all[ --j ];\r
266                                                         if( elm.UID === uid ){\r
267                                                                 Util.getPrivate( $ ).elm = elm;\r
268                                                                 delete $.UID;\r
269                                                                 elm.removeAttribute( 'UID' );\r
270                                                                 all.splice( j, 1 );     \r
271                                                                 break;\r
272                                                         } else\r
273                                                         if( !elm.UID ){\r
274                                                                 all.splice( j, 1 );\r
275                                                         };\r
276                                                 };              \r
277                                         };\r
278                                         return this;\r
279                                 }) :\r
280                                 (function(){}),\r
281                 destroy : function(){\r
282                         \r
283                 },\r
284                 before :\r
285                         document.getElementById ?\r
286                                 (function( v ){\r
287                                         var data = Util.getPrivate( this ),\r
288                                                 elm  = data.elm, div;\r
289                                         if( elm ){\r
290                                                 if( typeof v === 'string' ){\r
291                                                         div = document.createElement( 'div' );\r
292                                                         div.innerHTML = v;\r
293                                                         document.body.appendChild( div );\r
294                                                         v = div.firstChild;\r
295                                                         document.body.removeChild( div );\r
296                                                 };\r
297                                                 elm.parentNode && elm.parentNode.insertBefore( v, elm );\r
298                                         };\r
299                                         return this;\r
300                                 }) :\r
301                         document.all ?\r
302                                 (function( v ){\r
303                                         var data = Util.getPrivate( this ),\r
304                                                 elm  = data.elm,\r
305                                                 parent, _data, _elm, i, children;\r
306                                         if( !elm ) return this;\r
307                                         parent = elm.parentElement;\r
308                                         \r
309                                         switch( Util.getKind(v) ){\r
310                                                 case 0 :\r
311                                                         if( this === v ) return this;\r
312                                                         _data = Util.getPrivate( v );\r
313                                                         _elm  = _data.elm;\r
314                                                         if( _elm ){\r
315                                                                 if( parent === _elm || _elm.contains( elm ) === true ) return this;\r
316                                                                 v.remove();\r
317                                                         };\r
318                                                         elm.insertAdjacentHTML( 'BeforeBegin', _data.htmlText );\r
319                                                         for( children = X.Dom.getChildNodes( parent ), i = children.length; i; ){\r
320                                                                 if( children[ --i ] === elm ){\r
321                                                                         _data.elm = children[ --i ];\r
322                                                                         delete _data.htmlText;\r
323                                                                         break;\r
324                                                                 };\r
325                                                         };\r
326                                                         return this;\r
327                                                 case 1 :\r
328                                                         elm && elm.insertAdjacentHTML( 'BeforeBegin', v.outerHTML );\r
329                                                         return this;\r
330                                                 case 2 :\r
331                                                         elm && elm.insertAdjacentHTML( 'BeforeBegin', v );\r
332                                                         return this;\r
333                                         };\r
334                                         return this;\r
335                                 }) :\r
336                                 (function(){}),\r
337                 after :\r
338                         document.getElementById ?\r
339                                 (function( v ){\r
340                                         var data = Util.getPrivate( this ),\r
341                                                 elm  = data.elm, div;\r
342                                         if( elm ){\r
343                                                 if( typeof v === 'string' ){\r
344                                                         div = document.createElement( 'div' );\r
345                                                         div.innerHTML = v;\r
346                                                         document.body.appendChild( div );\r
347                                                         v = div.firstChild;\r
348                                                         document.body.removeChild( div );\r
349                                                 };\r
350                                                 elm.parentNode && elm.parentNode.insertBefore( v, elm.nextSibling );\r
351                                         };\r
352                                         return this;\r
353                                 }) :\r
354                         document.all ?\r
355                                 (function( v ){\r
356                                         var data = Util.getPrivate( this ),\r
357                                                 elm  = data.elm,\r
358                                                 parent, _data, _elm, i, children;\r
359                                         if( !elm ) return this;\r
360                                         parent = elm.parentElement;\r
361                                         \r
362                                         switch( Util.getKind(v) ){\r
363                                                 case 0 :\r
364                                                         if( this === v ) return this;\r
365                                                         _data = Util.getPrivate( v );\r
366                                                         _elm  = _data.elm;\r
367                                                         if( _elm ){\r
368                                                                 if( parent === _elm || _elm.contains( elm ) === true ) return this;\r
369                                                                 v.remove();\r
370                                                         };\r
371                                                         elm.insertAdjacentHTML( 'AfterEnd', _data.htmlText );\r
372                                                         for( children = X.Dom.getChildNodes( parent ), i = children.length; i; ){\r
373                                                                 if( children[ --i ] === elm ){\r
374                                                                         _data.elm = children[ ++i ];\r
375                                                                         delete _data.htmlText;\r
376                                                                         break;\r
377                                                                 };\r
378                                                         };\r
379                                                         return this;\r
380                                                 case 1 :\r
381                                                         elm && elm.insertAdjacentHTML( 'AfterEnd', v.outerHTML ); // elm の場合と string の場合がある\r
382                                                         return this;\r
383                                                 case 2 :\r
384                                                         elm && elm.insertAdjacentHTML( 'AfterEnd', v ); // elm の場合と string の場合がある\r
385                                                         return this;\r
386                                         };\r
387                                         return this;\r
388                                 }) :\r
389                                 (function(){}),\r
390                 find : function( v ){\r
391                         var querys = parser(v), query;\r
392                         var selector, name;\r
393                         var key, operator, value;\r
394                         var elms = [], _elms, j, m;\r
395                         var dom = X.Dom;\r
396                         for( var i = 0, l = querys.length; i < l; ++i ){\r
397                                 query = querys[ i ];\r
398                                 if( typeof query === 'number' ){\r
399                                         \r
400                                 } else\r
401                                 if( query.length === 2 ){\r
402                                         name  = query[ 1 ];\r
403                                         _elms = [];\r
404                                         j     = 0;\r
405                                         m     = elms.length;\r
406                                         switch( query[ 0 ] ){\r
407                                                 case 4 : // # id\r
408                                                         _elms.push( dom.getElementById( name ) );\r
409                                                         break;\r
410                                                 case 5 : // . classname\r
411                                                         for( ; j < m; ++j ){\r
412                                                                 _elms = _elms.concat( dom.getElementsByClassName( elms[ j ], name ));\r
413                                                         };\r
414                                                         break;\r
415                                                 case 6 : // :\r
416                                                         break;\r
417                                                 case 7 : // [\r
418                                                         break;  \r
419                                                 case 8 : // . tagname\r
420                                                         for( ; j < m; ++j ){\r
421                                                                 _elms = _elms.concat( dom.getElementsByTagName( elms[ j ], name ));\r
422                                                         };\r
423                                                         break;\r
424                                         };\r
425                                         elms = _elms;\r
426                                 } else {\r
427                                         \r
428                                 };\r
429                         };\r
430                         return new X.$( elms );\r
431                 },\r
432                 each : function( func /* func(index){ return false } */ ){\r
433                         var data = Util.getPrivate( this ),\r
434                                 elms = data.elms, $s = [];\r
435                         for( var i = 0, l = elms.length; i < l; ++i ){\r
436                                 $s[ $s.length ] = new X.$( elms[ i ] );\r
437                         };\r
438                         for( i = 0, l = $s.length; i < l; ++i ){\r
439                                 if( func.call( $s[ i ], i ) === false ) break;\r
440                         };\r
441                         return this;\r
442                 },\r
443                 html : function( v ){\r
444                         var data = Util.getPrivate( this ),\r
445                                 elm  = data.elm;\r
446                         return elm ? elm.innerHTML : data.htmlText;\r
447                 }\r
448         }\r
449 );\r
450 \r
451 HASH_SELECTOR = {\r
452         '>'   : 1,\r
453         '+'   : 2,\r
454         '~'   : 3,\r
455         '#'   : 4,\r
456         '.'   : 5,\r
457         ':'   : 6,\r
458         '['   : 7,\r
459         scope : 8,\r
460         root  : 9,\r
461         link  : 10\r
462 };\r
463 SELECTORS = ' >+~#.:[';\r
464 PASER = {\r
465         START                : 0,\r
466         FINISH               : 99,\r
467         SELECTOR             : 1,\r
468         // TAG_STRAT            : 5,\r
469         ERROR                : -99,\r
470         NAME                 : 2,\r
471         ATTR_FILTER_KEY      : 3,\r
472         ATTR_FILTER_OPERATOR : 4,\r
473         ATTR_FILTER_VALUE    : 5\r
474 };\r
475 OPERATORS = { "=": 1, "!=": 2, "~=": 3, "^=": 4, "$=": 5, "*=": 6, "|=": 7 };\r
476 ALPHABET  = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-0123456789';\r
477 \r
478 function parser( query ){\r
479         query += ' ';\r
480         var result = [];\r
481         var i = 0, l = query.length, s;\r
482         var selectors = [];\r
483         var mode = PASER.START;\r
484         var name = '', str, key, value, selector = -1, operator, lastSelector, nameString, nameFirst, escape;\r
485         for( ; i < l; ++i ){\r
486                 str        = query.charAt( i );\r
487                 nameString = ALPHABET.indexOf( str ) !== -1;\r
488                 nameFirst  = nameString && ALPHABET.indexOf( str ) < 52;\r
489                 escape     = str === '\\';\r
490                 switch( mode ){\r
491                         case PASER.NAME :\r
492                                 if( nameString ){\r
493                                         name += str;\r
494                                         break;\r
495                                 } else\r
496                                 if( escape && selector === 4 ){\r
497                                         str = query.charAt( i + 1 );\r
498                                         if( ':.'.indexOf( str ) !== -1 ){\r
499                                                 name += str;\r
500                                                 break;\r
501                                         };\r
502                                 } else {\r
503                                         result[ result.length ] = [ selector, name ];\r
504                                         mode = PASER.START;\r
505                                 };\r
506                         case PASER.START :\r
507                                 selector = SELECTORS.indexOf( str );\r
508                                 if( selector === -1 && nameFirst ){\r
509                                         selector = 8; // tag name\r
510                                         mode = PASER.NAME;\r
511                                         name = str;\r
512                                 } else\r
513                                 if( selector === 7 ){ // [\r
514                                         mode = PASER.ATTR_FILTER_START;\r
515                                 } else\r
516                                 if( 0 <= selector ){\r
517                                         name = '';\r
518                                         mode = selector < 4 ? PASER.FINISH : PASER.SELECTOR;// > ,+,~\r
519                                         if( selector === 0 && lastSelector === 0 ) mode = PASER.START; // 子孫セレクタ\r
520                                 } else\r
521                                 if( str !== ' ' ){\r
522                                         mode = PASER.ERROR;\r
523                                 };\r
524                                 break;\r
525                         case PASER.SELECTOR :\r
526                                 if( nameFirst ){\r
527                                         name = str;\r
528                                         mode = PASER.NAME;\r
529                                         break;\r
530                                 };\r
531                                 mode = PASER.ERROR;\r
532                                 break;\r
533                         case PASER.ATTR_FILTER_START :\r
534                                 if( nameFirst ){\r
535                                         mode  = PASER.ATTR_FILTER_KEY;\r
536                                         key   = str;\r
537                                         value = '';\r
538                                         break;\r
539                                 };\r
540                                 mode = PASER.ERROR;\r
541                                 break;\r
542                         case PASER.ATTR_FILTER_KEY :\r
543                                 operator = OPERATORS[ query.substr( i, 2 ) ];\r
544                                 if( nameString ){\r
545                                         key += str;\r
546                                         break;\r
547                                 } else\r
548                                 if( str === '=' ){\r
549                                         operator = 1;\r
550                                         mode = PASER.ATTR_FILTER_VALUE;\r
551                                 } else\r
552                                 if( operator !== -1 ){\r
553                                         mode = PASER.ATTR_FILTER_VALUE;\r
554                                         ++i;\r
555                                 } else\r
556                                 if( str !== ' ' ){\r
557                                         mode = PASER.ERROR;\r
558                                 };\r
559                                 break;\r
560                         case PASER.ATTR_FILTER_VALUE :\r
561                                 if( nameString ){\r
562                                         value += str;\r
563                                         break;\r
564                                 } else\r
565                                 if( str === ']' ){\r
566                                         mode = PASER.FINISH;\r
567                                         break;\r
568                                 };\r
569                                 mode = PASER.ERROR;\r
570                                 break;\r
571                         default :\r
572                 };\r
573                 //alert( str + ' ' + mode + ' ' + selector + ' ' + name + ' ' + nameFirst )\r
574                 if( mode === PASER.ERROR ) return [];\r
575                 \r
576                 if( mode === PASER.FINISH && 0 <= selector ){\r
577                         result[ result.length ] = selector === 7 ? [ key, operator, value ] :\r
578                                                                                 selector < 4 ? selector :\r
579                                                                                 [ selector, name ];\r
580                         lastSelector = selector;\r
581                         selector = -1;\r
582                         mode = PASER.START;\r
583                 };\r
584         };\r
585         return result;\r
586 };\r
587 \r
588         \r
589 })( window, document );