Page Menu
Home
Code
Search
Configure Global Search
Log In
Files
F390711
prototype.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
122 KB
Subscribers
None
prototype.js
View Options
/* Prototype JavaScript framework, version 1.6.0.1
* (c) 2005-2007 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
*
*--------------------------------------------------------------------------*/
var
Prototype
=
{
Version
:
'1.6.0.1'
,
Browser
:
{
IE
:
!!
(
window
.
attachEvent
&&
!
window
.
opera
),
Opera
:
!!
window
.
opera
,
WebKit
:
navigator
.
userAgent
.
indexOf
(
'AppleWebKit/'
)
>
-
1
,
Gecko
:
navigator
.
userAgent
.
indexOf
(
'Gecko'
)
>
-
1
&&
navigator
.
userAgent
.
indexOf
(
'KHTML'
)
==
-
1
,
MobileSafari
:
!!
navigator
.
userAgent
.
match
(
/Apple.*Mobile.*Safari/
)
},
BrowserFeatures
:
{
XPath
:
!!
document
.
evaluate
,
ElementExtensions
:
!!
window
.
HTMLElement
,
SpecificElementExtensions
:
document
.
createElement
(
'div'
).
__proto__
&&
document
.
createElement
(
'div'
).
__proto__
!==
document
.
createElement
(
'form'
).
__proto__
},
ScriptFragment
:
'<script[^>]*>([\\S\\s]*?)<\/script>'
,
JSONFilter
:
/^\/\*-secure-([\s\S]*)\*\/\s*$/
,
emptyFunction
:
function
()
{
},
K
:
function
(
x
)
{
return
x
}
};
if
(
Prototype
.
Browser
.
MobileSafari
)
Prototype
.
BrowserFeatures
.
SpecificElementExtensions
=
false
;
/* Based on Alex Arnell's inheritance implementation. */
var
Class
=
{
create
:
function
()
{
var
parent
=
null
,
properties
=
$A
(
arguments
);
if
(
Object
.
isFunction
(
properties
[
0
]))
parent
=
properties
.
shift
();
function
klass
()
{
this
.
initialize
.
apply
(
this
,
arguments
);
}
Object
.
extend
(
klass
,
Class
.
Methods
);
klass
.
superclass
=
parent
;
klass
.
subclasses
=
[];
if
(
parent
)
{
var
subclass
=
function
()
{
};
subclass
.
prototype
=
parent
.
prototype
;
klass
.
prototype
=
new
subclass
;
parent
.
subclasses
.
push
(
klass
);
}
for
(
var
i
=
0
;
i
<
properties
.
length
;
i
++
)
klass
.
addMethods
(
properties
[
i
]);
if
(
!
klass
.
prototype
.
initialize
)
klass
.
prototype
.
initialize
=
Prototype
.
emptyFunction
;
klass
.
prototype
.
constructor
=
klass
;
return
klass
;
}
};
Class
.
Methods
=
{
addMethods
:
function
(
source
)
{
var
ancestor
=
this
.
superclass
&&
this
.
superclass
.
prototype
;
var
properties
=
Object
.
keys
(
source
);
if
(
!
Object
.
keys
({
toString
:
true
}).
length
)
properties
.
push
(
"toString"
,
"valueOf"
);
for
(
var
i
=
0
,
length
=
properties
.
length
;
i
<
length
;
i
++
)
{
var
property
=
properties
[
i
],
value
=
source
[
property
];
if
(
ancestor
&&
Object
.
isFunction
(
value
)
&&
value
.
argumentNames
().
first
()
==
"$super"
)
{
var
method
=
value
,
value
=
Object
.
extend
((
function
(
m
)
{
return
function
()
{
return
ancestor
[
m
].
apply
(
this
,
arguments
)
};
})(
property
).
wrap
(
method
),
{
valueOf
:
function
()
{
return
method
},
toString
:
function
()
{
return
method
.
toString
()
}
});
}
this
.
prototype
[
property
]
=
value
;
}
return
this
;
}
};
var
Abstract
=
{
};
Object
.
extend
=
function
(
destination
,
source
)
{
for
(
var
property
in
source
)
destination
[
property
]
=
source
[
property
];
return
destination
;
};
Object
.
extend
(
Object
,
{
inspect
:
function
(
object
)
{
try
{
if
(
Object
.
isUndefined
(
object
))
return
'undefined'
;
if
(
object
===
null
)
return
'null'
;
return
object
.
inspect
?
object
.
inspect
()
:
object
.
toString
();
}
catch
(
e
)
{
if
(
e
instanceof
RangeError
)
return
'...'
;
throw
e
;
}
},
toJSON
:
function
(
object
)
{
var
type
=
typeof
object
;
switch
(
type
)
{
case
'undefined'
:
case
'function'
:
case
'unknown'
:
return
;
case
'boolean'
:
return
object
.
toString
();
}
if
(
object
===
null
)
return
'null'
;
if
(
object
.
toJSON
)
return
object
.
toJSON
();
if
(
Object
.
isElement
(
object
))
return
;
var
results
=
[];
for
(
var
property
in
object
)
{
var
value
=
Object
.
toJSON
(
object
[
property
]);
if
(
!
Object
.
isUndefined
(
value
))
results
.
push
(
property
.
toJSON
()
+
': '
+
value
);
}
return
'{'
+
results
.
join
(
', '
)
+
'}'
;
},
toQueryString
:
function
(
object
)
{
return
$H
(
object
).
toQueryString
();
},
toHTML
:
function
(
object
)
{
return
object
&&
object
.
toHTML
?
object
.
toHTML
()
:
String
.
interpret
(
object
);
},
keys
:
function
(
object
)
{
var
keys
=
[];
for
(
var
property
in
object
)
keys
.
push
(
property
);
return
keys
;
},
values
:
function
(
object
)
{
var
values
=
[];
for
(
var
property
in
object
)
values
.
push
(
object
[
property
]);
return
values
;
},
clone
:
function
(
object
)
{
return
Object
.
extend
({
},
object
);
},
isElement
:
function
(
object
)
{
return
object
&&
object
.
nodeType
==
1
;
},
isArray
:
function
(
object
)
{
return
object
&&
object
.
constructor
===
Array
;
},
isHash
:
function
(
object
)
{
return
object
instanceof
Hash
;
},
isFunction
:
function
(
object
)
{
return
typeof
object
==
"function"
;
},
isString
:
function
(
object
)
{
return
typeof
object
==
"string"
;
},
isNumber
:
function
(
object
)
{
return
typeof
object
==
"number"
;
},
isUndefined
:
function
(
object
)
{
return
typeof
object
==
"undefined"
;
}
});
Object
.
extend
(
Function
.
prototype
,
{
argumentNames
:
function
()
{
var
names
=
this
.
toString
().
match
(
/^[\s\(]*function[^(]*\((.*?)\)/
)[
1
].
split
(
","
).
invoke
(
"strip"
);
return
names
.
length
==
1
&&
!
names
[
0
]
?
[]
:
names
;
},
bind
:
function
()
{
if
(
arguments
.
length
<
2
&&
Object
.
isUndefined
(
arguments
[
0
]))
return
this
;
var
__method
=
this
,
args
=
$A
(
arguments
),
object
=
args
.
shift
();
return
function
()
{
return
__method
.
apply
(
object
,
args
.
concat
(
$A
(
arguments
)));
}
},
bindAsEventListener
:
function
()
{
var
__method
=
this
,
args
=
$A
(
arguments
),
object
=
args
.
shift
();
return
function
(
event
)
{
return
__method
.
apply
(
object
,
[
event
||
window
.
event
].
concat
(
args
));
}
},
curry
:
function
()
{
if
(
!
arguments
.
length
)
return
this
;
var
__method
=
this
,
args
=
$A
(
arguments
);
return
function
()
{
return
__method
.
apply
(
this
,
args
.
concat
(
$A
(
arguments
)));
}
},
delay
:
function
()
{
var
__method
=
this
,
args
=
$A
(
arguments
),
timeout
=
args
.
shift
()
*
1000
;
return
window
.
setTimeout
(
function
()
{
return
__method
.
apply
(
__method
,
args
);
},
timeout
);
},
wrap
:
function
(
wrapper
)
{
var
__method
=
this
;
return
function
()
{
return
wrapper
.
apply
(
this
,
[
__method
.
bind
(
this
)].
concat
(
$A
(
arguments
)));
}
},
methodize
:
function
()
{
if
(
this
.
_methodized
)
return
this
.
_methodized
;
var
__method
=
this
;
return
this
.
_methodized
=
function
()
{
return
__method
.
apply
(
null
,
[
this
].
concat
(
$A
(
arguments
)));
};
}
});
Function
.
prototype
.
defer
=
Function
.
prototype
.
delay
.
curry
(
0.01
);
Date
.
prototype
.
toJSON
=
function
()
{
return
'"'
+
this
.
getUTCFullYear
()
+
'-'
+
(
this
.
getUTCMonth
()
+
1
).
toPaddedString
(
2
)
+
'-'
+
this
.
getUTCDate
().
toPaddedString
(
2
)
+
'T'
+
this
.
getUTCHours
().
toPaddedString
(
2
)
+
':'
+
this
.
getUTCMinutes
().
toPaddedString
(
2
)
+
':'
+
this
.
getUTCSeconds
().
toPaddedString
(
2
)
+
'Z"'
;
};
var
Try
=
{
these
:
function
()
{
var
returnValue
;
for
(
var
i
=
0
,
length
=
arguments
.
length
;
i
<
length
;
i
++
)
{
var
lambda
=
arguments
[
i
];
try
{
returnValue
=
lambda
();
break
;
}
catch
(
e
)
{
}
}
return
returnValue
;
}
};
RegExp
.
prototype
.
match
=
RegExp
.
prototype
.
test
;
RegExp
.
escape
=
function
(
str
)
{
return
String
(
str
).
replace
(
/([.*+?^=!:${}()|[\]\/\\])/g
,
'\\$1'
);
};
/*--------------------------------------------------------------------------*/
var
PeriodicalExecuter
=
Class
.
create
({
initialize
:
function
(
callback
,
frequency
)
{
this
.
callback
=
callback
;
this
.
frequency
=
frequency
;
this
.
currentlyExecuting
=
false
;
this
.
registerCallback
();
},
registerCallback
:
function
()
{
this
.
timer
=
setInterval
(
this
.
onTimerEvent
.
bind
(
this
),
this
.
frequency
*
1000
);
},
execute
:
function
()
{
this
.
callback
(
this
);
},
stop
:
function
()
{
if
(
!
this
.
timer
)
return
;
clearInterval
(
this
.
timer
);
this
.
timer
=
null
;
},
onTimerEvent
:
function
()
{
if
(
!
this
.
currentlyExecuting
)
{
try
{
this
.
currentlyExecuting
=
true
;
this
.
execute
();
}
finally
{
this
.
currentlyExecuting
=
false
;
}
}
}
});
Object
.
extend
(
String
,
{
interpret
:
function
(
value
)
{
return
value
==
null
?
''
:
String
(
value
);
},
specialChar
:
{
'\b'
:
'\\b'
,
'\t'
:
'\\t'
,
'\n'
:
'\\n'
,
'\f'
:
'\\f'
,
'\r'
:
'\\r'
,
'\\'
:
'\\\\'
}
});
Object
.
extend
(
String
.
prototype
,
{
gsub
:
function
(
pattern
,
replacement
)
{
var
result
=
''
,
source
=
this
,
match
;
replacement
=
arguments
.
callee
.
prepareReplacement
(
replacement
);
while
(
source
.
length
>
0
)
{
if
(
match
=
source
.
match
(
pattern
))
{
result
+=
source
.
slice
(
0
,
match
.
index
);
result
+=
String
.
interpret
(
replacement
(
match
));
source
=
source
.
slice
(
match
.
index
+
match
[
0
].
length
);
}
else
{
result
+=
source
,
source
=
''
;
}
}
return
result
;
},
sub
:
function
(
pattern
,
replacement
,
count
)
{
replacement
=
this
.
gsub
.
prepareReplacement
(
replacement
);
count
=
Object
.
isUndefined
(
count
)
?
1
:
count
;
return
this
.
gsub
(
pattern
,
function
(
match
)
{
if
(
--
count
<
0
)
return
match
[
0
];
return
replacement
(
match
);
});
},
scan
:
function
(
pattern
,
iterator
)
{
this
.
gsub
(
pattern
,
iterator
);
return
String
(
this
);
},
truncate
:
function
(
length
,
truncation
)
{
length
=
length
||
30
;
truncation
=
Object
.
isUndefined
(
truncation
)
?
'...'
:
truncation
;
return
this
.
length
>
length
?
this
.
slice
(
0
,
length
-
truncation
.
length
)
+
truncation
:
String
(
this
);
},
strip
:
function
()
{
return
this
.
replace
(
/^\s+/
,
''
).
replace
(
/\s+$/
,
''
);
},
stripTags
:
function
()
{
return
this
.
replace
(
/<\/?[^>]+>/gi
,
''
);
},
stripScripts
:
function
()
{
return
this
.
replace
(
new
RegExp
(
Prototype
.
ScriptFragment
,
'img'
),
''
);
},
extractScripts
:
function
()
{
var
matchAll
=
new
RegExp
(
Prototype
.
ScriptFragment
,
'img'
);
var
matchOne
=
new
RegExp
(
Prototype
.
ScriptFragment
,
'im'
);
return
(
this
.
match
(
matchAll
)
||
[]).
map
(
function
(
scriptTag
)
{
return
(
scriptTag
.
match
(
matchOne
)
||
[
''
,
''
])[
1
];
});
},
evalScripts
:
function
()
{
return
this
.
extractScripts
().
map
(
function
(
script
)
{
return
eval
(
script
)
});
},
escapeHTML
:
function
()
{
var
self
=
arguments
.
callee
;
self
.
text
.
data
=
this
;
return
self
.
div
.
innerHTML
;
},
unescapeHTML
:
function
()
{
var
div
=
new
Element
(
'div'
);
div
.
innerHTML
=
this
.
stripTags
();
return
div
.
childNodes
[
0
]
?
(
div
.
childNodes
.
length
>
1
?
$A
(
div
.
childNodes
).
inject
(
''
,
function
(
memo
,
node
)
{
return
memo
+
node
.
nodeValue
})
:
div
.
childNodes
[
0
].
nodeValue
)
:
''
;
},
toQueryParams
:
function
(
separator
)
{
var
match
=
this
.
strip
().
match
(
/([^?#]*)(#.*)?$/
);
if
(
!
match
)
return
{
};
return
match
[
1
].
split
(
separator
||
'&'
).
inject
({
},
function
(
hash
,
pair
)
{
if
((
pair
=
pair
.
split
(
'='
))[
0
])
{
var
key
=
decodeURIComponent
(
pair
.
shift
());
var
value
=
pair
.
length
>
1
?
pair
.
join
(
'='
)
:
pair
[
0
];
if
(
value
!=
undefined
)
value
=
decodeURIComponent
(
value
);
if
(
key
in
hash
)
{
if
(
!
Object
.
isArray
(
hash
[
key
]))
hash
[
key
]
=
[
hash
[
key
]];
hash
[
key
].
push
(
value
);
}
else
hash
[
key
]
=
value
;
}
return
hash
;
});
},
toArray
:
function
()
{
return
this
.
split
(
''
);
},
succ
:
function
()
{
return
this
.
slice
(
0
,
this
.
length
-
1
)
+
String
.
fromCharCode
(
this
.
charCodeAt
(
this
.
length
-
1
)
+
1
);
},
times
:
function
(
count
)
{
return
count
<
1
?
''
:
new
Array
(
count
+
1
).
join
(
this
);
},
camelize
:
function
()
{
var
parts
=
this
.
split
(
'-'
),
len
=
parts
.
length
;
if
(
len
==
1
)
return
parts
[
0
];
var
camelized
=
this
.
charAt
(
0
)
==
'-'
?
parts
[
0
].
charAt
(
0
).
toUpperCase
()
+
parts
[
0
].
substring
(
1
)
:
parts
[
0
];
for
(
var
i
=
1
;
i
<
len
;
i
++
)
camelized
+=
parts
[
i
].
charAt
(
0
).
toUpperCase
()
+
parts
[
i
].
substring
(
1
);
return
camelized
;
},
capitalize
:
function
()
{
return
this
.
charAt
(
0
).
toUpperCase
()
+
this
.
substring
(
1
).
toLowerCase
();
},
underscore
:
function
()
{
return
this
.
gsub
(
/::/
,
'/'
).
gsub
(
/([A-Z]+)([A-Z][a-z])/
,
'#{1}_#{2}'
).
gsub
(
/([a-z\d])([A-Z])/
,
'#{1}_#{2}'
).
gsub
(
/-/
,
'_'
).
toLowerCase
();
},
dasherize
:
function
()
{
return
this
.
gsub
(
/_/
,
'-'
);
},
inspect
:
function
(
useDoubleQuotes
)
{
var
escapedString
=
this
.
gsub
(
/[\x00-\x1f\\]/
,
function
(
match
)
{
var
character
=
String
.
specialChar
[
match
[
0
]];
return
character
?
character
:
'\\u00'
+
match
[
0
].
charCodeAt
().
toPaddedString
(
2
,
16
);
});
if
(
useDoubleQuotes
)
return
'"'
+
escapedString
.
replace
(
/"/g
,
'\\"'
)
+
'"'
;
return
"'"
+
escapedString
.
replace
(
/'/g
,
'\\\''
)
+
"'"
;
},
toJSON
:
function
()
{
return
this
.
inspect
(
true
);
},
unfilterJSON
:
function
(
filter
)
{
return
this
.
sub
(
filter
||
Prototype
.
JSONFilter
,
'#{1}'
);
},
isJSON
:
function
()
{
var
str
=
this
;
if
(
str
.
blank
())
return
false
;
str
=
this
.
replace
(
/\\./g
,
'@'
).
replace
(
/"[^"\\\n\r]*"/g
,
''
);
return
(
/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/
).
test
(
str
);
},
evalJSON
:
function
(
sanitize
)
{
var
json
=
this
.
unfilterJSON
();
try
{
if
(
!
sanitize
||
json
.
isJSON
())
return
eval
(
'('
+
json
+
')'
);
}
catch
(
e
)
{
}
throw
new
SyntaxError
(
'Badly formed JSON string: '
+
this
.
inspect
());
},
include
:
function
(
pattern
)
{
return
this
.
indexOf
(
pattern
)
>
-
1
;
},
startsWith
:
function
(
pattern
)
{
return
this
.
indexOf
(
pattern
)
===
0
;
},
endsWith
:
function
(
pattern
)
{
var
d
=
this
.
length
-
pattern
.
length
;
return
d
>=
0
&&
this
.
lastIndexOf
(
pattern
)
===
d
;
},
empty
:
function
()
{
return
this
==
''
;
},
blank
:
function
()
{
return
/^\s*$/
.
test
(
this
);
},
interpolate
:
function
(
object
,
pattern
)
{
return
new
Template
(
this
,
pattern
).
evaluate
(
object
);
}
});
if
(
Prototype
.
Browser
.
WebKit
||
Prototype
.
Browser
.
IE
)
Object
.
extend
(
String
.
prototype
,
{
escapeHTML
:
function
()
{
return
this
.
replace
(
/&/g
,
'&'
).
replace
(
/</g
,
'<'
).
replace
(
/>/g
,
'>'
);
},
unescapeHTML
:
function
()
{
return
this
.
replace
(
/&/g
,
'&'
).
replace
(
/</g
,
'<'
).
replace
(
/>/g
,
'>'
);
}
});
String
.
prototype
.
gsub
.
prepareReplacement
=
function
(
replacement
)
{
if
(
Object
.
isFunction
(
replacement
))
return
replacement
;
var
template
=
new
Template
(
replacement
);
return
function
(
match
)
{
return
template
.
evaluate
(
match
)
};
};
String
.
prototype
.
parseQuery
=
String
.
prototype
.
toQueryParams
;
Object
.
extend
(
String
.
prototype
.
escapeHTML
,
{
div
:
document
.
createElement
(
'div'
),
text
:
document
.
createTextNode
(
''
)
});
with
(
String
.
prototype
.
escapeHTML
)
div
.
appendChild
(
text
);
var
Template
=
Class
.
create
({
initialize
:
function
(
template
,
pattern
)
{
this
.
template
=
template
.
toString
();
this
.
pattern
=
pattern
||
Template
.
Pattern
;
},
evaluate
:
function
(
object
)
{
if
(
Object
.
isFunction
(
object
.
toTemplateReplacements
))
object
=
object
.
toTemplateReplacements
();
return
this
.
template
.
gsub
(
this
.
pattern
,
function
(
match
)
{
if
(
object
==
null
)
return
''
;
var
before
=
match
[
1
]
||
''
;
if
(
before
==
'\\'
)
return
match
[
2
];
var
ctx
=
object
,
expr
=
match
[
3
];
var
pattern
=
/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/
;
match
=
pattern
.
exec
(
expr
);
if
(
match
==
null
)
return
before
;
while
(
match
!=
null
)
{
var
comp
=
match
[
1
].
startsWith
(
'['
)
?
match
[
2
].
gsub
(
'\\\\]'
,
']'
)
:
match
[
1
];
ctx
=
ctx
[
comp
];
if
(
null
==
ctx
||
''
==
match
[
3
])
break
;
expr
=
expr
.
substring
(
'['
==
match
[
3
]
?
match
[
1
].
length
:
match
[
0
].
length
);
match
=
pattern
.
exec
(
expr
);
}
return
before
+
String
.
interpret
(
ctx
);
}.
bind
(
this
));
}
});
Template
.
Pattern
=
/(^|.|\r|\n)(#\{(.*?)\})/
;
var
$break
=
{
};
var
Enumerable
=
{
each
:
function
(
iterator
,
context
)
{
var
index
=
0
;
iterator
=
iterator
.
bind
(
context
);
try
{
this
.
_each
(
function
(
value
)
{
iterator
(
value
,
index
++
);
});
}
catch
(
e
)
{
if
(
e
!=
$break
)
throw
e
;
}
return
this
;
},
eachSlice
:
function
(
number
,
iterator
,
context
)
{
iterator
=
iterator
?
iterator
.
bind
(
context
)
:
Prototype
.
K
;
var
index
=
-
number
,
slices
=
[],
array
=
this
.
toArray
();
while
((
index
+=
number
)
<
array
.
length
)
slices
.
push
(
array
.
slice
(
index
,
index
+
number
));
return
slices
.
collect
(
iterator
,
context
);
},
all
:
function
(
iterator
,
context
)
{
iterator
=
iterator
?
iterator
.
bind
(
context
)
:
Prototype
.
K
;
var
result
=
true
;
this
.
each
(
function
(
value
,
index
)
{
result
=
result
&&
!!
iterator
(
value
,
index
);
if
(
!
result
)
throw
$break
;
});
return
result
;
},
any
:
function
(
iterator
,
context
)
{
iterator
=
iterator
?
iterator
.
bind
(
context
)
:
Prototype
.
K
;
var
result
=
false
;
this
.
each
(
function
(
value
,
index
)
{
if
(
result
=
!!
iterator
(
value
,
index
))
throw
$break
;
});
return
result
;
},
collect
:
function
(
iterator
,
context
)
{
iterator
=
iterator
?
iterator
.
bind
(
context
)
:
Prototype
.
K
;
var
results
=
[];
this
.
each
(
function
(
value
,
index
)
{
results
.
push
(
iterator
(
value
,
index
));
});
return
results
;
},
detect
:
function
(
iterator
,
context
)
{
iterator
=
iterator
.
bind
(
context
);
var
result
;
this
.
each
(
function
(
value
,
index
)
{
if
(
iterator
(
value
,
index
))
{
result
=
value
;
throw
$break
;
}
});
return
result
;
},
findAll
:
function
(
iterator
,
context
)
{
iterator
=
iterator
.
bind
(
context
);
var
results
=
[];
this
.
each
(
function
(
value
,
index
)
{
if
(
iterator
(
value
,
index
))
results
.
push
(
value
);
});
return
results
;
},
grep
:
function
(
filter
,
iterator
,
context
)
{
iterator
=
iterator
?
iterator
.
bind
(
context
)
:
Prototype
.
K
;
var
results
=
[];
if
(
Object
.
isString
(
filter
))
filter
=
new
RegExp
(
filter
);
this
.
each
(
function
(
value
,
index
)
{
if
(
filter
.
match
(
value
))
results
.
push
(
iterator
(
value
,
index
));
});
return
results
;
},
include
:
function
(
object
)
{
if
(
Object
.
isFunction
(
this
.
indexOf
))
if
(
this
.
indexOf
(
object
)
!=
-
1
)
return
true
;
var
found
=
false
;
this
.
each
(
function
(
value
)
{
if
(
value
==
object
)
{
found
=
true
;
throw
$break
;
}
});
return
found
;
},
inGroupsOf
:
function
(
number
,
fillWith
)
{
fillWith
=
Object
.
isUndefined
(
fillWith
)
?
null
:
fillWith
;
return
this
.
eachSlice
(
number
,
function
(
slice
)
{
while
(
slice
.
length
<
number
)
slice
.
push
(
fillWith
);
return
slice
;
});
},
inject
:
function
(
memo
,
iterator
,
context
)
{
iterator
=
iterator
.
bind
(
context
);
this
.
each
(
function
(
value
,
index
)
{
memo
=
iterator
(
memo
,
value
,
index
);
});
return
memo
;
},
invoke
:
function
(
method
)
{
var
args
=
$A
(
arguments
).
slice
(
1
);
return
this
.
map
(
function
(
value
)
{
return
value
[
method
].
apply
(
value
,
args
);
});
},
max
:
function
(
iterator
,
context
)
{
iterator
=
iterator
?
iterator
.
bind
(
context
)
:
Prototype
.
K
;
var
result
;
this
.
each
(
function
(
value
,
index
)
{
value
=
iterator
(
value
,
index
);
if
(
result
==
null
||
value
>=
result
)
result
=
value
;
});
return
result
;
},
min
:
function
(
iterator
,
context
)
{
iterator
=
iterator
?
iterator
.
bind
(
context
)
:
Prototype
.
K
;
var
result
;
this
.
each
(
function
(
value
,
index
)
{
value
=
iterator
(
value
,
index
);
if
(
result
==
null
||
value
<
result
)
result
=
value
;
});
return
result
;
},
partition
:
function
(
iterator
,
context
)
{
iterator
=
iterator
?
iterator
.
bind
(
context
)
:
Prototype
.
K
;
var
trues
=
[],
falses
=
[];
this
.
each
(
function
(
value
,
index
)
{
(
iterator
(
value
,
index
)
?
trues
:
falses
).
push
(
value
);
});
return
[
trues
,
falses
];
},
pluck
:
function
(
property
)
{
var
results
=
[];
this
.
each
(
function
(
value
)
{
results
.
push
(
value
[
property
]);
});
return
results
;
},
reject
:
function
(
iterator
,
context
)
{
iterator
=
iterator
.
bind
(
context
);
var
results
=
[];
this
.
each
(
function
(
value
,
index
)
{
if
(
!
iterator
(
value
,
index
))
results
.
push
(
value
);
});
return
results
;
},
sortBy
:
function
(
iterator
,
context
)
{
iterator
=
iterator
.
bind
(
context
);
return
this
.
map
(
function
(
value
,
index
)
{
return
{
value
:
value
,
criteria
:
iterator
(
value
,
index
)};
}).
sort
(
function
(
left
,
right
)
{
var
a
=
left
.
criteria
,
b
=
right
.
criteria
;
return
a
<
b
?
-
1
:
a
>
b
?
1
:
0
;
}).
pluck
(
'value'
);
},
toArray
:
function
()
{
return
this
.
map
();
},
zip
:
function
()
{
var
iterator
=
Prototype
.
K
,
args
=
$A
(
arguments
);
if
(
Object
.
isFunction
(
args
.
last
()))
iterator
=
args
.
pop
();
var
collections
=
[
this
].
concat
(
args
).
map
(
$A
);
return
this
.
map
(
function
(
value
,
index
)
{
return
iterator
(
collections
.
pluck
(
index
));
});
},
size
:
function
()
{
return
this
.
toArray
().
length
;
},
inspect
:
function
()
{
return
'#<Enumerable:'
+
this
.
toArray
().
inspect
()
+
'>'
;
}
};
Object
.
extend
(
Enumerable
,
{
map
:
Enumerable
.
collect
,
find
:
Enumerable
.
detect
,
select
:
Enumerable
.
findAll
,
filter
:
Enumerable
.
findAll
,
member
:
Enumerable
.
include
,
entries
:
Enumerable
.
toArray
,
every
:
Enumerable
.
all
,
some
:
Enumerable
.
any
});
function
$A
(
iterable
)
{
if
(
!
iterable
)
return
[];
if
(
iterable
.
toArray
)
return
iterable
.
toArray
();
var
length
=
iterable
.
length
,
results
=
new
Array
(
length
);
while
(
length
--
)
results
[
length
]
=
iterable
[
length
];
return
results
;
}
if
(
Prototype
.
Browser
.
WebKit
)
{
function
$A
(
iterable
)
{
if
(
!
iterable
)
return
[];
if
(
!
(
Object
.
isFunction
(
iterable
)
&&
iterable
==
'[object NodeList]'
)
&&
iterable
.
toArray
)
return
iterable
.
toArray
();
var
length
=
iterable
.
length
,
results
=
new
Array
(
length
);
while
(
length
--
)
results
[
length
]
=
iterable
[
length
];
return
results
;
}
}
Array
.
from
=
$A
;
Object
.
extend
(
Array
.
prototype
,
Enumerable
);
if
(
!
Array
.
prototype
.
_reverse
)
Array
.
prototype
.
_reverse
=
Array
.
prototype
.
reverse
;
Object
.
extend
(
Array
.
prototype
,
{
_each
:
function
(
iterator
)
{
for
(
var
i
=
0
,
length
=
this
.
length
;
i
<
length
;
i
++
)
iterator
(
this
[
i
]);
},
clear
:
function
()
{
this
.
length
=
0
;
return
this
;
},
first
:
function
()
{
return
this
[
0
];
},
last
:
function
()
{
return
this
[
this
.
length
-
1
];
},
compact
:
function
()
{
return
this
.
select
(
function
(
value
)
{
return
value
!=
null
;
});
},
flatten
:
function
()
{
return
this
.
inject
([],
function
(
array
,
value
)
{
return
array
.
concat
(
Object
.
isArray
(
value
)
?
value
.
flatten
()
:
[
value
]);
});
},
without
:
function
()
{
var
values
=
$A
(
arguments
);
return
this
.
select
(
function
(
value
)
{
return
!
values
.
include
(
value
);
});
},
reverse
:
function
(
inline
)
{
return
(
inline
!==
false
?
this
:
this
.
toArray
()).
_reverse
();
},
reduce
:
function
()
{
return
this
.
length
>
1
?
this
:
this
[
0
];
},
uniq
:
function
(
sorted
)
{
return
this
.
inject
([],
function
(
array
,
value
,
index
)
{
if
(
0
==
index
||
(
sorted
?
array
.
last
()
!=
value
:
!
array
.
include
(
value
)))
array
.
push
(
value
);
return
array
;
});
},
intersect
:
function
(
array
)
{
return
this
.
uniq
().
findAll
(
function
(
item
)
{
return
array
.
detect
(
function
(
value
)
{
return
item
===
value
});
});
},
clone
:
function
()
{
return
[].
concat
(
this
);
},
size
:
function
()
{
return
this
.
length
;
},
inspect
:
function
()
{
return
'['
+
this
.
map
(
Object
.
inspect
).
join
(
', '
)
+
']'
;
},
toJSON
:
function
()
{
var
results
=
[];
this
.
each
(
function
(
object
)
{
var
value
=
Object
.
toJSON
(
object
);
if
(
!
Object
.
isUndefined
(
value
))
results
.
push
(
value
);
});
return
'['
+
results
.
join
(
', '
)
+
']'
;
}
});
// use native browser JS 1.6 implementation if available
if
(
Object
.
isFunction
(
Array
.
prototype
.
forEach
))
Array
.
prototype
.
_each
=
Array
.
prototype
.
forEach
;
if
(
!
Array
.
prototype
.
indexOf
)
Array
.
prototype
.
indexOf
=
function
(
item
,
i
)
{
i
||
(
i
=
0
);
var
length
=
this
.
length
;
if
(
i
<
0
)
i
=
length
+
i
;
for
(;
i
<
length
;
i
++
)
if
(
this
[
i
]
===
item
)
return
i
;
return
-
1
;
};
if
(
!
Array
.
prototype
.
lastIndexOf
)
Array
.
prototype
.
lastIndexOf
=
function
(
item
,
i
)
{
i
=
isNaN
(
i
)
?
this
.
length
:
(
i
<
0
?
this
.
length
+
i
:
i
)
+
1
;
var
n
=
this
.
slice
(
0
,
i
).
reverse
().
indexOf
(
item
);
return
(
n
<
0
)
?
n
:
i
-
n
-
1
;
};
Array
.
prototype
.
toArray
=
Array
.
prototype
.
clone
;
function
$w
(
string
)
{
if
(
!
Object
.
isString
(
string
))
return
[];
string
=
string
.
strip
();
return
string
?
string
.
split
(
/\s+/
)
:
[];
}
if
(
Prototype
.
Browser
.
Opera
){
Array
.
prototype
.
concat
=
function
()
{
var
array
=
[];
for
(
var
i
=
0
,
length
=
this
.
length
;
i
<
length
;
i
++
)
array
.
push
(
this
[
i
]);
for
(
var
i
=
0
,
length
=
arguments
.
length
;
i
<
length
;
i
++
)
{
if
(
Object
.
isArray
(
arguments
[
i
]))
{
for
(
var
j
=
0
,
arrayLength
=
arguments
[
i
].
length
;
j
<
arrayLength
;
j
++
)
array
.
push
(
arguments
[
i
][
j
]);
}
else
{
array
.
push
(
arguments
[
i
]);
}
}
return
array
;
};
}
Object
.
extend
(
Number
.
prototype
,
{
toColorPart
:
function
()
{
return
this
.
toPaddedString
(
2
,
16
);
},
succ
:
function
()
{
return
this
+
1
;
},
times
:
function
(
iterator
)
{
$R
(
0
,
this
,
true
).
each
(
iterator
);
return
this
;
},
toPaddedString
:
function
(
length
,
radix
)
{
var
string
=
this
.
toString
(
radix
||
10
);
return
'0'
.
times
(
length
-
string
.
length
)
+
string
;
},
toJSON
:
function
()
{
return
isFinite
(
this
)
?
this
.
toString
()
:
'null'
;
}
});
$w
(
'abs round ceil floor'
).
each
(
function
(
method
){
Number
.
prototype
[
method
]
=
Math
[
method
].
methodize
();
});
function
$H
(
object
)
{
return
new
Hash
(
object
);
};
var
Hash
=
Class
.
create
(
Enumerable
,
(
function
()
{
function
toQueryPair
(
key
,
value
)
{
if
(
Object
.
isUndefined
(
value
))
return
key
;
return
key
+
'='
+
encodeURIComponent
(
String
.
interpret
(
value
));
}
return
{
initialize
:
function
(
object
)
{
this
.
_object
=
Object
.
isHash
(
object
)
?
object
.
toObject
()
:
Object
.
clone
(
object
);
},
_each
:
function
(
iterator
)
{
for
(
var
key
in
this
.
_object
)
{
var
value
=
this
.
_object
[
key
],
pair
=
[
key
,
value
];
pair
.
key
=
key
;
pair
.
value
=
value
;
iterator
(
pair
);
}
},
set
:
function
(
key
,
value
)
{
return
this
.
_object
[
key
]
=
value
;
},
get
:
function
(
key
)
{
return
this
.
_object
[
key
];
},
unset
:
function
(
key
)
{
var
value
=
this
.
_object
[
key
];
delete
this
.
_object
[
key
];
return
value
;
},
toObject
:
function
()
{
return
Object
.
clone
(
this
.
_object
);
},
keys
:
function
()
{
return
this
.
pluck
(
'key'
);
},
values
:
function
()
{
return
this
.
pluck
(
'value'
);
},
index
:
function
(
value
)
{
var
match
=
this
.
detect
(
function
(
pair
)
{
return
pair
.
value
===
value
;
});
return
match
&&
match
.
key
;
},
merge
:
function
(
object
)
{
return
this
.
clone
().
update
(
object
);
},
update
:
function
(
object
)
{
return
new
Hash
(
object
).
inject
(
this
,
function
(
result
,
pair
)
{
result
.
set
(
pair
.
key
,
pair
.
value
);
return
result
;
});
},
toQueryString
:
function
()
{
return
this
.
map
(
function
(
pair
)
{
var
key
=
encodeURIComponent
(
pair
.
key
),
values
=
pair
.
value
;
if
(
values
&&
typeof
values
==
'object'
)
{
if
(
Object
.
isArray
(
values
))
return
values
.
map
(
toQueryPair
.
curry
(
key
)).
join
(
'&'
);
}
return
toQueryPair
(
key
,
values
);
}).
join
(
'&'
);
},
inspect
:
function
()
{
return
'#<Hash:{'
+
this
.
map
(
function
(
pair
)
{
return
pair
.
map
(
Object
.
inspect
).
join
(
': '
);
}).
join
(
', '
)
+
'}>'
;
},
toJSON
:
function
()
{
return
Object
.
toJSON
(
this
.
toObject
());
},
clone
:
function
()
{
return
new
Hash
(
this
);
}
}
})());
Hash
.
prototype
.
toTemplateReplacements
=
Hash
.
prototype
.
toObject
;
Hash
.
from
=
$H
;
var
ObjectRange
=
Class
.
create
(
Enumerable
,
{
initialize
:
function
(
start
,
end
,
exclusive
)
{
this
.
start
=
start
;
this
.
end
=
end
;
this
.
exclusive
=
exclusive
;
},
_each
:
function
(
iterator
)
{
var
value
=
this
.
start
;
while
(
this
.
include
(
value
))
{
iterator
(
value
);
value
=
value
.
succ
();
}
},
include
:
function
(
value
)
{
if
(
value
<
this
.
start
)
return
false
;
if
(
this
.
exclusive
)
return
value
<
this
.
end
;
return
value
<=
this
.
end
;
}
});
var
$R
=
function
(
start
,
end
,
exclusive
)
{
return
new
ObjectRange
(
start
,
end
,
exclusive
);
};
var
Ajax
=
{
getTransport
:
function
()
{
return
Try
.
these
(
function
()
{
return
new
XMLHttpRequest
()},
function
()
{
return
new
ActiveXObject
(
'Msxml2.XMLHTTP'
)},
function
()
{
return
new
ActiveXObject
(
'Microsoft.XMLHTTP'
)}
)
||
false
;
},
activeRequestCount
:
0
};
Ajax
.
Responders
=
{
responders
:
[],
_each
:
function
(
iterator
)
{
this
.
responders
.
_each
(
iterator
);
},
register
:
function
(
responder
)
{
if
(
!
this
.
include
(
responder
))
this
.
responders
.
push
(
responder
);
},
unregister
:
function
(
responder
)
{
this
.
responders
=
this
.
responders
.
without
(
responder
);
},
dispatch
:
function
(
callback
,
request
,
transport
,
json
)
{
this
.
each
(
function
(
responder
)
{
if
(
Object
.
isFunction
(
responder
[
callback
]))
{
try
{
responder
[
callback
].
apply
(
responder
,
[
request
,
transport
,
json
]);
}
catch
(
e
)
{
}
}
});
}
};
Object
.
extend
(
Ajax
.
Responders
,
Enumerable
);
Ajax
.
Responders
.
register
({
onCreate
:
function
()
{
Ajax
.
activeRequestCount
++
},
onComplete
:
function
()
{
Ajax
.
activeRequestCount
--
}
});
Ajax
.
Base
=
Class
.
create
({
initialize
:
function
(
options
)
{
this
.
options
=
{
method
:
'post'
,
asynchronous
:
true
,
contentType
:
'application/x-www-form-urlencoded'
,
encoding
:
'UTF-8'
,
parameters
:
''
,
evalJSON
:
true
,
evalJS
:
true
};
Object
.
extend
(
this
.
options
,
options
||
{
});
this
.
options
.
method
=
this
.
options
.
method
.
toLowerCase
();
if
(
Object
.
isString
(
this
.
options
.
parameters
))
this
.
options
.
parameters
=
this
.
options
.
parameters
.
toQueryParams
();
else
if
(
Object
.
isHash
(
this
.
options
.
parameters
))
this
.
options
.
parameters
=
this
.
options
.
parameters
.
toObject
();
}
});
Ajax
.
Request
=
Class
.
create
(
Ajax
.
Base
,
{
_complete
:
false
,
initialize
:
function
(
$super
,
url
,
options
)
{
$super
(
options
);
this
.
transport
=
Ajax
.
getTransport
();
this
.
request
(
url
);
},
request
:
function
(
url
)
{
this
.
url
=
url
;
this
.
method
=
this
.
options
.
method
;
var
params
=
Object
.
clone
(
this
.
options
.
parameters
);
if
(
!
[
'get'
,
'post'
].
include
(
this
.
method
))
{
// simulate other verbs over post
params
[
'_method'
]
=
this
.
method
;
this
.
method
=
'post'
;
}
this
.
parameters
=
params
;
if
(
params
=
Object
.
toQueryString
(
params
))
{
// when GET, append parameters to URL
if
(
this
.
method
==
'get'
)
this
.
url
+=
(
this
.
url
.
include
(
'?'
)
?
'&'
:
'?'
)
+
params
;
else
if
(
/Konqueror|Safari|KHTML/
.
test
(
navigator
.
userAgent
))
params
+=
'&_='
;
}
try
{
var
response
=
new
Ajax
.
Response
(
this
);
if
(
this
.
options
.
onCreate
)
this
.
options
.
onCreate
(
response
);
Ajax
.
Responders
.
dispatch
(
'onCreate'
,
this
,
response
);
this
.
transport
.
open
(
this
.
method
.
toUpperCase
(),
this
.
url
,
this
.
options
.
asynchronous
);
if
(
this
.
options
.
asynchronous
)
this
.
respondToReadyState
.
bind
(
this
).
defer
(
1
);
this
.
transport
.
onreadystatechange
=
this
.
onStateChange
.
bind
(
this
);
this
.
setRequestHeaders
();
this
.
body
=
this
.
method
==
'post'
?
(
this
.
options
.
postBody
||
params
)
:
null
;
this
.
transport
.
send
(
this
.
body
);
/* Force Firefox to handle ready state 4 for synchronous requests */
if
(
!
this
.
options
.
asynchronous
&&
this
.
transport
.
overrideMimeType
)
this
.
onStateChange
();
}
catch
(
e
)
{
this
.
dispatchException
(
e
);
}
},
onStateChange
:
function
()
{
var
readyState
=
this
.
transport
.
readyState
;
if
(
readyState
>
1
&&
!
((
readyState
==
4
)
&&
this
.
_complete
))
this
.
respondToReadyState
(
this
.
transport
.
readyState
);
},
setRequestHeaders
:
function
()
{
var
headers
=
{
'X-Requested-With'
:
'XMLHttpRequest'
,
'X-Prototype-Version'
:
Prototype
.
Version
,
'Accept'
:
'text/javascript, text/html, application/xml, text/xml, */*'
};
if
(
this
.
method
==
'post'
)
{
headers
[
'Content-type'
]
=
this
.
options
.
contentType
+
(
this
.
options
.
encoding
?
'; charset='
+
this
.
options
.
encoding
:
''
);
/* Force "Connection: close" for older Mozilla browsers to work
* around a bug where XMLHttpRequest sends an incorrect
* Content-length header. See Mozilla Bugzilla #246651.
*/
if
(
this
.
transport
.
overrideMimeType
&&
(
navigator
.
userAgent
.
match
(
/Gecko\/(\d{4})/
)
||
[
0
,
2005
])[
1
]
<
2005
)
headers
[
'Connection'
]
=
'close'
;
}
// user-defined headers
if
(
typeof
this
.
options
.
requestHeaders
==
'object'
)
{
var
extras
=
this
.
options
.
requestHeaders
;
if
(
Object
.
isFunction
(
extras
.
push
))
for
(
var
i
=
0
,
length
=
extras
.
length
;
i
<
length
;
i
+=
2
)
headers
[
extras
[
i
]]
=
extras
[
i
+
1
];
else
$H
(
extras
).
each
(
function
(
pair
)
{
headers
[
pair
.
key
]
=
pair
.
value
});
}
for
(
var
name
in
headers
)
this
.
transport
.
setRequestHeader
(
name
,
headers
[
name
]);
},
success
:
function
()
{
var
status
=
this
.
getStatus
();
return
!
status
||
(
status
>=
200
&&
status
<
300
);
},
getStatus
:
function
()
{
try
{
return
this
.
transport
.
status
||
0
;
}
catch
(
e
)
{
return
0
}
},
respondToReadyState
:
function
(
readyState
)
{
var
state
=
Ajax
.
Request
.
Events
[
readyState
],
response
=
new
Ajax
.
Response
(
this
);
if
(
state
==
'Complete'
)
{
try
{
this
.
_complete
=
true
;
(
this
.
options
[
'on'
+
response
.
status
]
||
this
.
options
[
'on'
+
(
this
.
success
()
?
'Success'
:
'Failure'
)]
||
Prototype
.
emptyFunction
)(
response
,
response
.
headerJSON
);
}
catch
(
e
)
{
this
.
dispatchException
(
e
);
}
var
contentType
=
response
.
getHeader
(
'Content-type'
);
if
(
this
.
options
.
evalJS
==
'force'
||
(
this
.
options
.
evalJS
&&
contentType
&&
contentType
.
match
(
/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i
)))
this
.
evalResponse
();
}
try
{
(
this
.
options
[
'on'
+
state
]
||
Prototype
.
emptyFunction
)(
response
,
response
.
headerJSON
);
Ajax
.
Responders
.
dispatch
(
'on'
+
state
,
this
,
response
,
response
.
headerJSON
);
}
catch
(
e
)
{
this
.
dispatchException
(
e
);
}
if
(
state
==
'Complete'
)
{
// avoid memory leak in MSIE: clean up
this
.
transport
.
onreadystatechange
=
Prototype
.
emptyFunction
;
}
},
getHeader
:
function
(
name
)
{
try
{
return
this
.
transport
.
getResponseHeader
(
name
);
}
catch
(
e
)
{
return
null
}
},
evalResponse
:
function
()
{
try
{
return
eval
((
this
.
transport
.
responseText
||
''
).
unfilterJSON
());
}
catch
(
e
)
{
this
.
dispatchException
(
e
);
}
},
dispatchException
:
function
(
exception
)
{
(
this
.
options
.
onException
||
Prototype
.
emptyFunction
)(
this
,
exception
);
Ajax
.
Responders
.
dispatch
(
'onException'
,
this
,
exception
);
}
});
Ajax
.
Request
.
Events
=
[
'Uninitialized'
,
'Loading'
,
'Loaded'
,
'Interactive'
,
'Complete'
];
Ajax
.
Response
=
Class
.
create
({
initialize
:
function
(
request
){
this
.
request
=
request
;
var
transport
=
this
.
transport
=
request
.
transport
,
readyState
=
this
.
readyState
=
transport
.
readyState
;
if
((
readyState
>
2
&&
!
Prototype
.
Browser
.
IE
)
||
readyState
==
4
)
{
this
.
status
=
this
.
getStatus
();
this
.
statusText
=
this
.
getStatusText
();
this
.
responseText
=
String
.
interpret
(
transport
.
responseText
);
this
.
headerJSON
=
this
.
_getHeaderJSON
();
}
if
(
readyState
==
4
)
{
var
xml
=
transport
.
responseXML
;
this
.
responseXML
=
Object
.
isUndefined
(
xml
)
?
null
:
xml
;
this
.
responseJSON
=
this
.
_getResponseJSON
();
}
},
status
:
0
,
statusText
:
''
,
getStatus
:
Ajax
.
Request
.
prototype
.
getStatus
,
getStatusText
:
function
()
{
try
{
return
this
.
transport
.
statusText
||
''
;
}
catch
(
e
)
{
return
''
}
},
getHeader
:
Ajax
.
Request
.
prototype
.
getHeader
,
getAllHeaders
:
function
()
{
try
{
return
this
.
getAllResponseHeaders
();
}
catch
(
e
)
{
return
null
}
},
getResponseHeader
:
function
(
name
)
{
return
this
.
transport
.
getResponseHeader
(
name
);
},
getAllResponseHeaders
:
function
()
{
return
this
.
transport
.
getAllResponseHeaders
();
},
_getHeaderJSON
:
function
()
{
var
json
=
this
.
getHeader
(
'X-JSON'
);
if
(
!
json
)
return
null
;
json
=
decodeURIComponent
(
escape
(
json
));
try
{
return
json
.
evalJSON
(
this
.
request
.
options
.
sanitizeJSON
);
}
catch
(
e
)
{
this
.
request
.
dispatchException
(
e
);
}
},
_getResponseJSON
:
function
()
{
var
options
=
this
.
request
.
options
;
if
(
!
options
.
evalJSON
||
(
options
.
evalJSON
!=
'force'
&&
!
(
this
.
getHeader
(
'Content-type'
)
||
''
).
include
(
'application/json'
))
||
this
.
responseText
.
blank
())
return
null
;
try
{
return
this
.
responseText
.
evalJSON
(
options
.
sanitizeJSON
);
}
catch
(
e
)
{
this
.
request
.
dispatchException
(
e
);
}
}
});
Ajax
.
Updater
=
Class
.
create
(
Ajax
.
Request
,
{
initialize
:
function
(
$super
,
container
,
url
,
options
)
{
this
.
container
=
{
success
:
(
container
.
success
||
container
),
failure
:
(
container
.
failure
||
(
container
.
success
?
null
:
container
))
};
options
=
Object
.
clone
(
options
);
var
onComplete
=
options
.
onComplete
;
options
.
onComplete
=
(
function
(
response
,
json
)
{
this
.
updateContent
(
response
.
responseText
);
if
(
Object
.
isFunction
(
onComplete
))
onComplete
(
response
,
json
);
}).
bind
(
this
);
$super
(
url
,
options
);
},
updateContent
:
function
(
responseText
)
{
var
receiver
=
this
.
container
[
this
.
success
()
?
'success'
:
'failure'
],
options
=
this
.
options
;
if
(
!
options
.
evalScripts
)
responseText
=
responseText
.
stripScripts
();
if
(
receiver
=
$
(
receiver
))
{
if
(
options
.
insertion
)
{
if
(
Object
.
isString
(
options
.
insertion
))
{
var
insertion
=
{
};
insertion
[
options
.
insertion
]
=
responseText
;
receiver
.
insert
(
insertion
);
}
else
options
.
insertion
(
receiver
,
responseText
);
}
else
receiver
.
update
(
responseText
);
}
}
});
Ajax
.
PeriodicalUpdater
=
Class
.
create
(
Ajax
.
Base
,
{
initialize
:
function
(
$super
,
container
,
url
,
options
)
{
$super
(
options
);
this
.
onComplete
=
this
.
options
.
onComplete
;
this
.
frequency
=
(
this
.
options
.
frequency
||
2
);
this
.
decay
=
(
this
.
options
.
decay
||
1
);
this
.
updater
=
{
};
this
.
container
=
container
;
this
.
url
=
url
;
this
.
start
();
},
start
:
function
()
{
this
.
options
.
onComplete
=
this
.
updateComplete
.
bind
(
this
);
this
.
onTimerEvent
();
},
stop
:
function
()
{
this
.
updater
.
options
.
onComplete
=
undefined
;
clearTimeout
(
this
.
timer
);
(
this
.
onComplete
||
Prototype
.
emptyFunction
).
apply
(
this
,
arguments
);
},
updateComplete
:
function
(
response
)
{
if
(
this
.
options
.
decay
)
{
this
.
decay
=
(
response
.
responseText
==
this
.
lastText
?
this
.
decay
*
this
.
options
.
decay
:
1
);
this
.
lastText
=
response
.
responseText
;
}
this
.
timer
=
this
.
onTimerEvent
.
bind
(
this
).
delay
(
this
.
decay
*
this
.
frequency
);
},
onTimerEvent
:
function
()
{
this
.
updater
=
new
Ajax
.
Updater
(
this
.
container
,
this
.
url
,
this
.
options
);
}
});
function
$
(
element
)
{
if
(
arguments
.
length
>
1
)
{
for
(
var
i
=
0
,
elements
=
[],
length
=
arguments
.
length
;
i
<
length
;
i
++
)
elements
.
push
(
$
(
arguments
[
i
]));
return
elements
;
}
if
(
Object
.
isString
(
element
))
element
=
document
.
getElementById
(
element
);
return
Element
.
extend
(
element
);
}
if
(
Prototype
.
BrowserFeatures
.
XPath
)
{
document
.
_getElementsByXPath
=
function
(
expression
,
parentElement
)
{
var
results
=
[];
var
query
=
document
.
evaluate
(
expression
,
$
(
parentElement
)
||
document
,
null
,
XPathResult
.
ORDERED_NODE_SNAPSHOT_TYPE
,
null
);
for
(
var
i
=
0
,
length
=
query
.
snapshotLength
;
i
<
length
;
i
++
)
results
.
push
(
Element
.
extend
(
query
.
snapshotItem
(
i
)));
return
results
;
};
}
/*--------------------------------------------------------------------------*/
if
(
!
window
.
Node
)
var
Node
=
{
};
if
(
!
Node
.
ELEMENT_NODE
)
{
// DOM level 2 ECMAScript Language Binding
Object
.
extend
(
Node
,
{
ELEMENT_NODE
:
1
,
ATTRIBUTE_NODE
:
2
,
TEXT_NODE
:
3
,
CDATA_SECTION_NODE
:
4
,
ENTITY_REFERENCE_NODE
:
5
,
ENTITY_NODE
:
6
,
PROCESSING_INSTRUCTION_NODE
:
7
,
COMMENT_NODE
:
8
,
DOCUMENT_NODE
:
9
,
DOCUMENT_TYPE_NODE
:
10
,
DOCUMENT_FRAGMENT_NODE
:
11
,
NOTATION_NODE
:
12
});
}
(
function
()
{
var
element
=
this
.
Element
;
this
.
Element
=
function
(
tagName
,
attributes
)
{
attributes
=
attributes
||
{
};
tagName
=
tagName
.
toLowerCase
();
var
cache
=
Element
.
cache
;
if
(
Prototype
.
Browser
.
IE
&&
attributes
.
name
)
{
tagName
=
'<'
+
tagName
+
' name="'
+
attributes
.
name
+
'">'
;
delete
attributes
.
name
;
return
Element
.
writeAttribute
(
document
.
createElement
(
tagName
),
attributes
);
}
if
(
!
cache
[
tagName
])
cache
[
tagName
]
=
Element
.
extend
(
document
.
createElement
(
tagName
));
return
Element
.
writeAttribute
(
cache
[
tagName
].
cloneNode
(
false
),
attributes
);
};
Object
.
extend
(
this
.
Element
,
element
||
{
});
}).
call
(
window
);
Element
.
cache
=
{
};
Element
.
Methods
=
{
visible
:
function
(
element
)
{
return
$
(
element
).
style
.
display
!=
'none'
;
},
toggle
:
function
(
element
)
{
element
=
$
(
element
);
Element
[
Element
.
visible
(
element
)
?
'hide'
:
'show'
](
element
);
return
element
;
},
hide
:
function
(
element
)
{
$
(
element
).
style
.
display
=
'none'
;
return
element
;
},
show
:
function
(
element
)
{
$
(
element
).
style
.
display
=
''
;
return
element
;
},
remove
:
function
(
element
)
{
element
=
$
(
element
);
element
.
parentNode
.
removeChild
(
element
);
return
element
;
},
update
:
function
(
element
,
content
)
{
element
=
$
(
element
);
if
(
content
&&
content
.
toElement
)
content
=
content
.
toElement
();
if
(
Object
.
isElement
(
content
))
return
element
.
update
().
insert
(
content
);
content
=
Object
.
toHTML
(
content
);
element
.
innerHTML
=
content
.
stripScripts
();
content
.
evalScripts
.
bind
(
content
).
defer
();
return
element
;
},
replace
:
function
(
element
,
content
)
{
element
=
$
(
element
);
if
(
content
&&
content
.
toElement
)
content
=
content
.
toElement
();
else
if
(
!
Object
.
isElement
(
content
))
{
content
=
Object
.
toHTML
(
content
);
var
range
=
element
.
ownerDocument
.
createRange
();
range
.
selectNode
(
element
);
content
.
evalScripts
.
bind
(
content
).
defer
();
content
=
range
.
createContextualFragment
(
content
.
stripScripts
());
}
element
.
parentNode
.
replaceChild
(
content
,
element
);
return
element
;
},
insert
:
function
(
element
,
insertions
)
{
element
=
$
(
element
);
if
(
Object
.
isString
(
insertions
)
||
Object
.
isNumber
(
insertions
)
||
Object
.
isElement
(
insertions
)
||
(
insertions
&&
(
insertions
.
toElement
||
insertions
.
toHTML
)))
insertions
=
{
bottom
:
insertions
};
var
content
,
t
,
range
;
for
(
position
in
insertions
)
{
content
=
insertions
[
position
];
position
=
position
.
toLowerCase
();
t
=
Element
.
_insertionTranslations
[
position
];
if
(
content
&&
content
.
toElement
)
content
=
content
.
toElement
();
if
(
Object
.
isElement
(
content
))
{
t
.
insert
(
element
,
content
);
continue
;
}
content
=
Object
.
toHTML
(
content
);
range
=
element
.
ownerDocument
.
createRange
();
t
.
initializeRange
(
element
,
range
);
t
.
insert
(
element
,
range
.
createContextualFragment
(
content
.
stripScripts
()));
content
.
evalScripts
.
bind
(
content
).
defer
();
}
return
element
;
},
wrap
:
function
(
element
,
wrapper
,
attributes
)
{
element
=
$
(
element
);
if
(
Object
.
isElement
(
wrapper
))
$
(
wrapper
).
writeAttribute
(
attributes
||
{
});
else
if
(
Object
.
isString
(
wrapper
))
wrapper
=
new
Element
(
wrapper
,
attributes
);
else
wrapper
=
new
Element
(
'div'
,
wrapper
);
if
(
element
.
parentNode
)
element
.
parentNode
.
replaceChild
(
wrapper
,
element
);
wrapper
.
appendChild
(
element
);
return
wrapper
;
},
inspect
:
function
(
element
)
{
element
=
$
(
element
);
var
result
=
'<'
+
element
.
tagName
.
toLowerCase
();
$H
({
'id'
:
'id'
,
'className'
:
'class'
}).
each
(
function
(
pair
)
{
var
property
=
pair
.
first
(),
attribute
=
pair
.
last
();
var
value
=
(
element
[
property
]
||
''
).
toString
();
if
(
value
)
result
+=
' '
+
attribute
+
'='
+
value
.
inspect
(
true
);
});
return
result
+
'>'
;
},
recursivelyCollect
:
function
(
element
,
property
)
{
element
=
$
(
element
);
var
elements
=
[];
while
(
element
=
element
[
property
])
if
(
element
.
nodeType
==
1
)
elements
.
push
(
Element
.
extend
(
element
));
return
elements
;
},
ancestors
:
function
(
element
)
{
return
$
(
element
).
recursivelyCollect
(
'parentNode'
);
},
descendants
:
function
(
element
)
{
return
$
(
element
).
getElementsBySelector
(
"*"
);
},
firstDescendant
:
function
(
element
)
{
element
=
$
(
element
).
firstChild
;
while
(
element
&&
element
.
nodeType
!=
1
)
element
=
element
.
nextSibling
;
return
$
(
element
);
},
immediateDescendants
:
function
(
element
)
{
if
(
!
(
element
=
$
(
element
).
firstChild
))
return
[];
while
(
element
&&
element
.
nodeType
!=
1
)
element
=
element
.
nextSibling
;
if
(
element
)
return
[
element
].
concat
(
$
(
element
).
nextSiblings
());
return
[];
},
previousSiblings
:
function
(
element
)
{
return
$
(
element
).
recursivelyCollect
(
'previousSibling'
);
},
nextSiblings
:
function
(
element
)
{
return
$
(
element
).
recursivelyCollect
(
'nextSibling'
);
},
siblings
:
function
(
element
)
{
element
=
$
(
element
);
return
element
.
previousSiblings
().
reverse
().
concat
(
element
.
nextSiblings
());
},
match
:
function
(
element
,
selector
)
{
if
(
Object
.
isString
(
selector
))
selector
=
new
Selector
(
selector
);
return
selector
.
match
(
$
(
element
));
},
up
:
function
(
element
,
expression
,
index
)
{
element
=
$
(
element
);
if
(
arguments
.
length
==
1
)
return
$
(
element
.
parentNode
);
var
ancestors
=
element
.
ancestors
();
return
expression
?
Selector
.
findElement
(
ancestors
,
expression
,
index
)
:
ancestors
[
index
||
0
];
},
down
:
function
(
element
,
expression
,
index
)
{
element
=
$
(
element
);
if
(
arguments
.
length
==
1
)
return
element
.
firstDescendant
();
var
descendants
=
element
.
descendants
();
return
expression
?
Selector
.
findElement
(
descendants
,
expression
,
index
)
:
descendants
[
index
||
0
];
},
previous
:
function
(
element
,
expression
,
index
)
{
element
=
$
(
element
);
if
(
arguments
.
length
==
1
)
return
$
(
Selector
.
handlers
.
previousElementSibling
(
element
));
var
previousSiblings
=
element
.
previousSiblings
();
return
expression
?
Selector
.
findElement
(
previousSiblings
,
expression
,
index
)
:
previousSiblings
[
index
||
0
];
},
next
:
function
(
element
,
expression
,
index
)
{
element
=
$
(
element
);
if
(
arguments
.
length
==
1
)
return
$
(
Selector
.
handlers
.
nextElementSibling
(
element
));
var
nextSiblings
=
element
.
nextSiblings
();
return
expression
?
Selector
.
findElement
(
nextSiblings
,
expression
,
index
)
:
nextSiblings
[
index
||
0
];
},
select
:
function
()
{
var
args
=
$A
(
arguments
),
element
=
$
(
args
.
shift
());
return
Selector
.
findChildElements
(
element
,
args
);
},
adjacent
:
function
()
{
var
args
=
$A
(
arguments
),
element
=
$
(
args
.
shift
());
return
Selector
.
findChildElements
(
element
.
parentNode
,
args
).
without
(
element
);
},
identify
:
function
(
element
)
{
element
=
$
(
element
);
var
id
=
element
.
readAttribute
(
'id'
),
self
=
arguments
.
callee
;
if
(
id
)
return
id
;
do
{
id
=
'anonymous_element_'
+
self
.
counter
++
}
while
(
$
(
id
));
element
.
writeAttribute
(
'id'
,
id
);
return
id
;
},
readAttribute
:
function
(
element
,
name
)
{
element
=
$
(
element
);
if
(
Prototype
.
Browser
.
IE
)
{
var
t
=
Element
.
_attributeTranslations
.
read
;
if
(
t
.
values
[
name
])
return
t
.
values
[
name
](
element
,
name
);
if
(
t
.
names
[
name
])
name
=
t
.
names
[
name
];
if
(
name
.
include
(
':'
))
{
return
(
!
element
.
attributes
||
!
element
.
attributes
[
name
])
?
null
:
element
.
attributes
[
name
].
value
;
}
}
return
element
.
getAttribute
(
name
);
},
writeAttribute
:
function
(
element
,
name
,
value
)
{
element
=
$
(
element
);
var
attributes
=
{
},
t
=
Element
.
_attributeTranslations
.
write
;
if
(
typeof
name
==
'object'
)
attributes
=
name
;
else
attributes
[
name
]
=
Object
.
isUndefined
(
value
)
?
true
:
value
;
for
(
var
attr
in
attributes
)
{
name
=
t
.
names
[
attr
]
||
attr
;
value
=
attributes
[
attr
];
if
(
t
.
values
[
attr
])
name
=
t
.
values
[
attr
](
element
,
value
);
if
(
value
===
false
||
value
===
null
)
element
.
removeAttribute
(
name
);
else
if
(
value
===
true
)
element
.
setAttribute
(
name
,
name
);
else
element
.
setAttribute
(
name
,
value
);
}
return
element
;
},
getHeight
:
function
(
element
)
{
return
$
(
element
).
getDimensions
().
height
;
},
getWidth
:
function
(
element
)
{
return
$
(
element
).
getDimensions
().
width
;
},
classNames
:
function
(
element
)
{
return
new
Element
.
ClassNames
(
element
);
},
hasClassName
:
function
(
element
,
className
)
{
if
(
!
(
element
=
$
(
element
)))
return
;
var
elementClassName
=
element
.
className
;
return
(
elementClassName
.
length
>
0
&&
(
elementClassName
==
className
||
new
RegExp
(
"(^|\\s)"
+
className
+
"(\\s|$)"
).
test
(
elementClassName
)));
},
addClassName
:
function
(
element
,
className
)
{
if
(
!
(
element
=
$
(
element
)))
return
;
if
(
!
element
.
hasClassName
(
className
))
element
.
className
+=
(
element
.
className
?
' '
:
''
)
+
className
;
return
element
;
},
removeClassName
:
function
(
element
,
className
)
{
if
(
!
(
element
=
$
(
element
)))
return
;
element
.
className
=
element
.
className
.
replace
(
new
RegExp
(
"(^|\\s+)"
+
className
+
"(\\s+|$)"
),
' '
).
strip
();
return
element
;
},
toggleClassName
:
function
(
element
,
className
)
{
if
(
!
(
element
=
$
(
element
)))
return
;
return
element
[
element
.
hasClassName
(
className
)
?
'removeClassName'
:
'addClassName'
](
className
);
},
// removes whitespace-only text node children
cleanWhitespace
:
function
(
element
)
{
element
=
$
(
element
);
var
node
=
element
.
firstChild
;
while
(
node
)
{
var
nextNode
=
node
.
nextSibling
;
if
(
node
.
nodeType
==
3
&&
!
/\S/
.
test
(
node
.
nodeValue
))
element
.
removeChild
(
node
);
node
=
nextNode
;
}
return
element
;
},
empty
:
function
(
element
)
{
return
$
(
element
).
innerHTML
.
blank
();
},
descendantOf
:
function
(
element
,
ancestor
)
{
element
=
$
(
element
),
ancestor
=
$
(
ancestor
);
var
originalAncestor
=
ancestor
;
if
(
element
.
compareDocumentPosition
)
return
(
element
.
compareDocumentPosition
(
ancestor
)
&
8
)
===
8
;
if
(
element
.
sourceIndex
&&
!
Prototype
.
Browser
.
Opera
)
{
var
e
=
element
.
sourceIndex
,
a
=
ancestor
.
sourceIndex
,
nextAncestor
=
ancestor
.
nextSibling
;
if
(
!
nextAncestor
)
{
do
{
ancestor
=
ancestor
.
parentNode
;
}
while
(
!
(
nextAncestor
=
ancestor
.
nextSibling
)
&&
ancestor
.
parentNode
);
}
if
(
nextAncestor
)
return
(
e
>
a
&&
e
<
nextAncestor
.
sourceIndex
);
}
while
(
element
=
element
.
parentNode
)
if
(
element
==
originalAncestor
)
return
true
;
return
false
;
},
scrollTo
:
function
(
element
)
{
element
=
$
(
element
);
var
pos
=
element
.
cumulativeOffset
();
window
.
scrollTo
(
pos
[
0
],
pos
[
1
]);
return
element
;
},
getStyle
:
function
(
element
,
style
)
{
element
=
$
(
element
);
style
=
style
==
'float'
?
'cssFloat'
:
style
.
camelize
();
var
value
=
element
.
style
[
style
];
if
(
!
value
)
{
var
css
=
document
.
defaultView
.
getComputedStyle
(
element
,
null
);
value
=
css
?
css
[
style
]
:
null
;
}
if
(
style
==
'opacity'
)
return
value
?
parseFloat
(
value
)
:
1.0
;
return
value
==
'auto'
?
null
:
value
;
},
getOpacity
:
function
(
element
)
{
return
$
(
element
).
getStyle
(
'opacity'
);
},
setStyle
:
function
(
element
,
styles
)
{
element
=
$
(
element
);
var
elementStyle
=
element
.
style
,
match
;
if
(
Object
.
isString
(
styles
))
{
element
.
style
.
cssText
+=
';'
+
styles
;
return
styles
.
include
(
'opacity'
)
?
element
.
setOpacity
(
styles
.
match
(
/opacity:\s*(\d?\.?\d*)/
)[
1
])
:
element
;
}
for
(
var
property
in
styles
)
if
(
property
==
'opacity'
)
element
.
setOpacity
(
styles
[
property
]);
else
elementStyle
[(
property
==
'float'
||
property
==
'cssFloat'
)
?
(
Object
.
isUndefined
(
elementStyle
.
styleFloat
)
?
'cssFloat'
:
'styleFloat'
)
:
property
]
=
styles
[
property
];
return
element
;
},
setOpacity
:
function
(
element
,
value
)
{
element
=
$
(
element
);
element
.
style
.
opacity
=
(
value
==
1
||
value
===
''
)
?
''
:
(
value
<
0.00001
)
?
0
:
value
;
return
element
;
},
getDimensions
:
function
(
element
)
{
element
=
$
(
element
);
var
display
=
$
(
element
).
getStyle
(
'display'
);
if
(
display
!=
'none'
&&
display
!=
null
)
// Safari bug
return
{
width
:
element
.
offsetWidth
,
height
:
element
.
offsetHeight
};
// All *Width and *Height properties give 0 on elements with display none,
// so enable the element temporarily
var
els
=
element
.
style
;
var
originalVisibility
=
els
.
visibility
;
var
originalPosition
=
els
.
position
;
var
originalDisplay
=
els
.
display
;
els
.
visibility
=
'hidden'
;
els
.
position
=
'absolute'
;
els
.
display
=
'block'
;
var
originalWidth
=
element
.
clientWidth
;
var
originalHeight
=
element
.
clientHeight
;
els
.
display
=
originalDisplay
;
els
.
position
=
originalPosition
;
els
.
visibility
=
originalVisibility
;
return
{
width
:
originalWidth
,
height
:
originalHeight
};
},
makePositioned
:
function
(
element
)
{
element
=
$
(
element
);
var
pos
=
Element
.
getStyle
(
element
,
'position'
);
if
(
pos
==
'static'
||
!
pos
)
{
element
.
_madePositioned
=
true
;
element
.
style
.
position
=
'relative'
;
// Opera returns the offset relative to the positioning context, when an
// element is position relative but top and left have not been defined
if
(
window
.
opera
)
{
element
.
style
.
top
=
0
;
element
.
style
.
left
=
0
;
}
}
return
element
;
},
undoPositioned
:
function
(
element
)
{
element
=
$
(
element
);
if
(
element
.
_madePositioned
)
{
element
.
_madePositioned
=
undefined
;
element
.
style
.
position
=
element
.
style
.
top
=
element
.
style
.
left
=
element
.
style
.
bottom
=
element
.
style
.
right
=
''
;
}
return
element
;
},
makeClipping
:
function
(
element
)
{
element
=
$
(
element
);
if
(
element
.
_overflow
)
return
element
;
element
.
_overflow
=
Element
.
getStyle
(
element
,
'overflow'
)
||
'auto'
;
if
(
element
.
_overflow
!==
'hidden'
)
element
.
style
.
overflow
=
'hidden'
;
return
element
;
},
undoClipping
:
function
(
element
)
{
element
=
$
(
element
);
if
(
!
element
.
_overflow
)
return
element
;
element
.
style
.
overflow
=
element
.
_overflow
==
'auto'
?
''
:
element
.
_overflow
;
element
.
_overflow
=
null
;
return
element
;
},
cumulativeOffset
:
function
(
element
)
{
var
valueT
=
0
,
valueL
=
0
;
do
{
valueT
+=
element
.
offsetTop
||
0
;
valueL
+=
element
.
offsetLeft
||
0
;
element
=
element
.
offsetParent
;
}
while
(
element
);
return
Element
.
_returnOffset
(
valueL
,
valueT
);
},
positionedOffset
:
function
(
element
)
{
var
valueT
=
0
,
valueL
=
0
;
do
{
valueT
+=
element
.
offsetTop
||
0
;
valueL
+=
element
.
offsetLeft
||
0
;
element
=
element
.
offsetParent
;
if
(
element
)
{
if
(
element
.
tagName
==
'BODY'
)
break
;
var
p
=
Element
.
getStyle
(
element
,
'position'
);
if
(
p
==
'relative'
||
p
==
'absolute'
)
break
;
}
}
while
(
element
);
return
Element
.
_returnOffset
(
valueL
,
valueT
);
},
absolutize
:
function
(
element
)
{
element
=
$
(
element
);
if
(
element
.
getStyle
(
'position'
)
==
'absolute'
)
return
;
// Position.prepare(); // To be done manually by Scripty when it needs it.
var
offsets
=
element
.
positionedOffset
();
var
top
=
offsets
[
1
];
var
left
=
offsets
[
0
];
var
width
=
element
.
clientWidth
;
var
height
=
element
.
clientHeight
;
element
.
_originalLeft
=
left
-
parseFloat
(
element
.
style
.
left
||
0
);
element
.
_originalTop
=
top
-
parseFloat
(
element
.
style
.
top
||
0
);
element
.
_originalWidth
=
element
.
style
.
width
;
element
.
_originalHeight
=
element
.
style
.
height
;
element
.
style
.
position
=
'absolute'
;
element
.
style
.
top
=
top
+
'px'
;
element
.
style
.
left
=
left
+
'px'
;
element
.
style
.
width
=
width
+
'px'
;
element
.
style
.
height
=
height
+
'px'
;
return
element
;
},
relativize
:
function
(
element
)
{
element
=
$
(
element
);
if
(
element
.
getStyle
(
'position'
)
==
'relative'
)
return
;
// Position.prepare(); // To be done manually by Scripty when it needs it.
element
.
style
.
position
=
'relative'
;
var
top
=
parseFloat
(
element
.
style
.
top
||
0
)
-
(
element
.
_originalTop
||
0
);
var
left
=
parseFloat
(
element
.
style
.
left
||
0
)
-
(
element
.
_originalLeft
||
0
);
element
.
style
.
top
=
top
+
'px'
;
element
.
style
.
left
=
left
+
'px'
;
element
.
style
.
height
=
element
.
_originalHeight
;
element
.
style
.
width
=
element
.
_originalWidth
;
return
element
;
},
cumulativeScrollOffset
:
function
(
element
)
{
var
valueT
=
0
,
valueL
=
0
;
do
{
valueT
+=
element
.
scrollTop
||
0
;
valueL
+=
element
.
scrollLeft
||
0
;
element
=
element
.
parentNode
;
}
while
(
element
);
return
Element
.
_returnOffset
(
valueL
,
valueT
);
},
getOffsetParent
:
function
(
element
)
{
if
(
element
.
offsetParent
)
return
$
(
element
.
offsetParent
);
if
(
element
==
document
.
body
)
return
$
(
element
);
while
((
element
=
element
.
parentNode
)
&&
element
!=
document
.
body
)
if
(
Element
.
getStyle
(
element
,
'position'
)
!=
'static'
)
return
$
(
element
);
return
$
(
document
.
body
);
},
viewportOffset
:
function
(
forElement
)
{
var
valueT
=
0
,
valueL
=
0
;
var
element
=
forElement
;
do
{
valueT
+=
element
.
offsetTop
||
0
;
valueL
+=
element
.
offsetLeft
||
0
;
// Safari fix
if
(
element
.
offsetParent
==
document
.
body
&&
Element
.
getStyle
(
element
,
'position'
)
==
'absolute'
)
break
;
}
while
(
element
=
element
.
offsetParent
);
element
=
forElement
;
do
{
if
(
!
Prototype
.
Browser
.
Opera
||
element
.
tagName
==
'BODY'
)
{
valueT
-=
element
.
scrollTop
||
0
;
valueL
-=
element
.
scrollLeft
||
0
;
}
}
while
(
element
=
element
.
parentNode
);
return
Element
.
_returnOffset
(
valueL
,
valueT
);
},
clonePosition
:
function
(
element
,
source
)
{
var
options
=
Object
.
extend
({
setLeft
:
true
,
setTop
:
true
,
setWidth
:
true
,
setHeight
:
true
,
offsetTop
:
0
,
offsetLeft
:
0
},
arguments
[
2
]
||
{
});
// find page position of source
source
=
$
(
source
);
var
p
=
source
.
viewportOffset
();
// find coordinate system to use
element
=
$
(
element
);
var
delta
=
[
0
,
0
];
var
parent
=
null
;
// delta [0,0] will do fine with position: fixed elements,
// position:absolute needs offsetParent deltas
if
(
Element
.
getStyle
(
element
,
'position'
)
==
'absolute'
)
{
parent
=
element
.
getOffsetParent
();
delta
=
parent
.
viewportOffset
();
}
// correct by body offsets (fixes Safari)
if
(
parent
==
document
.
body
)
{
delta
[
0
]
-=
document
.
body
.
offsetLeft
;
delta
[
1
]
-=
document
.
body
.
offsetTop
;
}
// set position
if
(
options
.
setLeft
)
element
.
style
.
left
=
(
p
[
0
]
-
delta
[
0
]
+
options
.
offsetLeft
)
+
'px'
;
if
(
options
.
setTop
)
element
.
style
.
top
=
(
p
[
1
]
-
delta
[
1
]
+
options
.
offsetTop
)
+
'px'
;
if
(
options
.
setWidth
)
element
.
style
.
width
=
source
.
offsetWidth
+
'px'
;
if
(
options
.
setHeight
)
element
.
style
.
height
=
source
.
offsetHeight
+
'px'
;
return
element
;
}
};
Element
.
Methods
.
identify
.
counter
=
1
;
Object
.
extend
(
Element
.
Methods
,
{
getElementsBySelector
:
Element
.
Methods
.
select
,
childElements
:
Element
.
Methods
.
immediateDescendants
});
Element
.
_attributeTranslations
=
{
write
:
{
names
:
{
className
:
'class'
,
htmlFor
:
'for'
},
values
:
{
}
}
};
if
(
!
document
.
createRange
||
Prototype
.
Browser
.
Opera
)
{
Element
.
Methods
.
insert
=
function
(
element
,
insertions
)
{
element
=
$
(
element
);
if
(
Object
.
isString
(
insertions
)
||
Object
.
isNumber
(
insertions
)
||
Object
.
isElement
(
insertions
)
||
(
insertions
&&
(
insertions
.
toElement
||
insertions
.
toHTML
)))
insertions
=
{
bottom
:
insertions
};
var
t
=
Element
.
_insertionTranslations
,
content
,
position
,
pos
,
tagName
;
for
(
position
in
insertions
)
{
content
=
insertions
[
position
];
position
=
position
.
toLowerCase
();
pos
=
t
[
position
];
if
(
content
&&
content
.
toElement
)
content
=
content
.
toElement
();
if
(
Object
.
isElement
(
content
))
{
pos
.
insert
(
element
,
content
);
continue
;
}
content
=
Object
.
toHTML
(
content
);
tagName
=
((
position
==
'before'
||
position
==
'after'
)
?
element
.
parentNode
:
element
).
tagName
.
toUpperCase
();
if
(
t
.
tags
[
tagName
])
{
var
fragments
=
Element
.
_getContentFromAnonymousElement
(
tagName
,
content
.
stripScripts
());
if
(
position
==
'top'
||
position
==
'after'
)
fragments
.
reverse
();
fragments
.
each
(
pos
.
insert
.
curry
(
element
));
}
else
element
.
insertAdjacentHTML
(
pos
.
adjacency
,
content
.
stripScripts
());
content
.
evalScripts
.
bind
(
content
).
defer
();
}
return
element
;
};
}
if
(
Prototype
.
Browser
.
Opera
)
{
Element
.
Methods
.
getStyle
=
Element
.
Methods
.
getStyle
.
wrap
(
function
(
proceed
,
element
,
style
)
{
switch
(
style
)
{
case
'left'
:
case
'top'
:
case
'right'
:
case
'bottom'
:
if
(
proceed
(
element
,
'position'
)
===
'static'
)
return
null
;
case
'height'
:
case
'width'
:
// returns '0px' for hidden elements; we want it to return null
if
(
!
Element
.
visible
(
element
))
return
null
;
// returns the border-box dimensions rather than the content-box
// dimensions, so we subtract padding and borders from the value
var
dim
=
parseInt
(
proceed
(
element
,
style
),
10
);
if
(
dim
!==
element
[
'offset'
+
style
.
capitalize
()])
return
dim
+
'px'
;
var
properties
;
if
(
style
===
'height'
)
{
properties
=
[
'border-top-width'
,
'padding-top'
,
'padding-bottom'
,
'border-bottom-width'
];
}
else
{
properties
=
[
'border-left-width'
,
'padding-left'
,
'padding-right'
,
'border-right-width'
];
}
return
properties
.
inject
(
dim
,
function
(
memo
,
property
)
{
var
val
=
proceed
(
element
,
property
);
return
val
===
null
?
memo
:
memo
-
parseInt
(
val
,
10
);
})
+
'px'
;
default
:
return
proceed
(
element
,
style
);
}
}
);
Element
.
Methods
.
readAttribute
=
Element
.
Methods
.
readAttribute
.
wrap
(
function
(
proceed
,
element
,
attribute
)
{
if
(
attribute
===
'title'
)
return
element
.
title
;
return
proceed
(
element
,
attribute
);
}
);
}
else
if
(
Prototype
.
Browser
.
IE
)
{
$w
(
'positionedOffset getOffsetParent viewportOffset'
).
each
(
function
(
method
)
{
Element
.
Methods
[
method
]
=
Element
.
Methods
[
method
].
wrap
(
function
(
proceed
,
element
)
{
element
=
$
(
element
);
var
position
=
element
.
getStyle
(
'position'
);
if
(
position
!=
'static'
)
return
proceed
(
element
);
element
.
setStyle
({
position
:
'relative'
});
var
value
=
proceed
(
element
);
element
.
setStyle
({
position
:
position
});
return
value
;
}
);
});
Element
.
Methods
.
getStyle
=
function
(
element
,
style
)
{
element
=
$
(
element
);
style
=
(
style
==
'float'
||
style
==
'cssFloat'
)
?
'styleFloat'
:
style
.
camelize
();
var
value
=
element
.
style
[
style
];
if
(
!
value
&&
element
.
currentStyle
)
value
=
element
.
currentStyle
[
style
];
if
(
style
==
'opacity'
)
{
if
(
value
=
(
element
.
getStyle
(
'filter'
)
||
''
).
match
(
/alpha\(opacity=(.*)\)/
))
if
(
value
[
1
])
return
parseFloat
(
value
[
1
])
/
100
;
return
1.0
;
}
if
(
value
==
'auto'
)
{
if
((
style
==
'width'
||
style
==
'height'
)
&&
(
element
.
getStyle
(
'display'
)
!=
'none'
))
return
element
[
'offset'
+
style
.
capitalize
()]
+
'px'
;
return
null
;
}
return
value
;
};
Element
.
Methods
.
setOpacity
=
function
(
element
,
value
)
{
function
stripAlpha
(
filter
){
return
filter
.
replace
(
/alpha\([^\)]*\)/gi
,
''
);
}
element
=
$
(
element
);
var
currentStyle
=
element
.
currentStyle
;
if
((
currentStyle
&&
!
currentStyle
.
hasLayout
)
||
(
!
currentStyle
&&
element
.
style
.
zoom
==
'normal'
))
element
.
style
.
zoom
=
1
;
var
filter
=
element
.
getStyle
(
'filter'
),
style
=
element
.
style
;
if
(
value
==
1
||
value
===
''
)
{
(
filter
=
stripAlpha
(
filter
))
?
style
.
filter
=
filter
:
style
.
removeAttribute
(
'filter'
);
return
element
;
}
else
if
(
value
<
0.00001
)
value
=
0
;
style
.
filter
=
stripAlpha
(
filter
)
+
'alpha(opacity='
+
(
value
*
100
)
+
')'
;
return
element
;
};
Element
.
_attributeTranslations
=
{
read
:
{
names
:
{
'class'
:
'className'
,
'for'
:
'htmlFor'
},
values
:
{
_getAttr
:
function
(
element
,
attribute
)
{
return
element
.
getAttribute
(
attribute
,
2
);
},
_getAttrNode
:
function
(
element
,
attribute
)
{
var
node
=
element
.
getAttributeNode
(
attribute
);
return
node
?
node
.
value
:
""
;
},
_getEv
:
function
(
element
,
attribute
)
{
attribute
=
element
.
getAttribute
(
attribute
);
return
attribute
?
attribute
.
toString
().
slice
(
23
,
-
2
)
:
null
;
},
_flag
:
function
(
element
,
attribute
)
{
return
$
(
element
).
hasAttribute
(
attribute
)
?
attribute
:
null
;
},
style
:
function
(
element
)
{
return
element
.
style
.
cssText
.
toLowerCase
();
},
title
:
function
(
element
)
{
return
element
.
title
;
}
}
}
};
Element
.
_attributeTranslations
.
write
=
{
names
:
Object
.
clone
(
Element
.
_attributeTranslations
.
read
.
names
),
values
:
{
checked
:
function
(
element
,
value
)
{
element
.
checked
=
!!
value
;
},
style
:
function
(
element
,
value
)
{
element
.
style
.
cssText
=
value
?
value
:
''
;
}
}
};
Element
.
_attributeTranslations
.
has
=
{};
$w
(
'colSpan rowSpan vAlign dateTime accessKey tabIndex '
+
'encType maxLength readOnly longDesc'
).
each
(
function
(
attr
)
{
Element
.
_attributeTranslations
.
write
.
names
[
attr
.
toLowerCase
()]
=
attr
;
Element
.
_attributeTranslations
.
has
[
attr
.
toLowerCase
()]
=
attr
;
});
(
function
(
v
)
{
Object
.
extend
(
v
,
{
href
:
v
.
_getAttr
,
src
:
v
.
_getAttr
,
type
:
v
.
_getAttr
,
action
:
v
.
_getAttrNode
,
disabled
:
v
.
_flag
,
checked
:
v
.
_flag
,
readonly
:
v
.
_flag
,
multiple
:
v
.
_flag
,
onload
:
v
.
_getEv
,
onunload
:
v
.
_getEv
,
onclick
:
v
.
_getEv
,
ondblclick
:
v
.
_getEv
,
onmousedown
:
v
.
_getEv
,
onmouseup
:
v
.
_getEv
,
onmouseover
:
v
.
_getEv
,
onmousemove
:
v
.
_getEv
,
onmouseout
:
v
.
_getEv
,
onfocus
:
v
.
_getEv
,
onblur
:
v
.
_getEv
,
onkeypress
:
v
.
_getEv
,
onkeydown
:
v
.
_getEv
,
onkeyup
:
v
.
_getEv
,
onsubmit
:
v
.
_getEv
,
onreset
:
v
.
_getEv
,
onselect
:
v
.
_getEv
,
onchange
:
v
.
_getEv
});
})(
Element
.
_attributeTranslations
.
read
.
values
);
}
else
if
(
Prototype
.
Browser
.
Gecko
&&
/rv:1\.8\.0/
.
test
(
navigator
.
userAgent
))
{
Element
.
Methods
.
setOpacity
=
function
(
element
,
value
)
{
element
=
$
(
element
);
element
.
style
.
opacity
=
(
value
==
1
)
?
0.999999
:
(
value
===
''
)
?
''
:
(
value
<
0.00001
)
?
0
:
value
;
return
element
;
};
}
else
if
(
Prototype
.
Browser
.
WebKit
)
{
Element
.
Methods
.
setOpacity
=
function
(
element
,
value
)
{
element
=
$
(
element
);
element
.
style
.
opacity
=
(
value
==
1
||
value
===
''
)
?
''
:
(
value
<
0.00001
)
?
0
:
value
;
if
(
value
==
1
)
if
(
element
.
tagName
==
'IMG'
&&
element
.
width
)
{
element
.
width
++
;
element
.
width
--
;
}
else
try
{
var
n
=
document
.
createTextNode
(
' '
);
element
.
appendChild
(
n
);
element
.
removeChild
(
n
);
}
catch
(
e
)
{
}
return
element
;
};
// Safari returns margins on body which is incorrect if the child is absolutely
// positioned. For performance reasons, redefine Element#cumulativeOffset for
// KHTML/WebKit only.
Element
.
Methods
.
cumulativeOffset
=
function
(
element
)
{
var
valueT
=
0
,
valueL
=
0
;
do
{
valueT
+=
element
.
offsetTop
||
0
;
valueL
+=
element
.
offsetLeft
||
0
;
if
(
element
.
offsetParent
==
document
.
body
)
if
(
Element
.
getStyle
(
element
,
'position'
)
==
'absolute'
)
break
;
element
=
element
.
offsetParent
;
}
while
(
element
);
return
Element
.
_returnOffset
(
valueL
,
valueT
);
};
}
if
(
Prototype
.
Browser
.
IE
||
Prototype
.
Browser
.
Opera
)
{
// IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
Element
.
Methods
.
update
=
function
(
element
,
content
)
{
element
=
$
(
element
);
if
(
content
&&
content
.
toElement
)
content
=
content
.
toElement
();
if
(
Object
.
isElement
(
content
))
return
element
.
update
().
insert
(
content
);
content
=
Object
.
toHTML
(
content
);
var
tagName
=
element
.
tagName
.
toUpperCase
();
if
(
tagName
in
Element
.
_insertionTranslations
.
tags
)
{
$A
(
element
.
childNodes
).
each
(
function
(
node
)
{
element
.
removeChild
(
node
)
});
Element
.
_getContentFromAnonymousElement
(
tagName
,
content
.
stripScripts
())
.
each
(
function
(
node
)
{
element
.
appendChild
(
node
)
});
}
else
element
.
innerHTML
=
content
.
stripScripts
();
content
.
evalScripts
.
bind
(
content
).
defer
();
return
element
;
};
}
if
(
document
.
createElement
(
'div'
).
outerHTML
)
{
Element
.
Methods
.
replace
=
function
(
element
,
content
)
{
element
=
$
(
element
);
if
(
content
&&
content
.
toElement
)
content
=
content
.
toElement
();
if
(
Object
.
isElement
(
content
))
{
element
.
parentNode
.
replaceChild
(
content
,
element
);
return
element
;
}
content
=
Object
.
toHTML
(
content
);
var
parent
=
element
.
parentNode
,
tagName
=
parent
.
tagName
.
toUpperCase
();
if
(
Element
.
_insertionTranslations
.
tags
[
tagName
])
{
var
nextSibling
=
element
.
next
();
var
fragments
=
Element
.
_getContentFromAnonymousElement
(
tagName
,
content
.
stripScripts
());
parent
.
removeChild
(
element
);
if
(
nextSibling
)
fragments
.
each
(
function
(
node
)
{
parent
.
insertBefore
(
node
,
nextSibling
)
});
else
fragments
.
each
(
function
(
node
)
{
parent
.
appendChild
(
node
)
});
}
else
element
.
outerHTML
=
content
.
stripScripts
();
content
.
evalScripts
.
bind
(
content
).
defer
();
return
element
;
};
}
Element
.
_returnOffset
=
function
(
l
,
t
)
{
var
result
=
[
l
,
t
];
result
.
left
=
l
;
result
.
top
=
t
;
return
result
;
};
Element
.
_getContentFromAnonymousElement
=
function
(
tagName
,
html
)
{
var
div
=
new
Element
(
'div'
),
t
=
Element
.
_insertionTranslations
.
tags
[
tagName
];
div
.
innerHTML
=
t
[
0
]
+
html
+
t
[
1
];
t
[
2
].
times
(
function
()
{
div
=
div
.
firstChild
});
return
$A
(
div
.
childNodes
);
};
Element
.
_insertionTranslations
=
{
before
:
{
adjacency
:
'beforeBegin'
,
insert
:
function
(
element
,
node
)
{
element
.
parentNode
.
insertBefore
(
node
,
element
);
},
initializeRange
:
function
(
element
,
range
)
{
range
.
setStartBefore
(
element
);
}
},
top
:
{
adjacency
:
'afterBegin'
,
insert
:
function
(
element
,
node
)
{
element
.
insertBefore
(
node
,
element
.
firstChild
);
},
initializeRange
:
function
(
element
,
range
)
{
range
.
selectNodeContents
(
element
);
range
.
collapse
(
true
);
}
},
bottom
:
{
adjacency
:
'beforeEnd'
,
insert
:
function
(
element
,
node
)
{
element
.
appendChild
(
node
);
}
},
after
:
{
adjacency
:
'afterEnd'
,
insert
:
function
(
element
,
node
)
{
element
.
parentNode
.
insertBefore
(
node
,
element
.
nextSibling
);
},
initializeRange
:
function
(
element
,
range
)
{
range
.
setStartAfter
(
element
);
}
},
tags
:
{
TABLE
:
[
'<table>'
,
'</table>'
,
1
],
TBODY
:
[
'<table><tbody>'
,
'</tbody></table>'
,
2
],
TR
:
[
'<table><tbody><tr>'
,
'</tr></tbody></table>'
,
3
],
TD
:
[
'<table><tbody><tr><td>'
,
'</td></tr></tbody></table>'
,
4
],
SELECT
:
[
'<select>'
,
'</select>'
,
1
]
}
};
(
function
()
{
this
.
bottom
.
initializeRange
=
this
.
top
.
initializeRange
;
Object
.
extend
(
this
.
tags
,
{
THEAD
:
this
.
tags
.
TBODY
,
TFOOT
:
this
.
tags
.
TBODY
,
TH
:
this
.
tags
.
TD
});
}).
call
(
Element
.
_insertionTranslations
);
Element
.
Methods
.
Simulated
=
{
hasAttribute
:
function
(
element
,
attribute
)
{
attribute
=
Element
.
_attributeTranslations
.
has
[
attribute
]
||
attribute
;
var
node
=
$
(
element
).
getAttributeNode
(
attribute
);
return
node
&&
node
.
specified
;
}
};
Element
.
Methods
.
ByTag
=
{
};
Object
.
extend
(
Element
,
Element
.
Methods
);
if
(
!
Prototype
.
BrowserFeatures
.
ElementExtensions
&&
document
.
createElement
(
'div'
).
__proto__
)
{
window
.
HTMLElement
=
{
};
window
.
HTMLElement
.
prototype
=
document
.
createElement
(
'div'
).
__proto__
;
Prototype
.
BrowserFeatures
.
ElementExtensions
=
true
;
}
Element
.
extend
=
(
function
()
{
if
(
Prototype
.
BrowserFeatures
.
SpecificElementExtensions
)
return
Prototype
.
K
;
var
Methods
=
{
},
ByTag
=
Element
.
Methods
.
ByTag
;
var
extend
=
Object
.
extend
(
function
(
element
)
{
if
(
!
element
||
element
.
_extendedByPrototype
||
element
.
nodeType
!=
1
||
element
==
window
)
return
element
;
var
methods
=
Object
.
clone
(
Methods
),
tagName
=
element
.
tagName
,
property
,
value
;
// extend methods for specific tags
if
(
ByTag
[
tagName
])
Object
.
extend
(
methods
,
ByTag
[
tagName
]);
for
(
property
in
methods
)
{
value
=
methods
[
property
];
if
(
Object
.
isFunction
(
value
)
&&
!
(
property
in
element
))
element
[
property
]
=
value
.
methodize
();
}
element
.
_extendedByPrototype
=
Prototype
.
emptyFunction
;
return
element
;
},
{
refresh
:
function
()
{
// extend methods for all tags (Safari doesn't need this)
if
(
!
Prototype
.
BrowserFeatures
.
ElementExtensions
)
{
Object
.
extend
(
Methods
,
Element
.
Methods
);
Object
.
extend
(
Methods
,
Element
.
Methods
.
Simulated
);
}
}
});
extend
.
refresh
();
return
extend
;
})();
Element
.
hasAttribute
=
function
(
element
,
attribute
)
{
if
(
element
.
hasAttribute
)
return
element
.
hasAttribute
(
attribute
);
return
Element
.
Methods
.
Simulated
.
hasAttribute
(
element
,
attribute
);
};
Element
.
addMethods
=
function
(
methods
)
{
var
F
=
Prototype
.
BrowserFeatures
,
T
=
Element
.
Methods
.
ByTag
;
if
(
!
methods
)
{
Object
.
extend
(
Form
,
Form
.
Methods
);
Object
.
extend
(
Form
.
Element
,
Form
.
Element
.
Methods
);
Object
.
extend
(
Element
.
Methods
.
ByTag
,
{
"FORM"
:
Object
.
clone
(
Form
.
Methods
),
"INPUT"
:
Object
.
clone
(
Form
.
Element
.
Methods
),
"SELECT"
:
Object
.
clone
(
Form
.
Element
.
Methods
),
"TEXTAREA"
:
Object
.
clone
(
Form
.
Element
.
Methods
)
});
}
if
(
arguments
.
length
==
2
)
{
var
tagName
=
methods
;
methods
=
arguments
[
1
];
}
if
(
!
tagName
)
Object
.
extend
(
Element
.
Methods
,
methods
||
{
});
else
{
if
(
Object
.
isArray
(
tagName
))
tagName
.
each
(
extend
);
else
extend
(
tagName
);
}
function
extend
(
tagName
)
{
tagName
=
tagName
.
toUpperCase
();
if
(
!
Element
.
Methods
.
ByTag
[
tagName
])
Element
.
Methods
.
ByTag
[
tagName
]
=
{
};
Object
.
extend
(
Element
.
Methods
.
ByTag
[
tagName
],
methods
);
}
function
copy
(
methods
,
destination
,
onlyIfAbsent
)
{
onlyIfAbsent
=
onlyIfAbsent
||
false
;
for
(
var
property
in
methods
)
{
var
value
=
methods
[
property
];
if
(
!
Object
.
isFunction
(
value
))
continue
;
if
(
!
onlyIfAbsent
||
!
(
property
in
destination
))
destination
[
property
]
=
value
.
methodize
();
}
}
function
findDOMClass
(
tagName
)
{
var
klass
;
var
trans
=
{
"OPTGROUP"
:
"OptGroup"
,
"TEXTAREA"
:
"TextArea"
,
"P"
:
"Paragraph"
,
"FIELDSET"
:
"FieldSet"
,
"UL"
:
"UList"
,
"OL"
:
"OList"
,
"DL"
:
"DList"
,
"DIR"
:
"Directory"
,
"H1"
:
"Heading"
,
"H2"
:
"Heading"
,
"H3"
:
"Heading"
,
"H4"
:
"Heading"
,
"H5"
:
"Heading"
,
"H6"
:
"Heading"
,
"Q"
:
"Quote"
,
"INS"
:
"Mod"
,
"DEL"
:
"Mod"
,
"A"
:
"Anchor"
,
"IMG"
:
"Image"
,
"CAPTION"
:
"TableCaption"
,
"COL"
:
"TableCol"
,
"COLGROUP"
:
"TableCol"
,
"THEAD"
:
"TableSection"
,
"TFOOT"
:
"TableSection"
,
"TBODY"
:
"TableSection"
,
"TR"
:
"TableRow"
,
"TH"
:
"TableCell"
,
"TD"
:
"TableCell"
,
"FRAMESET"
:
"FrameSet"
,
"IFRAME"
:
"IFrame"
};
if
(
trans
[
tagName
])
klass
=
'HTML'
+
trans
[
tagName
]
+
'Element'
;
if
(
window
[
klass
])
return
window
[
klass
];
klass
=
'HTML'
+
tagName
+
'Element'
;
if
(
window
[
klass
])
return
window
[
klass
];
klass
=
'HTML'
+
tagName
.
capitalize
()
+
'Element'
;
if
(
window
[
klass
])
return
window
[
klass
];
window
[
klass
]
=
{
};
window
[
klass
].
prototype
=
document
.
createElement
(
tagName
).
__proto__
;
return
window
[
klass
];
}
if
(
F
.
ElementExtensions
)
{
copy
(
Element
.
Methods
,
HTMLElement
.
prototype
);
copy
(
Element
.
Methods
.
Simulated
,
HTMLElement
.
prototype
,
true
);
}
if
(
F
.
SpecificElementExtensions
)
{
for
(
var
tag
in
Element
.
Methods
.
ByTag
)
{
var
klass
=
findDOMClass
(
tag
);
if
(
Object
.
isUndefined
(
klass
))
continue
;
copy
(
T
[
tag
],
klass
.
prototype
);
}
}
Object
.
extend
(
Element
,
Element
.
Methods
);
delete
Element
.
ByTag
;
if
(
Element
.
extend
.
refresh
)
Element
.
extend
.
refresh
();
Element
.
cache
=
{
};
};
document
.
viewport
=
{
getDimensions
:
function
()
{
var
dimensions
=
{
};
var
B
=
Prototype
.
Browser
;
$w
(
'width height'
).
each
(
function
(
d
)
{
var
D
=
d
.
capitalize
();
dimensions
[
d
]
=
(
B
.
WebKit
&&
!
document
.
evaluate
)
?
self
[
'inner'
+
D
]
:
(
B
.
Opera
)
?
document
.
body
[
'client'
+
D
]
:
document
.
documentElement
[
'client'
+
D
];
});
return
dimensions
;
},
getWidth
:
function
()
{
return
this
.
getDimensions
().
width
;
},
getHeight
:
function
()
{
return
this
.
getDimensions
().
height
;
},
getScrollOffsets
:
function
()
{
return
Element
.
_returnOffset
(
window
.
pageXOffset
||
document
.
documentElement
.
scrollLeft
||
document
.
body
.
scrollLeft
,
window
.
pageYOffset
||
document
.
documentElement
.
scrollTop
||
document
.
body
.
scrollTop
);
}
};
/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
* part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
* license. Please see http://www.yui-ext.com/ for more information. */
var
Selector
=
Class
.
create
({
initialize
:
function
(
expression
)
{
this
.
expression
=
expression
.
strip
();
this
.
compileMatcher
();
},
shouldUseXPath
:
function
()
{
if
(
!
Prototype
.
BrowserFeatures
.
XPath
)
return
false
;
var
e
=
this
.
expression
;
// Safari 3 chokes on :*-of-type and :empty
if
(
Prototype
.
Browser
.
WebKit
&&
(
e
.
include
(
"-of-type"
)
||
e
.
include
(
":empty"
)))
return
false
;
// XPath can't do namespaced attributes, nor can it read
// the "checked" property from DOM nodes
if
((
/(\[[\w-]*?:|:checked)/
).
test
(
this
.
expression
))
return
false
;
return
true
;
},
compileMatcher
:
function
()
{
if
(
this
.
shouldUseXPath
())
return
this
.
compileXPathMatcher
();
var
e
=
this
.
expression
,
ps
=
Selector
.
patterns
,
h
=
Selector
.
handlers
,
c
=
Selector
.
criteria
,
le
,
p
,
m
;
if
(
Selector
.
_cache
[
e
])
{
this
.
matcher
=
Selector
.
_cache
[
e
];
return
;
}
this
.
matcher
=
[
"this.matcher = function(root) {"
,
"var r = root, h = Selector.handlers, c = false, n;"
];
while
(
e
&&
le
!=
e
&&
(
/\S/
).
test
(
e
))
{
le
=
e
;
for
(
var
i
in
ps
)
{
p
=
ps
[
i
];
if
(
m
=
e
.
match
(
p
))
{
this
.
matcher
.
push
(
Object
.
isFunction
(
c
[
i
])
?
c
[
i
](
m
)
:
new
Template
(
c
[
i
]).
evaluate
(
m
));
e
=
e
.
replace
(
m
[
0
],
''
);
break
;
}
}
}
this
.
matcher
.
push
(
"return h.unique(n);\n}"
);
eval
(
this
.
matcher
.
join
(
'\n'
));
Selector
.
_cache
[
this
.
expression
]
=
this
.
matcher
;
},
compileXPathMatcher
:
function
()
{
var
e
=
this
.
expression
,
ps
=
Selector
.
patterns
,
x
=
Selector
.
xpath
,
le
,
m
;
if
(
Selector
.
_cache
[
e
])
{
this
.
xpath
=
Selector
.
_cache
[
e
];
return
;
}
this
.
matcher
=
[
'.//*'
];
while
(
e
&&
le
!=
e
&&
(
/\S/
).
test
(
e
))
{
le
=
e
;
for
(
var
i
in
ps
)
{
if
(
m
=
e
.
match
(
ps
[
i
]))
{
this
.
matcher
.
push
(
Object
.
isFunction
(
x
[
i
])
?
x
[
i
](
m
)
:
new
Template
(
x
[
i
]).
evaluate
(
m
));
e
=
e
.
replace
(
m
[
0
],
''
);
break
;
}
}
}
this
.
xpath
=
this
.
matcher
.
join
(
''
);
Selector
.
_cache
[
this
.
expression
]
=
this
.
xpath
;
},
findElements
:
function
(
root
)
{
root
=
root
||
document
;
if
(
this
.
xpath
)
return
document
.
_getElementsByXPath
(
this
.
xpath
,
root
);
return
this
.
matcher
(
root
);
},
match
:
function
(
element
)
{
this
.
tokens
=
[];
var
e
=
this
.
expression
,
ps
=
Selector
.
patterns
,
as
=
Selector
.
assertions
;
var
le
,
p
,
m
;
while
(
e
&&
le
!==
e
&&
(
/\S/
).
test
(
e
))
{
le
=
e
;
for
(
var
i
in
ps
)
{
p
=
ps
[
i
];
if
(
m
=
e
.
match
(
p
))
{
// use the Selector.assertions methods unless the selector
// is too complex.
if
(
as
[
i
])
{
this
.
tokens
.
push
([
i
,
Object
.
clone
(
m
)]);
e
=
e
.
replace
(
m
[
0
],
''
);
}
else
{
// reluctantly do a document-wide search
// and look for a match in the array
return
this
.
findElements
(
document
).
include
(
element
);
}
}
}
}
var
match
=
true
,
name
,
matches
;
for
(
var
i
=
0
,
token
;
token
=
this
.
tokens
[
i
];
i
++
)
{
name
=
token
[
0
],
matches
=
token
[
1
];
if
(
!
Selector
.
assertions
[
name
](
element
,
matches
))
{
match
=
false
;
break
;
}
}
return
match
;
},
toString
:
function
()
{
return
this
.
expression
;
},
inspect
:
function
()
{
return
"#<Selector:"
+
this
.
expression
.
inspect
()
+
">"
;
}
});
Object
.
extend
(
Selector
,
{
_cache
:
{
},
xpath
:
{
descendant
:
"//*"
,
child
:
"/*"
,
adjacent
:
"/following-sibling::*[1]"
,
laterSibling
:
'/following-sibling::*'
,
tagName
:
function
(
m
)
{
if
(
m
[
1
]
==
'*'
)
return
''
;
return
"[local-name()='"
+
m
[
1
].
toLowerCase
()
+
"' or local-name()='"
+
m
[
1
].
toUpperCase
()
+
"']"
;
},
className
:
"[contains(concat(' ', @class, ' '), ' #{1} ')]"
,
id
:
"[@id='#{1}']"
,
attrPresence
:
function
(
m
)
{
m
[
1
]
=
m
[
1
].
toLowerCase
();
return
new
Template
(
"[@#{1}]"
).
evaluate
(
m
);
},
attr
:
function
(
m
)
{
m
[
1
]
=
m
[
1
].
toLowerCase
();
m
[
3
]
=
m
[
5
]
||
m
[
6
];
return
new
Template
(
Selector
.
xpath
.
operators
[
m
[
2
]]).
evaluate
(
m
);
},
pseudo
:
function
(
m
)
{
var
h
=
Selector
.
xpath
.
pseudos
[
m
[
1
]];
if
(
!
h
)
return
''
;
if
(
Object
.
isFunction
(
h
))
return
h
(
m
);
return
new
Template
(
Selector
.
xpath
.
pseudos
[
m
[
1
]]).
evaluate
(
m
);
},
operators
:
{
'='
:
"[@#{1}='#{3}']"
,
'!='
:
"[@#{1}!='#{3}']"
,
'^='
:
"[starts-with(@#{1}, '#{3}')]"
,
'$='
:
"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']"
,
'*='
:
"[contains(@#{1}, '#{3}')]"
,
'~='
:
"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]"
,
'|='
:
"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
},
pseudos
:
{
'first-child'
:
'[not(preceding-sibling::*)]'
,
'last-child'
:
'[not(following-sibling::*)]'
,
'only-child'
:
'[not(preceding-sibling::* or following-sibling::*)]'
,
'empty'
:
"[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]"
,
'checked'
:
"[@checked]"
,
'disabled'
:
"[@disabled]"
,
'enabled'
:
"[not(@disabled)]"
,
'not'
:
function
(
m
)
{
var
e
=
m
[
6
],
p
=
Selector
.
patterns
,
x
=
Selector
.
xpath
,
le
,
v
;
var
exclusion
=
[];
while
(
e
&&
le
!=
e
&&
(
/\S/
).
test
(
e
))
{
le
=
e
;
for
(
var
i
in
p
)
{
if
(
m
=
e
.
match
(
p
[
i
]))
{
v
=
Object
.
isFunction
(
x
[
i
])
?
x
[
i
](
m
)
:
new
Template
(
x
[
i
]).
evaluate
(
m
);
exclusion
.
push
(
"("
+
v
.
substring
(
1
,
v
.
length
-
1
)
+
")"
);
e
=
e
.
replace
(
m
[
0
],
''
);
break
;
}
}
}
return
"[not("
+
exclusion
.
join
(
" and "
)
+
")]"
;
},
'nth-child'
:
function
(
m
)
{
return
Selector
.
xpath
.
pseudos
.
nth
(
"(count(./preceding-sibling::*) + 1) "
,
m
);
},
'nth-last-child'
:
function
(
m
)
{
return
Selector
.
xpath
.
pseudos
.
nth
(
"(count(./following-sibling::*) + 1) "
,
m
);
},
'nth-of-type'
:
function
(
m
)
{
return
Selector
.
xpath
.
pseudos
.
nth
(
"position() "
,
m
);
},
'nth-last-of-type'
:
function
(
m
)
{
return
Selector
.
xpath
.
pseudos
.
nth
(
"(last() + 1 - position()) "
,
m
);
},
'first-of-type'
:
function
(
m
)
{
m
[
6
]
=
"1"
;
return
Selector
.
xpath
.
pseudos
[
'nth-of-type'
](
m
);
},
'last-of-type'
:
function
(
m
)
{
m
[
6
]
=
"1"
;
return
Selector
.
xpath
.
pseudos
[
'nth-last-of-type'
](
m
);
},
'only-of-type'
:
function
(
m
)
{
var
p
=
Selector
.
xpath
.
pseudos
;
return
p
[
'first-of-type'
](
m
)
+
p
[
'last-of-type'
](
m
);
},
nth
:
function
(
fragment
,
m
)
{
var
mm
,
formula
=
m
[
6
],
predicate
;
if
(
formula
==
'even'
)
formula
=
'2n+0'
;
if
(
formula
==
'odd'
)
formula
=
'2n+1'
;
if
(
mm
=
formula
.
match
(
/^(\d+)$/
))
// digit only
return
'['
+
fragment
+
"= "
+
mm
[
1
]
+
']'
;
if
(
mm
=
formula
.
match
(
/^(-?\d*)?n(([+-])(\d+))?/
))
{
// an+b
if
(
mm
[
1
]
==
"-"
)
mm
[
1
]
=
-
1
;
var
a
=
mm
[
1
]
?
Number
(
mm
[
1
])
:
1
;
var
b
=
mm
[
2
]
?
Number
(
mm
[
2
])
:
0
;
predicate
=
"[((#{fragment} - #{b}) mod #{a} = 0) and "
+
"((#{fragment} - #{b}) div #{a} >= 0)]"
;
return
new
Template
(
predicate
).
evaluate
({
fragment
:
fragment
,
a
:
a
,
b
:
b
});
}
}
}
},
criteria
:
{
tagName
:
'n = h.tagName(n, r, "#{1}", c); c = false;'
,
className
:
'n = h.className(n, r, "#{1}", c); c = false;'
,
id
:
'n = h.id(n, r, "#{1}", c); c = false;'
,
attrPresence
:
'n = h.attrPresence(n, r, "#{1}"); c = false;'
,
attr
:
function
(
m
)
{
m
[
3
]
=
(
m
[
5
]
||
m
[
6
]);
return
new
Template
(
'n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;'
).
evaluate
(
m
);
},
pseudo
:
function
(
m
)
{
if
(
m
[
6
])
m
[
6
]
=
m
[
6
].
replace
(
/"/g
,
'\\"'
);
return
new
Template
(
'n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;'
).
evaluate
(
m
);
},
descendant
:
'c = "descendant";'
,
child
:
'c = "child";'
,
adjacent
:
'c = "adjacent";'
,
laterSibling
:
'c = "laterSibling";'
},
patterns
:
{
// combinators must be listed first
// (and descendant needs to be last combinator)
laterSibling
:
/^\s*~\s*/
,
child
:
/^\s*>\s*/
,
adjacent
:
/^\s*\+\s*/
,
descendant
:
/^\s/
,
// selectors follow
tagName
:
/^\s*(\*|[\w\-]+)(\b|$)?/
,
id
:
/^#([\w\-\*]+)(\b|$)/
,
className
:
/^\.([\w\-\*]+)(\b|$)/
,
pseudo
:
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/
,
attrPresence
:
/^\[([\w]+)\]/
,
attr
:
/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
},
// for Selector.match and Element#match
assertions
:
{
tagName
:
function
(
element
,
matches
)
{
return
matches
[
1
].
toUpperCase
()
==
element
.
tagName
.
toUpperCase
();
},
className
:
function
(
element
,
matches
)
{
return
Element
.
hasClassName
(
element
,
matches
[
1
]);
},
id
:
function
(
element
,
matches
)
{
return
element
.
id
===
matches
[
1
];
},
attrPresence
:
function
(
element
,
matches
)
{
return
Element
.
hasAttribute
(
element
,
matches
[
1
]);
},
attr
:
function
(
element
,
matches
)
{
var
nodeValue
=
Element
.
readAttribute
(
element
,
matches
[
1
]);
return
Selector
.
operators
[
matches
[
2
]](
nodeValue
,
matches
[
3
]);
}
},
handlers
:
{
// UTILITY FUNCTIONS
// joins two collections
concat
:
function
(
a
,
b
)
{
for
(
var
i
=
0
,
node
;
node
=
b
[
i
];
i
++
)
a
.
push
(
node
);
return
a
;
},
// marks an array of nodes for counting
mark
:
function
(
nodes
)
{
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
node
.
_counted
=
true
;
return
nodes
;
},
unmark
:
function
(
nodes
)
{
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
node
.
_counted
=
undefined
;
return
nodes
;
},
// mark each child node with its position (for nth calls)
// "ofType" flag indicates whether we're indexing for nth-of-type
// rather than nth-child
index
:
function
(
parentNode
,
reverse
,
ofType
)
{
parentNode
.
_counted
=
true
;
if
(
reverse
)
{
for
(
var
nodes
=
parentNode
.
childNodes
,
i
=
nodes
.
length
-
1
,
j
=
1
;
i
>=
0
;
i
--
)
{
var
node
=
nodes
[
i
];
if
(
node
.
nodeType
==
1
&&
(
!
ofType
||
node
.
_counted
))
node
.
nodeIndex
=
j
++
;
}
}
else
{
for
(
var
i
=
0
,
j
=
1
,
nodes
=
parentNode
.
childNodes
;
node
=
nodes
[
i
];
i
++
)
if
(
node
.
nodeType
==
1
&&
(
!
ofType
||
node
.
_counted
))
node
.
nodeIndex
=
j
++
;
}
},
// filters out duplicates and extends all nodes
unique
:
function
(
nodes
)
{
if
(
nodes
.
length
==
0
)
return
nodes
;
var
results
=
[],
n
;
for
(
var
i
=
0
,
l
=
nodes
.
length
;
i
<
l
;
i
++
)
if
(
!
(
n
=
nodes
[
i
]).
_counted
)
{
n
.
_counted
=
true
;
results
.
push
(
Element
.
extend
(
n
));
}
return
Selector
.
handlers
.
unmark
(
results
);
},
// COMBINATOR FUNCTIONS
descendant
:
function
(
nodes
)
{
var
h
=
Selector
.
handlers
;
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
h
.
concat
(
results
,
node
.
getElementsByTagName
(
'*'
));
return
results
;
},
child
:
function
(
nodes
)
{
var
h
=
Selector
.
handlers
;
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
{
for
(
var
j
=
0
,
child
;
child
=
node
.
childNodes
[
j
];
j
++
)
if
(
child
.
nodeType
==
1
&&
child
.
tagName
!=
'!'
)
results
.
push
(
child
);
}
return
results
;
},
adjacent
:
function
(
nodes
)
{
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
{
var
next
=
this
.
nextElementSibling
(
node
);
if
(
next
)
results
.
push
(
next
);
}
return
results
;
},
laterSibling
:
function
(
nodes
)
{
var
h
=
Selector
.
handlers
;
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
h
.
concat
(
results
,
Element
.
nextSiblings
(
node
));
return
results
;
},
nextElementSibling
:
function
(
node
)
{
while
(
node
=
node
.
nextSibling
)
if
(
node
.
nodeType
==
1
)
return
node
;
return
null
;
},
previousElementSibling
:
function
(
node
)
{
while
(
node
=
node
.
previousSibling
)
if
(
node
.
nodeType
==
1
)
return
node
;
return
null
;
},
// TOKEN FUNCTIONS
tagName
:
function
(
nodes
,
root
,
tagName
,
combinator
)
{
tagName
=
tagName
.
toUpperCase
();
var
results
=
[],
h
=
Selector
.
handlers
;
if
(
nodes
)
{
if
(
combinator
)
{
// fastlane for ordinary descendant combinators
if
(
combinator
==
"descendant"
)
{
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
h
.
concat
(
results
,
node
.
getElementsByTagName
(
tagName
));
return
results
;
}
else
nodes
=
this
[
combinator
](
nodes
);
if
(
tagName
==
"*"
)
return
nodes
;
}
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
if
(
node
.
tagName
.
toUpperCase
()
==
tagName
)
results
.
push
(
node
);
return
results
;
}
else
return
root
.
getElementsByTagName
(
tagName
);
},
id
:
function
(
nodes
,
root
,
id
,
combinator
)
{
var
targetNode
=
$
(
id
),
h
=
Selector
.
handlers
;
if
(
!
targetNode
)
return
[];
if
(
!
nodes
&&
root
==
document
)
return
[
targetNode
];
if
(
nodes
)
{
if
(
combinator
)
{
if
(
combinator
==
'child'
)
{
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
if
(
targetNode
.
parentNode
==
node
)
return
[
targetNode
];
}
else
if
(
combinator
==
'descendant'
)
{
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
if
(
Element
.
descendantOf
(
targetNode
,
node
))
return
[
targetNode
];
}
else
if
(
combinator
==
'adjacent'
)
{
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
if
(
Selector
.
handlers
.
previousElementSibling
(
targetNode
)
==
node
)
return
[
targetNode
];
}
else
nodes
=
h
[
combinator
](
nodes
);
}
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
if
(
node
==
targetNode
)
return
[
targetNode
];
return
[];
}
return
(
targetNode
&&
Element
.
descendantOf
(
targetNode
,
root
))
?
[
targetNode
]
:
[];
},
className
:
function
(
nodes
,
root
,
className
,
combinator
)
{
if
(
nodes
&&
combinator
)
nodes
=
this
[
combinator
](
nodes
);
return
Selector
.
handlers
.
byClassName
(
nodes
,
root
,
className
);
},
byClassName
:
function
(
nodes
,
root
,
className
)
{
if
(
!
nodes
)
nodes
=
Selector
.
handlers
.
descendant
([
root
]);
var
needle
=
' '
+
className
+
' '
;
for
(
var
i
=
0
,
results
=
[],
node
,
nodeClassName
;
node
=
nodes
[
i
];
i
++
)
{
nodeClassName
=
node
.
className
;
if
(
nodeClassName
.
length
==
0
)
continue
;
if
(
nodeClassName
==
className
||
(
' '
+
nodeClassName
+
' '
).
include
(
needle
))
results
.
push
(
node
);
}
return
results
;
},
attrPresence
:
function
(
nodes
,
root
,
attr
)
{
if
(
!
nodes
)
nodes
=
root
.
getElementsByTagName
(
"*"
);
var
results
=
[];
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
if
(
Element
.
hasAttribute
(
node
,
attr
))
results
.
push
(
node
);
return
results
;
},
attr
:
function
(
nodes
,
root
,
attr
,
value
,
operator
)
{
if
(
!
nodes
)
nodes
=
root
.
getElementsByTagName
(
"*"
);
var
handler
=
Selector
.
operators
[
operator
],
results
=
[];
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
{
var
nodeValue
=
Element
.
readAttribute
(
node
,
attr
);
if
(
nodeValue
===
null
)
continue
;
if
(
handler
(
nodeValue
,
value
))
results
.
push
(
node
);
}
return
results
;
},
pseudo
:
function
(
nodes
,
name
,
value
,
root
,
combinator
)
{
if
(
nodes
&&
combinator
)
nodes
=
this
[
combinator
](
nodes
);
if
(
!
nodes
)
nodes
=
root
.
getElementsByTagName
(
"*"
);
return
Selector
.
pseudos
[
name
](
nodes
,
value
,
root
);
}
},
pseudos
:
{
'first-child'
:
function
(
nodes
,
value
,
root
)
{
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
{
if
(
Selector
.
handlers
.
previousElementSibling
(
node
))
continue
;
results
.
push
(
node
);
}
return
results
;
},
'last-child'
:
function
(
nodes
,
value
,
root
)
{
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
{
if
(
Selector
.
handlers
.
nextElementSibling
(
node
))
continue
;
results
.
push
(
node
);
}
return
results
;
},
'only-child'
:
function
(
nodes
,
value
,
root
)
{
var
h
=
Selector
.
handlers
;
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
if
(
!
h
.
previousElementSibling
(
node
)
&&
!
h
.
nextElementSibling
(
node
))
results
.
push
(
node
);
return
results
;
},
'nth-child'
:
function
(
nodes
,
formula
,
root
)
{
return
Selector
.
pseudos
.
nth
(
nodes
,
formula
,
root
);
},
'nth-last-child'
:
function
(
nodes
,
formula
,
root
)
{
return
Selector
.
pseudos
.
nth
(
nodes
,
formula
,
root
,
true
);
},
'nth-of-type'
:
function
(
nodes
,
formula
,
root
)
{
return
Selector
.
pseudos
.
nth
(
nodes
,
formula
,
root
,
false
,
true
);
},
'nth-last-of-type'
:
function
(
nodes
,
formula
,
root
)
{
return
Selector
.
pseudos
.
nth
(
nodes
,
formula
,
root
,
true
,
true
);
},
'first-of-type'
:
function
(
nodes
,
formula
,
root
)
{
return
Selector
.
pseudos
.
nth
(
nodes
,
"1"
,
root
,
false
,
true
);
},
'last-of-type'
:
function
(
nodes
,
formula
,
root
)
{
return
Selector
.
pseudos
.
nth
(
nodes
,
"1"
,
root
,
true
,
true
);
},
'only-of-type'
:
function
(
nodes
,
formula
,
root
)
{
var
p
=
Selector
.
pseudos
;
return
p
[
'last-of-type'
](
p
[
'first-of-type'
](
nodes
,
formula
,
root
),
formula
,
root
);
},
// handles the an+b logic
getIndices
:
function
(
a
,
b
,
total
)
{
if
(
a
==
0
)
return
b
>
0
?
[
b
]
:
[];
return
$R
(
1
,
total
).
inject
([],
function
(
memo
,
i
)
{
if
(
0
==
(
i
-
b
)
%
a
&&
(
i
-
b
)
/
a
>=
0
)
memo
.
push
(
i
);
return
memo
;
});
},
// handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
nth
:
function
(
nodes
,
formula
,
root
,
reverse
,
ofType
)
{
if
(
nodes
.
length
==
0
)
return
[];
if
(
formula
==
'even'
)
formula
=
'2n+0'
;
if
(
formula
==
'odd'
)
formula
=
'2n+1'
;
var
h
=
Selector
.
handlers
,
results
=
[],
indexed
=
[],
m
;
h
.
mark
(
nodes
);
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
{
if
(
!
node
.
parentNode
.
_counted
)
{
h
.
index
(
node
.
parentNode
,
reverse
,
ofType
);
indexed
.
push
(
node
.
parentNode
);
}
}
if
(
formula
.
match
(
/^\d+$/
))
{
// just a number
formula
=
Number
(
formula
);
for
(
var
i
=
0
,
node
;
node
=
nodes
[
i
];
i
++
)
if
(
node
.
nodeIndex
==
formula
)
results
.
push
(
node
);
}
else
if
(
m
=
formula
.
match
(
/^(-?\d*)?n(([+-])(\d+))?/
))
{
// an+b
if
(
m
[
1
]
==
"-"
)
m
[
1
]
=
-
1
;
var
a
=
m
[
1
]
?
Number
(
m
[
1
])
:
1
;
var
b
=
m
[
2
]
?
Number
(
m
[
2
])
:
0
;
var
indices
=
Selector
.
pseudos
.
getIndices
(
a
,
b
,
nodes
.
length
);
for
(
var
i
=
0
,
node
,
l
=
indices
.
length
;
node
=
nodes
[
i
];
i
++
)
{
for
(
var
j
=
0
;
j
<
l
;
j
++
)
if
(
node
.
nodeIndex
==
indices
[
j
])
results
.
push
(
node
);
}
}
h
.
unmark
(
nodes
);
h
.
unmark
(
indexed
);
return
results
;
},
'empty'
:
function
(
nodes
,
value
,
root
)
{
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
{
// IE treats comments as element nodes
if
(
node
.
tagName
==
'!'
||
(
node
.
firstChild
&&
!
node
.
innerHTML
.
match
(
/^\s*$/
)))
continue
;
results
.
push
(
node
);
}
return
results
;
},
'not'
:
function
(
nodes
,
selector
,
root
)
{
var
h
=
Selector
.
handlers
,
selectorType
,
m
;
var
exclusions
=
new
Selector
(
selector
).
findElements
(
root
);
h
.
mark
(
exclusions
);
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
if
(
!
node
.
_counted
)
results
.
push
(
node
);
h
.
unmark
(
exclusions
);
return
results
;
},
'enabled'
:
function
(
nodes
,
value
,
root
)
{
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
if
(
!
node
.
disabled
)
results
.
push
(
node
);
return
results
;
},
'disabled'
:
function
(
nodes
,
value
,
root
)
{
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
if
(
node
.
disabled
)
results
.
push
(
node
);
return
results
;
},
'checked'
:
function
(
nodes
,
value
,
root
)
{
for
(
var
i
=
0
,
results
=
[],
node
;
node
=
nodes
[
i
];
i
++
)
if
(
node
.
checked
)
results
.
push
(
node
);
return
results
;
}
},
operators
:
{
'='
:
function
(
nv
,
v
)
{
return
nv
==
v
;
},
'!='
:
function
(
nv
,
v
)
{
return
nv
!=
v
;
},
'^='
:
function
(
nv
,
v
)
{
return
nv
.
startsWith
(
v
);
},
'$='
:
function
(
nv
,
v
)
{
return
nv
.
endsWith
(
v
);
},
'*='
:
function
(
nv
,
v
)
{
return
nv
.
include
(
v
);
},
'~='
:
function
(
nv
,
v
)
{
return
(
' '
+
nv
+
' '
).
include
(
' '
+
v
+
' '
);
},
'|='
:
function
(
nv
,
v
)
{
return
(
'-'
+
nv
.
toUpperCase
()
+
'-'
).
include
(
'-'
+
v
.
toUpperCase
()
+
'-'
);
}
},
matchElements
:
function
(
elements
,
expression
)
{
var
matches
=
new
Selector
(
expression
).
findElements
(),
h
=
Selector
.
handlers
;
h
.
mark
(
matches
);
for
(
var
i
=
0
,
results
=
[],
element
;
element
=
elements
[
i
];
i
++
)
if
(
element
.
_counted
)
results
.
push
(
element
);
h
.
unmark
(
matches
);
return
results
;
},
findElement
:
function
(
elements
,
expression
,
index
)
{
if
(
Object
.
isNumber
(
expression
))
{
index
=
expression
;
expression
=
false
;
}
return
Selector
.
matchElements
(
elements
,
expression
||
'*'
)[
index
||
0
];
},
findChildElements
:
function
(
element
,
expressions
)
{
var
exprs
=
expressions
.
join
(
','
);
expressions
=
[];
exprs
.
scan
(
/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/
,
function
(
m
)
{
expressions
.
push
(
m
[
1
].
strip
());
});
var
results
=
[],
h
=
Selector
.
handlers
;
for
(
var
i
=
0
,
l
=
expressions
.
length
,
selector
;
i
<
l
;
i
++
)
{
selector
=
new
Selector
(
expressions
[
i
].
strip
());
h
.
concat
(
results
,
selector
.
findElements
(
element
));
}
return
(
l
>
1
)
?
h
.
unique
(
results
)
:
results
;
}
});
if
(
Prototype
.
Browser
.
IE
)
{
// IE returns comment nodes on getElementsByTagName("*").
// Filter them out.
Selector
.
handlers
.
concat
=
function
(
a
,
b
)
{
for
(
var
i
=
0
,
node
;
node
=
b
[
i
];
i
++
)
if
(
node
.
tagName
!==
"!"
)
a
.
push
(
node
);
return
a
;
};
}
function
$$
()
{
return
Selector
.
findChildElements
(
document
,
$A
(
arguments
));
}
var
Form
=
{
reset
:
function
(
form
)
{
$
(
form
).
reset
();
return
form
;
},
serializeElements
:
function
(
elements
,
options
)
{
if
(
typeof
options
!=
'object'
)
options
=
{
hash
:
!!
options
};
else
if
(
Object
.
isUndefined
(
options
.
hash
))
options
.
hash
=
true
;
var
key
,
value
,
submitted
=
false
,
submit
=
options
.
submit
;
var
data
=
elements
.
inject
({
},
function
(
result
,
element
)
{
if
(
!
element
.
disabled
&&
element
.
name
)
{
key
=
element
.
name
;
value
=
$
(
element
).
getValue
();
if
(
value
!=
null
&&
(
element
.
type
!=
'submit'
||
(
!
submitted
&&
submit
!==
false
&&
(
!
submit
||
key
==
submit
)
&&
(
submitted
=
true
))))
{
if
(
key
in
result
)
{
// a key is already present; construct an array of values
if
(
!
Object
.
isArray
(
result
[
key
]))
result
[
key
]
=
[
result
[
key
]];
result
[
key
].
push
(
value
);
}
else
result
[
key
]
=
value
;
}
}
return
result
;
});
return
options
.
hash
?
data
:
Object
.
toQueryString
(
data
);
}
};
Form
.
Methods
=
{
serialize
:
function
(
form
,
options
)
{
return
Form
.
serializeElements
(
Form
.
getElements
(
form
),
options
);
},
getElements
:
function
(
form
)
{
return
$A
(
$
(
form
).
getElementsByTagName
(
'*'
)).
inject
([],
function
(
elements
,
child
)
{
if
(
Form
.
Element
.
Serializers
[
child
.
tagName
.
toLowerCase
()])
elements
.
push
(
Element
.
extend
(
child
));
return
elements
;
}
);
},
getInputs
:
function
(
form
,
typeName
,
name
)
{
form
=
$
(
form
);
var
inputs
=
form
.
getElementsByTagName
(
'input'
);
if
(
!
typeName
&&
!
name
)
return
$A
(
inputs
).
map
(
Element
.
extend
);
for
(
var
i
=
0
,
matchingInputs
=
[],
length
=
inputs
.
length
;
i
<
length
;
i
++
)
{
var
input
=
inputs
[
i
];
if
((
typeName
&&
input
.
type
!=
typeName
)
||
(
name
&&
input
.
name
!=
name
))
continue
;
matchingInputs
.
push
(
Element
.
extend
(
input
));
}
return
matchingInputs
;
},
disable
:
function
(
form
)
{
form
=
$
(
form
);
Form
.
getElements
(
form
).
invoke
(
'disable'
);
return
form
;
},
enable
:
function
(
form
)
{
form
=
$
(
form
);
Form
.
getElements
(
form
).
invoke
(
'enable'
);
return
form
;
},
findFirstElement
:
function
(
form
)
{
var
elements
=
$
(
form
).
getElements
().
findAll
(
function
(
element
)
{
return
'hidden'
!=
element
.
type
&&
!
element
.
disabled
;
});
var
firstByIndex
=
elements
.
findAll
(
function
(
element
)
{
return
element
.
hasAttribute
(
'tabIndex'
)
&&
element
.
tabIndex
>=
0
;
}).
sortBy
(
function
(
element
)
{
return
element
.
tabIndex
}).
first
();
return
firstByIndex
?
firstByIndex
:
elements
.
find
(
function
(
element
)
{
return
[
'input'
,
'select'
,
'textarea'
].
include
(
element
.
tagName
.
toLowerCase
());
});
},
focusFirstElement
:
function
(
form
)
{
form
=
$
(
form
);
form
.
findFirstElement
().
activate
();
return
form
;
},
request
:
function
(
form
,
options
)
{
form
=
$
(
form
),
options
=
Object
.
clone
(
options
||
{
});
var
params
=
options
.
parameters
,
action
=
form
.
readAttribute
(
'action'
)
||
''
;
if
(
action
.
blank
())
action
=
window
.
location
.
href
;
options
.
parameters
=
form
.
serialize
(
true
);
if
(
params
)
{
if
(
Object
.
isString
(
params
))
params
=
params
.
toQueryParams
();
Object
.
extend
(
options
.
parameters
,
params
);
}
if
(
form
.
hasAttribute
(
'method'
)
&&
!
options
.
method
)
options
.
method
=
form
.
method
;
return
new
Ajax
.
Request
(
action
,
options
);
}
};
/*--------------------------------------------------------------------------*/
Form
.
Element
=
{
focus
:
function
(
element
)
{
$
(
element
).
focus
();
return
element
;
},
select
:
function
(
element
)
{
$
(
element
).
select
();
return
element
;
}
};
Form
.
Element
.
Methods
=
{
serialize
:
function
(
element
)
{
element
=
$
(
element
);
if
(
!
element
.
disabled
&&
element
.
name
)
{
var
value
=
element
.
getValue
();
if
(
value
!=
undefined
)
{
var
pair
=
{
};
pair
[
element
.
name
]
=
value
;
return
Object
.
toQueryString
(
pair
);
}
}
return
''
;
},
getValue
:
function
(
element
)
{
element
=
$
(
element
);
var
method
=
element
.
tagName
.
toLowerCase
();
return
Form
.
Element
.
Serializers
[
method
](
element
);
},
setValue
:
function
(
element
,
value
)
{
element
=
$
(
element
);
var
method
=
element
.
tagName
.
toLowerCase
();
Form
.
Element
.
Serializers
[
method
](
element
,
value
);
return
element
;
},
clear
:
function
(
element
)
{
$
(
element
).
value
=
''
;
return
element
;
},
present
:
function
(
element
)
{
return
$
(
element
).
value
!=
''
;
},
activate
:
function
(
element
)
{
element
=
$
(
element
);
try
{
element
.
focus
();
if
(
element
.
select
&&
(
element
.
tagName
.
toLowerCase
()
!=
'input'
||
!
[
'button'
,
'reset'
,
'submit'
].
include
(
element
.
type
)))
element
.
select
();
}
catch
(
e
)
{
}
return
element
;
},
disable
:
function
(
element
)
{
element
=
$
(
element
);
element
.
blur
();
element
.
disabled
=
true
;
return
element
;
},
enable
:
function
(
element
)
{
element
=
$
(
element
);
element
.
disabled
=
false
;
return
element
;
}
};
/*--------------------------------------------------------------------------*/
var
Field
=
Form
.
Element
;
var
$F
=
Form
.
Element
.
Methods
.
getValue
;
/*--------------------------------------------------------------------------*/
Form
.
Element
.
Serializers
=
{
input
:
function
(
element
,
value
)
{
switch
(
element
.
type
.
toLowerCase
())
{
case
'checkbox'
:
case
'radio'
:
return
Form
.
Element
.
Serializers
.
inputSelector
(
element
,
value
);
default
:
return
Form
.
Element
.
Serializers
.
textarea
(
element
,
value
);
}
},
inputSelector
:
function
(
element
,
value
)
{
if
(
Object
.
isUndefined
(
value
))
return
element
.
checked
?
element
.
value
:
null
;
else
element
.
checked
=
!!
value
;
},
textarea
:
function
(
element
,
value
)
{
if
(
Object
.
isUndefined
(
value
))
return
element
.
value
;
else
element
.
value
=
value
;
},
select
:
function
(
element
,
index
)
{
if
(
Object
.
isUndefined
(
index
))
return
this
[
element
.
type
==
'select-one'
?
'selectOne'
:
'selectMany'
](
element
);
else
{
var
opt
,
value
,
single
=
!
Object
.
isArray
(
index
);
for
(
var
i
=
0
,
length
=
element
.
length
;
i
<
length
;
i
++
)
{
opt
=
element
.
options
[
i
];
value
=
this
.
optionValue
(
opt
);
if
(
single
)
{
if
(
value
==
index
)
{
opt
.
selected
=
true
;
return
;
}
}
else
opt
.
selected
=
index
.
include
(
value
);
}
}
},
selectOne
:
function
(
element
)
{
var
index
=
element
.
selectedIndex
;
return
index
>=
0
?
this
.
optionValue
(
element
.
options
[
index
])
:
null
;
},
selectMany
:
function
(
element
)
{
var
values
,
length
=
element
.
length
;
if
(
!
length
)
return
null
;
for
(
var
i
=
0
,
values
=
[];
i
<
length
;
i
++
)
{
var
opt
=
element
.
options
[
i
];
if
(
opt
.
selected
)
values
.
push
(
this
.
optionValue
(
opt
));
}
return
values
;
},
optionValue
:
function
(
opt
)
{
// extend element because hasAttribute may not be native
return
Element
.
extend
(
opt
).
hasAttribute
(
'value'
)
?
opt
.
value
:
opt
.
text
;
}
};
/*--------------------------------------------------------------------------*/
Abstract
.
TimedObserver
=
Class
.
create
(
PeriodicalExecuter
,
{
initialize
:
function
(
$super
,
element
,
frequency
,
callback
)
{
$super
(
callback
,
frequency
);
this
.
element
=
$
(
element
);
this
.
lastValue
=
this
.
getValue
();
},
execute
:
function
()
{
var
value
=
this
.
getValue
();
if
(
Object
.
isString
(
this
.
lastValue
)
&&
Object
.
isString
(
value
)
?
this
.
lastValue
!=
value
:
String
(
this
.
lastValue
)
!=
String
(
value
))
{
this
.
callback
(
this
.
element
,
value
);
this
.
lastValue
=
value
;
}
}
});
Form
.
Element
.
Observer
=
Class
.
create
(
Abstract
.
TimedObserver
,
{
getValue
:
function
()
{
return
Form
.
Element
.
getValue
(
this
.
element
);
}
});
Form
.
Observer
=
Class
.
create
(
Abstract
.
TimedObserver
,
{
getValue
:
function
()
{
return
Form
.
serialize
(
this
.
element
);
}
});
/*--------------------------------------------------------------------------*/
Abstract
.
EventObserver
=
Class
.
create
({
initialize
:
function
(
element
,
callback
)
{
this
.
element
=
$
(
element
);
this
.
callback
=
callback
;
this
.
lastValue
=
this
.
getValue
();
if
(
this
.
element
.
tagName
.
toLowerCase
()
==
'form'
)
this
.
registerFormCallbacks
();
else
this
.
registerCallback
(
this
.
element
);
},
onElementEvent
:
function
()
{
var
value
=
this
.
getValue
();
if
(
this
.
lastValue
!=
value
)
{
this
.
callback
(
this
.
element
,
value
);
this
.
lastValue
=
value
;
}
},
registerFormCallbacks
:
function
()
{
Form
.
getElements
(
this
.
element
).
each
(
this
.
registerCallback
,
this
);
},
registerCallback
:
function
(
element
)
{
if
(
element
.
type
)
{
switch
(
element
.
type
.
toLowerCase
())
{
case
'checkbox'
:
case
'radio'
:
Event
.
observe
(
element
,
'click'
,
this
.
onElementEvent
.
bind
(
this
));
break
;
default
:
Event
.
observe
(
element
,
'change'
,
this
.
onElementEvent
.
bind
(
this
));
break
;
}
}
}
});
Form
.
Element
.
EventObserver
=
Class
.
create
(
Abstract
.
EventObserver
,
{
getValue
:
function
()
{
return
Form
.
Element
.
getValue
(
this
.
element
);
}
});
Form
.
EventObserver
=
Class
.
create
(
Abstract
.
EventObserver
,
{
getValue
:
function
()
{
return
Form
.
serialize
(
this
.
element
);
}
});
if
(
!
window
.
Event
)
var
Event
=
{
};
Object
.
extend
(
Event
,
{
KEY_BACKSPACE
:
8
,
KEY_TAB
:
9
,
KEY_RETURN
:
13
,
KEY_ESC
:
27
,
KEY_LEFT
:
37
,
KEY_UP
:
38
,
KEY_RIGHT
:
39
,
KEY_DOWN
:
40
,
KEY_DELETE
:
46
,
KEY_HOME
:
36
,
KEY_END
:
35
,
KEY_PAGEUP
:
33
,
KEY_PAGEDOWN
:
34
,
KEY_INSERT
:
45
,
cache
:
{
},
relatedTarget
:
function
(
event
)
{
var
element
;
switch
(
event
.
type
)
{
case
'mouseover'
:
element
=
event
.
fromElement
;
break
;
case
'mouseout'
:
element
=
event
.
toElement
;
break
;
default
:
return
null
;
}
return
Element
.
extend
(
element
);
}
});
Event
.
Methods
=
(
function
()
{
var
isButton
;
if
(
Prototype
.
Browser
.
IE
)
{
var
buttonMap
=
{
0
:
1
,
1
:
4
,
2
:
2
};
isButton
=
function
(
event
,
code
)
{
return
event
.
button
==
buttonMap
[
code
];
};
}
else
if
(
Prototype
.
Browser
.
WebKit
)
{
isButton
=
function
(
event
,
code
)
{
switch
(
code
)
{
case
0
:
return
event
.
which
==
1
&&
!
event
.
metaKey
;
case
1
:
return
event
.
which
==
1
&&
event
.
metaKey
;
default
:
return
false
;
}
};
}
else
{
isButton
=
function
(
event
,
code
)
{
return
event
.
which
?
(
event
.
which
===
code
+
1
)
:
(
event
.
button
===
code
);
};
}
return
{
isLeftClick
:
function
(
event
)
{
return
isButton
(
event
,
0
)
},
isMiddleClick
:
function
(
event
)
{
return
isButton
(
event
,
1
)
},
isRightClick
:
function
(
event
)
{
return
isButton
(
event
,
2
)
},
element
:
function
(
event
)
{
var
node
=
Event
.
extend
(
event
).
target
;
return
Element
.
extend
(
node
.
nodeType
==
Node
.
TEXT_NODE
?
node
.
parentNode
:
node
);
},
findElement
:
function
(
event
,
expression
)
{
var
element
=
Event
.
element
(
event
);
if
(
!
expression
)
return
element
;
var
elements
=
[
element
].
concat
(
element
.
ancestors
());
return
Selector
.
findElement
(
elements
,
expression
,
0
);
},
pointer
:
function
(
event
)
{
return
{
x
:
event
.
pageX
||
(
event
.
clientX
+
(
document
.
documentElement
.
scrollLeft
||
document
.
body
.
scrollLeft
)),
y
:
event
.
pageY
||
(
event
.
clientY
+
(
document
.
documentElement
.
scrollTop
||
document
.
body
.
scrollTop
))
};
},
pointerX
:
function
(
event
)
{
return
Event
.
pointer
(
event
).
x
},
pointerY
:
function
(
event
)
{
return
Event
.
pointer
(
event
).
y
},
stop
:
function
(
event
)
{
Event
.
extend
(
event
);
event
.
preventDefault
();
event
.
stopPropagation
();
event
.
stopped
=
true
;
}
};
})();
Event
.
extend
=
(
function
()
{
var
methods
=
Object
.
keys
(
Event
.
Methods
).
inject
({
},
function
(
m
,
name
)
{
m
[
name
]
=
Event
.
Methods
[
name
].
methodize
();
return
m
;
});
if
(
Prototype
.
Browser
.
IE
)
{
Object
.
extend
(
methods
,
{
stopPropagation
:
function
()
{
this
.
cancelBubble
=
true
},
preventDefault
:
function
()
{
this
.
returnValue
=
false
},
inspect
:
function
()
{
return
"[object Event]"
}
});
return
function
(
event
)
{
if
(
!
event
)
return
false
;
if
(
event
.
_extendedByPrototype
)
return
event
;
event
.
_extendedByPrototype
=
Prototype
.
emptyFunction
;
var
pointer
=
Event
.
pointer
(
event
);
Object
.
extend
(
event
,
{
target
:
event
.
srcElement
,
relatedTarget
:
Event
.
relatedTarget
(
event
),
pageX
:
pointer
.
x
,
pageY
:
pointer
.
y
});
return
Object
.
extend
(
event
,
methods
);
};
}
else
{
Event
.
prototype
=
Event
.
prototype
||
document
.
createEvent
(
"HTMLEvents"
).
__proto__
;
Object
.
extend
(
Event
.
prototype
,
methods
);
return
Prototype
.
K
;
}
})();
Object
.
extend
(
Event
,
(
function
()
{
var
cache
=
Event
.
cache
;
function
getEventID
(
element
)
{
if
(
element
.
_eventID
)
return
element
.
_eventID
;
arguments
.
callee
.
id
=
arguments
.
callee
.
id
||
1
;
return
element
.
_eventID
=
++
arguments
.
callee
.
id
;
}
function
getDOMEventName
(
eventName
)
{
if
(
eventName
&&
eventName
.
include
(
':'
))
return
"dataavailable"
;
return
eventName
;
}
function
getCacheForID
(
id
)
{
return
cache
[
id
]
=
cache
[
id
]
||
{
};
}
function
getWrappersForEventName
(
id
,
eventName
)
{
var
c
=
getCacheForID
(
id
);
return
c
[
eventName
]
=
c
[
eventName
]
||
[];
}
function
createWrapper
(
element
,
eventName
,
handler
)
{
var
id
=
getEventID
(
element
);
var
c
=
getWrappersForEventName
(
id
,
eventName
);
if
(
c
.
pluck
(
"handler"
).
include
(
handler
))
return
false
;
var
wrapper
=
function
(
event
)
{
if
(
!
Event
||
!
Event
.
extend
||
(
event
.
eventName
&&
event
.
eventName
!=
eventName
))
return
false
;
Event
.
extend
(
event
);
handler
.
call
(
element
,
event
)
};
wrapper
.
handler
=
handler
;
c
.
push
(
wrapper
);
return
wrapper
;
}
function
findWrapper
(
id
,
eventName
,
handler
)
{
var
c
=
getWrappersForEventName
(
id
,
eventName
);
return
c
.
find
(
function
(
wrapper
)
{
return
wrapper
.
handler
==
handler
});
}
function
destroyWrapper
(
id
,
eventName
,
handler
)
{
var
c
=
getCacheForID
(
id
);
if
(
!
c
[
eventName
])
return
false
;
c
[
eventName
]
=
c
[
eventName
].
without
(
findWrapper
(
id
,
eventName
,
handler
));
}
function
destroyCache
()
{
for
(
var
id
in
cache
)
for
(
var
eventName
in
cache
[
id
])
cache
[
id
][
eventName
]
=
null
;
}
if
(
window
.
attachEvent
)
{
window
.
attachEvent
(
"onunload"
,
destroyCache
);
}
return
{
observe
:
function
(
element
,
eventName
,
handler
)
{
element
=
$
(
element
);
var
name
=
getDOMEventName
(
eventName
);
var
wrapper
=
createWrapper
(
element
,
eventName
,
handler
);
if
(
!
wrapper
)
return
element
;
if
(
element
.
addEventListener
)
{
element
.
addEventListener
(
name
,
wrapper
,
false
);
}
else
{
element
.
attachEvent
(
"on"
+
name
,
wrapper
);
}
return
element
;
},
stopObserving
:
function
(
element
,
eventName
,
handler
)
{
element
=
$
(
element
);
var
id
=
getEventID
(
element
),
name
=
getDOMEventName
(
eventName
);
if
(
!
handler
&&
eventName
)
{
getWrappersForEventName
(
id
,
eventName
).
each
(
function
(
wrapper
)
{
element
.
stopObserving
(
eventName
,
wrapper
.
handler
);
});
return
element
;
}
else
if
(
!
eventName
)
{
Object
.
keys
(
getCacheForID
(
id
)).
each
(
function
(
eventName
)
{
element
.
stopObserving
(
eventName
);
});
return
element
;
}
var
wrapper
=
findWrapper
(
id
,
eventName
,
handler
);
if
(
!
wrapper
)
return
element
;
if
(
element
.
removeEventListener
)
{
element
.
removeEventListener
(
name
,
wrapper
,
false
);
}
else
{
element
.
detachEvent
(
"on"
+
name
,
wrapper
);
}
destroyWrapper
(
id
,
eventName
,
handler
);
return
element
;
},
fire
:
function
(
element
,
eventName
,
memo
)
{
element
=
$
(
element
);
if
(
element
==
document
&&
document
.
createEvent
&&
!
element
.
dispatchEvent
)
element
=
document
.
documentElement
;
if
(
document
.
createEvent
)
{
var
event
=
document
.
createEvent
(
"HTMLEvents"
);
event
.
initEvent
(
"dataavailable"
,
true
,
true
);
}
else
{
var
event
=
document
.
createEventObject
();
event
.
eventType
=
"ondataavailable"
;
}
event
.
eventName
=
eventName
;
event
.
memo
=
memo
||
{
};
if
(
document
.
createEvent
)
{
element
.
dispatchEvent
(
event
);
}
else
{
element
.
fireEvent
(
event
.
eventType
,
event
);
}
return
Event
.
extend
(
event
);
}
};
})());
Object
.
extend
(
Event
,
Event
.
Methods
);
Element
.
addMethods
({
fire
:
Event
.
fire
,
observe
:
Event
.
observe
,
stopObserving
:
Event
.
stopObserving
});
Object
.
extend
(
document
,
{
fire
:
Element
.
Methods
.
fire
.
methodize
(),
observe
:
Element
.
Methods
.
observe
.
methodize
(),
stopObserving
:
Element
.
Methods
.
stopObserving
.
methodize
()
});
(
function
()
{
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
Matthias Miller, Dean Edwards and John Resig. */
var
timer
,
fired
=
false
;
function
fireContentLoadedEvent
()
{
if
(
fired
)
return
;
if
(
timer
)
window
.
clearInterval
(
timer
);
document
.
fire
(
"dom:loaded"
);
fired
=
true
;
}
if
(
document
.
addEventListener
)
{
if
(
Prototype
.
Browser
.
WebKit
)
{
timer
=
window
.
setInterval
(
function
()
{
if
(
/loaded|complete/
.
test
(
document
.
readyState
))
fireContentLoadedEvent
();
},
0
);
Event
.
observe
(
window
,
"load"
,
fireContentLoadedEvent
);
}
else
{
document
.
addEventListener
(
"DOMContentLoaded"
,
fireContentLoadedEvent
,
false
);
}
}
else
{
document
.
write
(
"<script id=__onDOMContentLoaded defer src=//:><\/script>"
);
$
(
"__onDOMContentLoaded"
).
onreadystatechange
=
function
()
{
if
(
this
.
readyState
==
"complete"
)
{
this
.
onreadystatechange
=
null
;
fireContentLoadedEvent
();
}
};
}
})();
/*------------------------------- DEPRECATED -------------------------------*/
Hash
.
toQueryString
=
Object
.
toQueryString
;
var
Toggle
=
{
display
:
Element
.
toggle
};
Element
.
Methods
.
childOf
=
Element
.
Methods
.
descendantOf
;
var
Insertion
=
{
Before
:
function
(
element
,
content
)
{
return
Element
.
insert
(
element
,
{
before
:
content
});
},
Top
:
function
(
element
,
content
)
{
return
Element
.
insert
(
element
,
{
top
:
content
});
},
Bottom
:
function
(
element
,
content
)
{
return
Element
.
insert
(
element
,
{
bottom
:
content
});
},
After
:
function
(
element
,
content
)
{
return
Element
.
insert
(
element
,
{
after
:
content
});
}
};
var
$continue
=
new
Error
(
'"throw $continue" is deprecated, use "return" instead'
);
// This should be moved to script.aculo.us; notice the deprecated methods
// further below, that map to the newer Element methods.
var
Position
=
{
// set to true if needed, warning: firefox performance problems
// NOT neeeded for page scrolling, only if draggable contained in
// scrollable elements
includeScrollOffsets
:
false
,
// must be called before calling withinIncludingScrolloffset, every time the
// page is scrolled
prepare
:
function
()
{
this
.
deltaX
=
window
.
pageXOffset
||
document
.
documentElement
.
scrollLeft
||
document
.
body
.
scrollLeft
||
0
;
this
.
deltaY
=
window
.
pageYOffset
||
document
.
documentElement
.
scrollTop
||
document
.
body
.
scrollTop
||
0
;
},
// caches x/y coordinate pair to use with overlap
within
:
function
(
element
,
x
,
y
)
{
if
(
this
.
includeScrollOffsets
)
return
this
.
withinIncludingScrolloffsets
(
element
,
x
,
y
);
this
.
xcomp
=
x
;
this
.
ycomp
=
y
;
this
.
offset
=
Element
.
cumulativeOffset
(
element
);
return
(
y
>=
this
.
offset
[
1
]
&&
y
<
this
.
offset
[
1
]
+
element
.
offsetHeight
&&
x
>=
this
.
offset
[
0
]
&&
x
<
this
.
offset
[
0
]
+
element
.
offsetWidth
);
},
withinIncludingScrolloffsets
:
function
(
element
,
x
,
y
)
{
var
offsetcache
=
Element
.
cumulativeScrollOffset
(
element
);
this
.
xcomp
=
x
+
offsetcache
[
0
]
-
this
.
deltaX
;
this
.
ycomp
=
y
+
offsetcache
[
1
]
-
this
.
deltaY
;
this
.
offset
=
Element
.
cumulativeOffset
(
element
);
return
(
this
.
ycomp
>=
this
.
offset
[
1
]
&&
this
.
ycomp
<
this
.
offset
[
1
]
+
element
.
offsetHeight
&&
this
.
xcomp
>=
this
.
offset
[
0
]
&&
this
.
xcomp
<
this
.
offset
[
0
]
+
element
.
offsetWidth
);
},
// within must be called directly before
overlap
:
function
(
mode
,
element
)
{
if
(
!
mode
)
return
0
;
if
(
mode
==
'vertical'
)
return
((
this
.
offset
[
1
]
+
element
.
offsetHeight
)
-
this
.
ycomp
)
/
element
.
offsetHeight
;
if
(
mode
==
'horizontal'
)
return
((
this
.
offset
[
0
]
+
element
.
offsetWidth
)
-
this
.
xcomp
)
/
element
.
offsetWidth
;
},
// Deprecation layer -- use newer Element methods now (1.5.2).
cumulativeOffset
:
Element
.
Methods
.
cumulativeOffset
,
positionedOffset
:
Element
.
Methods
.
positionedOffset
,
absolutize
:
function
(
element
)
{
Position
.
prepare
();
return
Element
.
absolutize
(
element
);
},
relativize
:
function
(
element
)
{
Position
.
prepare
();
return
Element
.
relativize
(
element
);
},
realOffset
:
Element
.
Methods
.
cumulativeScrollOffset
,
offsetParent
:
Element
.
Methods
.
getOffsetParent
,
page
:
Element
.
Methods
.
viewportOffset
,
clone
:
function
(
source
,
target
,
options
)
{
options
=
options
||
{
};
return
Element
.
clonePosition
(
target
,
source
,
options
);
}
};
/*--------------------------------------------------------------------------*/
if
(
!
document
.
getElementsByClassName
)
document
.
getElementsByClassName
=
function
(
instanceMethods
){
function
iter
(
name
)
{
return
name
.
blank
()
?
null
:
"[contains(concat(' ', @class, ' '), ' "
+
name
+
" ')]"
;
}
instanceMethods
.
getElementsByClassName
=
Prototype
.
BrowserFeatures
.
XPath
?
function
(
element
,
className
)
{
className
=
className
.
toString
().
strip
();
var
cond
=
/\s/
.
test
(
className
)
?
$w
(
className
).
map
(
iter
).
join
(
''
)
:
iter
(
className
);
return
cond
?
document
.
_getElementsByXPath
(
'.//*'
+
cond
,
element
)
:
[];
}
:
function
(
element
,
className
)
{
className
=
className
.
toString
().
strip
();
var
elements
=
[],
classNames
=
(
/\s/
.
test
(
className
)
?
$w
(
className
)
:
null
);
if
(
!
classNames
&&
!
className
)
return
elements
;
var
nodes
=
$
(
element
).
getElementsByTagName
(
'*'
);
className
=
' '
+
className
+
' '
;
for
(
var
i
=
0
,
child
,
cn
;
child
=
nodes
[
i
];
i
++
)
{
if
(
child
.
className
&&
(
cn
=
' '
+
child
.
className
+
' '
)
&&
(
cn
.
include
(
className
)
||
(
classNames
&&
classNames
.
all
(
function
(
name
)
{
return
!
name
.
toString
().
blank
()
&&
cn
.
include
(
' '
+
name
+
' '
);
}))))
elements
.
push
(
Element
.
extend
(
child
));
}
return
elements
;
};
return
function
(
className
,
parentElement
)
{
return
$
(
parentElement
||
document
.
body
).
getElementsByClassName
(
className
);
};
}(
Element
.
Methods
);
/*--------------------------------------------------------------------------*/
Element
.
ClassNames
=
Class
.
create
();
Element
.
ClassNames
.
prototype
=
{
initialize
:
function
(
element
)
{
this
.
element
=
$
(
element
);
},
_each
:
function
(
iterator
)
{
this
.
element
.
className
.
split
(
/\s+/
).
select
(
function
(
name
)
{
return
name
.
length
>
0
;
}).
_each
(
iterator
);
},
set
:
function
(
className
)
{
this
.
element
.
className
=
className
;
},
add
:
function
(
classNameToAdd
)
{
if
(
this
.
include
(
classNameToAdd
))
return
;
this
.
set
(
$A
(
this
).
concat
(
classNameToAdd
).
join
(
' '
));
},
remove
:
function
(
classNameToRemove
)
{
if
(
!
this
.
include
(
classNameToRemove
))
return
;
this
.
set
(
$A
(
this
).
without
(
classNameToRemove
).
join
(
' '
));
},
toString
:
function
()
{
return
$A
(
this
).
join
(
' '
);
}
};
Object
.
extend
(
Element
.
ClassNames
.
prototype
,
Enumerable
);
/*--------------------------------------------------------------------------*/
Element
.
addMethods
();
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Feb 22, 15:27 (1 h, 22 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
22327
Default Alt Text
prototype.js (122 KB)
Attached To
rZEDHG ZedLegacy
Event Timeline
Log In to Comment