file:///home/developper/svn/phpcompta/branches/rel500_javascript
................
r2352 | danydb | 2009-02-20 20:43:25 +0100 (Fri, 20 Feb 2009) | 3 lines
Initialized merge tracking via "svnmerge" with revisions "1-2351" from
svn+ssh://danydb@svn/svn/phpcompta/trunk
................
r2353 | danydb | 2009-02-20 21:34:06 +0100 (Fri, 20 Feb 2009) | 1 line
Code cleaning
................
r2363 | danydb | 2009-02-26 19:03:33 +0100 (Thu, 26 Feb 2009) | 41 lines
Merged revisions 2352-2362 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2354 | danydb | 2009-02-24 23:16:33 +0100 (Tue, 24 Feb 2009) | 1 line
bug add a "All ledger" into the ledger choice for reporting balance
........
r2355 | danydb | 2009-02-25 09:06:00 +0100 (Wed, 25 Feb 2009) | 1 line
default value
........
r2356 | danydb | 2009-02-25 09:19:31 +0100 (Wed, 25 Feb 2009) | 1 line
fix mini report
........
r2357 | danydb | 2009-02-25 14:18:26 +0100 (Wed, 25 Feb 2009) | 1 line
Remove warning about work_mem et use_trans_sid
........
r2358 | danydb | 2009-02-25 16:21:39 +0100 (Wed, 25 Feb 2009) | 1 line
Bug ajax
........
r2359 | danydb | 2009-02-25 16:28:28 +0100 (Wed, 25 Feb 2009) | 1 line
Cosmetic
........
r2360 | danydb | 2009-02-25 16:29:29 +0100 (Wed, 25 Feb 2009) | 1 line
Cosmetic
........
r2361 | danydb | 2009-02-25 16:40:01 +0100 (Wed, 25 Feb 2009) | 2 lines
Fix problem with local admin
........
r2362 | danydb | 2009-02-25 18:44:58 +0100 (Wed, 25 Feb 2009) | 1 line
Fix bug opening
........
................
r2364 | danydb | 2009-03-01 20:45:04 +0100 (Sun, 01 Mar 2009) | 4 lines
Class widget has been replaced by HtmlInput and children class (as IText, IButton...)
Code Cleaning : remove obsolete and unused function
................
r2365 | danydb | 2009-03-01 21:02:30 +0100 (Sun, 01 Mar 2009) | 1 line
Rewrite class widget : bug
................
r2368 | danydb | 2009-03-01 23:00:21 +0100 (Sun, 01 Mar 2009) | 13 lines
Merged revisions 2363-2367 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2366 | danydb | 2009-03-01 21:29:42 +0100 (Sun, 01 Mar 2009) | 1 line
Security
........
r2367 | danydb | 2009-03-01 21:35:57 +0100 (Sun, 01 Mar 2009) | 1 line
Security : can_request must not be in a test
........
................
r2370 | danydb | 2009-03-04 22:18:23 +0100 (Wed, 04 Mar 2009) | 1 line
Progress HtmlInput
................
r2371 | danydb | 2009-03-04 22:19:15 +0100 (Wed, 04 Mar 2009) | 9 lines
Merged revisions 2368-2370 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2369 | danydb | 2009-03-03 19:02:18 +0100 (Tue, 03 Mar 2009) | 1 line
Fix bug class_user.php : the password is not checked in the function checked
........
................
r2377 | danydb | 2009-03-05 21:21:30 +0100 (Thu, 05 Mar 2009) | 1 line
progress class_widget -> class_html_input
................
r2378 | danydb | 2009-03-05 21:24:56 +0100 (Thu, 05 Mar 2009) | 25 lines
Merged revisions 2371-2377 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2372 | danydb | 2009-03-05 19:09:13 +0100 (Thu, 05 Mar 2009) | 1 line
Bug : all the ledgers are not shown
........
r2373 | danydb | 2009-03-05 19:12:26 +0100 (Thu, 05 Mar 2009) | 1 line
Bug : Layout in quick writing
........
r2374 | danydb | 2009-03-05 19:17:31 +0100 (Thu, 05 Mar 2009) | 1 line
Add missing file
........
r2375 | danydb | 2009-03-05 19:28:11 +0100 (Thu, 05 Mar 2009) | 1 line
Bug : reconciliation not possible
........
r2376 | danydb | 2009-03-05 19:44:02 +0100 (Thu, 05 Mar 2009) | 1 line
Bug : can't list unpaid operatio,s in sold ledger
........
................
r2379 | danydb | 2009-03-06 23:29:01 +0100 (Fri, 06 Mar 2009) | 1 line
Progress class_html_input
................
r2380 | danydb | 2009-03-08 20:25:48 +0100 (Sun, 08 Mar 2009) | 1 line
Progress class_html_input
................
r2383 | danydb | 2009-03-11 20:03:58 +0100 (Wed, 11 Mar 2009) | 13 lines
Merged revisions 2378-2382 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2381 | danydb | 2009-03-11 19:33:03 +0100 (Wed, 11 Mar 2009) | 1 line
Erreur rec.
........
r2382 | danydb | 2009-03-11 19:57:57 +0100 (Wed, 11 Mar 2009) | 1 line
Erreur rec. in fin ledger
........
................
r2386 | danydb | 2009-03-14 21:55:08 +0100 (Sat, 14 Mar 2009) | 13 lines
Merged revisions 2383-2385 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2384 | danydb | 2009-03-14 21:38:05 +0100 (Sat, 14 Mar 2009) | 2 lines
Fix Bug : search for rec.
........
r2385 | danydb | 2009-03-14 21:44:20 +0100 (Sat, 14 Mar 2009) | 1 line
Bug : cannot see list financial
........
................
r2387 | danydb | 2009-03-14 23:36:24 +0100 (Sat, 14 Mar 2009) | 1 line
progress class_widget -> class_html_input
................
r2388 | danydb | 2009-03-14 23:43:30 +0100 (Sat, 14 Mar 2009) | 1 line
Remove file check_priv.php; all the security API is now is class_user
................
r2391 | danydb | 2009-03-17 18:47:43 +0100 (Tue, 17 Mar 2009) | 3 lines
* Input type submit replace by HtmlInput::Submit
* Add documentation for javascript
................
r2392 | danydb | 2009-03-17 19:29:25 +0100 (Tue, 17 Mar 2009) | 1 line
Fix small bugs
................
r2393 | danydb | 2009-03-17 19:34:49 +0100 (Tue, 17 Mar 2009) | 1 line
Documentation fiche_search.php
................
r2394 | danydb | 2009-03-19 17:38:27 +0100 (Thu, 19 Mar 2009) | 2 lines
remove a widget object
................
r2395 | danydb | 2009-03-19 17:40:32 +0100 (Thu, 19 Mar 2009) | 2 lines
Bug : error with get_list_fiche
................
r2396 | danydb | 2009-03-19 17:43:09 +0100 (Thu, 19 Mar 2009) | 2 lines
Bug : typo
................
r2397 | danydb | 2009-03-19 18:07:34 +0100 (Thu, 19 Mar 2009) | 2 lines
Bug : wrong next pj
................
r2398 | danydb | 2009-03-19 18:14:15 +0100 (Thu, 19 Mar 2009) | 2 lines
infobulle add onmouseover for displaying the infobulle
................
r2399 | danydb | 2009-03-19 18:37:58 +0100 (Thu, 19 Mar 2009) | 3 lines
* Remove periode in Ledger, the periode is deduced from the date, it depends of the parameter MY_CHECK_PERIODE
* Remove AcException
* Ledger Sold is correct
................
r2400 | danydb | 2009-03-19 18:39:47 +0100 (Thu, 19 Mar 2009) | 13 lines
Merged revisions 2386-2399 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2389 | danydb | 2009-03-16 21:55:54 +0100 (Mon, 16 Mar 2009) | 2 lines
Fix Escape HTML string
........
r2390 | danydb | 2009-03-16 22:00:44 +0100 (Mon, 16 Mar 2009) | 2 lines
Bug in security : FIN Ledger confusion between check_action and get_ledger_access
........
................
r2401 | danydb | 2009-03-19 22:59:56 +0100 (Thu, 19 Mar 2009) | 1 line
Bug : Ledger sold with check periode
................
r2402 | danydb | 2009-03-19 23:08:09 +0100 (Thu, 19 Mar 2009) | 1 line
Problem sequence
................
r2404 | danydb | 2009-03-21 00:47:30 +0100 (Sat, 21 Mar 2009) | 10 lines
Merged revisions 2400-2403 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2403 | danydb | 2009-03-20 21:36:05 +0100 (Fri, 20 Mar 2009) | 3 lines
The summary of the amount of the customers with a vat number is now based on
the quickcode instead of the accountancy number
........
................
r2405 | danydb | 2009-03-23 21:32:48 +0100 (Mon, 23 Mar 2009) | 3 lines
* IPeriod throw an exception is no rows is found (code != 0)
* receipt problem with the numbering of the sequences
* SearchCard = the p_jrn is not taken from a hidden elt but must be given
................
r2406 | danydb | 2009-03-23 21:40:15 +0100 (Mon, 23 Mar 2009) | 1 line
Fix missing lib
................
r2407 | danydb | 2009-03-23 21:41:27 +0100 (Mon, 23 Mar 2009) | 1 line
Fix missing semicol
................
r2408 | danydb | 2009-03-23 21:42:05 +0100 (Mon, 23 Mar 2009) | 1 line
Fix missing semicol
................
r2409 | danydb | 2009-03-23 21:44:09 +0100 (Mon, 23 Mar 2009) | 1 line
button static cannot be redefined as dynamic
................
r2410 | danydb | 2009-03-23 22:00:11 +0100 (Mon, 23 Mar 2009) | 1 line
Prob Numbering receipt
................
r2413 | danydb | 2009-03-24 20:11:01 +0100 (Tue, 24 Mar 2009) | 7 lines
* Remove todo (add security, improve documentation,...)
* Fix small bugs
* class fiche_def : template for adding a cat. of card
* Fix bug : add card + button
* remove obsolete file : class_widget.php poste.php fiche_inc.php
* rename CountSql to count_sql
................
r2414 | danydb | 2009-03-24 20:12:00 +0100 (Tue, 24 Mar 2009) | 13 lines
Merged revisions 2404-2413 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2411 | danydb | 2009-03-24 00:48:51 +0100 (Tue, 24 Mar 2009) | 1 line
Fix bug when installing for windows
........
r2412 | danydb | 2009-03-24 00:53:18 +0100 (Tue, 24 Mar 2009) | 1 line
Update doc windows
........
................
r2415 | danydb | 2009-03-24 23:17:09 +0100 (Tue, 24 Mar 2009) | 2 lines
* ledger purchase fix cosmetic + periode is deduced from date
................
r2416 | danydb | 2009-03-24 23:48:40 +0100 (Tue, 24 Mar 2009) | 2 lines
remove the add command in the list
................
r2417 | danydb | 2009-03-24 23:58:35 +0100 (Tue, 24 Mar 2009) | 1 line
Remove the button to add a customer or a supplier from the list of s/c
................
r2418 | danydb | 2009-03-25 00:02:31 +0100 (Wed, 25 Mar 2009) | 2 lines
Add bug + todo
................
r2419 | danydb | 2009-03-25 00:09:23 +0100 (Wed, 25 Mar 2009) | 1 line
Cosmetic change css table.result
................
r2420 | danydb | 2009-03-25 21:05:50 +0100 (Wed, 25 Mar 2009) | 2 lines
Add generate_micro
................
r2421 | danydb | 2009-03-26 09:03:57 +0100 (Thu, 26 Mar 2009) | 1 line
add domain
................
r2422 | danydb | 2009-03-30 22:45:09 +0200 (Mon, 30 Mar 2009) | 1 line
Rewrite of encode sold, usage of template
................
r2423 | danydb | 2009-04-02 13:48:16 +0200 (Thu, 02 Apr 2009) | 3 lines
Add microsecond to check if it is a double reload
................
r2424 | danydb | 2009-04-02 14:21:47 +0200 (Thu, 02 Apr 2009) | 1 line
Cosmetic in acc_ledger_sold
................
r2425 | danydb | 2009-04-02 15:53:42 +0200 (Thu, 02 Apr 2009) | 1 line
transform form fin in template/form_ledger_fin.php
................
r2426 | danydb | 2009-04-02 19:13:27 +0200 (Thu, 02 Apr 2009) | 1 line
Correct bug in preference
................
r2427 | danydb | 2009-04-03 10:57:39 +0200 (Fri, 03 Apr 2009) | 2 lines
Fix Periode
................
r2428 | danydb | 2009-04-03 12:27:04 +0200 (Fri, 03 Apr 2009) | 7 lines
Remove obsolete plpgsql
fix bug mini report
Improve protection against reload
Improve periode in ODS
Add Receipt number in ListJrn
Fix cosmetic Bug in fiche_new
................
r2429 | danydb | 2009-04-03 13:52:27 +0200 (Fri, 03 Apr 2009) | 2 lines
Improve after updating the status paid in ListJrn, we come back to the good screen
................
r2430 | danydb | 2009-04-03 16:39:14 +0200 (Fri, 03 Apr 2009) | 2 lines
Bug : the button for searching a Account is not given by IPoste
................
r2431 | danydb | 2009-04-03 17:04:40 +0200 (Fri, 03 Apr 2009) | 2 lines
Replace hard coded input type by IButton
................
r2432 | danydb | 2009-04-03 17:06:30 +0200 (Fri, 03 Apr 2009) | 2 lines
improve doc
................
r2433 | danydb | 2009-04-03 18:01:58 +0200 (Fri, 03 Apr 2009) | 1 line
remove unused line
................
r2434 | danydb | 2009-04-04 01:29:30 +0200 (Sat, 04 Apr 2009) | 4 lines
Improve doc
Code cleaning remove old function
Fix Bug payment by
................
r2440 | danydb | 2009-04-17 13:32:56 +0200 (Fri, 17 Apr 2009) | 25 lines
Merged revisions 2414-2439 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2435 | danydb | 2009-04-10 12:41:25 +0200 (Fri, 10 Apr 2009) | 1 line
On the welcome page, check if a mini report exist before trying to display it
........
r2436 | danydb | 2009-04-15 23:41:23 +0200 (Wed, 15 Apr 2009) | 1 line
Improve add saldo by qcode
........
r2437 | danydb | 2009-04-15 23:48:57 +0200 (Wed, 15 Apr 2009) | 1 line
Fix bug in financial ledger, there were no negative saldo
........
r2438 | danydb | 2009-04-16 13:17:14 +0200 (Thu, 16 Apr 2009) | 1 line
Fix Bug : financial ledger, first sold is clean
........
r2439 | danydb | 2009-04-17 10:41:02 +0200 (Fri, 17 Apr 2009) | 1 line
Fix Bug : in strict mode, when you start a new ledger, there is no last date of operation
........
................
r2441 | danydb | 2009-04-17 20:28:33 +0200 (Fri, 17 Apr 2009) | 2 lines
Fix Bug in impress->balance
Variable undefined in IPeriod and Acc_Account::get_lib
................
r2443 | danydb | 2009-04-18 21:41:28 +0200 (Sat, 18 Apr 2009) | 3 lines
Improve : permit to see all the ledgers in the listing
Improve : the noadd function for SearchCard
................
r2444 | danydb | 2009-04-18 23:57:07 +0200 (Sat, 18 Apr 2009) | 1 line
Improve : listing ledger, show all the ledgers
................
r2445 | danydb | 2009-04-19 00:00:24 +0200 (Sun, 19 Apr 2009) | 2 lines
Cosmetic
................
r2446 | danydb | 2009-04-19 00:07:54 +0200 (Sun, 19 Apr 2009) | 2 lines
Cosmetic : search card must be unique
................
r2447 | danydb | 2009-04-19 00:44:27 +0200 (Sun, 19 Apr 2009) | 1 line
Cosmetic ListJrn
................
r2448 | danydb | 2009-04-19 00:52:08 +0200 (Sun, 19 Apr 2009) | 1 line
Cosmetic : style sheet
................
r2450 | danydb | 2009-04-24 12:43:52 +0200 (Fri, 24 Apr 2009) | 1 line
Adapt svnmerge
................
r2451 | danydb | 2009-04-24 13:14:12 +0200 (Fri, 24 Apr 2009) | 4 lines
Fix : IMPORTANT this file doesn't work properly : the problem is the
javascript enable_type_periode which makes the from_periode,
to_periode, p_step... undefined
................
r2453 | danydb | 2009-04-25 17:47:11 +0200 (Sat, 25 Apr 2009) | 1 line
user_menu: no possibility to add card
................
r2454 | danydb | 2009-04-25 17:47:33 +0200 (Sat, 25 Apr 2009) | 9 lines
Merged revisions 2450-2453 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2452 | danydb | 2009-04-24 22:52:49 +0200 (Fri, 24 Apr 2009) | 1 line
Fix bug in reconciliation in fin ledger
........
................
r2455 | danydb | 2009-04-27 13:59:58 +0200 (Mon, 27 Apr 2009) | 1 line
class_iposte: add table = 2
................
r2456 | danydb | 2009-04-27 14:00:23 +0200 (Mon, 27 Apr 2009) | 1 line
Gestion : start with changes
................
r2457 | danydb | 2009-04-27 14:00:49 +0200 (Mon, 27 Apr 2009) | 1 line
class_fiche : fix cosmetic with label
................
r2461 | danydb | 2009-04-28 15:38:59 +0200 (Tue, 28 Apr 2009) | 13 lines
Merged revisions 2454-2459 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2458 | danydb | 2009-04-27 16:11:21 +0200 (Mon, 27 Apr 2009) | 2 lines
user_menu : change order of the menu
........
r2459 | danydb | 2009-04-28 15:35:06 +0200 (Tue, 28 Apr 2009) | 1 line
modify_op : fix bug in CA
........
................
r2462 | danydb | 2009-04-28 15:40:26 +0200 (Tue, 28 Apr 2009) | 1 line
Do not include rev. 2460 due to conflicts
................
r2463 | danydb | 2009-05-20 23:03:25 +0200 (Wed, 20 May 2009) | 1 line
Action : remove action from gestion->customer
................
r2464 | danydb | 2009-05-20 23:03:49 +0200 (Wed, 20 May 2009) | 1 line
Action : remove action from gestion->customer
................
r2465 | danydb | 2009-05-22 20:43:30 +0200 (Fri, 22 May 2009) | 1 line
Customer : start new version with ajax
................
r2467 | danydb | 2009-05-30 19:24:07 +0200 (Sat, 30 May 2009) | 9 lines
Merged revisions 2461-2466 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2466 | danydb | 2009-05-30 19:23:04 +0200 (Sat, 30 May 2009) | 2 lines
Typo Aciotn -> Action
........
................
r2468 | danydb | 2009-06-06 20:42:26 +0200 (Sat, 06 Jun 2009) | 1 line
Fix property on dia
................
r2469 | danydb | 2009-06-06 20:52:44 +0200 (Sat, 06 Jun 2009) | 1 line
Add doc
................
r2470 | danydb | 2009-06-07 15:10:25 +0200 (Sun, 07 Jun 2009) | 1 line
Fix problem with todo_list in access page
................
r2472 | danydb | 2009-07-04 20:13:03 +0200 (Sat, 04 Jul 2009) | 1 line
Add doc
................
r2473 | danydb | 2009-07-04 20:13:41 +0200 (Sat, 04 Jul 2009) | 9 lines
Merged revisions 2471 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2471 | danydb | 2009-07-01 19:48:38 +0200 (Wed, 01 Jul 2009) | 1 line
Bug : analytic accountancy in "gestion mode" not possible to update a description
........
................
r2474 | danydb | 2009-07-06 22:48:34 +0200 (Mon, 06 Jul 2009) | 2 lines
Add the warnbulle function
................
r2475 | danydb | 2009-07-06 22:54:07 +0200 (Mon, 06 Jul 2009) | 1 line
Add warnbulle + start new design of customer
................
r2476 | danydb | 2009-07-13 23:07:54 +0200 (Mon, 13 Jul 2009) | 1 line
Remove obsolete function and start new design
................
r2478 | danydb | 2009-07-15 21:57:03 +0200 (Wed, 15 Jul 2009) | 4 lines
Implement the object Database and replace completely the old functions
The file postgres.php has been removed
................
r2480 | danydb | 2009-07-16 20:20:48 +0200 (Thu, 16 Jul 2009) | 13 lines
Merged revisions 2477,2479 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2477 | danydb | 2009-07-14 21:48:05 +0200 (Tue, 14 Jul 2009) | 1 line
Bug : exception instead of new exception
........
r2479 | danydb | 2009-07-16 19:56:40 +0200 (Thu, 16 Jul 2009) | 1 line
Fix Bug for Postgresql 8.3
........
................
r2481 | danydb | 2009-07-17 00:14:47 +0200 (Fri, 17 Jul 2009) | 1 line
Correct test_me
................
r2482 | danydb | 2009-07-28 21:47:08 +0200 (Tue, 28 Jul 2009) | 1 line
Documentation
................
r2483 | danydb | 2009-07-28 21:48:14 +0200 (Tue, 28 Jul 2009) | 1 line
Doc
................
r2484 | danydb | 2009-07-29 00:25:14 +0200 (Wed, 29 Jul 2009) | 1 line
Fix numerous problem due to the new Object Database
................
r2485 | danydb | 2009-07-29 21:43:41 +0200 (Wed, 29 Jul 2009) | 2 lines
fix bug value -> label for ibutton
................
r2486 | danydb | 2009-07-30 00:25:36 +0200 (Thu, 30 Jul 2009) | 1 line
Catch Exception is no period is open && complete the change to class_database
................
r2487 | danydb | 2009-07-30 01:08:34 +0200 (Thu, 30 Jul 2009) | 5 lines
Improve class_iperiode (add 2 variables + doc)
fix bug in class_balance
add unicode in header_print
fix prob. due to new Database objet
................
r2496 | danydb | 2009-08-08 12:34:37 +0200 (Sat, 08 Aug 2009) | 37 lines
Merged revisions 2488-2495 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2488 | danydb | 2009-08-05 21:39:43 +0200 (Wed, 05 Aug 2009) | 1 line
Skipper : add account label in report
........
r2489 | danydb | 2009-08-05 22:33:29 +0200 (Wed, 05 Aug 2009) | 1 line
Add Libelle to Bilan
........
r2490 | danydb | 2009-08-05 23:25:23 +0200 (Wed, 05 Aug 2009) | 2 lines
Class_acc_bilan : protect XML
........
r2491 | danydb | 2009-08-05 23:29:58 +0200 (Wed, 05 Aug 2009) | 2 lines
class_acc_account : quote problem
........
r2492 | danydb | 2009-08-05 23:41:19 +0200 (Wed, 05 Aug 2009) | 1 line
Fix quote problem in line_update and fix header problem in class_acc_bilan::generate_odt
........
r2493 | danydb | 2009-08-06 21:30:35 +0200 (Thu, 06 Aug 2009) | 1 line
Add documentation about new tag
........
r2494 | danydb | 2009-08-06 21:45:26 +0200 (Thu, 06 Aug 2009) | 1 line
Update Doc Bilan
........
r2495 | danydb | 2009-08-06 21:50:22 +0200 (Thu, 06 Aug 2009) | 1 line
remove debug flag
........
................
r2497 | danydb | 2009-08-08 17:01:43 +0200 (Sat, 08 Aug 2009) | 1 line
Database : get_value set the this->ret
................
r2498 | danydb | 2009-08-10 21:47:53 +0200 (Mon, 10 Aug 2009) | 1 line
FIX BUG payment method, fix problem when searching or adding
................
r2499 | danydb | 2009-08-11 00:16:08 +0200 (Tue, 11 Aug 2009) | 1 line
Improve database abstraction : remove all the pg_ function
................
r2500 | danydb | 2009-08-20 00:06:54 +0200 (Thu, 20 Aug 2009) | 1 line
Fix bug in setup.php caused by the new Database obj
................
r2503 | danydb | 2009-08-27 22:10:08 +0200 (Thu, 27 Aug 2009) | 1 line
Fix Bug : not possible to grant an access to a ledger for an user (menu -> administration->utilisateur)
................
r2504 | danydb | 2009-08-27 22:16:22 +0200 (Thu, 27 Aug 2009) | 1 line
Block rev 2501
................
r2505 | danydb | 2009-08-27 22:19:07 +0200 (Thu, 27 Aug 2009) | 9 lines
Merged revisions 2502 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2502 | danydb | 2009-08-27 21:33:36 +0200 (Thu, 27 Aug 2009) | 2 lines
When an invoice is generated, the TVA_LABEL is an empty string is there is no merchandise
........
................
r2509 | danydb | 2009-08-29 21:11:49 +0200 (Sat, 29 Aug 2009) | 1 line
Block the rev 2508
................
r2510 | danydb | 2009-08-29 21:12:33 +0200 (Sat, 29 Aug 2009) | 13 lines
Merged revisions 2506-2507 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2506 | danydb | 2009-08-29 18:04:55 +0200 (Sat, 29 Aug 2009) | 1 line
Fix Bug when clicking on pj
........
r2507 | danydb | 2009-08-29 18:05:26 +0200 (Sat, 29 Aug 2009) | 1 line
Fix Bug for HTML
........
................
r2511 | danydb | 2009-08-29 21:16:27 +0200 (Sat, 29 Aug 2009) | 2 lines
Fix bug : undefined p_oid in the functions lo_unlinks and lo_export
................
r2512 | danydb | 2009-08-29 21:27:22 +0200 (Sat, 29 Aug 2009) | 1 line
Fix Bug : rollback in class_document_modele
................
r2513 | danydb | 2009-08-29 22:21:36 +0200 (Sat, 29 Aug 2009) | 1 line
Fix Bug : due to a error into echo_debug it was not possible to create new sale or new purchase
................
r2514 | danydb | 2009-09-02 21:05:04 +0200 (Wed, 02 Sep 2009) | 3 lines
remove useless debug info
add a __toString method for the database
fix small bugs due to the object Database
................
r2516 | danydb | 2009-09-05 18:57:18 +0200 (Sat, 05 Sep 2009) | 2 lines
Add a new Widget : IAction
................
r2517 | danydb | 2009-09-10 23:45:04 +0200 (Thu, 10 Sep 2009) | 1 line
Replace menu "Contact" by menu "Fiche"
................
r2518 | danydb | 2009-09-11 21:19:37 +0200 (Fri, 11 Sep 2009) | 2 lines
Typo change fiche by Fiche
................
r2519 | danydb | 2009-09-11 22:47:27 +0200 (Fri, 11 Sep 2009) | 1 line
fix bug : not readonly for Display
................
r2520 | danydb | 2009-09-11 22:48:40 +0200 (Fri, 11 Sep 2009) | 1 line
Add new function for counting the number of category by fiche type + fix bug with the button cherche
................
r2521 | danydb | 2009-09-11 22:49:10 +0200 (Fri, 11 Sep 2009) | 1 line
fix bug : the Cherche button does not work
................
r2522 | danydb | 2009-09-12 16:12:04 +0200 (Sat, 12 Sep 2009) | 1 line
Add a new HTML Widget IAction
................
r2523 | danydb | 2009-09-12 18:02:27 +0200 (Sat, 12 Sep 2009) | 7 lines
Customer changes :
==================
Add new layout
Add new customer card
Add new customer category
improve Customer::Summary
................
r2524 | danydb | 2009-09-12 18:10:43 +0200 (Sat, 12 Sep 2009) | 2 lines
Change class action by class Action
................
r2525 | danydb | 2009-09-13 22:46:35 +0200 (Sun, 13 Sep 2009) | 1 line
Set 2 times the same variable $l_sessid + correct indent
................
r2527 | danydb | 2009-09-16 22:45:18 +0200 (Wed, 16 Sep 2009) | 7 lines
Improve "Suivi Courrier"
======================
* the document::d_state containing the status is replaced by action::ag_state
* It is now possible to add several documents to an action
* There is no longer one 'Expediteur' and one 'Destinataire', it is replaced by one card
................
r2529 | danydb | 2009-09-17 19:30:12 +0200 (Thu, 17 Sep 2009) | 2 lines
change get_array, returns an empty array if nothing is found
................
r2530 | danydb | 2009-09-17 23:28:34 +0200 (Thu, 17 Sep 2009) | 15 lines
Improve "Suivi Courrier"
========================
* Change f_id : now we can a SQL where clause, it fixed a bug with suivi client
* Add several documents
* Remove Document thanks javascript (file scripts + show_document.php)
* Remove all the documents of a deleted action
* Not longer a blank document when adding an action
* Improve Layout of "Suivi Courrier"
* remove Rich text widget which is replace by a textarea
* the state of an action is in action and not longer in document
* Remove Destinataire and Expediteur, replaced by only one
* Add / update / delete action is one step
................
r2531 | danydb | 2009-09-17 23:29:53 +0200 (Thu, 17 Sep 2009) | 2 lines
Improve the button_href, which looks now as IAction + doc
................
r2532 | danydb | 2009-09-17 23:58:37 +0200 (Thu, 17 Sep 2009) | 2 lines
Add a concerned link in Action::Display
................
r2533 | danydb | 2009-09-18 00:13:59 +0200 (Fri, 18 Sep 2009) | 1 line
Place the return button inside the fieldset
................
r2534 | danydb | 2009-09-18 15:08:17 +0200 (Fri, 18 Sep 2009) | 2 lines
Database::get_value print a warning if returns more than one value
................
r2535 | danydb | 2009-09-18 20:27:03 +0200 (Fri, 18 Sep 2009) | 3 lines
datatabase::get_value returns a warning if several values are returns,
it gives a bug for the function limit_year
................
r2536 | danydb | 2009-09-18 21:53:32 +0200 (Fri, 18 Sep 2009) | 2 lines
Bug in fiche_search when using the type [SQL] in the filter for the card
................
r2537 | danydb | 2009-09-18 21:59:21 +0200 (Fri, 18 Sep 2009) | 2 lines
Inn exec_sql the array is printed if the pg_query fails
................
r2538 | danydb | 2009-09-18 23:30:16 +0200 (Fri, 18 Sep 2009) | 2 lines
Suivi courrier : generate the document and add a draft for the items to sell / order / deliver
................
r2539 | danydb | 2009-09-18 23:38:55 +0200 (Fri, 18 Sep 2009) | 1 line
suivi_courrier change f_id_exp by f_id_dest
................
r2540 | danydb | 2009-09-18 23:49:19 +0200 (Fri, 18 Sep 2009) | 14 lines
table action_gestion
---------------------
* remove col. f_id_exp
* add col. ag_state
* add a trigger to cut the col. ag_title to 70 char
Function account_parent
-----------------------
fix bug : exit loop when a account parent is found
table invoice drop because useless
table parm_code add code SUPPLIER
drop useless function insert_quant_purchase, insert_quant_sold
add index for jrn(jr_mt) (double encoding detection)
................
r2545 | danydb | 2009-09-19 18:19:27 +0200 (Sat, 19 Sep 2009) | 1 line
Improve layout of form for adding/modifying an action
................
r2546 | danydb | 2009-09-20 00:11:05 +0200 (Sun, 20 Sep 2009) | 11 lines
Suivi client
=======
Add the owner to the table ag_action
Add the hours (format HH:MM) and a javascript to check the format
Add the affected to
Add a flag if the action have to be seen in the calendar
filter the list thanks the cloture or note
change ag_state to 'to be done, done, to follow, cancel'
Highlight the High priority in the list
................
r2547 | danydb | 2009-09-20 00:11:43 +0200 (Sun, 20 Sep 2009) | 1 line
Improve appereance of generated documentation
................
r2548 | danydb | 2009-09-20 00:12:37 +0200 (Sun, 20 Sep 2009) | 1 line
function get_by_qcode If it is not possible to find the quick_code of card then his id is 0
................
r2549 | danydb | 2009-09-20 00:26:34 +0200 (Sun, 20 Sep 2009) | 1 line
Fix bug in search card and change cosmetic in Action::Display for ag_ref_ag_ref_id
................
r2550 | danydb | 2009-09-20 00:52:11 +0200 (Sun, 20 Sep 2009) | 1 line
Suivi courrier : show only my action
................
r2551 | danydb | 2009-09-20 21:05:09 +0200 (Sun, 20 Sep 2009) | 1 line
Suivi courrier : Add the contact in the action form (ag_action)
................
r2552 | danydb | 2009-09-26 21:12:45 +0200 (Sat, 26 Sep 2009) | 1 line
FIX : remove a small cosmetic bugs
................
r2553 | danydb | 2009-09-26 21:15:36 +0200 (Sat, 26 Sep 2009) | 1 line
DOC : add documentation
................
r2554 | danydb | 2009-09-26 21:16:47 +0200 (Sat, 26 Sep 2009) | 4 lines
IMPROVE : when a card is found the label is updated, there is a test (tagName) to determine
if we have to use innerHTML or value
................
r2555 | danydb | 2009-09-26 21:17:41 +0200 (Sat, 26 Sep 2009) | 1 line
Remove XML output in Doxygen
................
r2560 | danydb | 2009-10-03 01:28:30 +0200 (Sat, 03 Oct 2009) | 1 line
Infobulle : add example
................
r2561 | danydb | 2009-10-03 01:31:50 +0200 (Sat, 03 Oct 2009) | 1 line
Class fiche : rewrite code for get_by_qcode
................
r2562 | danydb | 2009-10-03 01:33:46 +0200 (Sat, 03 Oct 2009) | 1 line
Style sheet add span action
................
r2563 | danydb | 2009-10-03 01:35:16 +0200 (Sat, 03 Oct 2009) | 1 line
Class document : remove waiting message when generating a document
................
r2564 | danydb | 2009-10-03 01:35:50 +0200 (Sat, 03 Oct 2009) | 1 line
update document schema
................
r2565 | danydb | 2009-10-03 01:36:43 +0200 (Sat, 03 Oct 2009) | 5 lines
Suivi
=====
Finished the new layout of follow up
................
r2566 | danydb | 2009-10-03 01:37:22 +0200 (Sat, 03 Oct 2009) | 1 line
Suivi client add List action
................
r2567 | danydb | 2009-10-03 01:46:08 +0200 (Sat, 03 Oct 2009) | 9 lines
Merged revisions 2515 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2515 | danydb | 2009-09-04 21:44:42 +0200 (Fri, 04 Sep 2009) | 1 line
For the bilan, fix partially a bug in the html headers for OOo document and allowed the use of the numeric format in ods document (from Bertrand)
........
................
r2568 | danydb | 2009-10-03 01:52:20 +0200 (Sat, 03 Oct 2009) | 30 lines
Merged revisions 2526,2528,2541,2543,2558-2559 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/trunk
........
r2526 | danydb | 2009-09-14 23:21:41 +0200 (Mon, 14 Sep 2009) | 1 line
Fix Bug with the todo list, in the "Accueil" if there several line in a todo list, you cannot modify it
........
r2528 | danydb | 2009-09-17 16:44:14 +0200 (Thu, 17 Sep 2009) | 4 lines
Changement to let the user to enter manually the vat amount in the Ledger of sold.
It must be tested and accepted
........
r2541 | danydb | 2009-09-19 00:53:18 +0200 (Sat, 19 Sep 2009) | 2 lines
bug : impress->poste give duplicate if the same card is used several times in an operation
........
r2543 | danydb | 2009-09-19 01:14:36 +0200 (Sat, 19 Sep 2009) | 1 line
Revert the change from rev 2528 about the manual encoding of vat in sold ledger
........
r2558 | danydb | 2009-09-28 22:08:01 +0200 (Mon, 28 Sep 2009) | 1 line
fix bug postgresql 8.3 : the restart sequence must be > 1
........
r2559 | danydb | 2009-09-28 22:09:11 +0200 (Mon, 28 Sep 2009) | 2 lines
FIX BUG in sql_filter_per for the centralized printing
........
................
r2570 | danydb | 2009-10-07 23:34:28 +0200 (Wed, 07 Oct 2009) | 8 lines
Blocked revisions 2569 via svnmerge
........
r2569 | danydb | 2009-10-07 23:27:49 +0200 (Wed, 07 Oct 2009) | 2 lines
Fix problem when multiple lines
........
................
r2571 | danydb | 2009-10-08 00:09:28 +0200 (Thu, 08 Oct 2009) | 1 line
Fix Bug : decode uri
................
r2572 | danydb | 2009-10-08 00:41:04 +0200 (Thu, 08 Oct 2009) | 3 lines
Add the PHP function encodeURI decodeURI to match the behaviour of
those functions in javascript
................
r2573 | danydb | 2009-10-08 19:54:23 +0200 (Thu, 08 Oct 2009) | 6 lines
**********************************************************************
create a branch for the rewrite of javascript
**********************************************************************
................
r2575 | danydb | 2009-10-08 21:02:08 +0200 (Thu, 08 Oct 2009) | 1 line
javascript : Remove useless files and regroup differently
................
r2576 | danydb | 2009-10-09 00:36:13 +0200 (Fri, 09 Oct 2009) | 1 line
Rename search_post to account_item + code rewriting
................
r2577 | danydb | 2009-10-09 00:36:27 +0200 (Fri, 09 Oct 2009) | 1 line
Rename search_post to account_item + code rewriting
................
r2578 | danydb | 2009-10-09 00:36:49 +0200 (Fri, 09 Oct 2009) | 1 line
Rename search_card to card + code rewriting
................
r2579 | danydb | 2009-10-09 00:38:02 +0200 (Fri, 09 Oct 2009) | 1 line
put ajax op into anc_script
................
r2580 | danydb | 2009-10-09 00:40:14 +0200 (Fri, 09 Oct 2009) | 1 line
Add the Ajax object + encodeJSON function
................
r2581 | danydb | 2009-10-09 00:40:39 +0200 (Fri, 09 Oct 2009) | 1 line
rewrite code
................
r2582 | danydb | 2009-10-09 00:42:37 +0200 (Fri, 09 Oct 2009) | 2 lines
Remove obsolete javascript file
and test for javascript into test.php
................
r2584 | danydb | 2009-10-17 14:49:41 +0200 (Sat, 17 Oct 2009) | 1 line
ReAdd prototype.js
................
r2585 | danydb | 2009-10-17 16:47:44 +0200 (Sat, 17 Oct 2009) | 2 lines
access : Fix size report for IE
................
r2586 | danydb | 2009-10-17 17:16:58 +0200 (Sat, 17 Oct 2009) | 4 lines
Sort and regroup the javascript
Replace PNG image with GIF image for compatibility with IE
Modify CSS for compatibility with IE
................
r2587 | danydb | 2009-10-17 17:18:25 +0200 (Sat, 17 Oct 2009) | 9 lines
Merged revisions 2583 via svnmerge from
svn+ssh://danydb@svn/svn/phpcompta/branches/rel500
........
r2583 | danydb | 2009-10-14 23:41:11 +0200 (Wed, 14 Oct 2009) | 1 line
Add the function encodeURI to avoid problem with JSON
........
................
r2588 | danydb | 2009-10-17 17:26:43 +0200 (Sat, 17 Oct 2009) | 2 lines
Fix Bug with the add button
................
r2589 | danydb | 2009-10-17 19:01:10 +0200 (Sat, 17 Oct 2009) | 1 line
Remove obsolete image files
................
r2590 | danydb | 2009-10-19 19:46:21 +0200 (Mon, 19 Oct 2009) | 2 lines
Modify echo_error
................
r2596 | danydb | 2009-10-20 23:34:31 +0200 (Tue, 20 Oct 2009) | 3 lines
FIX IE 7 Cosmetic BUG
Avoid connection with IE6
Add the ipopupsearchcard
................
r2597 | danydb | 2009-10-21 14:56:29 +0200 (Wed, 21 Oct 2009) | 1 line
Add new version of prototype
................
r2599 | danydb | 2009-10-24 18:16:43 +0200 (Sat, 24 Oct 2009) | 2 lines
Doc
................
r2600 | danydb | 2009-10-25 11:22:04 +0100 (Sun, 25 Oct 2009) | 1 line
Add create_script and js_include function
................
r2601 | danydb | 2009-10-25 11:23:29 +0100 (Sun, 25 Oct 2009) | 3 lines
Finished the autocomplete feature for the ledger of sales
................
r2602 | danydb | 2009-10-25 11:34:45 +0100 (Sun, 25 Oct 2009) | 1 line
Update Documentation
................
r2603 | danydb | 2009-10-25 12:19:40 +0100 (Sun, 25 Oct 2009) | 2 lines
Cosmetic : add a limit for autocomplete card (12)
................
r2604 | danydb | 2009-10-25 13:44:06 +0100 (Sun, 25 Oct 2009) | 1 line
Delay to be redirected is reduce to 1 sec
................
r2605 | danydb | 2009-10-25 18:11:50 +0100 (Sun, 25 Oct 2009) | 8 lines
This version contains the icard with autocomplete working
Only implemented in Ledger of sale
Some bugs and questions remain
* the payment by must be improved
* verify if the tva_id is updated
* Nothing happens if we don't selected in the hint list
................
r2606 | danydb | 2009-10-25 18:22:50 +0100 (Sun, 25 Oct 2009) | 3 lines
Autocomplete in Ledger of sales
Improve ICard : add an onchange event
................
r2607 | danydb | 2009-10-25 18:33:58 +0100 (Sun, 25 Oct 2009) | 8 lines
Autocomplete in Ledger of sales
Improve ICard
=============
* add an error message if the card is not found when card is not selected into the list
* remove the animated indicator
................
r2608 | danydb | 2009-10-25 18:37:44 +0100 (Sun, 25 Oct 2009) | 2 lines
Fix small bug due the removal of the animation
................
r2609 | danydb | 2009-10-27 14:23:23 +0100 (Tue, 27 Oct 2009) | 1 line
add phpcompta_psql_host is the config_file, this variable is the postgresql host in case it is not in local, fix the return carriage for windows
................
r2611 | danydb | 2009-10-27 21:42:41 +0100 (Tue, 27 Oct 2009) | 1 line
Add variable phpcompta_psql_host in config.inc.php
................
r2612 | danydb | 2009-10-27 21:45:10 +0100 (Tue, 27 Oct 2009) | 8 lines
Blocked revisions 2610 via svnmerge
........
r2610 | danydb | 2009-10-27 21:07:16 +0100 (Tue, 27 Oct 2009) | 1 line
add variable phpcompta_psql_host to set the postgres server on another server
........
................
r2613 | danydb | 2009-10-27 21:47:44 +0100 (Tue, 27 Oct 2009) | 2 lines
Add script.aculous script
................
r2614 | danydb | 2009-10-27 22:14:15 +0100 (Tue, 27 Oct 2009) | 2 lines
get_by_qcode remove the heading and trailing space
................
r2615 | danydb | 2009-10-27 22:42:32 +0100 (Tue, 27 Oct 2009) | 2 lines
Remove trailing and heading space for insert_quant_purchase and insert_quant_sold
................
r2616 | danydb | 2009-10-27 22:46:26 +0100 (Tue, 27 Oct 2009) | 1 line
Fix bug : if there is no file to upload, returns immediately
................
r2617 | danydb | 2009-10-27 22:46:54 +0100 (Tue, 27 Oct 2009) | 1 line
Add documentation
................
r2618 | danydb | 2009-10-27 22:48:14 +0100 (Tue, 27 Oct 2009) | 1 line
Autocomplete in Ledger of purchase, still missing : detail and add card
................
r2619 | danydb | 2009-10-28 12:08:19 +0100 (Wed, 28 Oct 2009) | 4 lines
For the auto complete, we can now seek in the quick_code, in the name and in the description
the part of string which is found is in bold
Those feature must tested
................
r2620 | danydb | 2009-10-28 15:34:34 +0100 (Wed, 28 Oct 2009) | 3 lines
* Change the function Acc_Ledger_Purchase::display_form by Acc_Ledger_Purchase::input
* change the name of form_ledger
................
r2621 | danydb | 2009-10-28 15:35:10 +0100 (Wed, 28 Oct 2009) | 1 line
Remove form_ledger_detail.php
................
r2622 | danydb | 2009-10-28 15:35:42 +0100 (Wed, 28 Oct 2009) | 1 line
Rename form_ledger_ven.php to form_ledger_detail.php
................
r2623 | danydb | 2009-10-28 22:26:04 +0100 (Wed, 28 Oct 2009) | 6 lines
Make the search in description qcode or name
Add ICard autocomplete to :
- Financial ledger
- Gestion : details
................
r2625 | danydb | 2009-10-28 23:30:49 +0100 (Wed, 28 Oct 2009) | 2 lines
ICard autocomplete : add the price
................
r2628 | danydb | 2009-10-31 02:42:15 +0100 (Sat, 31 Oct 2009) | 10 lines
Improve the facture HTML in the contrib
Fix bug in generate invoice
Manual VAT amount in the ledger of sales
Add ICard to Ledger Sales, purchase and fin
Rewrite of javascript for ledger
Ledger purchase use template
Fix prob with infobulle in FIN ledger
Improve ICard and make it work with IE7 and IE8
Improve support of IE7 and IE8
................
r2629 | danydb | 2009-10-31 03:03:43 +0100 (Sat, 31 Oct 2009) | 4 lines
Add ajax_saldo
Fix bug with amount computing
Improve CSS : input text with 2 px of margin
................
r2630 | danydb | 2009-10-31 13:17:05 +0100 (Sat, 31 Oct 2009) | 2 lines
Set redirect if disconnected to 1 sec
................
r2631 | danydb | 2009-10-31 20:07:10 +0100 (Sat, 31 Oct 2009) | 1 line
rewrite of the listing of ledger, with a hidden div for the search
................
r2632 | danydb | 2009-10-31 20:32:08 +0100 (Sat, 31 Oct 2009) | 1 line
Add name of ledger into list_operation
................
r2633 | danydb | 2009-10-31 20:33:39 +0100 (Sat, 31 Oct 2009) | 1 line
Add search form for ledger
................
r2634 | danydb | 2009-10-31 20:39:13 +0100 (Sat, 31 Oct 2009) | 2 lines
Add documentation for new functions
................
r2635 | danydb | 2009-11-01 12:44:56 +0100 (Sun, 01 Nov 2009) | 7 lines
search :
* by default the search is on the default period,
* move openrecherche into scripts
* search ok for list VEN ACH ALL
* rewrite of recherche.php
* deprecated function showMenuRecherche
................
r2636 | danydb | 2009-11-01 12:54:12 +0100 (Sun, 01 Nov 2009) | 3 lines
Add in attr_def a nr of customer by default
Clean code constant.php
................
r2637 | danydb | 2009-11-01 14:26:52 +0100 (Sun, 01 Nov 2009) | 2 lines
Icard + new search : working for quick_writing
................
r2638 | danydb | 2009-11-01 14:43:31 +0100 (Sun, 01 Nov 2009) | 2 lines
remove debug info
................
r2639 | danydb | 2009-11-01 17:48:39 +0100 (Sun, 01 Nov 2009) | 3 lines
For each ledger it is now possible to see the details of card
when double-clicking on the field
................
r2640 | danydb | 2009-11-01 18:34:02 +0100 (Sun, 01 Nov 2009) | 2 lines
todo : bug IE cannot solved : bad position IPOPUP
................
r2641 | danydb | 2009-11-01 18:34:41 +0100 (Sun, 01 Nov 2009) | 1 line
Try to fix problem with IE, IPopup does not WORK !!
................
r2642 | danydb | 2009-11-01 19:00:24 +0100 (Sun, 01 Nov 2009) | 1 line
Fix position IPopup for card
................
r2643 | danydb | 2009-11-01 19:55:26 +0100 (Sun, 01 Nov 2009) | 1 line
Fix Problem IE with XML handling; add INum in each ledger
................
r2644 | danydb | 2009-11-01 22:12:40 +0100 (Sun, 01 Nov 2009) | 2 lines
Improve cosmetic
................
r2645 | danydb | 2009-11-02 17:36:14 +0100 (Mon, 02 Nov 2009) | 3 lines
Add a button for adding card inside a ledger form, there is no
popup window any more for adding a card
................
r2650 | danydb | 2009-11-03 23:27:30 +0100 (Tue, 03 Nov 2009) | 1 line
ICard : add a new static method for creating the IPopup ICard::ipopup()
................
r2651 | danydb | 2009-11-04 00:46:05 +0100 (Wed, 04 Nov 2009) | 1 line
Change javascript for IE compatibility for adding row in table
................
r2652 | danydb | 2009-11-04 10:20:48 +0100 (Wed, 04 Nov 2009) | 1 line
Rename button_href to button_anchor
................
r2654 | danydb | 2009-11-04 10:29:07 +0100 (Wed, 04 Nov 2009) | 3 lines
Removed merge tracking for "svnmerge" for
file:///home/developper/svn/phpcompta/branches/rel500
................
r2657 | danydb | 2009-11-04 10:56:21 +0100 (Wed, 04 Nov 2009) | 1 line
Update Changelog svn2cl -r 2351:HEAD, 2351 was the start on rel500 branch
................
r2658 | danydb | 2009-11-04 18:30:35 +0100 (Wed, 04 Nov 2009) | 4 lines
Javascript prob.
Put the javascript script file in the top of the file
................
r2659 | danydb | 2009-11-04 18:33:19 +0100 (Wed, 04 Nov 2009) | 4 lines
Rename ajax_get.php to ajax_card.js
................
r2660 | danydb | 2009-11-04 19:36:52 +0100 (Wed, 04 Nov 2009) | 2 lines
complete documentation of ajax_card
................
r2661 | danydb | 2009-11-04 19:57:36 +0100 (Wed, 04 Nov 2009) | 2 lines
add the function escape_xml
................
r2662 | danydb | 2009-11-05 16:14:02 +0100 (Thu, 05 Nov 2009) | 1 line
Remove useless comment
................
r2663 | danydb | 2009-11-05 21:34:52 +0100 (Thu, 05 Nov 2009) | 6 lines
Improve IPopup
--------------
Add the draggable feature for all ipopup
Fix position problem with IE
................
r2664 | danydb | 2009-11-07 00:07:24 +0100 (Sat, 07 Nov 2009) | 2 lines
fix bug in get_row : order must appear in the select
................
r2665 | danydb | 2009-11-07 01:00:08 +0100 (Sat, 07 Nov 2009) | 6 lines
Accounting
===========
* finish to add everywhere the ICard
* finish to add everywhere the IPost
................
r2666 | danydb | 2009-11-07 12:38:30 +0100 (Sat, 07 Nov 2009) | 1 line
Correct cosmetic + Tabel CSS
................
r2667 | danydb | 2009-11-07 12:40:21 +0100 (Sat, 07 Nov 2009) | 1 line
Respond to ajax request to manager Accouting item (search)
................
r2668 | danydb | 2009-11-08 18:39:02 +0100 (Sun, 08 Nov 2009) | 12 lines
Gestion Client
==============
Add the operations
add the contacts
General
=======
Improve search into ledger (accouting item + quick code card)
Improve search into ledger (internal number)
................
r2669 | danydb | 2009-11-09 14:12:38 +0100 (Mon, 09 Nov 2009) | 2 lines
Split action.inc.php into 2 parts, the second is usable from anywhere
................
r2670 | danydb | 2009-11-09 18:31:07 +0100 (Mon, 09 Nov 2009) | 6 lines
Firefox XML
=============
Firefox split the XML answer in a 4k block, IE doesn't.
We add a function to retrieve the full content of a XML node
................
r2671 | danydb | 2009-11-10 14:23:16 +0100 (Tue, 10 Nov 2009) | 7 lines
Firefox XML
=============
Firefox split the XML answer in a 4k block, IE doesn't.
We add a function to retrieve the full content of a XML node
................
r2672 | danydb | 2009-11-11 16:56:47 +0100 (Wed, 11 Nov 2009) | 5 lines
Todo List
=========
To avoid any problem, the JSON format has been dropped and replaced by
the XML format
................
r2673 | danydb | 2009-11-12 16:16:47 +0100 (Thu, 12 Nov 2009) | 7 lines
Dev. Scripts
============
* delete old useless scripts
* add comments to scripts (purpose, gpl...)
* add scripts for adding languages
................
r2674 | danydb | 2009-11-12 21:12:50 +0100 (Thu, 12 Nov 2009) | 5 lines
Translation
===========
Start translation to English
................
r2675 | danydb | 2009-11-14 00:58:37 +0100 (Sat, 14 Nov 2009) | 5 lines
Card search button
-------------------
Add a search button in accountancy
................
r2676 | danydb | 2009-11-14 16:57:01 +0100 (Sat, 14 Nov 2009) | 2 lines
Class database : with postgresql > 8.2 the sequence can be less than 1
................
r2677 | danydb | 2009-11-14 17:00:13 +0100 (Sat, 14 Nov 2009) | 6 lines
Bug
===
Fix Bug in the creation of ledger, and add the new IPoste class
for searching for an accounting item
................
r2678 | danydb | 2009-11-15 17:12:59 +0100 (Sun, 15 Nov 2009) | 3 lines
remove debug code
Add translation
................
r2679 | danydb | 2009-11-15 21:48:05 +0100 (Sun, 15 Nov 2009) | 7 lines
Fiche cat
=========
Add IPoste,
Add correction of accounting item for the cat
Add correction of auto create for the cat
................
r2680 | danydb | 2009-11-16 16:06:55 +0100 (Mon, 16 Nov 2009) | 1 line
Add translations
................
r2681 | danydb | 2009-11-17 20:51:18 +0100 (Tue, 17 Nov 2009) | 5 lines
Card
====
Fix bug with the accounting item when it is not automatically
computed
................
r2682 | danydb | 2009-11-17 21:13:13 +0100 (Tue, 17 Nov 2009) | 1 line
remove debug info and correct the printing of account
................
r2683 | danydb | 2009-11-17 21:49:31 +0100 (Tue, 17 Nov 2009) | 4 lines
Report
======
Fix bug with report, add IPoste for helping in creation of new report
................
r2684 | danydb | 2009-11-18 17:02:36 +0100 (Wed, 18 Nov 2009) | 3 lines
Translation of the template
................
r2685 | danydb | 2009-11-18 17:20:00 +0100 (Wed, 18 Nov 2009) | 5 lines
BUDGET
======
Remove completely the old BUDGET module
................
r2686 | danydb | 2009-11-18 17:31:49 +0100 (Wed, 18 Nov 2009) | 1 line
Cosmetic : size of span as row
................
r2687 | danydb | 2009-11-18 17:32:05 +0100 (Wed, 18 Nov 2009) | 1 line
Typo
................
r2688 | danydb | 2009-11-19 12:21:12 +0100 (Thu, 19 Nov 2009) | 2 lines
redirect faster
................
r2689 | danydb | 2009-11-19 12:22:27 +0100 (Thu, 19 Nov 2009) | 2 lines
Change Liste des tâches to Pense Bete
................
r2690 | danydb | 2009-11-19 16:58:27 +0100 (Thu, 19 Nov 2009) | 5 lines
Ledger VEN & ACH
================
Translation
................
r2691 | danydb | 2009-11-19 22:55:15 +0100 (Thu, 19 Nov 2009) | 2 lines
Fix bug with f_id_Dest
................
r2692 | danydb | 2009-11-19 23:13:20 +0100 (Thu, 19 Nov 2009) | 1 line
Fix small bug in "gestion"
................
r2693 | danydb | 2009-11-20 11:57:39 +0100 (Fri, 20 Nov 2009) | 2 lines
Doxygen : introduction in English
................
r2694 | danydb | 2009-11-20 12:20:43 +0100 (Fri, 20 Nov 2009) | 1 line
Typo in SQL
................
r2695 | danydb | 2009-11-20 15:30:09 +0100 (Fri, 20 Nov 2009) | 2 lines
Add comment to database
................
r2696 | danydb | 2009-11-22 11:02:14 +0100 (Sun, 22 Nov 2009) | 1 line
Dashboad
................
r2697 | danydb | 2009-11-22 11:02:46 +0100 (Sun, 22 Nov 2009) | 1 line
Dashboad
................
r2698 | danydb | 2009-11-22 11:03:09 +0100 (Sun, 22 Nov 2009) | 1 line
Reconciliation : fix bug
................
r2699 | danydb | 2009-11-22 11:21:56 +0100 (Sun, 22 Nov 2009) | 2 lines
fix bug for period and show the selected language
................
r2700 | danydb | 2009-11-22 11:40:10 +0100 (Sun, 22 Nov 2009) | 2 lines
IPeriod improve doc and add javascript
................
r2701 | danydb | 2009-11-22 11:50:24 +0100 (Sun, 22 Nov 2009) | 5 lines
class ICard
-----------
No button search if readOnly is true
display show the value and add a hidden value
................
r2702 | danydb | 2009-11-22 12:20:22 +0100 (Sun, 22 Nov 2009) | 6 lines
Import Bank
-----------
Fix bug import bank
Add possibility to select directly the period
................
r2703 | danydb | 2009-11-22 14:10:49 +0100 (Sun, 22 Nov 2009) | 6 lines
Customer
---------
Add a new card in a popup
Reload window after adding card
................
r2704 | danydb | 2009-11-22 18:48:07 +0100 (Sun, 22 Nov 2009) | 5 lines
Customer
==========
Add category by ipopup
................
r2705 | danydb | 2009-11-22 18:59:44 +0100 (Sun, 22 Nov 2009) | 4 lines
Deprecated
==========
remove deprecated function code
................
r2706 | danydb | 2009-11-22 19:01:53 +0100 (Sun, 22 Nov 2009) | 1 line
code cleaning : remove dead code
................
r2707 | danydb | 2009-11-22 19:06:34 +0100 (Sun, 22 Nov 2009) | 1 line
remove useless option
................
r2708 | danydb | 2009-11-22 19:12:53 +0100 (Sun, 22 Nov 2009) | 1 line
Code cleaning : remove dead code
................
r2709 | danydb | 2009-11-22 22:32:12 +0100 (Sun, 22 Nov 2009) | 1 line
fix bug char set and update translation
................
r2710 | danydb | 2009-11-23 15:23:09 +0100 (Mon, 23 Nov 2009) | 4 lines
Code cleaning
=============
Remove Dead Code
................
r2711 | danydb | 2009-11-23 16:09:54 +0100 (Mon, 23 Nov 2009) | 1 line
ICard : improve doc and remove dead code
................
r2712 | danydb | 2009-11-23 23:36:41 +0100 (Mon, 23 Nov 2009) | 2 lines
Improve appearance
................
r2713 | danydb | 2009-11-24 00:42:25 +0100 (Tue, 24 Nov 2009) | 7 lines
Acc_Ledger Sales and Expense
-----------------------------
* Fix last bugs
* Add 2 columns : total without VAT, total with VAT
* Improve INum, the readonly TAGS are in light grey
................
r2714 | danydb | 2009-11-24 14:48:59 +0100 (Tue, 24 Nov 2009) | 1 line
Generate Doc : clean table document after generating
................
r2715 | danydb | 2009-11-24 17:28:48 +0100 (Tue, 24 Nov 2009) | 6 lines
Doxygen
change setting :
remove code in the documentation
Show comment
................
r2716 | danydb | 2009-11-24 17:29:55 +0100 (Tue, 24 Nov 2009) | 2 lines
Backup - restore : Add the flag --no-owner to avoid some security issues
................
r2717 | danydb | 2009-11-24 17:31:04 +0100 (Tue, 24 Nov 2009) | 8 lines
Action - customer
==================
Add the search button
Add the detail double click
Improve documentation
Improve search build_sql
................
r2718 | danydb | 2009-11-24 22:51:53 +0100 (Tue, 24 Nov 2009) | 1 line
Fix char set
................
r2719 | danydb | 2009-11-24 23:52:39 +0100 (Tue, 24 Nov 2009) | 1 line
cosmetic
................
r2720 | danydb | 2009-11-24 23:52:41 +0100 (Tue, 24 Nov 2009) | 1 line
Class fiche: add toArray
................
r2721 | danydb | 2009-11-24 23:53:38 +0100 (Tue, 24 Nov 2009) | 1 line
add button for the search of action
................
r2722 | danydb | 2009-11-24 23:54:01 +0100 (Tue, 24 Nov 2009) | 2 lines
Improve ISpan : add the attribute style
................
r2723 | danydb | 2009-11-26 16:58:23 +0100 (Thu, 26 Nov 2009) | 1 line
Improve doc + test card
................
r2724 | danydb | 2009-11-28 01:22:43 +0100 (Sat, 28 Nov 2009) | 6 lines
Fix bug in GESTION
Add search in Recherche (acc_ledger)
Improve doc and style
Create file for extension
................
r2725 | danydb | 2009-11-29 18:13:07 +0100 (Sun, 29 Nov 2009) | 1 line
Card Search in the ledger for all the cards
................
r2726 | danydb | 2009-11-29 18:26:30 +0100 (Sun, 29 Nov 2009) | 1 line
Add check to avoid to enter twice the same name for cat. of card
................
r2727 | danydb | 2009-11-29 18:30:13 +0100 (Sun, 29 Nov 2009) | 1 line
Finish customer
................
r2728 | danydb | 2009-11-29 18:35:46 +0100 (Sun, 29 Nov 2009) | 1 line
Operatio customer
................
r2729 | danydb | 2009-11-29 18:55:34 +0100 (Sun, 29 Nov 2009) | 5 lines
SUPPLIER
========
Add Supplier
................
r2730 | danydb | 2009-11-29 19:31:42 +0100 (Sun, 29 Nov 2009) | 1 line
Add security for Administration
................
r2731 | danydb | 2009-11-29 19:32:13 +0100 (Sun, 29 Nov 2009) | 1 line
Add security for Administration
................
r2732 | danydb | 2009-11-29 19:39:50 +0100 (Sun, 29 Nov 2009) | 2 lines
Change client by supplier
................
r2733 | danydb | 2009-11-29 20:17:36 +0100 (Sun, 29 Nov 2009) | 5 lines
Administration
==============
Add administration follow-up, detail, history
................
r2734 | danydb | 2009-11-29 20:24:46 +0100 (Sun, 29 Nov 2009) | 1 line
Strict Contact::Summary not correct
................
r2735 | danydb | 2009-11-29 20:31:05 +0100 (Sun, 29 Nov 2009) | 1 line
Fix bug in follow up and ADM
................
r2736 | danydb | 2009-11-29 20:36:34 +0100 (Sun, 29 Nov 2009) | 1 line
Show the search in Follow up in a criteria exist
................
r2737 | danydb | 2009-11-30 15:52:21 +0100 (Mon, 30 Nov 2009) | 1 line
Improve ShowPopup: keep the Dialog Box in the current view
................
r2738 | danydb | 2009-12-01 21:56:24 +0100 (Tue, 01 Dec 2009) | 7 lines
Dashboard
---------
Add last action
Add Calendar
Add last operation
................
r2739 | danydb | 2009-12-01 22:07:12 +0100 (Tue, 01 Dec 2009) | 1 line
Fix bug in middle of payment
................
r2740 | danydb | 2009-12-01 22:09:28 +0100 (Tue, 01 Dec 2009) | 2 lines
Use gettext
................
r2741 | danydb | 2009-12-01 22:13:11 +0100 (Tue, 01 Dec 2009) | 2 lines
Add gettext
................
r2742 | danydb | 2009-12-01 22:15:28 +0100 (Tue, 01 Dec 2009) | 2 lines
Fix bug : add row : 9 col instead of 6
................
r2743 | danydb | 2009-12-01 22:42:10 +0100 (Tue, 01 Dec 2009) | 1 line
Adapt for MS IE7µ
................
r2744 | danydb | 2009-12-04 16:15:36 +0100 (Fri, 04 Dec 2009) | 1 line
add iposte, fix size in css
................
r2745 | danydb | 2009-12-05 01:52:50 +0100 (Sat, 05 Dec 2009) | 8 lines
Parameters
==========
* Move VAT into Divers
* Update doc iposte
* Add iposte to Parm Code
* Add security for extension
................
r2746 | danydb | 2009-12-06 21:36:16 +0100 (Sun, 06 Dec 2009) | 1 line
Remove autocomplete from the Acc_Ledger::search_form due to a bug in the autocompleter
................
r2747 | danydb | 2009-12-06 22:12:24 +0100 (Sun, 06 Dec 2009) | 2 lines
add security
................
r2748 | danydb | 2009-12-06 22:15:23 +0100 (Sun, 06 Dec 2009) | 2 lines
Add documentation
................
r2749 | danydb | 2009-12-06 22:27:27 +0100 (Sun, 06 Dec 2009) | 4 lines
EXtension
=========
Add structure for extension
................
r2750 | danydb | 2009-12-06 22:35:26 +0100 (Sun, 06 Dec 2009) | 1 line
Fix cosmetic
................
r2751 | danydb | 2009-12-09 16:36:39 +0100 (Wed, 09 Dec 2009) | 2 lines
remove richtext.js which is obsolete
................
r2752 | danydb | 2009-12-09 16:52:56 +0100 (Wed, 09 Dec 2009) | 4 lines
Bug in restore
===============
Can not upload a file, the _POST array is empty, because the post_max_size was too small
................
r2753 | danydb | 2009-12-10 21:05:55 +0100 (Thu, 10 Dec 2009) | 8 lines
Dashboard
=========
Improve Layout : size of comment = 20 char
Follow-up
=========
Set default values
................
r2754 | danydb | 2009-12-10 21:25:05 +0100 (Thu, 10 Dec 2009) | 2 lines
Add the month year in calendar
................
r2755 | danydb | 2009-12-10 21:25:40 +0100 (Thu, 10 Dec 2009) | 2 lines
Calendar : add documentation and fill from todo list
................
r2756 | danydb | 2009-12-11 00:12:15 +0100 (Fri, 11 Dec 2009) | 5 lines
Extension
=========
Add the class
Adapt code and template
................
r2757 | danydb | 2009-12-12 00:38:37 +0100 (Sat, 12 Dec 2009) | 4 lines
Extension
=========
Menu for manage extension
................
r2758 | danydb | 2009-12-12 00:39:27 +0100 (Sat, 12 Dec 2009) | 1 line
add todo : remove plugin
................
r2759 | danydb | 2009-12-15 21:57:19 +0100 (Tue, 15 Dec 2009) | 2 lines
add documentation
................
r2760 | danydb | 2009-12-16 19:54:22 +0100 (Wed, 16 Dec 2009) | 1 line
Extension : add security and item in the menu
................
r2761 | danydb | 2009-12-16 19:58:15 +0100 (Wed, 16 Dec 2009) | 2 lines
typo
................
r2762 | danydb | 2009-12-16 20:05:26 +0100 (Wed, 16 Dec 2009) | 3 lines
Gestion
Add printing
................
r2763 | danydb | 2009-12-16 20:14:13 +0100 (Wed, 16 Dec 2009) | 2 lines
Add prevision to security
................
r2764 | danydb | 2009-12-16 20:14:28 +0100 (Wed, 16 Dec 2009) | 2 lines
Add prevision to security
................
r2765 | danydb | 2009-12-16 20:14:44 +0100 (Wed, 16 Dec 2009) | 2 lines
Add prevision to security
................
r2766 | danydb | 2009-12-16 20:18:22 +0100 (Wed, 16 Dec 2009) | 2 lines
security prevision : mod and consultation
................
r2767 | danydb | 2009-12-16 20:45:24 +0100 (Wed, 16 Dec 2009) | 1 line
Add security for prevision
................
r2768 | danydb | 2009-12-18 20:30:59 +0100 (Fri, 18 Dec 2009) | 1 line
Compatible with IE
................
r2769 | danydb | 2009-12-18 20:36:03 +0100 (Fri, 18 Dec 2009) | 1 line
Remove debug info
................
r2770 | danydb | 2009-12-18 21:00:02 +0100 (Fri, 18 Dec 2009) | 2 lines
remove debug information
................
r2771 | danydb | 2009-12-18 21:03:55 +0100 (Fri, 18 Dec 2009) | 2 lines
Add todo
................
r2772 | danydb | 2009-12-18 21:28:06 +0100 (Fri, 18 Dec 2009) | 1 line
resize todo list and maximize windows when logon
................
r2773 | danydb | 2009-12-23 22:48:59 +0100 (Wed, 23 Dec 2009) | 1 line
Action : Improve location button generate document
................
r2774 | danydb | 2009-12-27 14:26:16 +0100 (Sun, 27 Dec 2009) | 1 line
clean up
................
r2775 | danydb | 2009-12-27 14:26:32 +0100 (Sun, 27 Dec 2009) | 2 lines
cleanup
................
r2776 | danydb | 2009-12-27 19:05:53 +0100 (Sun, 27 Dec 2009) | 1 line
Add Documentation
................
r2777 | danydb | 2009-12-27 19:51:29 +0100 (Sun, 27 Dec 2009) | 1 line
Start Forecast
................
r2778 | danydb | 2009-12-28 02:27:56 +0100 (Mon, 28 Dec 2009) | 1 line
Add the class for managing the tables forecast, forecast_cat and forecast_item
................
r2779 | danydb | 2009-12-30 05:55:38 +0100 (Wed, 30 Dec 2009) | 1 line
Bug : missing the search card popup
................
r2780 | danydb | 2010-01-02 16:48:25 +0100 (Sat, 02 Jan 2010) | 1 line
Code cleaning : remove blank lines
................
r2781 | danydb | 2010-01-02 16:50:20 +0100 (Sat, 02 Jan 2010) | 1 line
Change filename prevision.inc.php by forecast.inc.php
................
r2782 | danydb | 2010-01-02 16:50:53 +0100 (Sat, 02 Jan 2010) | 1 line
remove trailing space
................
r2783 | danydb | 2010-01-02 16:51:28 +0100 (Sat, 02 Jan 2010) | 1 line
remove trailing space
................
r2784 | danydb | 2010-01-02 16:51:54 +0100 (Sat, 02 Jan 2010) | 1 line
remove trailing space
................
r2785 | danydb | 2010-01-02 16:57:19 +0100 (Sat, 02 Jan 2010) | 4 lines
Business Forecast
=================
The BF module is now finished
................
r2786 | danydb | 2010-01-02 16:57:46 +0100 (Sat, 02 Jan 2010) | 4 lines
Business Forecast
=================
The BF module is now finished
................
r2787 | danydb | 2010-01-02 21:46:48 +0100 (Sat, 02 Jan 2010) | 2 lines
Analytic accountancy : fixed bug
Cosmetic bugs
................
r2788 | danydb | 2010-01-02 22:14:56 +0100 (Sat, 02 Jan 2010) | 2 lines
Analytic accountancy : fixed bug
Cosmetic bugs
................
r2789 | danydb | 2010-01-03 00:53:28 +0100 (Sun, 03 Jan 2010) | 1 line
................
r2790 | danydb | 2010-01-03 01:24:42 +0100 (Sun, 03 Jan 2010) | 1 line
Remove files
................
r2791 | danydb | 2010-01-03 01:50:21 +0100 (Sun, 03 Jan 2010) | 5 lines
Class periode :
=============
change id by p_id
................
r2792 | danydb | 2010-01-03 02:03:41 +0100 (Sun, 03 Jan 2010) | 1 line
Ad for firefox
................
r2793 | danydb | 2010-01-03 17:52:58 +0100 (Sun, 03 Jan 2010) | 1 line
Bug : last date was not shown
................
r2794 | danydb | 2010-01-03 17:58:05 +0100 (Sun, 03 Jan 2010) | 1 line
Translate
................
r2795 | danydb | 2010-01-03 18:07:24 +0100 (Sun, 03 Jan 2010) | 1 line
Bug : ISelect
................
r2796 | danydb | 2010-01-03 18:17:41 +0100 (Sun, 03 Jan 2010) | 1 line
Bug : Costing accountancy
................
r2797 | danydb | 2010-01-03 18:23:13 +0100 (Sun, 03 Jan 2010) | 1 line
Fix bug and correct translation
................
r2798 | danydb | 2010-01-04 14:58:51 +0100 (Mon, 04 Jan 2010) | 1 line
Cosmetic bug
................
r2799 | danydb | 2010-01-04 15:37:02 +0100 (Mon, 04 Jan 2010) | 1 line
Cosmetic fix problem button anchor
................
r2800 | danydb | 2010-01-04 19:30:31 +0100 (Mon, 04 Jan 2010) | 2 lines
Update Doc
................
r2801 | danydb | 2010-01-04 19:57:41 +0100 (Mon, 04 Jan 2010) | 2 lines
Fix bug : report : if a FROM clause do not exist (for example from a previous year) then the report failed with a SQL error
................
r2802 | danydb | 2010-01-04 20:11:19 +0100 (Mon, 04 Jan 2010) | 1 line
Code cleaning
................
r2803 | danydb | 2010-01-04 20:11:47 +0100 (Mon, 04 Jan 2010) | 1 line
Change setting for generating doc
................
r2804 | danydb | 2010-01-04 20:12:25 +0100 (Mon, 04 Jan 2010) | 1 line
Code improve + translation
................
r2805 | danydb | 2010-01-06 14:50:09 +0100 (Wed, 06 Jan 2010) | 1 line
Dashboad : add card name in last action
................
r2806 | danydb | 2010-01-06 15:00:06 +0100 (Wed, 06 Jan 2010) | 1 line
Parameter : move Poste to Divers
................
r2807 | danydb | 2010-01-06 15:22:48 +0100 (Wed, 06 Jan 2010) | 4 lines
Parameters
Move Extension from Divers to Main
Move Cat of card from Main to Divers
................
r2808 | danydb | 2010-01-06 18:08:43 +0100 (Wed, 06 Jan 2010) | 1 line
Extension : plugin in the folder ext
................
r2809 | danydb | 2010-01-06 19:16:17 +0100 (Wed, 06 Jan 2010) | 1 line
Plugin : locate into the folder ext
................
r2810 | danydb | 2010-01-06 19:59:55 +0100 (Wed, 06 Jan 2010) | 1 line
CSS : modify button
................
r2811 | danydb | 2010-01-07 18:55:07 +0100 (Thu, 07 Jan 2010) | 2 lines
Cosmetic : quick code in upper case
................
r2812 | danydb | 2010-01-07 19:00:07 +0100 (Thu, 07 Jan 2010) | 2 lines
If there is no document template, then hide the generate button
................
r2813 | danydb | 2010-01-07 19:50:44 +0100 (Thu, 07 Jan 2010) | 2 lines
Cosmetic change TODO
................
r2814 | danydb | 2010-01-07 20:17:33 +0100 (Thu, 07 Jan 2010) | 1 line
set color to todo in the calendar
................
r2815 | danydb | 2010-01-07 20:18:22 +0100 (Thu, 07 Jan 2010) | 1 line
Problem with round
................
r2816 | danydb | 2010-01-07 20:18:37 +0100 (Thu, 07 Jan 2010) | 1 line
set color to todo in the calendar
................
r2817 | danydb | 2010-01-07 20:26:09 +0100 (Thu, 07 Jan 2010) | 2 lines
Opening entries : account is never found
................
r2818 | danydb | 2010-01-07 20:32:42 +0100 (Thu, 07 Jan 2010) | 2 lines
Fix Bug : If the name is empty, we don't go backward to correct the name
................
r2819 | danydb | 2010-01-07 20:36:51 +0100 (Thu, 07 Jan 2010) | 2 lines
Fix Bug: Extension show several times the same user
................
r2820 | danydb | 2010-01-07 20:59:59 +0100 (Thu, 07 Jan 2010) | 1 line
Modify func alert
................
r2821 | danydb | 2010-01-07 21:00:59 +0100 (Thu, 07 Jan 2010) | 1 line
Fix Bug : the extension can be saved with an empty name or code
................
r2822 | danydb | 2010-01-07 21:01:42 +0100 (Thu, 07 Jan 2010) | 2 lines
indent code
................
r2823 | danydb | 2010-01-07 21:18:16 +0100 (Thu, 07 Jan 2010) | 2 lines
Protect against forbidden char (javascript attack)
................
r2824 | danydb | 2010-01-07 21:21:10 +0100 (Thu, 07 Jan 2010) | 1 line
Protect again javascript attack + alert if save extension failed
................
r2825 | danydb | 2010-01-07 21:25:13 +0100 (Thu, 07 Jan 2010) | 2 lines
Protect against javascript attack
................
r2826 | danydb | 2010-01-07 21:32:44 +0100 (Thu, 07 Jan 2010) | 1 line
Protect against forb. char
................
r2827 | danydb | 2010-01-07 22:53:13 +0100 (Thu, 07 Jan 2010) | 1 line
AJAX : add security to ajax file
................
r2828 | danydb | 2010-01-07 22:57:24 +0100 (Thu, 07 Jan 2010) | 2 lines
Cosmetic
................
r2829 | danydb | 2010-01-07 23:11:42 +0100 (Thu, 07 Jan 2010) | 2 lines
Fix Bug : cannot update name of cost accounting
................
r2830 | danydb | 2010-01-07 23:12:52 +0100 (Thu, 07 Jan 2010) | 1 line
Add forgotten file for extension
................
r2831 | danydb | 2010-01-08 14:03:03 +0100 (Fri, 08 Jan 2010) | 1 line
Fix Bug : too many error in the table TVA for France
................
r2832 | danydb | 2010-01-08 14:04:12 +0100 (Fri, 08 Jan 2010) | 1 line
Fix Bug : too many error in the table TVA for France
................
r2833 | danydb | 2010-01-08 14:50:15 +0100 (Fri, 08 Jan 2010) | 1 line
Update Belgium accountancy
................
r2834 | danydb | 2010-01-08 16:53:40 +0100 (Fri, 08 Jan 2010) | 1 line
Improve replace periode by date in print Poste
................
r2835 | danydb | 2010-01-08 19:20:38 +0100 (Fri, 08 Jan 2010) | 2 lines
correct tva_FR
................
r2836 | danydb | 2010-01-08 19:21:11 +0100 (Fri, 08 Jan 2010) | 1 line
Cosmetic CSS
................
r2837 | danydb | 2010-01-08 19:53:12 +0100 (Fri, 08 Jan 2010) | 1 line
fix bug tva_france
................
r2838 | danydb | 2010-01-08 20:11:53 +0100 (Fri, 08 Jan 2010) | 1 line
Correct order for printing accounting
................
r2839 | danydb | 2010-01-08 20:18:18 +0100 (Fri, 08 Jan 2010) | 2 lines
Bug : Printing ledger simple, show always the same line
................
r2840 | danydb | 2010-01-10 15:16:48 +0100 (Sun, 10 Jan 2010) | 1 line
Fix problem accentuated char + view vw_fiche_def
................
r2841 | danydb | 2010-01-10 15:19:19 +0100 (Sun, 10 Jan 2010) | 2 lines
Remove owner SQL command
................
r2842 | danydb | 2010-01-10 15:37:37 +0100 (Sun, 10 Jan 2010) | 1 line
Improve Detail operation : simple
................
r2843 | danydb | 2010-01-11 13:59:49 +0100 (Mon, 11 Jan 2010) | 2 lines
Fix bug : when type an sale and a payment, user gets a warning about unknown variable mt
................
r2844 | danydb | 2010-01-11 14:17:22 +0100 (Mon, 11 Jan 2010) | 2 lines
Fix Bug : double click in "middle of payment" does not work
................
r2845 | danydb | 2010-01-11 14:26:19 +0100 (Mon, 11 Jan 2010) | 1 line
Improve popup detail operation : align amount to right
................
r2846 | danydb | 2010-01-11 18:59:29 +0100 (Mon, 11 Jan 2010) | 1 line
Bug : generate document does not work
................
r2847 | danydb | 2010-01-11 19:25:57 +0100 (Mon, 11 Jan 2010) | 1 line
Bug : after creating an invoice or a fee note, the link does not show the generated document
................
r2848 | danydb | 2010-01-11 19:30:08 +0100 (Mon, 11 Jan 2010) | 1 line
Bug Cosmetic : improve link for Receipt
................
r2849 | danydb | 2010-01-11 19:32:47 +0100 (Mon, 11 Jan 2010) | 1 line
Bug : no security on remove or consult a document
................
r2850 | danydb | 2010-01-11 21:29:32 +0100 (Mon, 11 Jan 2010) | 2 lines
Bug : does not show accounting when po_description is null (costing accounting)
................
r2851 | danydb | 2010-01-12 14:02:32 +0100 (Tue, 12 Jan 2010) | 1 line
Update StyleSheet
................
r2852 | danydb | 2010-01-12 14:16:16 +0100 (Tue, 12 Jan 2010) | 1 line
Update EN translation
................
r2853 | danydb | 2010-01-12 15:14:08 +0100 (Tue, 12 Jan 2010) | 1 line
Remove deprecated functions
................
r2854 | danydb | 2010-01-12 15:43:52 +0100 (Tue, 12 Jan 2010) | 1 line
Complete all the todo
................
r2855 | danydb | 2010-01-12 21:11:45 +0100 (Tue, 12 Jan 2010) | 1 line
Cosmetic : add the calc in ACH + move button, bug in recherche.php, the qcode does not appear after request
................
r2856 | danydb | 2010-01-13 12:16:01 +0100 (Wed, 13 Jan 2010) | 1 line
Dashboard: add the possibility to change the periode
................
r2857 | danydb | 2010-01-13 14:15:45 +0100 (Wed, 13 Jan 2010) | 3 lines
add translation
Fix Bug : The query in follow up does not work when a part of the title was specified
................
4874 lines
137 KiB
JavaScript
4874 lines
137 KiB
JavaScript
/* Prototype JavaScript framework, version 1.6.1
|
|
* (c) 2005-2009 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.1',
|
|
|
|
Browser: (function(){
|
|
var ua = navigator.userAgent;
|
|
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
|
|
return {
|
|
IE: !!window.attachEvent && !isOpera,
|
|
Opera: isOpera,
|
|
WebKit: ua.indexOf('AppleWebKit/') > -1,
|
|
Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
|
|
MobileSafari: /Apple.*Mobile.*Safari/.test(ua)
|
|
}
|
|
})(),
|
|
|
|
BrowserFeatures: {
|
|
XPath: !!document.evaluate,
|
|
SelectorsAPI: !!document.querySelector,
|
|
ElementExtensions: (function() {
|
|
var constructor = window.Element || window.HTMLElement;
|
|
return !!(constructor && constructor.prototype);
|
|
})(),
|
|
SpecificElementExtensions: (function() {
|
|
if (typeof window.HTMLDivElement !== 'undefined')
|
|
return true;
|
|
|
|
var div = document.createElement('div');
|
|
var form = document.createElement('form');
|
|
var isSupported = false;
|
|
|
|
if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
|
|
isSupported = true;
|
|
}
|
|
|
|
div = form = null;
|
|
|
|
return isSupported;
|
|
})()
|
|
},
|
|
|
|
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;
|
|
|
|
|
|
var Abstract = { };
|
|
|
|
|
|
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;
|
|
}
|
|
};
|
|
|
|
/* Based on Alex Arnell's inheritance implementation. */
|
|
|
|
var Class = (function() {
|
|
function subclass() {};
|
|
function create() {
|
|
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) {
|
|
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;
|
|
}
|
|
|
|
function addMethods(source) {
|
|
var ancestor = this.superclass && this.superclass.prototype;
|
|
var properties = Object.keys(source);
|
|
|
|
if (!Object.keys({ toString: true }).length) {
|
|
if (source.toString != Object.prototype.toString)
|
|
properties.push("toString");
|
|
if (source.valueOf != Object.prototype.valueOf)
|
|
properties.push("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 = (function(m) {
|
|
return function() { return ancestor[m].apply(this, arguments); };
|
|
})(property).wrap(method);
|
|
|
|
value.valueOf = method.valueOf.bind(method);
|
|
value.toString = method.toString.bind(method);
|
|
}
|
|
this.prototype[property] = value;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
return {
|
|
create: create,
|
|
Methods: {
|
|
addMethods: addMethods
|
|
}
|
|
};
|
|
})();
|
|
(function() {
|
|
|
|
var _toString = Object.prototype.toString;
|
|
|
|
function extend(destination, source) {
|
|
for (var property in source)
|
|
destination[property] = source[property];
|
|
return destination;
|
|
}
|
|
|
|
function inspect(object) {
|
|
try {
|
|
if (isUndefined(object)) return 'undefined';
|
|
if (object === null) return 'null';
|
|
return object.inspect ? object.inspect() : String(object);
|
|
} catch (e) {
|
|
if (e instanceof RangeError) return '...';
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
function toJSON(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 (isElement(object)) return;
|
|
|
|
var results = [];
|
|
for (var property in object) {
|
|
var value = toJSON(object[property]);
|
|
if (!isUndefined(value))
|
|
results.push(property.toJSON() + ': ' + value);
|
|
}
|
|
|
|
return '{' + results.join(', ') + '}';
|
|
}
|
|
|
|
function toQueryString(object) {
|
|
return $H(object).toQueryString();
|
|
}
|
|
|
|
function toHTML(object) {
|
|
return object && object.toHTML ? object.toHTML() : String.interpret(object);
|
|
}
|
|
|
|
function keys(object) {
|
|
var results = [];
|
|
for (var property in object)
|
|
results.push(property);
|
|
return results;
|
|
}
|
|
|
|
function values(object) {
|
|
var results = [];
|
|
for (var property in object)
|
|
results.push(object[property]);
|
|
return results;
|
|
}
|
|
|
|
function clone(object) {
|
|
return extend({ }, object);
|
|
}
|
|
|
|
function isElement(object) {
|
|
return !!(object && object.nodeType == 1);
|
|
}
|
|
|
|
function isArray(object) {
|
|
return _toString.call(object) == "[object Array]";
|
|
}
|
|
|
|
|
|
function isHash(object) {
|
|
return object instanceof Hash;
|
|
}
|
|
|
|
function isFunction(object) {
|
|
return typeof object === "function";
|
|
}
|
|
|
|
function isString(object) {
|
|
return _toString.call(object) == "[object String]";
|
|
}
|
|
|
|
function isNumber(object) {
|
|
return _toString.call(object) == "[object Number]";
|
|
}
|
|
|
|
function isUndefined(object) {
|
|
return typeof object === "undefined";
|
|
}
|
|
|
|
extend(Object, {
|
|
extend: extend,
|
|
inspect: inspect,
|
|
toJSON: toJSON,
|
|
toQueryString: toQueryString,
|
|
toHTML: toHTML,
|
|
keys: keys,
|
|
values: values,
|
|
clone: clone,
|
|
isElement: isElement,
|
|
isArray: isArray,
|
|
isHash: isHash,
|
|
isFunction: isFunction,
|
|
isString: isString,
|
|
isNumber: isNumber,
|
|
isUndefined: isUndefined
|
|
});
|
|
})();
|
|
Object.extend(Function.prototype, (function() {
|
|
var slice = Array.prototype.slice;
|
|
|
|
function update(array, args) {
|
|
var arrayLength = array.length, length = args.length;
|
|
while (length--) array[arrayLength + length] = args[length];
|
|
return array;
|
|
}
|
|
|
|
function merge(array, args) {
|
|
array = slice.call(array, 0);
|
|
return update(array, args);
|
|
}
|
|
|
|
function argumentNames() {
|
|
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
|
|
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
|
|
.replace(/\s+/g, '').split(',');
|
|
return names.length == 1 && !names[0] ? [] : names;
|
|
}
|
|
|
|
function bind(context) {
|
|
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
|
|
var __method = this, args = slice.call(arguments, 1);
|
|
return function() {
|
|
var a = merge(args, arguments);
|
|
return __method.apply(context, a);
|
|
}
|
|
}
|
|
|
|
function bindAsEventListener(context) {
|
|
var __method = this, args = slice.call(arguments, 1);
|
|
return function(event) {
|
|
var a = update([event || window.event], args);
|
|
return __method.apply(context, a);
|
|
}
|
|
}
|
|
|
|
function curry() {
|
|
if (!arguments.length) return this;
|
|
var __method = this, args = slice.call(arguments, 0);
|
|
return function() {
|
|
var a = merge(args, arguments);
|
|
return __method.apply(this, a);
|
|
}
|
|
}
|
|
|
|
function delay(timeout) {
|
|
var __method = this, args = slice.call(arguments, 1);
|
|
timeout = timeout * 1000
|
|
return window.setTimeout(function() {
|
|
return __method.apply(__method, args);
|
|
}, timeout);
|
|
}
|
|
|
|
function defer() {
|
|
var args = update([0.01], arguments);
|
|
return this.delay.apply(this, args);
|
|
}
|
|
|
|
function wrap(wrapper) {
|
|
var __method = this;
|
|
return function() {
|
|
var a = update([__method.bind(this)], arguments);
|
|
return wrapper.apply(this, a);
|
|
}
|
|
}
|
|
|
|
function methodize() {
|
|
if (this._methodized) return this._methodized;
|
|
var __method = this;
|
|
return this._methodized = function() {
|
|
var a = update([this], arguments);
|
|
return __method.apply(null, a);
|
|
};
|
|
}
|
|
|
|
return {
|
|
argumentNames: argumentNames,
|
|
bind: bind,
|
|
bindAsEventListener: bindAsEventListener,
|
|
curry: curry,
|
|
delay: delay,
|
|
defer: defer,
|
|
wrap: wrap,
|
|
methodize: methodize
|
|
}
|
|
})());
|
|
|
|
|
|
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"';
|
|
};
|
|
|
|
|
|
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();
|
|
this.currentlyExecuting = false;
|
|
} catch(e) {
|
|
this.currentlyExecuting = false;
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
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, (function() {
|
|
|
|
function prepareReplacement(replacement) {
|
|
if (Object.isFunction(replacement)) return replacement;
|
|
var template = new Template(replacement);
|
|
return function(match) { return template.evaluate(match) };
|
|
}
|
|
|
|
function gsub(pattern, replacement) {
|
|
var result = '', source = this, match;
|
|
replacement = prepareReplacement(replacement);
|
|
|
|
if (Object.isString(pattern))
|
|
pattern = RegExp.escape(pattern);
|
|
|
|
if (!(pattern.length || pattern.source)) {
|
|
replacement = replacement('');
|
|
return replacement + source.split('').join(replacement) + 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;
|
|
}
|
|
|
|
function sub(pattern, replacement, count) {
|
|
replacement = prepareReplacement(replacement);
|
|
count = Object.isUndefined(count) ? 1 : count;
|
|
|
|
return this.gsub(pattern, function(match) {
|
|
if (--count < 0) return match[0];
|
|
return replacement(match);
|
|
});
|
|
}
|
|
|
|
function scan(pattern, iterator) {
|
|
this.gsub(pattern, iterator);
|
|
return String(this);
|
|
}
|
|
|
|
function truncate(length, truncation) {
|
|
length = length || 30;
|
|
truncation = Object.isUndefined(truncation) ? '...' : truncation;
|
|
return this.length > length ?
|
|
this.slice(0, length - truncation.length) + truncation : String(this);
|
|
}
|
|
|
|
function strip() {
|
|
return this.replace(/^\s+/, '').replace(/\s+$/, '');
|
|
}
|
|
|
|
function stripTags() {
|
|
return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
|
|
}
|
|
|
|
function stripScripts() {
|
|
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
|
|
}
|
|
|
|
function extractScripts() {
|
|
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];
|
|
});
|
|
}
|
|
|
|
function evalScripts() {
|
|
return this.extractScripts().map(function(script) { return eval(script) });
|
|
}
|
|
|
|
function escapeHTML() {
|
|
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
|
}
|
|
|
|
function unescapeHTML() {
|
|
return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');
|
|
}
|
|
|
|
|
|
function toQueryParams(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;
|
|
});
|
|
}
|
|
|
|
function toArray() {
|
|
return this.split('');
|
|
}
|
|
|
|
function succ() {
|
|
return this.slice(0, this.length - 1) +
|
|
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
|
|
}
|
|
|
|
function times(count) {
|
|
return count < 1 ? '' : new Array(count + 1).join(this);
|
|
}
|
|
|
|
function camelize() {
|
|
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;
|
|
}
|
|
|
|
function capitalize() {
|
|
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
|
|
}
|
|
|
|
function underscore() {
|
|
return this.replace(/::/g, '/')
|
|
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
|
|
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
|
|
.replace(/-/g, '_')
|
|
.toLowerCase();
|
|
}
|
|
|
|
function dasherize() {
|
|
return this.replace(/_/g, '-');
|
|
}
|
|
|
|
function inspect(useDoubleQuotes) {
|
|
var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
|
|
if (character in String.specialChar) {
|
|
return String.specialChar[character];
|
|
}
|
|
return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
|
|
});
|
|
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
|
|
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
|
|
}
|
|
|
|
function toJSON() {
|
|
return this.inspect(true);
|
|
}
|
|
|
|
function unfilterJSON(filter) {
|
|
return this.replace(filter || Prototype.JSONFilter, '$1');
|
|
}
|
|
|
|
function isJSON() {
|
|
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);
|
|
}
|
|
|
|
function evalJSON(sanitize) {
|
|
var json = this.unfilterJSON();
|
|
try {
|
|
if (!sanitize || json.isJSON()) return eval('(' + json + ')');
|
|
} catch (e) { }
|
|
throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
|
|
}
|
|
|
|
function include(pattern) {
|
|
return this.indexOf(pattern) > -1;
|
|
}
|
|
|
|
function startsWith(pattern) {
|
|
return this.indexOf(pattern) === 0;
|
|
}
|
|
|
|
function endsWith(pattern) {
|
|
var d = this.length - pattern.length;
|
|
return d >= 0 && this.lastIndexOf(pattern) === d;
|
|
}
|
|
|
|
function empty() {
|
|
return this == '';
|
|
}
|
|
|
|
function blank() {
|
|
return /^\s*$/.test(this);
|
|
}
|
|
|
|
function interpolate(object, pattern) {
|
|
return new Template(this, pattern).evaluate(object);
|
|
}
|
|
|
|
return {
|
|
gsub: gsub,
|
|
sub: sub,
|
|
scan: scan,
|
|
truncate: truncate,
|
|
strip: String.prototype.trim ? String.prototype.trim : strip,
|
|
stripTags: stripTags,
|
|
stripScripts: stripScripts,
|
|
extractScripts: extractScripts,
|
|
evalScripts: evalScripts,
|
|
escapeHTML: escapeHTML,
|
|
unescapeHTML: unescapeHTML,
|
|
toQueryParams: toQueryParams,
|
|
parseQuery: toQueryParams,
|
|
toArray: toArray,
|
|
succ: succ,
|
|
times: times,
|
|
camelize: camelize,
|
|
capitalize: capitalize,
|
|
underscore: underscore,
|
|
dasherize: dasherize,
|
|
inspect: inspect,
|
|
toJSON: toJSON,
|
|
unfilterJSON: unfilterJSON,
|
|
isJSON: isJSON,
|
|
evalJSON: evalJSON,
|
|
include: include,
|
|
startsWith: startsWith,
|
|
endsWith: endsWith,
|
|
empty: empty,
|
|
blank: blank,
|
|
interpolate: interpolate
|
|
};
|
|
})());
|
|
|
|
var Template = Class.create({
|
|
initialize: function(template, pattern) {
|
|
this.template = template.toString();
|
|
this.pattern = pattern || Template.Pattern;
|
|
},
|
|
|
|
evaluate: function(object) {
|
|
if (object && Object.isFunction(object.toTemplateReplacements))
|
|
object = object.toTemplateReplacements();
|
|
|
|
return this.template.gsub(this.pattern, function(match) {
|
|
if (object == null) return (match[1] + '');
|
|
|
|
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].replace(/\\\\]/g, ']') : 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);
|
|
});
|
|
}
|
|
});
|
|
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
|
|
|
|
var $break = { };
|
|
|
|
var Enumerable = (function() {
|
|
function each(iterator, context) {
|
|
var index = 0;
|
|
try {
|
|
this._each(function(value) {
|
|
iterator.call(context, value, index++);
|
|
});
|
|
} catch (e) {
|
|
if (e != $break) throw e;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
function eachSlice(number, iterator, context) {
|
|
var index = -number, slices = [], array = this.toArray();
|
|
if (number < 1) return array;
|
|
while ((index += number) < array.length)
|
|
slices.push(array.slice(index, index+number));
|
|
return slices.collect(iterator, context);
|
|
}
|
|
|
|
function all(iterator, context) {
|
|
iterator = iterator || Prototype.K;
|
|
var result = true;
|
|
this.each(function(value, index) {
|
|
result = result && !!iterator.call(context, value, index);
|
|
if (!result) throw $break;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
function any(iterator, context) {
|
|
iterator = iterator || Prototype.K;
|
|
var result = false;
|
|
this.each(function(value, index) {
|
|
if (result = !!iterator.call(context, value, index))
|
|
throw $break;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
function collect(iterator, context) {
|
|
iterator = iterator || Prototype.K;
|
|
var results = [];
|
|
this.each(function(value, index) {
|
|
results.push(iterator.call(context, value, index));
|
|
});
|
|
return results;
|
|
}
|
|
|
|
function detect(iterator, context) {
|
|
var result;
|
|
this.each(function(value, index) {
|
|
if (iterator.call(context, value, index)) {
|
|
result = value;
|
|
throw $break;
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
function findAll(iterator, context) {
|
|
var results = [];
|
|
this.each(function(value, index) {
|
|
if (iterator.call(context, value, index))
|
|
results.push(value);
|
|
});
|
|
return results;
|
|
}
|
|
|
|
function grep(filter, iterator, context) {
|
|
iterator = iterator || Prototype.K;
|
|
var results = [];
|
|
|
|
if (Object.isString(filter))
|
|
filter = new RegExp(RegExp.escape(filter));
|
|
|
|
this.each(function(value, index) {
|
|
if (filter.match(value))
|
|
results.push(iterator.call(context, value, index));
|
|
});
|
|
return results;
|
|
}
|
|
|
|
function include(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;
|
|
}
|
|
|
|
function inGroupsOf(number, fillWith) {
|
|
fillWith = Object.isUndefined(fillWith) ? null : fillWith;
|
|
return this.eachSlice(number, function(slice) {
|
|
while(slice.length < number) slice.push(fillWith);
|
|
return slice;
|
|
});
|
|
}
|
|
|
|
function inject(memo, iterator, context) {
|
|
this.each(function(value, index) {
|
|
memo = iterator.call(context, memo, value, index);
|
|
});
|
|
return memo;
|
|
}
|
|
|
|
function invoke(method) {
|
|
var args = $A(arguments).slice(1);
|
|
return this.map(function(value) {
|
|
return value[method].apply(value, args);
|
|
});
|
|
}
|
|
|
|
function max(iterator, context) {
|
|
iterator = iterator || Prototype.K;
|
|
var result;
|
|
this.each(function(value, index) {
|
|
value = iterator.call(context, value, index);
|
|
if (result == null || value >= result)
|
|
result = value;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
function min(iterator, context) {
|
|
iterator = iterator || Prototype.K;
|
|
var result;
|
|
this.each(function(value, index) {
|
|
value = iterator.call(context, value, index);
|
|
if (result == null || value < result)
|
|
result = value;
|
|
});
|
|
return result;
|
|
}
|
|
|
|
function partition(iterator, context) {
|
|
iterator = iterator || Prototype.K;
|
|
var trues = [], falses = [];
|
|
this.each(function(value, index) {
|
|
(iterator.call(context, value, index) ?
|
|
trues : falses).push(value);
|
|
});
|
|
return [trues, falses];
|
|
}
|
|
|
|
function pluck(property) {
|
|
var results = [];
|
|
this.each(function(value) {
|
|
results.push(value[property]);
|
|
});
|
|
return results;
|
|
}
|
|
|
|
function reject(iterator, context) {
|
|
var results = [];
|
|
this.each(function(value, index) {
|
|
if (!iterator.call(context, value, index))
|
|
results.push(value);
|
|
});
|
|
return results;
|
|
}
|
|
|
|
function sortBy(iterator, context) {
|
|
return this.map(function(value, index) {
|
|
return {
|
|
value: value,
|
|
criteria: iterator.call(context, value, index)
|
|
};
|
|
}).sort(function(left, right) {
|
|
var a = left.criteria, b = right.criteria;
|
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
}).pluck('value');
|
|
}
|
|
|
|
function toArray() {
|
|
return this.map();
|
|
}
|
|
|
|
function zip() {
|
|
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));
|
|
});
|
|
}
|
|
|
|
function size() {
|
|
return this.toArray().length;
|
|
}
|
|
|
|
function inspect() {
|
|
return '#<Enumerable:' + this.toArray().inspect() + '>';
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
each: each,
|
|
eachSlice: eachSlice,
|
|
all: all,
|
|
every: all,
|
|
any: any,
|
|
some: any,
|
|
collect: collect,
|
|
map: collect,
|
|
detect: detect,
|
|
findAll: findAll,
|
|
select: findAll,
|
|
filter: findAll,
|
|
grep: grep,
|
|
include: include,
|
|
member: include,
|
|
inGroupsOf: inGroupsOf,
|
|
inject: inject,
|
|
invoke: invoke,
|
|
max: max,
|
|
min: min,
|
|
partition: partition,
|
|
pluck: pluck,
|
|
reject: reject,
|
|
sortBy: sortBy,
|
|
toArray: toArray,
|
|
entries: toArray,
|
|
zip: zip,
|
|
size: size,
|
|
inspect: inspect,
|
|
find: detect
|
|
};
|
|
})();
|
|
function $A(iterable) {
|
|
if (!iterable) return [];
|
|
if ('toArray' in Object(iterable)) return iterable.toArray();
|
|
var length = iterable.length || 0, results = new Array(length);
|
|
while (length--) results[length] = iterable[length];
|
|
return results;
|
|
}
|
|
|
|
function $w(string) {
|
|
if (!Object.isString(string)) return [];
|
|
string = string.strip();
|
|
return string ? string.split(/\s+/) : [];
|
|
}
|
|
|
|
Array.from = $A;
|
|
|
|
|
|
(function() {
|
|
var arrayProto = Array.prototype,
|
|
slice = arrayProto.slice,
|
|
_each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
|
|
|
|
function each(iterator) {
|
|
for (var i = 0, length = this.length; i < length; i++)
|
|
iterator(this[i]);
|
|
}
|
|
if (!_each) _each = each;
|
|
|
|
function clear() {
|
|
this.length = 0;
|
|
return this;
|
|
}
|
|
|
|
function first() {
|
|
return this[0];
|
|
}
|
|
|
|
function last() {
|
|
return this[this.length - 1];
|
|
}
|
|
|
|
function compact() {
|
|
return this.select(function(value) {
|
|
return value != null;
|
|
});
|
|
}
|
|
|
|
function flatten() {
|
|
return this.inject([], function(array, value) {
|
|
if (Object.isArray(value))
|
|
return array.concat(value.flatten());
|
|
array.push(value);
|
|
return array;
|
|
});
|
|
}
|
|
|
|
function without() {
|
|
var values = slice.call(arguments, 0);
|
|
return this.select(function(value) {
|
|
return !values.include(value);
|
|
});
|
|
}
|
|
|
|
function reverse(inline) {
|
|
return (inline !== false ? this : this.toArray())._reverse();
|
|
}
|
|
|
|
function uniq(sorted) {
|
|
return this.inject([], function(array, value, index) {
|
|
if (0 == index || (sorted ? array.last() != value : !array.include(value)))
|
|
array.push(value);
|
|
return array;
|
|
});
|
|
}
|
|
|
|
function intersect(array) {
|
|
return this.uniq().findAll(function(item) {
|
|
return array.detect(function(value) { return item === value });
|
|
});
|
|
}
|
|
|
|
|
|
function clone() {
|
|
return slice.call(this, 0);
|
|
}
|
|
|
|
function size() {
|
|
return this.length;
|
|
}
|
|
|
|
function inspect() {
|
|
return '[' + this.map(Object.inspect).join(', ') + ']';
|
|
}
|
|
|
|
function toJSON() {
|
|
var results = [];
|
|
this.each(function(object) {
|
|
var value = Object.toJSON(object);
|
|
if (!Object.isUndefined(value)) results.push(value);
|
|
});
|
|
return '[' + results.join(', ') + ']';
|
|
}
|
|
|
|
function indexOf(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;
|
|
}
|
|
|
|
function lastIndexOf(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;
|
|
}
|
|
|
|
function concat() {
|
|
var array = slice.call(this, 0), item;
|
|
for (var i = 0, length = arguments.length; i < length; i++) {
|
|
item = arguments[i];
|
|
if (Object.isArray(item) && !('callee' in item)) {
|
|
for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
|
|
array.push(item[j]);
|
|
} else {
|
|
array.push(item);
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
Object.extend(arrayProto, Enumerable);
|
|
|
|
if (!arrayProto._reverse)
|
|
arrayProto._reverse = arrayProto.reverse;
|
|
|
|
Object.extend(arrayProto, {
|
|
_each: _each,
|
|
clear: clear,
|
|
first: first,
|
|
last: last,
|
|
compact: compact,
|
|
flatten: flatten,
|
|
without: without,
|
|
reverse: reverse,
|
|
uniq: uniq,
|
|
intersect: intersect,
|
|
clone: clone,
|
|
toArray: clone,
|
|
size: size,
|
|
inspect: inspect,
|
|
toJSON: toJSON
|
|
});
|
|
|
|
var CONCAT_ARGUMENTS_BUGGY = (function() {
|
|
return [].concat(arguments)[0][0] !== 1;
|
|
})(1,2)
|
|
|
|
if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
|
|
|
|
if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
|
|
if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
|
|
})();
|
|
function $H(object) {
|
|
return new Hash(object);
|
|
};
|
|
|
|
var Hash = Class.create(Enumerable, (function() {
|
|
function initialize(object) {
|
|
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
|
|
}
|
|
|
|
function _each(iterator) {
|
|
for (var key in this._object) {
|
|
var value = this._object[key], pair = [key, value];
|
|
pair.key = key;
|
|
pair.value = value;
|
|
iterator(pair);
|
|
}
|
|
}
|
|
|
|
function set(key, value) {
|
|
return this._object[key] = value;
|
|
}
|
|
|
|
function get(key) {
|
|
if (this._object[key] !== Object.prototype[key])
|
|
return this._object[key];
|
|
}
|
|
|
|
function unset(key) {
|
|
var value = this._object[key];
|
|
delete this._object[key];
|
|
return value;
|
|
}
|
|
|
|
function toObject() {
|
|
return Object.clone(this._object);
|
|
}
|
|
|
|
function keys() {
|
|
return this.pluck('key');
|
|
}
|
|
|
|
function values() {
|
|
return this.pluck('value');
|
|
}
|
|
|
|
function index(value) {
|
|
var match = this.detect(function(pair) {
|
|
return pair.value === value;
|
|
});
|
|
return match && match.key;
|
|
}
|
|
|
|
function merge(object) {
|
|
return this.clone().update(object);
|
|
}
|
|
|
|
function update(object) {
|
|
return new Hash(object).inject(this, function(result, pair) {
|
|
result.set(pair.key, pair.value);
|
|
return result;
|
|
});
|
|
}
|
|
|
|
function toQueryPair(key, value) {
|
|
if (Object.isUndefined(value)) return key;
|
|
return key + '=' + encodeURIComponent(String.interpret(value));
|
|
}
|
|
|
|
function toQueryString() {
|
|
return this.inject([], function(results, pair) {
|
|
var key = encodeURIComponent(pair.key), values = pair.value;
|
|
|
|
if (values && typeof values == 'object') {
|
|
if (Object.isArray(values))
|
|
return results.concat(values.map(toQueryPair.curry(key)));
|
|
} else results.push(toQueryPair(key, values));
|
|
return results;
|
|
}).join('&');
|
|
}
|
|
|
|
function inspect() {
|
|
return '#<Hash:{' + this.map(function(pair) {
|
|
return pair.map(Object.inspect).join(': ');
|
|
}).join(', ') + '}>';
|
|
}
|
|
|
|
function toJSON() {
|
|
return Object.toJSON(this.toObject());
|
|
}
|
|
|
|
function clone() {
|
|
return new Hash(this);
|
|
}
|
|
|
|
return {
|
|
initialize: initialize,
|
|
_each: _each,
|
|
set: set,
|
|
get: get,
|
|
unset: unset,
|
|
toObject: toObject,
|
|
toTemplateReplacements: toObject,
|
|
keys: keys,
|
|
values: values,
|
|
index: index,
|
|
merge: merge,
|
|
update: update,
|
|
toQueryString: toQueryString,
|
|
inspect: inspect,
|
|
toJSON: toJSON,
|
|
clone: clone
|
|
};
|
|
})());
|
|
|
|
Hash.from = $H;
|
|
Object.extend(Number.prototype, (function() {
|
|
function toColorPart() {
|
|
return this.toPaddedString(2, 16);
|
|
}
|
|
|
|
function succ() {
|
|
return this + 1;
|
|
}
|
|
|
|
function times(iterator, context) {
|
|
$R(0, this, true).each(iterator, context);
|
|
return this;
|
|
}
|
|
|
|
function toPaddedString(length, radix) {
|
|
var string = this.toString(radix || 10);
|
|
return '0'.times(length - string.length) + string;
|
|
}
|
|
|
|
function toJSON() {
|
|
return isFinite(this) ? this.toString() : 'null';
|
|
}
|
|
|
|
function abs() {
|
|
return Math.abs(this);
|
|
}
|
|
|
|
function round() {
|
|
return Math.round(this);
|
|
}
|
|
|
|
function ceil() {
|
|
return Math.ceil(this);
|
|
}
|
|
|
|
function floor() {
|
|
return Math.floor(this);
|
|
}
|
|
|
|
return {
|
|
toColorPart: toColorPart,
|
|
succ: succ,
|
|
times: times,
|
|
toPaddedString: toPaddedString,
|
|
toJSON: toJSON,
|
|
abs: abs,
|
|
round: round,
|
|
ceil: ceil,
|
|
floor: floor
|
|
};
|
|
})());
|
|
|
|
function $R(start, end, exclusive) {
|
|
return new ObjectRange(start, end, exclusive);
|
|
}
|
|
|
|
var ObjectRange = Class.create(Enumerable, (function() {
|
|
function initialize(start, end, exclusive) {
|
|
this.start = start;
|
|
this.end = end;
|
|
this.exclusive = exclusive;
|
|
}
|
|
|
|
function _each(iterator) {
|
|
var value = this.start;
|
|
while (this.include(value)) {
|
|
iterator(value);
|
|
value = value.succ();
|
|
}
|
|
}
|
|
|
|
function include(value) {
|
|
if (value < this.start)
|
|
return false;
|
|
if (this.exclusive)
|
|
return value < this.end;
|
|
return value <= this.end;
|
|
}
|
|
|
|
return {
|
|
initialize: initialize,
|
|
_each: _each,
|
|
include: include
|
|
};
|
|
})());
|
|
|
|
|
|
|
|
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)) {
|
|
params['_method'] = this.method;
|
|
this.method = 'post';
|
|
}
|
|
|
|
this.parameters = params;
|
|
|
|
if (params = Object.toQueryString(params)) {
|
|
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';
|
|
}
|
|
|
|
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 && this.isSameOrigin() && 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') {
|
|
this.transport.onreadystatechange = Prototype.emptyFunction;
|
|
}
|
|
},
|
|
|
|
isSameOrigin: function() {
|
|
var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
|
|
return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
|
|
protocol: location.protocol,
|
|
domain: document.domain,
|
|
port: location.port ? ':' + location.port : ''
|
|
}));
|
|
},
|
|
|
|
getHeader: function(name) {
|
|
try {
|
|
return this.transport.getResponseHeader(name) || null;
|
|
} 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 ||
|
|
!this.request.isSameOrigin());
|
|
} 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 ||
|
|
!this.request.isSameOrigin());
|
|
} 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) {
|
|
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(global) {
|
|
|
|
var SETATTRIBUTE_IGNORES_NAME = (function(){
|
|
var elForm = document.createElement("form");
|
|
var elInput = document.createElement("input");
|
|
var root = document.documentElement;
|
|
elInput.setAttribute("name", "test");
|
|
elForm.appendChild(elInput);
|
|
root.appendChild(elForm);
|
|
var isBuggy = elForm.elements
|
|
? (typeof elForm.elements.test == "undefined")
|
|
: null;
|
|
root.removeChild(elForm);
|
|
elForm = elInput = null;
|
|
return isBuggy;
|
|
})();
|
|
|
|
var element = global.Element;
|
|
global.Element = function(tagName, attributes) {
|
|
attributes = attributes || { };
|
|
tagName = tagName.toLowerCase();
|
|
var cache = Element.cache;
|
|
if (SETATTRIBUTE_IGNORES_NAME && 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(global.Element, element || { });
|
|
if (element) global.Element.prototype = element.prototype;
|
|
})(this);
|
|
|
|
Element.cache = { };
|
|
Element.idCounter = 1;
|
|
|
|
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 = $(element);
|
|
element.style.display = 'none';
|
|
return element;
|
|
},
|
|
|
|
show: function(element) {
|
|
element = $(element);
|
|
element.style.display = '';
|
|
return element;
|
|
},
|
|
|
|
remove: function(element) {
|
|
element = $(element);
|
|
element.parentNode.removeChild(element);
|
|
return element;
|
|
},
|
|
|
|
update: (function(){
|
|
|
|
var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
|
|
var el = document.createElement("select"),
|
|
isBuggy = true;
|
|
el.innerHTML = "<option value=\"test\">test</option>";
|
|
if (el.options && el.options[0]) {
|
|
isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
|
|
}
|
|
el = null;
|
|
return isBuggy;
|
|
})();
|
|
|
|
var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
|
|
try {
|
|
var el = document.createElement("table");
|
|
if (el && el.tBodies) {
|
|
el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
|
|
var isBuggy = typeof el.tBodies[0] == "undefined";
|
|
el = null;
|
|
return isBuggy;
|
|
}
|
|
} catch (e) {
|
|
return true;
|
|
}
|
|
})();
|
|
|
|
var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
|
|
var s = document.createElement("script"),
|
|
isBuggy = false;
|
|
try {
|
|
s.appendChild(document.createTextNode(""));
|
|
isBuggy = !s.firstChild ||
|
|
s.firstChild && s.firstChild.nodeType !== 3;
|
|
} catch (e) {
|
|
isBuggy = true;
|
|
}
|
|
s = null;
|
|
return isBuggy;
|
|
})();
|
|
|
|
function update(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 === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
|
|
element.text = content;
|
|
return element;
|
|
}
|
|
|
|
if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
|
|
if (tagName in Element._insertionTranslations.tags) {
|
|
while (element.firstChild) {
|
|
element.removeChild(element.firstChild);
|
|
}
|
|
Element._getContentFromAnonymousElement(tagName, content.stripScripts())
|
|
.each(function(node) {
|
|
element.appendChild(node)
|
|
});
|
|
}
|
|
else {
|
|
element.innerHTML = content.stripScripts();
|
|
}
|
|
}
|
|
else {
|
|
element.innerHTML = content.stripScripts();
|
|
}
|
|
|
|
content.evalScripts.bind(content).defer();
|
|
return element;
|
|
}
|
|
|
|
return update;
|
|
})(),
|
|
|
|
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, insert, tagName, childNodes;
|
|
|
|
for (var position in insertions) {
|
|
content = insertions[position];
|
|
position = position.toLowerCase();
|
|
insert = Element._insertionTranslations[position];
|
|
|
|
if (content && content.toElement) content = content.toElement();
|
|
if (Object.isElement(content)) {
|
|
insert(element, content);
|
|
continue;
|
|
}
|
|
|
|
content = Object.toHTML(content);
|
|
|
|
tagName = ((position == 'before' || position == 'after')
|
|
? element.parentNode : element).tagName.toUpperCase();
|
|
|
|
childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
|
|
|
|
if (position == 'top' || position == 'after') childNodes.reverse();
|
|
childNodes.each(insert.curry(element));
|
|
|
|
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(element, 'parentNode');
|
|
},
|
|
|
|
descendants: function(element) {
|
|
return Element.select(element, "*");
|
|
},
|
|
|
|
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(element, 'previousSibling');
|
|
},
|
|
|
|
nextSiblings: function(element) {
|
|
return Element.recursivelyCollect(element, 'nextSibling');
|
|
},
|
|
|
|
siblings: function(element) {
|
|
element = $(element);
|
|
return Element.previousSiblings(element).reverse()
|
|
.concat(Element.nextSiblings(element));
|
|
},
|
|
|
|
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(element);
|
|
return Object.isNumber(expression) ? ancestors[expression] :
|
|
Selector.findElement(ancestors, expression, index);
|
|
},
|
|
|
|
down: function(element, expression, index) {
|
|
element = $(element);
|
|
if (arguments.length == 1) return Element.firstDescendant(element);
|
|
return Object.isNumber(expression) ? Element.descendants(element)[expression] :
|
|
Element.select(element, expression)[index || 0];
|
|
},
|
|
|
|
previous: function(element, expression, index) {
|
|
element = $(element);
|
|
if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
|
|
var previousSiblings = Element.previousSiblings(element);
|
|
return Object.isNumber(expression) ? previousSiblings[expression] :
|
|
Selector.findElement(previousSiblings, expression, index);
|
|
},
|
|
|
|
next: function(element, expression, index) {
|
|
element = $(element);
|
|
if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
|
|
var nextSiblings = Element.nextSiblings(element);
|
|
return Object.isNumber(expression) ? nextSiblings[expression] :
|
|
Selector.findElement(nextSiblings, expression, index);
|
|
},
|
|
|
|
|
|
select: function(element) {
|
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
return Selector.findChildElements(element, args);
|
|
},
|
|
|
|
adjacent: function(element) {
|
|
var args = Array.prototype.slice.call(arguments, 1);
|
|
return Selector.findChildElements(element.parentNode, args).without(element);
|
|
},
|
|
|
|
identify: function(element) {
|
|
element = $(element);
|
|
var id = Element.readAttribute(element, 'id');
|
|
if (id) return id;
|
|
do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
|
|
Element.writeAttribute(element, '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(element).height;
|
|
},
|
|
|
|
getWidth: function(element) {
|
|
return Element.getDimensions(element).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(element, 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(element, className) ?
|
|
'removeClassName' : 'addClassName'](element, className);
|
|
},
|
|
|
|
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);
|
|
|
|
if (element.compareDocumentPosition)
|
|
return (element.compareDocumentPosition(ancestor) & 8) === 8;
|
|
|
|
if (ancestor.contains)
|
|
return ancestor.contains(element) && ancestor !== element;
|
|
|
|
while (element = element.parentNode)
|
|
if (element == ancestor) return true;
|
|
|
|
return false;
|
|
},
|
|
|
|
scrollTo: function(element) {
|
|
element = $(element);
|
|
var pos = Element.cumulativeOffset(element);
|
|
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 || value == 'auto') {
|
|
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(element, 'display');
|
|
if (display != 'none' && display != null) // Safari bug
|
|
return {width: element.offsetWidth, height: element.offsetHeight};
|
|
|
|
var els = element.style;
|
|
var originalVisibility = els.visibility;
|
|
var originalPosition = els.position;
|
|
var originalDisplay = els.display;
|
|
els.visibility = 'hidden';
|
|
if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
|
|
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';
|
|
if (Prototype.Browser.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.toUpperCase() == 'BODY') break;
|
|
var p = Element.getStyle(element, 'position');
|
|
if (p !== 'static') break;
|
|
}
|
|
} while (element);
|
|
return Element._returnOffset(valueL, valueT);
|
|
},
|
|
|
|
absolutize: function(element) {
|
|
element = $(element);
|
|
if (Element.getStyle(element, 'position') == 'absolute') return element;
|
|
|
|
var offsets = Element.positionedOffset(element);
|
|
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(element, 'position') == 'relative') return element;
|
|
|
|
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;
|
|
|
|
if (element.offsetParent == document.body &&
|
|
Element.getStyle(element, 'position') == 'absolute') break;
|
|
|
|
} while (element = element.offsetParent);
|
|
|
|
element = forElement;
|
|
do {
|
|
if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == '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] || { });
|
|
|
|
source = $(source);
|
|
var p = Element.viewportOffset(source);
|
|
|
|
element = $(element);
|
|
var delta = [0, 0];
|
|
var parent = null;
|
|
if (Element.getStyle(element, 'position') == 'absolute') {
|
|
parent = Element.getOffsetParent(element);
|
|
delta = Element.viewportOffset(parent);
|
|
}
|
|
|
|
if (parent == document.body) {
|
|
delta[0] -= document.body.offsetLeft;
|
|
delta[1] -= document.body.offsetTop;
|
|
}
|
|
|
|
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;
|
|
}
|
|
};
|
|
|
|
Object.extend(Element.Methods, {
|
|
getElementsBySelector: Element.Methods.select,
|
|
|
|
childElements: Element.Methods.immediateDescendants
|
|
});
|
|
|
|
Element._attributeTranslations = {
|
|
write: {
|
|
names: {
|
|
className: 'class',
|
|
htmlFor: 'for'
|
|
},
|
|
values: { }
|
|
}
|
|
};
|
|
|
|
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':
|
|
if (!Element.visible(element)) return null;
|
|
|
|
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) {
|
|
Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
|
|
function(proceed, element) {
|
|
element = $(element);
|
|
try { element.offsetParent }
|
|
catch(e) { return $(document.body) }
|
|
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;
|
|
}
|
|
);
|
|
|
|
$w('positionedOffset viewportOffset').each(function(method) {
|
|
Element.Methods[method] = Element.Methods[method].wrap(
|
|
function(proceed, element) {
|
|
element = $(element);
|
|
try { element.offsetParent }
|
|
catch(e) { return Element._returnOffset(0,0) }
|
|
var position = element.getStyle('position');
|
|
if (position !== 'static') return proceed(element);
|
|
var offsetParent = element.getOffsetParent();
|
|
if (offsetParent && offsetParent.getStyle('position') === 'fixed')
|
|
offsetParent.setStyle({ zoom: 1 });
|
|
element.setStyle({ position: 'relative' });
|
|
var value = proceed(element);
|
|
element.setStyle({ position: position });
|
|
return value;
|
|
}
|
|
);
|
|
});
|
|
|
|
Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
|
|
function(proceed, element) {
|
|
try { element.offsetParent }
|
|
catch(e) { return Element._returnOffset(0,0) }
|
|
return proceed(element);
|
|
}
|
|
);
|
|
|
|
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 = (function(){
|
|
|
|
var classProp = 'className';
|
|
var forProp = 'for';
|
|
|
|
var el = document.createElement('div');
|
|
|
|
el.setAttribute(classProp, 'x');
|
|
|
|
if (el.className !== 'x') {
|
|
el.setAttribute('class', 'x');
|
|
if (el.className === 'x') {
|
|
classProp = 'class';
|
|
}
|
|
}
|
|
el = null;
|
|
|
|
el = document.createElement('label');
|
|
el.setAttribute(forProp, 'x');
|
|
if (el.htmlFor !== 'x') {
|
|
el.setAttribute('htmlFor', 'x');
|
|
if (el.htmlFor === 'x') {
|
|
forProp = 'htmlFor';
|
|
}
|
|
}
|
|
el = null;
|
|
|
|
return {
|
|
read: {
|
|
names: {
|
|
'class': classProp,
|
|
'className': classProp,
|
|
'for': forProp,
|
|
'htmlFor': forProp
|
|
},
|
|
values: {
|
|
_getAttr: function(element, attribute) {
|
|
return element.getAttribute(attribute);
|
|
},
|
|
_getAttr2: function(element, attribute) {
|
|
return element.getAttribute(attribute, 2);
|
|
},
|
|
_getAttrNode: function(element, attribute) {
|
|
var node = element.getAttributeNode(attribute);
|
|
return node ? node.value : "";
|
|
},
|
|
_getEv: (function(){
|
|
|
|
var el = document.createElement('div');
|
|
el.onclick = Prototype.emptyFunction;
|
|
var value = el.getAttribute('onclick');
|
|
var f;
|
|
|
|
if (String(value).indexOf('{') > -1) {
|
|
f = function(element, attribute) {
|
|
attribute = element.getAttribute(attribute);
|
|
if (!attribute) return null;
|
|
attribute = attribute.toString();
|
|
attribute = attribute.split('{')[1];
|
|
attribute = attribute.split('}')[0];
|
|
return attribute.strip();
|
|
};
|
|
}
|
|
else if (value === '') {
|
|
f = function(element, attribute) {
|
|
attribute = element.getAttribute(attribute);
|
|
if (!attribute) return null;
|
|
return attribute.strip();
|
|
};
|
|
}
|
|
el = null;
|
|
return f;
|
|
})(),
|
|
_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.extend({
|
|
cellpadding: 'cellPadding',
|
|
cellspacing: 'cellSpacing'
|
|
}, 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 frameBorder').each(function(attr) {
|
|
Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
|
|
Element._attributeTranslations.has[attr.toLowerCase()] = attr;
|
|
});
|
|
|
|
(function(v) {
|
|
Object.extend(v, {
|
|
href: v._getAttr2,
|
|
src: v._getAttr2,
|
|
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);
|
|
|
|
if (Prototype.BrowserFeatures.ElementExtensions) {
|
|
(function() {
|
|
function _descendants(element) {
|
|
var nodes = element.getElementsByTagName('*'), results = [];
|
|
for (var i = 0, node; node = nodes[i]; i++)
|
|
if (node.tagName !== "!") // Filter out comment nodes.
|
|
results.push(node);
|
|
return results;
|
|
}
|
|
|
|
Element.Methods.down = function(element, expression, index) {
|
|
element = $(element);
|
|
if (arguments.length == 1) return element.firstDescendant();
|
|
return Object.isNumber(expression) ? _descendants(element)[expression] :
|
|
Element.select(element, expression)[index || 0];
|
|
}
|
|
})();
|
|
}
|
|
|
|
}
|
|
|
|
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.toUpperCase() == 'IMG' && element.width) {
|
|
element.width++; element.width--;
|
|
} else try {
|
|
var n = document.createTextNode(' ');
|
|
element.appendChild(n);
|
|
element.removeChild(n);
|
|
} catch (e) { }
|
|
|
|
return element;
|
|
};
|
|
|
|
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 ('outerHTML' in document.documentElement) {
|
|
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];
|
|
if (t) {
|
|
div.innerHTML = t[0] + html + t[1];
|
|
t[2].times(function() { div = div.firstChild });
|
|
} else div.innerHTML = html;
|
|
return $A(div.childNodes);
|
|
};
|
|
|
|
Element._insertionTranslations = {
|
|
before: function(element, node) {
|
|
element.parentNode.insertBefore(node, element);
|
|
},
|
|
top: function(element, node) {
|
|
element.insertBefore(node, element.firstChild);
|
|
},
|
|
bottom: function(element, node) {
|
|
element.appendChild(node);
|
|
},
|
|
after: function(element, node) {
|
|
element.parentNode.insertBefore(node, element.nextSibling);
|
|
},
|
|
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() {
|
|
var tags = Element._insertionTranslations.tags;
|
|
Object.extend(tags, {
|
|
THEAD: tags.TBODY,
|
|
TFOOT: tags.TBODY,
|
|
TH: tags.TD
|
|
});
|
|
})();
|
|
|
|
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);
|
|
|
|
(function(div) {
|
|
|
|
if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
|
|
window.HTMLElement = { };
|
|
window.HTMLElement.prototype = div['__proto__'];
|
|
Prototype.BrowserFeatures.ElementExtensions = true;
|
|
}
|
|
|
|
div = null;
|
|
|
|
})(document.createElement('div'))
|
|
|
|
Element.extend = (function() {
|
|
|
|
function checkDeficiency(tagName) {
|
|
if (typeof window.Element != 'undefined') {
|
|
var proto = window.Element.prototype;
|
|
if (proto) {
|
|
var id = '_' + (Math.random()+'').slice(2);
|
|
var el = document.createElement(tagName);
|
|
proto[id] = 'x';
|
|
var isBuggy = (el[id] !== 'x');
|
|
delete proto[id];
|
|
el = null;
|
|
return isBuggy;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function extendElementWith(element, methods) {
|
|
for (var property in methods) {
|
|
var value = methods[property];
|
|
if (Object.isFunction(value) && !(property in element))
|
|
element[property] = value.methodize();
|
|
}
|
|
}
|
|
|
|
var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
|
|
|
|
if (Prototype.BrowserFeatures.SpecificElementExtensions) {
|
|
if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
|
|
return function(element) {
|
|
if (element && typeof element._extendedByPrototype == 'undefined') {
|
|
var t = element.tagName;
|
|
if (t && (/^(?:object|applet|embed)$/i.test(t))) {
|
|
extendElementWith(element, Element.Methods);
|
|
extendElementWith(element, Element.Methods.Simulated);
|
|
extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
|
|
}
|
|
}
|
|
return element;
|
|
}
|
|
}
|
|
return Prototype.K;
|
|
}
|
|
|
|
var Methods = { }, ByTag = Element.Methods.ByTag;
|
|
|
|
var extend = Object.extend(function(element) {
|
|
if (!element || typeof element._extendedByPrototype != 'undefined' ||
|
|
element.nodeType != 1 || element == window) return element;
|
|
|
|
var methods = Object.clone(Methods),
|
|
tagName = element.tagName.toUpperCase();
|
|
|
|
if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
|
|
|
|
extendElementWith(element, methods);
|
|
|
|
element._extendedByPrototype = Prototype.emptyFunction;
|
|
return element;
|
|
|
|
}, {
|
|
refresh: function() {
|
|
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];
|
|
|
|
var element = document.createElement(tagName);
|
|
var proto = element['__proto__'] || element.constructor.prototype;
|
|
element = null;
|
|
return proto;
|
|
}
|
|
|
|
var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
|
|
Element.prototype;
|
|
|
|
if (F.ElementExtensions) {
|
|
copy(Element.Methods, elementPrototype);
|
|
copy(Element.Methods.Simulated, elementPrototype, 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() {
|
|
return { width: this.getWidth(), height: this.getHeight() };
|
|
},
|
|
|
|
getScrollOffsets: function() {
|
|
return Element._returnOffset(
|
|
window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
|
|
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
|
|
}
|
|
};
|
|
|
|
(function(viewport) {
|
|
var B = Prototype.Browser, doc = document, element, property = {};
|
|
|
|
function getRootElement() {
|
|
if (B.WebKit && !doc.evaluate)
|
|
return document;
|
|
|
|
if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
|
|
return document.body;
|
|
|
|
return document.documentElement;
|
|
}
|
|
|
|
function define(D) {
|
|
if (!element) element = getRootElement();
|
|
|
|
property[D] = 'client' + D;
|
|
|
|
viewport['get' + D] = function() { return element[property[D]] };
|
|
return viewport['get' + D]();
|
|
}
|
|
|
|
viewport.getWidth = define.curry('Width');
|
|
|
|
viewport.getHeight = define.curry('Height');
|
|
})(document.viewport);
|
|
|
|
|
|
Element.Storage = {
|
|
UID: 1
|
|
};
|
|
|
|
Element.addMethods({
|
|
getStorage: function(element) {
|
|
if (!(element = $(element))) return;
|
|
|
|
var uid;
|
|
if (element === window) {
|
|
uid = 0;
|
|
} else {
|
|
if (typeof element._prototypeUID === "undefined")
|
|
element._prototypeUID = [Element.Storage.UID++];
|
|
uid = element._prototypeUID[0];
|
|
}
|
|
|
|
if (!Element.Storage[uid])
|
|
Element.Storage[uid] = $H();
|
|
|
|
return Element.Storage[uid];
|
|
},
|
|
|
|
store: function(element, key, value) {
|
|
if (!(element = $(element))) return;
|
|
|
|
if (arguments.length === 2) {
|
|
Element.getStorage(element).update(key);
|
|
} else {
|
|
Element.getStorage(element).set(key, value);
|
|
}
|
|
|
|
return element;
|
|
},
|
|
|
|
retrieve: function(element, key, defaultValue) {
|
|
if (!(element = $(element))) return;
|
|
var hash = Element.getStorage(element), value = hash.get(key);
|
|
|
|
if (Object.isUndefined(value)) {
|
|
hash.set(key, defaultValue);
|
|
value = defaultValue;
|
|
}
|
|
|
|
return value;
|
|
},
|
|
|
|
clone: function(element, deep) {
|
|
if (!(element = $(element))) return;
|
|
var clone = element.cloneNode(deep);
|
|
clone._prototypeUID = void 0;
|
|
if (deep) {
|
|
var descendants = Element.select(clone, '*'),
|
|
i = descendants.length;
|
|
while (i--) {
|
|
descendants[i]._prototypeUID = void 0;
|
|
}
|
|
}
|
|
return Element.extend(clone);
|
|
}
|
|
});
|
|
/* 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();
|
|
|
|
if (this.shouldUseSelectorsAPI()) {
|
|
this.mode = 'selectorsAPI';
|
|
} else if (this.shouldUseXPath()) {
|
|
this.mode = 'xpath';
|
|
this.compileXPathMatcher();
|
|
} else {
|
|
this.mode = "normal";
|
|
this.compileMatcher();
|
|
}
|
|
|
|
},
|
|
|
|
shouldUseXPath: (function() {
|
|
|
|
var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
|
|
var isBuggy = false;
|
|
if (document.evaluate && window.XPathResult) {
|
|
var el = document.createElement('div');
|
|
el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
|
|
|
|
var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
|
|
"//*[local-name()='li' or local-name()='LI']";
|
|
|
|
var result = document.evaluate(xpath, el, null,
|
|
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
|
|
|
|
isBuggy = (result.snapshotLength !== 2);
|
|
el = null;
|
|
}
|
|
return isBuggy;
|
|
})();
|
|
|
|
return function() {
|
|
if (!Prototype.BrowserFeatures.XPath) return false;
|
|
|
|
var e = this.expression;
|
|
|
|
if (Prototype.Browser.WebKit &&
|
|
(e.include("-of-type") || e.include(":empty")))
|
|
return false;
|
|
|
|
if ((/(\[[\w-]*?:|:checked)/).test(e))
|
|
return false;
|
|
|
|
if (IS_DESCENDANT_SELECTOR_BUGGY) return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
})(),
|
|
|
|
shouldUseSelectorsAPI: function() {
|
|
if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
|
|
|
|
if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false;
|
|
|
|
if (!Selector._div) Selector._div = new Element('div');
|
|
|
|
try {
|
|
Selector._div.querySelector(this.expression);
|
|
} catch(e) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
compileMatcher: function() {
|
|
var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
|
|
c = Selector.criteria, le, p, m, len = ps.length, name;
|
|
|
|
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 = 0; i<len; i++) {
|
|
p = ps[i].re;
|
|
name = ps[i].name;
|
|
if (m = e.match(p)) {
|
|
this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
|
|
new Template(c[name]).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, len = ps.length, name;
|
|
|
|
if (Selector._cache[e]) {
|
|
this.xpath = Selector._cache[e]; return;
|
|
}
|
|
|
|
this.matcher = ['.//*'];
|
|
while (e && le != e && (/\S/).test(e)) {
|
|
le = e;
|
|
for (var i = 0; i<len; i++) {
|
|
name = ps[i].name;
|
|
if (m = e.match(ps[i].re)) {
|
|
this.matcher.push(Object.isFunction(x[name]) ? x[name](m) :
|
|
new Template(x[name]).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;
|
|
var e = this.expression, results;
|
|
|
|
switch (this.mode) {
|
|
case 'selectorsAPI':
|
|
if (root !== document) {
|
|
var oldId = root.id, id = $(root).identify();
|
|
id = id.replace(/([\.:])/g, "\\$1");
|
|
e = "#" + id + " " + e;
|
|
}
|
|
|
|
results = $A(root.querySelectorAll(e)).map(Element.extend);
|
|
root.id = oldId;
|
|
|
|
return results;
|
|
case 'xpath':
|
|
return document._getElementsByXPath(this.xpath, root);
|
|
default:
|
|
return this.matcher(root);
|
|
}
|
|
},
|
|
|
|
match: function(element) {
|
|
this.tokens = [];
|
|
|
|
var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
|
|
var le, p, m, len = ps.length, name;
|
|
|
|
while (e && le !== e && (/\S/).test(e)) {
|
|
le = e;
|
|
for (var i = 0; i<len; i++) {
|
|
p = ps[i].re;
|
|
name = ps[i].name;
|
|
if (m = e.match(p)) {
|
|
if (as[name]) {
|
|
this.tokens.push([name, Object.clone(m)]);
|
|
e = e.replace(m[0], '');
|
|
} else {
|
|
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() + ">";
|
|
}
|
|
});
|
|
|
|
if (Prototype.BrowserFeatures.SelectorsAPI &&
|
|
document.compatMode === 'BackCompat') {
|
|
Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){
|
|
var div = document.createElement('div'),
|
|
span = document.createElement('span');
|
|
|
|
div.id = "prototype_test_id";
|
|
span.className = 'Test';
|
|
div.appendChild(span);
|
|
var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
|
|
div = span = null;
|
|
return isIgnored;
|
|
})();
|
|
}
|
|
|
|
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)]",
|
|
'checked': "[@checked]",
|
|
'disabled': "[(@disabled) and (@type!='hidden')]",
|
|
'enabled': "[not(@disabled) and (@type!='hidden')]",
|
|
'not': function(m) {
|
|
var e = m[6], p = Selector.patterns,
|
|
x = Selector.xpath, le, v, len = p.length, name;
|
|
|
|
var exclusion = [];
|
|
while (e && le != e && (/\S/).test(e)) {
|
|
le = e;
|
|
for (var i = 0; i<len; i++) {
|
|
name = p[i].name
|
|
if (m = e.match(p[i].re)) {
|
|
v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).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); c = false;',
|
|
attr: function(m) {
|
|
m[3] = (m[5] || m[6]);
|
|
return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); 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: [
|
|
{ name: 'laterSibling', re: /^\s*~\s*/ },
|
|
{ name: 'child', re: /^\s*>\s*/ },
|
|
{ name: 'adjacent', re: /^\s*\+\s*/ },
|
|
{ name: 'descendant', re: /^\s/ },
|
|
|
|
{ name: 'tagName', re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
|
|
{ name: 'id', re: /^#([\w\-\*]+)(\b|$)/ },
|
|
{ name: 'className', re: /^\.([\w\-\*]+)(\b|$)/ },
|
|
{ name: 'pseudo', re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
|
|
{ name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ },
|
|
{ name: 'attr', re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
|
|
],
|
|
|
|
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 nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
|
|
}
|
|
},
|
|
|
|
handlers: {
|
|
concat: function(a, b) {
|
|
for (var i = 0, node; node = b[i]; i++)
|
|
a.push(node);
|
|
return a;
|
|
},
|
|
|
|
mark: function(nodes) {
|
|
var _true = Prototype.emptyFunction;
|
|
for (var i = 0, node; node = nodes[i]; i++)
|
|
node._countedByPrototype = _true;
|
|
return nodes;
|
|
},
|
|
|
|
unmark: (function(){
|
|
|
|
var PROPERTIES_ATTRIBUTES_MAP = (function(){
|
|
var el = document.createElement('div'),
|
|
isBuggy = false,
|
|
propName = '_countedByPrototype',
|
|
value = 'x'
|
|
el[propName] = value;
|
|
isBuggy = (el.getAttribute(propName) === value);
|
|
el = null;
|
|
return isBuggy;
|
|
})();
|
|
|
|
return PROPERTIES_ATTRIBUTES_MAP ?
|
|
function(nodes) {
|
|
for (var i = 0, node; node = nodes[i]; i++)
|
|
node.removeAttribute('_countedByPrototype');
|
|
return nodes;
|
|
} :
|
|
function(nodes) {
|
|
for (var i = 0, node; node = nodes[i]; i++)
|
|
node._countedByPrototype = void 0;
|
|
return nodes;
|
|
}
|
|
})(),
|
|
|
|
index: function(parentNode, reverse, ofType) {
|
|
parentNode._countedByPrototype = Prototype.emptyFunction;
|
|
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._countedByPrototype)) node.nodeIndex = j++;
|
|
}
|
|
} else {
|
|
for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
|
|
if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
|
|
}
|
|
},
|
|
|
|
unique: function(nodes) {
|
|
if (nodes.length == 0) return nodes;
|
|
var results = [], n;
|
|
for (var i = 0, l = nodes.length; i < l; i++)
|
|
if (typeof (n = nodes[i])._countedByPrototype == 'undefined') {
|
|
n._countedByPrototype = Prototype.emptyFunction;
|
|
results.push(Element.extend(n));
|
|
}
|
|
return Selector.handlers.unmark(results);
|
|
},
|
|
|
|
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;
|
|
},
|
|
|
|
tagName: function(nodes, root, tagName, combinator) {
|
|
var uTagName = tagName.toUpperCase();
|
|
var results = [], h = Selector.handlers;
|
|
if (nodes) {
|
|
if (combinator) {
|
|
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() === uTagName) results.push(node);
|
|
return results;
|
|
} else return root.getElementsByTagName(tagName);
|
|
},
|
|
|
|
id: function(nodes, root, id, combinator) {
|
|
var targetNode = $(id), h = Selector.handlers;
|
|
|
|
if (root == document) {
|
|
if (!targetNode) return [];
|
|
if (!nodes) return [targetNode];
|
|
} else {
|
|
if (!root.sourceIndex || root.sourceIndex < 1) {
|
|
var nodes = root.getElementsByTagName('*');
|
|
for (var j = 0, node; node = nodes[j]; j++) {
|
|
if (node.id === id) return [node];
|
|
}
|
|
}
|
|
}
|
|
|
|
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, combinator) {
|
|
if (!nodes) nodes = root.getElementsByTagName("*");
|
|
if (nodes && combinator) nodes = this[combinator](nodes);
|
|
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, combinator) {
|
|
if (!nodes) nodes = root.getElementsByTagName("*");
|
|
if (nodes && combinator) nodes = this[combinator](nodes);
|
|
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);
|
|
},
|
|
|
|
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;
|
|
});
|
|
},
|
|
|
|
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._countedByPrototype) {
|
|
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++) {
|
|
if (node.tagName == '!' || node.firstChild) 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._countedByPrototype) 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 && (!node.type || node.type !== 'hidden'))
|
|
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 == v || nv && nv.startsWith(v); },
|
|
'$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
|
|
'*=': function(nv, v) { return nv == v || nv && nv.include(v); },
|
|
'~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
|
|
'|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
|
|
'-').include('-' + (v || "").toUpperCase() + '-'); }
|
|
},
|
|
|
|
split: function(expression) {
|
|
var expressions = [];
|
|
expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
|
|
expressions.push(m[1].strip());
|
|
});
|
|
return expressions;
|
|
},
|
|
|
|
matchElements: function(elements, expression) {
|
|
var matches = $$(expression), h = Selector.handlers;
|
|
h.mark(matches);
|
|
for (var i = 0, results = [], element; element = elements[i]; i++)
|
|
if (element._countedByPrototype) 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) {
|
|
expressions = Selector.split(expressions.join(','));
|
|
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) {
|
|
Object.extend(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 = $(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 != 'file' && (element.type != 'submit' || (!submitted &&
|
|
submit !== false && (!submit || key == submit) && (submitted = true)))) {
|
|
if (key in result) {
|
|
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) {
|
|
var elements = $(form).getElementsByTagName('*'),
|
|
element,
|
|
arr = [ ],
|
|
serializers = Form.Element.Serializers;
|
|
for (var i = 0; element = elements[i]; i++) {
|
|
arr.push(element);
|
|
}
|
|
return arr.inject([], function(elements, child) {
|
|
if (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)$/i.test(element.tagName);
|
|
});
|
|
},
|
|
|
|
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)$/i.test(element.type))))
|
|
element.select();
|
|
} catch (e) { }
|
|
return element;
|
|
},
|
|
|
|
disable: function(element) {
|
|
element = $(element);
|
|
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, value) {
|
|
if (Object.isUndefined(value))
|
|
return this[element.type == 'select-one' ?
|
|
'selectOne' : 'selectMany'](element);
|
|
else {
|
|
var opt, currentValue, single = !Object.isArray(value);
|
|
for (var i = 0, length = element.length; i < length; i++) {
|
|
opt = element.options[i];
|
|
currentValue = this.optionValue(opt);
|
|
if (single) {
|
|
if (currentValue == value) {
|
|
opt.selected = true;
|
|
return;
|
|
}
|
|
}
|
|
else opt.selected = value.include(currentValue);
|
|
}
|
|
}
|
|
},
|
|
|
|
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) {
|
|
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);
|
|
}
|
|
});
|
|
(function() {
|
|
|
|
var 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: {}
|
|
};
|
|
|
|
var docEl = document.documentElement;
|
|
var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
|
|
&& 'onmouseleave' in docEl;
|
|
|
|
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);
|
|
};
|
|
}
|
|
|
|
function isLeftClick(event) { return _isButton(event, 0) }
|
|
|
|
function isMiddleClick(event) { return _isButton(event, 1) }
|
|
|
|
function isRightClick(event) { return _isButton(event, 2) }
|
|
|
|
function element(event) {
|
|
event = Event.extend(event);
|
|
|
|
var node = event.target, type = event.type,
|
|
currentTarget = event.currentTarget;
|
|
|
|
if (currentTarget && currentTarget.tagName) {
|
|
if (type === 'load' || type === 'error' ||
|
|
(type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
|
|
&& currentTarget.type === 'radio'))
|
|
node = currentTarget;
|
|
}
|
|
|
|
if (node.nodeType == Node.TEXT_NODE)
|
|
node = node.parentNode;
|
|
|
|
return Element.extend(node);
|
|
}
|
|
|
|
function findElement(event, expression) {
|
|
var element = Event.element(event);
|
|
if (!expression) return element;
|
|
var elements = [element].concat(element.ancestors());
|
|
return Selector.findElement(elements, expression, 0);
|
|
}
|
|
|
|
function pointer(event) {
|
|
return { x: pointerX(event), y: pointerY(event) };
|
|
}
|
|
|
|
function pointerX(event) {
|
|
var docElement = document.documentElement,
|
|
body = document.body || { scrollLeft: 0 };
|
|
|
|
return event.pageX || (event.clientX +
|
|
(docElement.scrollLeft || body.scrollLeft) -
|
|
(docElement.clientLeft || 0));
|
|
}
|
|
|
|
function pointerY(event) {
|
|
var docElement = document.documentElement,
|
|
body = document.body || { scrollTop: 0 };
|
|
|
|
return event.pageY || (event.clientY +
|
|
(docElement.scrollTop || body.scrollTop) -
|
|
(docElement.clientTop || 0));
|
|
}
|
|
|
|
|
|
function stop(event) {
|
|
Event.extend(event);
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
event.stopped = true;
|
|
}
|
|
|
|
Event.Methods = {
|
|
isLeftClick: isLeftClick,
|
|
isMiddleClick: isMiddleClick,
|
|
isRightClick: isRightClick,
|
|
|
|
element: element,
|
|
findElement: findElement,
|
|
|
|
pointer: pointer,
|
|
pointerX: pointerX,
|
|
pointerY: pointerY,
|
|
|
|
stop: stop
|
|
};
|
|
|
|
|
|
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
|
|
m[name] = Event.Methods[name].methodize();
|
|
return m;
|
|
});
|
|
|
|
if (Prototype.Browser.IE) {
|
|
function _relatedTarget(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);
|
|
}
|
|
|
|
Object.extend(methods, {
|
|
stopPropagation: function() { this.cancelBubble = true },
|
|
preventDefault: function() { this.returnValue = false },
|
|
inspect: function() { return '[object Event]' }
|
|
});
|
|
|
|
Event.extend = function(event, element) {
|
|
if (!event) return false;
|
|
if (event._extendedByPrototype) return event;
|
|
|
|
event._extendedByPrototype = Prototype.emptyFunction;
|
|
var pointer = Event.pointer(event);
|
|
|
|
Object.extend(event, {
|
|
target: event.srcElement || element,
|
|
relatedTarget: _relatedTarget(event),
|
|
pageX: pointer.x,
|
|
pageY: pointer.y
|
|
});
|
|
|
|
return Object.extend(event, methods);
|
|
};
|
|
} else {
|
|
Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
|
|
Object.extend(Event.prototype, methods);
|
|
Event.extend = Prototype.K;
|
|
}
|
|
|
|
function _createResponder(element, eventName, handler) {
|
|
var registry = Element.retrieve(element, 'prototype_event_registry');
|
|
|
|
if (Object.isUndefined(registry)) {
|
|
CACHE.push(element);
|
|
registry = Element.retrieve(element, 'prototype_event_registry', $H());
|
|
}
|
|
|
|
var respondersForEvent = registry.get(eventName);
|
|
if (Object.isUndefined(respondersForEvent)) {
|
|
respondersForEvent = [];
|
|
registry.set(eventName, respondersForEvent);
|
|
}
|
|
|
|
if (respondersForEvent.pluck('handler').include(handler)) return false;
|
|
|
|
var responder;
|
|
if (eventName.include(":")) {
|
|
responder = function(event) {
|
|
if (Object.isUndefined(event.eventName))
|
|
return false;
|
|
|
|
if (event.eventName !== eventName)
|
|
return false;
|
|
|
|
Event.extend(event, element);
|
|
handler.call(element, event);
|
|
};
|
|
} else {
|
|
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
|
|
(eventName === "mouseenter" || eventName === "mouseleave")) {
|
|
if (eventName === "mouseenter" || eventName === "mouseleave") {
|
|
responder = function(event) {
|
|
Event.extend(event, element);
|
|
|
|
var parent = event.relatedTarget;
|
|
while (parent && parent !== element) {
|
|
try { parent = parent.parentNode; }
|
|
catch(e) { parent = element; }
|
|
}
|
|
|
|
if (parent === element) return;
|
|
|
|
handler.call(element, event);
|
|
};
|
|
}
|
|
} else {
|
|
responder = function(event) {
|
|
Event.extend(event, element);
|
|
handler.call(element, event);
|
|
};
|
|
}
|
|
}
|
|
|
|
responder.handler = handler;
|
|
respondersForEvent.push(responder);
|
|
return responder;
|
|
}
|
|
|
|
function _destroyCache() {
|
|
for (var i = 0, length = CACHE.length; i < length; i++) {
|
|
Event.stopObserving(CACHE[i]);
|
|
CACHE[i] = null;
|
|
}
|
|
}
|
|
|
|
var CACHE = [];
|
|
|
|
if (Prototype.Browser.IE)
|
|
window.attachEvent('onunload', _destroyCache);
|
|
|
|
if (Prototype.Browser.WebKit)
|
|
window.addEventListener('unload', Prototype.emptyFunction, false);
|
|
|
|
|
|
var _getDOMEventName = Prototype.K;
|
|
|
|
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
|
|
_getDOMEventName = function(eventName) {
|
|
var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
|
|
return eventName in translations ? translations[eventName] : eventName;
|
|
};
|
|
}
|
|
|
|
function observe(element, eventName, handler) {
|
|
element = $(element);
|
|
|
|
var responder = _createResponder(element, eventName, handler);
|
|
|
|
if (!responder) return element;
|
|
|
|
if (eventName.include(':')) {
|
|
if (element.addEventListener)
|
|
element.addEventListener("dataavailable", responder, false);
|
|
else {
|
|
element.attachEvent("ondataavailable", responder);
|
|
element.attachEvent("onfilterchange", responder);
|
|
}
|
|
} else {
|
|
var actualEventName = _getDOMEventName(eventName);
|
|
|
|
if (element.addEventListener)
|
|
element.addEventListener(actualEventName, responder, false);
|
|
else
|
|
element.attachEvent("on" + actualEventName, responder);
|
|
}
|
|
|
|
return element;
|
|
}
|
|
|
|
function stopObserving(element, eventName, handler) {
|
|
element = $(element);
|
|
|
|
var registry = Element.retrieve(element, 'prototype_event_registry');
|
|
|
|
if (Object.isUndefined(registry)) return element;
|
|
|
|
if (eventName && !handler) {
|
|
var responders = registry.get(eventName);
|
|
|
|
if (Object.isUndefined(responders)) return element;
|
|
|
|
responders.each( function(r) {
|
|
Element.stopObserving(element, eventName, r.handler);
|
|
});
|
|
return element;
|
|
} else if (!eventName) {
|
|
registry.each( function(pair) {
|
|
var eventName = pair.key, responders = pair.value;
|
|
|
|
responders.each( function(r) {
|
|
Element.stopObserving(element, eventName, r.handler);
|
|
});
|
|
});
|
|
return element;
|
|
}
|
|
|
|
var responders = registry.get(eventName);
|
|
|
|
if (!responders) return;
|
|
|
|
var responder = responders.find( function(r) { return r.handler === handler; });
|
|
if (!responder) return element;
|
|
|
|
var actualEventName = _getDOMEventName(eventName);
|
|
|
|
if (eventName.include(':')) {
|
|
if (element.removeEventListener)
|
|
element.removeEventListener("dataavailable", responder, false);
|
|
else {
|
|
element.detachEvent("ondataavailable", responder);
|
|
element.detachEvent("onfilterchange", responder);
|
|
}
|
|
} else {
|
|
if (element.removeEventListener)
|
|
element.removeEventListener(actualEventName, responder, false);
|
|
else
|
|
element.detachEvent('on' + actualEventName, responder);
|
|
}
|
|
|
|
registry.set(eventName, responders.without(responder));
|
|
|
|
return element;
|
|
}
|
|
|
|
function fire(element, eventName, memo, bubble) {
|
|
element = $(element);
|
|
|
|
if (Object.isUndefined(bubble))
|
|
bubble = true;
|
|
|
|
if (element == document && document.createEvent && !element.dispatchEvent)
|
|
element = document.documentElement;
|
|
|
|
var event;
|
|
if (document.createEvent) {
|
|
event = document.createEvent('HTMLEvents');
|
|
event.initEvent('dataavailable', true, true);
|
|
} else {
|
|
event = document.createEventObject();
|
|
event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
|
|
}
|
|
|
|
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);
|
|
|
|
Object.extend(Event, {
|
|
fire: fire,
|
|
observe: observe,
|
|
stopObserving: stopObserving
|
|
});
|
|
|
|
Element.addMethods({
|
|
fire: fire,
|
|
|
|
observe: observe,
|
|
|
|
stopObserving: stopObserving
|
|
});
|
|
|
|
Object.extend(document, {
|
|
fire: fire.methodize(),
|
|
|
|
observe: observe.methodize(),
|
|
|
|
stopObserving: stopObserving.methodize(),
|
|
|
|
loaded: false
|
|
});
|
|
|
|
if (window.Event) Object.extend(window.Event, Event);
|
|
else window.Event = Event;
|
|
})();
|
|
|
|
(function() {
|
|
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
|
|
Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
|
|
|
|
var timer;
|
|
|
|
function fireContentLoadedEvent() {
|
|
if (document.loaded) return;
|
|
if (timer) window.clearTimeout(timer);
|
|
document.loaded = true;
|
|
document.fire('dom:loaded');
|
|
}
|
|
|
|
function checkReadyState() {
|
|
if (document.readyState === 'complete') {
|
|
document.stopObserving('readystatechange', checkReadyState);
|
|
fireContentLoadedEvent();
|
|
}
|
|
}
|
|
|
|
function pollDoScroll() {
|
|
try { document.documentElement.doScroll('left'); }
|
|
catch(e) {
|
|
timer = pollDoScroll.defer();
|
|
return;
|
|
}
|
|
fireContentLoadedEvent();
|
|
}
|
|
|
|
if (document.addEventListener) {
|
|
document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
|
|
} else {
|
|
document.observe('readystatechange', checkReadyState);
|
|
if (window == top)
|
|
timer = pollDoScroll.defer();
|
|
}
|
|
|
|
Event.observe(window, 'load', fireContentLoadedEvent);
|
|
})();
|
|
|
|
Element.addMethods();
|
|
|
|
/*------------------------------- 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');
|
|
|
|
var Position = {
|
|
includeScrollOffsets: false,
|
|
|
|
prepare: function() {
|
|
this.deltaX = window.pageXOffset
|
|
|| document.documentElement.scrollLeft
|
|
|| document.body.scrollLeft
|
|
|| 0;
|
|
this.deltaY = window.pageYOffset
|
|
|| document.documentElement.scrollTop
|
|
|| document.body.scrollTop
|
|
|| 0;
|
|
},
|
|
|
|
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);
|
|
},
|
|
|
|
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;
|
|
},
|
|
|
|
|
|
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);
|
|
|
|
/*--------------------------------------------------------------------------*/
|