diff --git a/UI/Contacts/Images/delete.png b/UI/Contacts/Images/delete.png deleted file mode 100644 index 3abba4ceb..000000000 Binary files a/UI/Contacts/Images/delete.png and /dev/null differ diff --git a/UI/MailerUI/Images/COPYING b/UI/MailerUI/Images/COPYING deleted file mode 100644 index 74925c7d0..000000000 --- a/UI/MailerUI/Images/COPYING +++ /dev/null @@ -1,5 +0,0 @@ -The default theme icons are derived from the icons provided as -part of the Mozilla Thunderbird application. -The licensing terms of Mozilla Thunderbird are available in the -LICENSE-thunderbird.txt file. - diff --git a/UI/MailerUI/Images/LICENSE-thunderbird.txt b/UI/MailerUI/Images/LICENSE-thunderbird.txt deleted file mode 100644 index 18f8109b7..000000000 --- a/UI/MailerUI/Images/LICENSE-thunderbird.txt +++ /dev/null @@ -1,567 +0,0 @@ - MOZILLA PUBLIC LICENSE - Version 1.1 - - --------------- - -1. Definitions. - - 1.0.1. "Commercial Use" means distribution or otherwise making the - Covered Code available to a third party. - - 1.1. "Contributor" means each entity that creates or contributes to - the creation of Modifications. - - 1.2. "Contributor Version" means the combination of the Original - Code, prior Modifications used by a Contributor, and the Modifications - made by that particular Contributor. - - 1.3. "Covered Code" means the Original Code or Modifications or the - combination of the Original Code and Modifications, in each case - including portions thereof. - - 1.4. "Electronic Distribution Mechanism" means a mechanism generally - accepted in the software development community for the electronic - transfer of data. - - 1.5. "Executable" means Covered Code in any form other than Source - Code. - - 1.6. "Initial Developer" means the individual or entity identified - as the Initial Developer in the Source Code notice required by Exhibit - A. - - 1.7. "Larger Work" means a work which combines Covered Code or - portions thereof with code not governed by the terms of this License. - - 1.8. "License" means this document. - - 1.8.1. "Licensable" means having the right to grant, to the maximum - extent possible, whether at the time of the initial grant or - subsequently acquired, any and all of the rights conveyed herein. - - 1.9. "Modifications" means any addition to or deletion from the - substance or structure of either the Original Code or any previous - Modifications. When Covered Code is released as a series of files, a - Modification is: - A. Any addition to or deletion from the contents of a file - containing Original Code or previous Modifications. - - B. Any new file that contains any part of the Original Code or - previous Modifications. - - 1.10. "Original Code" means Source Code of computer software code - which is described in the Source Code notice required by Exhibit A as - Original Code, and which, at the time of its release under this - License is not already Covered Code governed by this License. - - 1.10.1. "Patent Claims" means any patent claim(s), now owned or - hereafter acquired, including without limitation, method, process, - and apparatus claims, in any patent Licensable by grantor. - - 1.11. "Source Code" means the preferred form of the Covered Code for - making modifications to it, including all modules it contains, plus - any associated interface definition files, scripts used to control - compilation and installation of an Executable, or source code - differential comparisons against either the Original Code or another - well known, available Covered Code of the Contributor's choice. The - Source Code can be in a compressed or archival form, provided the - appropriate decompression or de-archiving software is widely available - for no charge. - - 1.12. "You" (or "Your") means an individual or a legal entity - exercising rights under, and complying with all of the terms of, this - License or a future version of this License issued under Section 6.1. - For legal entities, "You" includes any entity which controls, is - controlled by, or is under common control with You. For purposes of - this definition, "control" means (a) the power, direct or indirect, - to cause the direction or management of such entity, whether by - contract or otherwise, or (b) ownership of more than fifty percent - (50%) of the outstanding shares or beneficial ownership of such - entity. - -2. Source Code License. - - 2.1. The Initial Developer Grant. - The Initial Developer hereby grants You a world-wide, royalty-free, - non-exclusive license, subject to third party intellectual property - claims: - (a) under intellectual property rights (other than patent or - trademark) Licensable by Initial Developer to use, reproduce, - modify, display, perform, sublicense and distribute the Original - Code (or portions thereof) with or without Modifications, and/or - as part of a Larger Work; and - - (b) under Patents Claims infringed by the making, using or - selling of Original Code, to make, have made, use, practice, - sell, and offer for sale, and/or otherwise dispose of the - Original Code (or portions thereof). - - (c) the licenses granted in this Section 2.1(a) and (b) are - effective on the date Initial Developer first distributes - Original Code under the terms of this License. - - (d) Notwithstanding Section 2.1(b) above, no patent license is - granted: 1) for code that You delete from the Original Code; 2) - separate from the Original Code; or 3) for infringements caused - by: i) the modification of the Original Code or ii) the - combination of the Original Code with other software or devices. - - 2.2. Contributor Grant. - Subject to third party intellectual property claims, each Contributor - hereby grants You a world-wide, royalty-free, non-exclusive license - - (a) under intellectual property rights (other than patent or - trademark) Licensable by Contributor, to use, reproduce, modify, - display, perform, sublicense and distribute the Modifications - created by such Contributor (or portions thereof) either on an - unmodified basis, with other Modifications, as Covered Code - and/or as part of a Larger Work; and - - (b) under Patent Claims infringed by the making, using, or - selling of Modifications made by that Contributor either alone - and/or in combination with its Contributor Version (or portions - of such combination), to make, use, sell, offer for sale, have - made, and/or otherwise dispose of: 1) Modifications made by that - Contributor (or portions thereof); and 2) the combination of - Modifications made by that Contributor with its Contributor - Version (or portions of such combination). - - (c) the licenses granted in Sections 2.2(a) and 2.2(b) are - effective on the date Contributor first makes Commercial Use of - the Covered Code. - - (d) Notwithstanding Section 2.2(b) above, no patent license is - granted: 1) for any code that Contributor has deleted from the - Contributor Version; 2) separate from the Contributor Version; - 3) for infringements caused by: i) third party modifications of - Contributor Version or ii) the combination of Modifications made - by that Contributor with other software (except as part of the - Contributor Version) or other devices; or 4) under Patent Claims - infringed by Covered Code in the absence of Modifications made by - that Contributor. - -3. Distribution Obligations. - - 3.1. Application of License. - The Modifications which You create or to which You contribute are - governed by the terms of this License, including without limitation - Section 2.2. The Source Code version of Covered Code may be - distributed only under the terms of this License or a future version - of this License released under Section 6.1, and You must include a - copy of this License with every copy of the Source Code You - distribute. You may not offer or impose any terms on any Source Code - version that alters or restricts the applicable version of this - License or the recipients' rights hereunder. However, You may include - an additional document offering the additional rights described in - Section 3.5. - - 3.2. Availability of Source Code. - Any Modification which You create or to which You contribute must be - made available in Source Code form under the terms of this License - either on the same media as an Executable version or via an accepted - Electronic Distribution Mechanism to anyone to whom you made an - Executable version available; and if made available via Electronic - Distribution Mechanism, must remain available for at least twelve (12) - months after the date it initially became available, or at least six - (6) months after a subsequent version of that particular Modification - has been made available to such recipients. You are responsible for - ensuring that the Source Code version remains available even if the - Electronic Distribution Mechanism is maintained by a third party. - - 3.3. Description of Modifications. - You must cause all Covered Code to which You contribute to contain a - file documenting the changes You made to create that Covered Code and - the date of any change. You must include a prominent statement that - the Modification is derived, directly or indirectly, from Original - Code provided by the Initial Developer and including the name of the - Initial Developer in (a) the Source Code, and (b) in any notice in an - Executable version or related documentation in which You describe the - origin or ownership of the Covered Code. - - 3.4. Intellectual Property Matters - (a) Third Party Claims. - If Contributor has knowledge that a license under a third party's - intellectual property rights is required to exercise the rights - granted by such Contributor under Sections 2.1 or 2.2, - Contributor must include a text file with the Source Code - distribution titled "LEGAL" which describes the claim and the - party making the claim in sufficient detail that a recipient will - know whom to contact. If Contributor obtains such knowledge after - the Modification is made available as described in Section 3.2, - Contributor shall promptly modify the LEGAL file in all copies - Contributor makes available thereafter and shall take other steps - (such as notifying appropriate mailing lists or newsgroups) - reasonably calculated to inform those who received the Covered - Code that new knowledge has been obtained. - - (b) Contributor APIs. - If Contributor's Modifications include an application programming - interface and Contributor has knowledge of patent licenses which - are reasonably necessary to implement that API, Contributor must - also include this information in the LEGAL file. - - (c) Representations. - Contributor represents that, except as disclosed pursuant to - Section 3.4(a) above, Contributor believes that Contributor's - Modifications are Contributor's original creation(s) and/or - Contributor has sufficient rights to grant the rights conveyed by - this License. - - 3.5. Required Notices. - You must duplicate the notice in Exhibit A in each file of the Source - Code. If it is not possible to put such notice in a particular Source - Code file due to its structure, then You must include such notice in a - location (such as a relevant directory) where a user would be likely - to look for such a notice. If You created one or more Modification(s) - You may add your name as a Contributor to the notice described in - Exhibit A. You must also duplicate this License in any documentation - for the Source Code where You describe recipients' rights or ownership - rights relating to Covered Code. You may choose to offer, and to - charge a fee for, warranty, support, indemnity or liability - obligations to one or more recipients of Covered Code. However, You - may do so only on Your own behalf, and not on behalf of the Initial - Developer or any Contributor. You must make it absolutely clear than - any such warranty, support, indemnity or liability obligation is - offered by You alone, and You hereby agree to indemnify the Initial - Developer and every Contributor for any liability incurred by the - Initial Developer or such Contributor as a result of warranty, - support, indemnity or liability terms You offer. - - 3.6. Distribution of Executable Versions. - You may distribute Covered Code in Executable form only if the - requirements of Section 3.1-3.5 have been met for that Covered Code, - and if You include a notice stating that the Source Code version of - the Covered Code is available under the terms of this License, - including a description of how and where You have fulfilled the - obligations of Section 3.2. The notice must be conspicuously included - in any notice in an Executable version, related documentation or - collateral in which You describe recipients' rights relating to the - Covered Code. You may distribute the Executable version of Covered - Code or ownership rights under a license of Your choice, which may - contain terms different from this License, provided that You are in - compliance with the terms of this License and that the license for the - Executable version does not attempt to limit or alter the recipient's - rights in the Source Code version from the rights set forth in this - License. If You distribute the Executable version under a different - license You must make it absolutely clear that any terms which differ - from this License are offered by You alone, not by the Initial - Developer or any Contributor. You hereby agree to indemnify the - Initial Developer and every Contributor for any liability incurred by - the Initial Developer or such Contributor as a result of any such - terms You offer. - - 3.7. Larger Works. - You may create a Larger Work by combining Covered Code with other code - not governed by the terms of this License and distribute the Larger - Work as a single product. In such a case, You must make sure the - requirements of this License are fulfilled for the Covered Code. - -4. Inability to Comply Due to Statute or Regulation. - - If it is impossible for You to comply with any of the terms of this - License with respect to some or all of the Covered Code due to - statute, judicial order, or regulation then You must: (a) comply with - the terms of this License to the maximum extent possible; and (b) - describe the limitations and the code they affect. Such description - must be included in the LEGAL file described in Section 3.4 and must - be included with all distributions of the Source Code. Except to the - extent prohibited by statute or regulation, such description must be - sufficiently detailed for a recipient of ordinary skill to be able to - understand it. - -5. Application of this License. - - This License applies to code to which the Initial Developer has - attached the notice in Exhibit A and to related Covered Code. - -6. Versions of the License. - - 6.1. New Versions. - Netscape Communications Corporation ("Netscape") may publish revised - and/or new versions of the License from time to time. Each version - will be given a distinguishing version number. - - 6.2. Effect of New Versions. - Once Covered Code has been published under a particular version of the - License, You may always continue to use it under the terms of that - version. You may also choose to use such Covered Code under the terms - of any subsequent version of the License published by Netscape. No one - other than Netscape has the right to modify the terms applicable to - Covered Code created under this License. - - 6.3. Derivative Works. - If You create or use a modified version of this License (which you may - only do in order to apply it to code which is not already Covered Code - governed by this License), You must (a) rename Your license so that - the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", - "MPL", "NPL" or any confusingly similar phrase do not appear in your - license (except to note that your license differs from this License) - and (b) otherwise make it clear that Your version of the license - contains terms which differ from the Mozilla Public License and - Netscape Public License. (Filling in the name of the Initial - Developer, Original Code or Contributor in the notice described in - Exhibit A shall not of themselves be deemed to be modifications of - this License.) - -7. DISCLAIMER OF WARRANTY. - - COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF - DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. - THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE - IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, - YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE - COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER - OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF - ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. - -8. TERMINATION. - - 8.1. This License and the rights granted hereunder will terminate - automatically if You fail to comply with terms herein and fail to cure - such breach within 30 days of becoming aware of the breach. All - sublicenses to the Covered Code which are properly granted shall - survive any termination of this License. Provisions which, by their - nature, must remain in effect beyond the termination of this License - shall survive. - - 8.2. If You initiate litigation by asserting a patent infringement - claim (excluding declatory judgment actions) against Initial Developer - or a Contributor (the Initial Developer or Contributor against whom - You file such action is referred to as "Participant") alleging that: - - (a) such Participant's Contributor Version directly or indirectly - infringes any patent, then any and all rights granted by such - Participant to You under Sections 2.1 and/or 2.2 of this License - shall, upon 60 days notice from Participant terminate prospectively, - unless if within 60 days after receipt of notice You either: (i) - agree in writing to pay Participant a mutually agreeable reasonable - royalty for Your past and future use of Modifications made by such - Participant, or (ii) withdraw Your litigation claim with respect to - the Contributor Version against such Participant. If within 60 days - of notice, a reasonable royalty and payment arrangement are not - mutually agreed upon in writing by the parties or the litigation claim - is not withdrawn, the rights granted by Participant to You under - Sections 2.1 and/or 2.2 automatically terminate at the expiration of - the 60 day notice period specified above. - - (b) any software, hardware, or device, other than such Participant's - Contributor Version, directly or indirectly infringes any patent, then - any rights granted to You by such Participant under Sections 2.1(b) - and 2.2(b) are revoked effective as of the date You first made, used, - sold, distributed, or had made, Modifications made by that - Participant. - - 8.3. If You assert a patent infringement claim against Participant - alleging that such Participant's Contributor Version directly or - indirectly infringes any patent where such claim is resolved (such as - by license or settlement) prior to the initiation of patent - infringement litigation, then the reasonable value of the licenses - granted by such Participant under Sections 2.1 or 2.2 shall be taken - into account in determining the amount or value of any payment or - license. - - 8.4. In the event of termination under Sections 8.1 or 8.2 above, - all end user license agreements (excluding distributors and resellers) - which have been validly granted by You or any distributor hereunder - prior to termination shall survive termination. - -9. LIMITATION OF LIABILITY. - - UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT - (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL - DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, - OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR - ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY - CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, - WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER - COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN - INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF - LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY - RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW - PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE - EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO - THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. - -10. U.S. GOVERNMENT END USERS. - - The Covered Code is a "commercial item," as that term is defined in - 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer - software" and "commercial computer software documentation," as such - terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 - C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), - all U.S. Government End Users acquire Covered Code with only those - rights set forth herein. - -11. MISCELLANEOUS. - - This License represents the complete agreement concerning subject - matter hereof. If any provision of this License is held to be - unenforceable, such provision shall be reformed only to the extent - necessary to make it enforceable. This License shall be governed by - California law provisions (except to the extent applicable law, if - any, provides otherwise), excluding its conflict-of-law provisions. - With respect to disputes in which at least one party is a citizen of, - or an entity chartered or registered to do business in the United - States of America, any litigation relating to this License shall be - subject to the jurisdiction of the Federal Courts of the Northern - District of California, with venue lying in Santa Clara County, - California, with the losing party responsible for costs, including - without limitation, court costs and reasonable attorneys' fees and - expenses. The application of the United Nations Convention on - Contracts for the International Sale of Goods is expressly excluded. - Any law or regulation which provides that the language of a contract - shall be construed against the drafter shall not apply to this - License. - -12. RESPONSIBILITY FOR CLAIMS. - - As between Initial Developer and the Contributors, each party is - responsible for claims and damages arising, directly or indirectly, - out of its utilization of rights under this License and You agree to - work with Initial Developer and Contributors to distribute such - responsibility on an equitable basis. Nothing herein is intended or - shall be deemed to constitute any admission of liability. - -13. MULTIPLE-LICENSED CODE. - - Initial Developer may designate portions of the Covered Code as - "Multiple-Licensed". "Multiple-Licensed" means that the Initial - Developer permits you to utilize portions of the Covered Code under - Your choice of the NPL or the alternative licenses, if any, specified - by the Initial Developer in the file described in Exhibit A. - -EXHIBIT A -Mozilla Public License. - - ``The contents of this file are subject to the Mozilla Public License - Version 1.1 (the "License"); you may not use this file except in - compliance with the License. You may obtain a copy of the License at - http://www.mozilla.org/MPL/ - - Software distributed under the License is distributed on an "AS IS" - basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the - License for the specific language governing rights and limitations - under the License. - - The Original Code is ______________________________________. - - The Initial Developer of the Original Code is ________________________. - Portions created by ______________________ are Copyright (C) ______ - _______________________. All Rights Reserved. - - Contributor(s): ______________________________________. - - Alternatively, the contents of this file may be used under the terms - of the _____ license (the "[___] License"), in which case the - provisions of [______] License are applicable instead of those - above. If you wish to allow use of your version of this file only - under the terms of the [____] License and not to allow others to use - your version of this file under the MPL, indicate your decision by - deleting the provisions above and replace them with the notice and - other provisions required by the [___] License. If you do not delete - the provisions above, a recipient may use your version of this file - under either the MPL or the [___] License." - - [NOTE: The text of this Exhibit A may differ slightly from the text of - the notices in the Source Code files of the Original Code. You should - use the text of this Exhibit A rather than the text found in the - Original Code Source Code for Your Modifications.] - - ---------------------------------------------------------------------- - - AMENDMENTS - - The Netscape Public License Version 1.1 ("NPL") consists of the - Mozilla Public License Version 1.1 with the following Amendments, - including Exhibit A-Netscape Public License. Files identified with - "Exhibit A-Netscape Public License" are governed by the Netscape - Public License Version 1.1. - - Additional Terms applicable to the Netscape Public License. - I. Effect. - These additional terms described in this Netscape Public - License -- Amendments shall apply to the Mozilla Communicator - client code and to all Covered Code under this License. - - II. "Netscape's Branded Code" means Covered Code that Netscape - distributes and/or permits others to distribute under one or more - trademark(s) which are controlled by Netscape but which are not - licensed for use under this License. - - III. Netscape and logo. - This License does not grant any rights to use the trademarks - "Netscape", the "Netscape N and horizon" logo or the "Netscape - lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript", - "Smart Browsing" even if such marks are included in the Original - Code or Modifications. - - IV. Inability to Comply Due to Contractual Obligation. - Prior to licensing the Original Code under this License, Netscape - has licensed third party code for use in Netscape's Branded Code. - To the extent that Netscape is limited contractually from making - such third party code available under this License, Netscape may - choose to reintegrate such code into Covered Code without being - required to distribute such code in Source Code form, even if - such code would otherwise be considered "Modifications" under - this License. - - V. Use of Modifications and Covered Code by Initial Developer. - V.1. In General. - The obligations of Section 3 apply to Netscape, except to - the extent specified in this Amendment, Section V.2 and V.3. - - V.2. Other Products. - Netscape may include Covered Code in products other than the - Netscape's Branded Code which are released by Netscape - during the two (2) years following the release date of the - Original Code, without such additional products becoming - subject to the terms of this License, and may license such - additional products on different terms from those contained - in this License. - - V.3. Alternative Licensing. - Netscape may license the Source Code of Netscape's Branded - Code, including Modifications incorporated therein, without - such Netscape Branded Code becoming subject to the terms of - this License, and may license such Netscape Branded Code on - different terms from those contained in this License. - - VI. Litigation. - Notwithstanding the limitations of Section 11 above, the - provisions regarding litigation in Section 11(a), (b) and (c) of - the License shall apply to all disputes relating to this License. - - EXHIBIT A-Netscape Public License. - - "The contents of this file are subject to the Netscape Public - License Version 1.1 (the "License"); you may not use this file - except in compliance with the License. You may obtain a copy of - the License at http://www.mozilla.org/NPL/ - - Software distributed under the License is distributed on an "AS - IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - implied. See the License for the specific language governing - rights and limitations under the License. - - The Original Code is Mozilla Communicator client code, released - March 31, 1998. - - The Initial Developer of the Original Code is Netscape - Communications Corporation. Portions created by Netscape are - Copyright (C) 1998-1999 Netscape Communications Corporation. All - Rights Reserved. - - Contributor(s): ______________________________________. - - Alternatively, the contents of this file may be used under the - terms of the _____ license (the "[___] License"), in which case - the provisions of [______] License are applicable instead of - those above. If you wish to allow use of your version of this - file only under the terms of the [____] License and not to allow - others to use your version of this file under the NPL, indicate - your decision by deleting the provisions above and replace them - with the notice and other provisions required by the [___] - License. If you do not delete the provisions above, a recipient - may use your version of this file under either the NPL or the - [___] License." diff --git a/UI/MailerUI/Images/tb-ab-delete-flat-24x24.png b/UI/MailerUI/Images/tb-ab-delete-flat-24x24.png deleted file mode 100644 index cf2908466..000000000 Binary files a/UI/MailerUI/Images/tb-ab-delete-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-ab-instantmessage-flat-24x24.png b/UI/MailerUI/Images/tb-ab-instantmessage-flat-24x24.png deleted file mode 100644 index 50ae076bb..000000000 Binary files a/UI/MailerUI/Images/tb-ab-instantmessage-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-ab-newcard-flat-24x24.png b/UI/MailerUI/Images/tb-ab-newcard-flat-24x24.png deleted file mode 100644 index a94ac2c96..000000000 Binary files a/UI/MailerUI/Images/tb-ab-newcard-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-ab-newlist-flat-24x24.png b/UI/MailerUI/Images/tb-ab-newlist-flat-24x24.png deleted file mode 100644 index 319696892..000000000 Binary files a/UI/MailerUI/Images/tb-ab-newlist-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-ab-properties-flat-24x24.png b/UI/MailerUI/Images/tb-ab-properties-flat-24x24.png deleted file mode 100644 index 72f233c98..000000000 Binary files a/UI/MailerUI/Images/tb-ab-properties-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-ab-write-flat-24x24.png b/UI/MailerUI/Images/tb-ab-write-flat-24x24.png deleted file mode 100644 index dc65f210f..000000000 Binary files a/UI/MailerUI/Images/tb-ab-write-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-attach-flat-24x24.png b/UI/MailerUI/Images/tb-compose-attach-flat-24x24.png deleted file mode 100644 index 717a7e6af..000000000 Binary files a/UI/MailerUI/Images/tb-compose-attach-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-contacts-flat-24x24.png b/UI/MailerUI/Images/tb-compose-contacts-flat-24x24.png deleted file mode 100644 index 489eadf8d..000000000 Binary files a/UI/MailerUI/Images/tb-compose-contacts-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-copy-flat-24x24.png b/UI/MailerUI/Images/tb-compose-copy-flat-24x24.png deleted file mode 100644 index fc1c5f2aa..000000000 Binary files a/UI/MailerUI/Images/tb-compose-copy-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-cut-flat-24x24.png b/UI/MailerUI/Images/tb-compose-cut-flat-24x24.png deleted file mode 100644 index 5b52d3240..000000000 Binary files a/UI/MailerUI/Images/tb-compose-cut-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-paste-flat-24x24.png b/UI/MailerUI/Images/tb-compose-paste-flat-24x24.png deleted file mode 100644 index 79a55f382..000000000 Binary files a/UI/MailerUI/Images/tb-compose-paste-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-quote-flat-24x24.png b/UI/MailerUI/Images/tb-compose-quote-flat-24x24.png deleted file mode 100644 index 786962650..000000000 Binary files a/UI/MailerUI/Images/tb-compose-quote-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-save-flat-24x24.png b/UI/MailerUI/Images/tb-compose-save-flat-24x24.png deleted file mode 100644 index 28d6f178e..000000000 Binary files a/UI/MailerUI/Images/tb-compose-save-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-security-flat-24x24.png b/UI/MailerUI/Images/tb-compose-security-flat-24x24.png deleted file mode 100644 index a6a1fbd9e..000000000 Binary files a/UI/MailerUI/Images/tb-compose-security-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-send-flat-24x24.png b/UI/MailerUI/Images/tb-compose-send-flat-24x24.png deleted file mode 100644 index 9c1290700..000000000 Binary files a/UI/MailerUI/Images/tb-compose-send-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-compose-spell-flat-24x24.png b/UI/MailerUI/Images/tb-compose-spell-flat-24x24.png deleted file mode 100644 index 44fadc7ad..000000000 Binary files a/UI/MailerUI/Images/tb-compose-spell-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-addressbook-flat-24x24.png b/UI/MailerUI/Images/tb-mail-addressbook-flat-24x24.png deleted file mode 100644 index 98473e190..000000000 Binary files a/UI/MailerUI/Images/tb-mail-addressbook-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-delete-flat-24x24.png b/UI/MailerUI/Images/tb-mail-delete-flat-24x24.png deleted file mode 100644 index 66e9f236f..000000000 Binary files a/UI/MailerUI/Images/tb-mail-delete-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-file-flat-24x24.png b/UI/MailerUI/Images/tb-mail-file-flat-24x24.png deleted file mode 100644 index 59749929e..000000000 Binary files a/UI/MailerUI/Images/tb-mail-file-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-forward-flat-24x24.png b/UI/MailerUI/Images/tb-mail-forward-flat-24x24.png deleted file mode 100644 index 40e140231..000000000 Binary files a/UI/MailerUI/Images/tb-mail-forward-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-getmail-flat-24x24.png b/UI/MailerUI/Images/tb-mail-getmail-flat-24x24.png deleted file mode 100644 index 4a35c6033..000000000 Binary files a/UI/MailerUI/Images/tb-mail-getmail-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-junk-flat-24x24.png b/UI/MailerUI/Images/tb-mail-junk-flat-24x24.png deleted file mode 100644 index 24ace63e8..000000000 Binary files a/UI/MailerUI/Images/tb-mail-junk-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-mark-flat-24x24.png b/UI/MailerUI/Images/tb-mail-mark-flat-24x24.png deleted file mode 100644 index 1f009b32b..000000000 Binary files a/UI/MailerUI/Images/tb-mail-mark-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-next-flat-24x24.png b/UI/MailerUI/Images/tb-mail-next-flat-24x24.png deleted file mode 100644 index 83a47cb67..000000000 Binary files a/UI/MailerUI/Images/tb-mail-next-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-prev-flat-24x24.png b/UI/MailerUI/Images/tb-mail-prev-flat-24x24.png deleted file mode 100644 index d2a9f725b..000000000 Binary files a/UI/MailerUI/Images/tb-mail-prev-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-print-flat-24x24.png b/UI/MailerUI/Images/tb-mail-print-flat-24x24.png deleted file mode 100644 index 5f7d2824d..000000000 Binary files a/UI/MailerUI/Images/tb-mail-print-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-reply-flat-24x24.png b/UI/MailerUI/Images/tb-mail-reply-flat-24x24.png deleted file mode 100644 index ea32a1b90..000000000 Binary files a/UI/MailerUI/Images/tb-mail-reply-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-replyall-flat-24x24.png b/UI/MailerUI/Images/tb-mail-replyall-flat-24x24.png deleted file mode 100644 index d2b49c463..000000000 Binary files a/UI/MailerUI/Images/tb-mail-replyall-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-stop-flat-24x24.png b/UI/MailerUI/Images/tb-mail-stop-flat-24x24.png deleted file mode 100644 index bc6e96b94..000000000 Binary files a/UI/MailerUI/Images/tb-mail-stop-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tb-mail-write-flat-24x24.png b/UI/MailerUI/Images/tb-mail-write-flat-24x24.png deleted file mode 100644 index 649ccbc80..000000000 Binary files a/UI/MailerUI/Images/tb-mail-write-flat-24x24.png and /dev/null differ diff --git a/UI/MailerUI/Images/tbtb_anais.png b/UI/MailerUI/Images/tbtb_anais.png deleted file mode 100644 index 96c113c72..000000000 Binary files a/UI/MailerUI/Images/tbtb_anais.png and /dev/null differ diff --git a/UI/MailerUI/Images/tbtb_folderadd.png b/UI/MailerUI/Images/tbtb_folderadd.png deleted file mode 100644 index 3f256e163..000000000 Binary files a/UI/MailerUI/Images/tbtb_folderadd.png and /dev/null differ diff --git a/UI/MailerUI/Images/tbtb_folderdel.png b/UI/MailerUI/Images/tbtb_folderdel.png deleted file mode 100644 index 9eaa44016..000000000 Binary files a/UI/MailerUI/Images/tbtb_folderdel.png and /dev/null differ diff --git a/UI/Scheduler/English.lproj/skycalendar.html b/UI/WebServerResources/English.lproj/skycalendar.html similarity index 100% rename from UI/Scheduler/English.lproj/skycalendar.html rename to UI/WebServerResources/English.lproj/skycalendar.html diff --git a/UI/Scheduler/English.lproj/skycalendar.js b/UI/WebServerResources/English.lproj/skycalendar.js similarity index 100% rename from UI/Scheduler/English.lproj/skycalendar.js rename to UI/WebServerResources/English.lproj/skycalendar.js diff --git a/UI/Scheduler/French.lproj/skycalendar.html b/UI/WebServerResources/French.lproj/skycalendar.html similarity index 100% rename from UI/Scheduler/French.lproj/skycalendar.html rename to UI/WebServerResources/French.lproj/skycalendar.html diff --git a/UI/Scheduler/French.lproj/skycalendar.js b/UI/WebServerResources/French.lproj/skycalendar.js similarity index 100% rename from UI/Scheduler/French.lproj/skycalendar.js rename to UI/WebServerResources/French.lproj/skycalendar.js diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index 74771f321..3cf6d7282 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -1,13 +1,24 @@ function newEvent(sender) { - var urlstr; - - urlstr = "new"; + var urlstr = ApplicationBaseURL + "new"; + window.open(urlstr, "SOGo_compose", "width=680,height=520,resizable=1,scrollbars=1,toolbar=0," + "location=0,directories=0,status=0,menubar=0,copyhistory=0"); return false; /* stop following the link */ } +function displayAppointment(sender) { + var aptId = sender.getAttribute("aptId"); + var urlstr = ApplicationBaseURL + aptId + "/view"; + + var win = window.open(urlstr, "SOGo_view_" + aptId, + "width=680,height=520,resizable=1,scrollbars=1,toolbar=0," + + "location=0,directories=0,status=0,menubar=0,copyhistory=0"); + win.focus(); + + return false; /* stop following the link */ +} + function onContactRefresh(node) { var parentNode = node.parentNode; diff --git a/UI/MailerUI/Images/account-settings.png b/UI/WebServerResources/account-settings.png similarity index 100% rename from UI/MailerUI/Images/account-settings.png rename to UI/WebServerResources/account-settings.png diff --git a/UI/Scheduler/images/apt_icon_private.gif b/UI/WebServerResources/apt_icon_private.gif similarity index 100% rename from UI/Scheduler/images/apt_icon_private.gif rename to UI/WebServerResources/apt_icon_private.gif diff --git a/UI/MailerUI/Images/create-account.png b/UI/WebServerResources/create-account.png similarity index 100% rename from UI/MailerUI/Images/create-account.png rename to UI/WebServerResources/create-account.png diff --git a/UI/Scheduler/images/day-view.png b/UI/WebServerResources/day-view.png similarity index 100% rename from UI/Scheduler/images/day-view.png rename to UI/WebServerResources/day-view.png diff --git a/UI/Scheduler/images/delete.png b/UI/WebServerResources/delete.png similarity index 100% rename from UI/Scheduler/images/delete.png rename to UI/WebServerResources/delete.png diff --git a/UI/WebServerResources/downstairs.gif b/UI/WebServerResources/downstairs.gif new file mode 100644 index 000000000..898418d66 Binary files /dev/null and b/UI/WebServerResources/downstairs.gif differ diff --git a/UI/Scheduler/images/edit.png b/UI/WebServerResources/edit.png similarity index 100% rename from UI/Scheduler/images/edit.png rename to UI/WebServerResources/edit.png diff --git a/UI/Scheduler/images/first.gif b/UI/WebServerResources/first.gif similarity index 100% rename from UI/Scheduler/images/first.gif rename to UI/WebServerResources/first.gif diff --git a/UI/Scheduler/images/goto-today.png b/UI/WebServerResources/goto-today.png similarity index 100% rename from UI/Scheduler/images/goto-today.png rename to UI/WebServerResources/goto-today.png diff --git a/UI/Scheduler/images/green_corner.gif b/UI/WebServerResources/green_corner.gif similarity index 100% rename from UI/Scheduler/images/green_corner.gif rename to UI/WebServerResources/green_corner.gif diff --git a/UI/MainUI/homepage.js b/UI/WebServerResources/homepage.js similarity index 100% rename from UI/MainUI/homepage.js rename to UI/WebServerResources/homepage.js diff --git a/UI/Scheduler/images/icon_popupcalendar.gif b/UI/WebServerResources/icon_popupcalendar.gif similarity index 100% rename from UI/Scheduler/images/icon_popupcalendar.gif rename to UI/WebServerResources/icon_popupcalendar.gif diff --git a/UI/Scheduler/images/icon_view_chart.gif b/UI/WebServerResources/icon_view_chart.gif similarity index 100% rename from UI/Scheduler/images/icon_view_chart.gif rename to UI/WebServerResources/icon_view_chart.gif diff --git a/UI/Scheduler/images/icon_view_chart_inactive.gif b/UI/WebServerResources/icon_view_chart_inactive.gif similarity index 100% rename from UI/Scheduler/images/icon_view_chart_inactive.gif rename to UI/WebServerResources/icon_view_chart_inactive.gif diff --git a/UI/Scheduler/images/icon_view_columns.gif b/UI/WebServerResources/icon_view_columns.gif similarity index 100% rename from UI/Scheduler/images/icon_view_columns.gif rename to UI/WebServerResources/icon_view_columns.gif diff --git a/UI/Scheduler/images/icon_view_columns_inactive.gif b/UI/WebServerResources/icon_view_columns_inactive.gif similarity index 100% rename from UI/Scheduler/images/icon_view_columns_inactive.gif rename to UI/WebServerResources/icon_view_columns_inactive.gif diff --git a/UI/Scheduler/images/icon_view_list.gif b/UI/WebServerResources/icon_view_list.gif similarity index 100% rename from UI/Scheduler/images/icon_view_list.gif rename to UI/WebServerResources/icon_view_list.gif diff --git a/UI/Scheduler/images/icon_view_list_inactive.gif b/UI/WebServerResources/icon_view_list_inactive.gif similarity index 100% rename from UI/Scheduler/images/icon_view_list_inactive.gif rename to UI/WebServerResources/icon_view_list_inactive.gif diff --git a/UI/Scheduler/images/icon_view_overview.gif b/UI/WebServerResources/icon_view_overview.gif similarity index 100% rename from UI/Scheduler/images/icon_view_overview.gif rename to UI/WebServerResources/icon_view_overview.gif diff --git a/UI/Scheduler/images/icon_view_overview_inactive.gif b/UI/WebServerResources/icon_view_overview_inactive.gif similarity index 100% rename from UI/Scheduler/images/icon_view_overview_inactive.gif rename to UI/WebServerResources/icon_view_overview_inactive.gif diff --git a/UI/Scheduler/images/invisible_space_2.gif b/UI/WebServerResources/invisible_space_2.gif similarity index 100% rename from UI/Scheduler/images/invisible_space_2.gif rename to UI/WebServerResources/invisible_space_2.gif diff --git a/UI/Scheduler/images/last.gif b/UI/WebServerResources/last.gif similarity index 100% rename from UI/Scheduler/images/last.gif rename to UI/WebServerResources/last.gif diff --git a/UI/MailerUI/Images/manage-filters.png b/UI/WebServerResources/manage-filters.png similarity index 100% rename from UI/MailerUI/Images/manage-filters.png rename to UI/WebServerResources/manage-filters.png diff --git a/UI/MailerUI/Images/manage-imap.png b/UI/WebServerResources/manage-imap.png similarity index 100% rename from UI/MailerUI/Images/manage-imap.png rename to UI/WebServerResources/manage-imap.png diff --git a/UI/MailerUI/Images/manage-newsgroups.png b/UI/WebServerResources/manage-newsgroups.png similarity index 100% rename from UI/MailerUI/Images/manage-newsgroups.png rename to UI/WebServerResources/manage-newsgroups.png diff --git a/UI/MailerUI/Images/manage-rss.png b/UI/WebServerResources/manage-rss.png similarity index 100% rename from UI/MailerUI/Images/manage-rss.png rename to UI/WebServerResources/manage-rss.png diff --git a/UI/Scheduler/images/month-view.png b/UI/WebServerResources/month-view.png similarity index 100% rename from UI/Scheduler/images/month-view.png rename to UI/WebServerResources/month-view.png diff --git a/UI/Scheduler/images/multiweek-view.png b/UI/WebServerResources/multiweek-view.png similarity index 100% rename from UI/Scheduler/images/multiweek-view.png rename to UI/WebServerResources/multiweek-view.png diff --git a/UI/Contacts/Images/new-card.png b/UI/WebServerResources/new-card.png similarity index 100% rename from UI/Contacts/Images/new-card.png rename to UI/WebServerResources/new-card.png diff --git a/UI/Scheduler/images/new-event.png b/UI/WebServerResources/new-event.png similarity index 100% rename from UI/Scheduler/images/new-event.png rename to UI/WebServerResources/new-event.png diff --git a/UI/Contacts/Images/new-list.png b/UI/WebServerResources/new-list.png similarity index 100% rename from UI/Contacts/Images/new-list.png rename to UI/WebServerResources/new-list.png diff --git a/UI/Scheduler/images/new-task.png b/UI/WebServerResources/new-task.png similarity index 100% rename from UI/Scheduler/images/new-task.png rename to UI/WebServerResources/new-task.png diff --git a/UI/Scheduler/images/next.gif b/UI/WebServerResources/next.gif similarity index 100% rename from UI/Scheduler/images/next.gif rename to UI/WebServerResources/next.gif diff --git a/UI/Scheduler/images/next_week.gif b/UI/WebServerResources/next_week.gif similarity index 100% rename from UI/Scheduler/images/next_week.gif rename to UI/WebServerResources/next_week.gif diff --git a/UI/MailerUI/Images/offline-settings.png b/UI/WebServerResources/offline-settings.png similarity index 100% rename from UI/MailerUI/Images/offline-settings.png rename to UI/WebServerResources/offline-settings.png diff --git a/UI/Scheduler/images/previous.gif b/UI/WebServerResources/previous.gif similarity index 100% rename from UI/Scheduler/images/previous.gif rename to UI/WebServerResources/previous.gif diff --git a/UI/Scheduler/images/previous_week.gif b/UI/WebServerResources/previous_week.gif similarity index 100% rename from UI/Scheduler/images/previous_week.gif rename to UI/WebServerResources/previous_week.gif diff --git a/UI/Contacts/Images/properties.png b/UI/WebServerResources/properties.png similarity index 100% rename from UI/Contacts/Images/properties.png rename to UI/WebServerResources/properties.png diff --git a/UI/WebServerResources/prototype.js b/UI/WebServerResources/prototype.js new file mode 100644 index 000000000..0e85338ba --- /dev/null +++ b/UI/WebServerResources/prototype.js @@ -0,0 +1,1781 @@ +/* Prototype JavaScript framework, version 1.4.0 + * (c) 2005 Sam Stephenson + * + * Prototype is freely distributable under the terms of an MIT-style license. + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.4.0', + ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)', + + emptyFunction: function() {}, + K: function(x) {return x} +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.extend = function(destination, source) { + for (property in source) { + destination[property] = source[property]; + } + return destination; +} + +Object.inspect = function(object) { + try { + if (object == undefined) return 'undefined'; + if (object == null) return 'null'; + return object.inspect ? object.inspect() : object.toString(); + } catch (e) { + if (e instanceof RangeError) return '...'; + throw e; + } +} + +Function.prototype.bind = function() { + var __method = this, args = $A(arguments), object = args.shift(); + return function() { + return __method.apply(object, args.concat($A(arguments))); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var __method = this; + return function(event) { + return __method.call(object, event || window.event); + } +} + +Object.extend(Number.prototype, { + toColorPart: function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; + }, + + succ: function() { + return this + 1; + }, + + times: function(iterator) { + $R(0, this, true).each(iterator); + return this; + } +}); + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(); + } finally { + this.currentlyExecuting = false; + } + } + } +} + +/*--------------------------------------------------------------------------*/ + +function $() { + var elements = new Array(); + + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + + if (arguments.length == 1) + return element; + + elements.push(element); + } + + return elements; +} +Object.extend(String.prototype, { + stripTags: function() { + return this.replace(/<\/?[^>]+>/gi, ''); + }, + + stripScripts: function() { + return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); + }, + + extractScripts: function() { + var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); + var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); + return (this.match(matchAll) || []).map(function(scriptTag) { + return (scriptTag.match(matchOne) || ['', ''])[1]; + }); + }, + + evalScripts: function() { + return this.extractScripts().map(eval); + }, + + escapeHTML: function() { + var div = document.createElement('div'); + var text = document.createTextNode(this); + div.appendChild(text); + return div.innerHTML; + }, + + unescapeHTML: function() { + var div = document.createElement('div'); + div.innerHTML = this.stripTags(); + return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; + }, + + toQueryParams: function() { + var pairs = this.match(/^\??(.*)$/)[1].split('&'); + return pairs.inject({}, function(params, pairString) { + var pair = pairString.split('='); + params[pair[0]] = pair[1]; + return params; + }); + }, + + toArray: function() { + return this.split(''); + }, + + camelize: function() { + var oStringList = this.split('-'); + if (oStringList.length == 1) return oStringList[0]; + + var camelizedString = this.indexOf('-') == 0 + ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) + : oStringList[0]; + + for (var i = 1, len = oStringList.length; i < len; i++) { + var s = oStringList[i]; + camelizedString += s.charAt(0).toUpperCase() + s.substring(1); + } + + return camelizedString; + }, + + inspect: function() { + return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; + } +}); + +String.prototype.parseQuery = String.prototype.toQueryParams; + +var $break = new Object(); +var $continue = new Object(); + +var Enumerable = { + each: function(iterator) { + var index = 0; + try { + this._each(function(value) { + try { + iterator(value, index++); + } catch (e) { + if (e != $continue) throw e; + } + }); + } catch (e) { + if (e != $break) throw e; + } + }, + + all: function(iterator) { + var result = true; + this.each(function(value, index) { + result = result && !!(iterator || Prototype.K)(value, index); + if (!result) throw $break; + }); + return result; + }, + + any: function(iterator) { + var result = true; + this.each(function(value, index) { + if (result = !!(iterator || Prototype.K)(value, index)) + throw $break; + }); + return result; + }, + + collect: function(iterator) { + var results = []; + this.each(function(value, index) { + results.push(iterator(value, index)); + }); + return results; + }, + + detect: function (iterator) { + var result; + this.each(function(value, index) { + if (iterator(value, index)) { + result = value; + throw $break; + } + }); + return result; + }, + + findAll: function(iterator) { + var results = []; + this.each(function(value, index) { + if (iterator(value, index)) + results.push(value); + }); + return results; + }, + + grep: function(pattern, iterator) { + var results = []; + this.each(function(value, index) { + var stringValue = value.toString(); + if (stringValue.match(pattern)) + results.push((iterator || Prototype.K)(value, index)); + }) + return results; + }, + + include: function(object) { + var found = false; + this.each(function(value) { + if (value == object) { + found = true; + throw $break; + } + }); + return found; + }, + + inject: function(memo, iterator) { + this.each(function(value, index) { + memo = iterator(memo, value, index); + }); + return memo; + }, + + invoke: function(method) { + var args = $A(arguments).slice(1); + return this.collect(function(value) { + return value[method].apply(value, args); + }); + }, + + max: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value >= (result || value)) + result = value; + }); + return result; + }, + + min: function(iterator) { + var result; + this.each(function(value, index) { + value = (iterator || Prototype.K)(value, index); + if (value <= (result || value)) + result = value; + }); + return result; + }, + + partition: function(iterator) { + var trues = [], falses = []; + this.each(function(value, index) { + ((iterator || Prototype.K)(value, index) ? + trues : falses).push(value); + }); + return [trues, falses]; + }, + + pluck: function(property) { + var results = []; + this.each(function(value, index) { + results.push(value[property]); + }); + return results; + }, + + reject: function(iterator) { + var results = []; + this.each(function(value, index) { + if (!iterator(value, index)) + results.push(value); + }); + return results; + }, + + sortBy: function(iterator) { + return this.collect(function(value, index) { + return {value: value, criteria: iterator(value, index)}; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }).pluck('value'); + }, + + toArray: function() { + return this.collect(Prototype.K); + }, + + zip: function() { + var iterator = Prototype.K, args = $A(arguments); + if (typeof args.last() == 'function') + iterator = args.pop(); + + var collections = [this].concat(args).map($A); + return this.map(function(value, index) { + iterator(value = collections.pluck(index)); + return value; + }); + }, + + inspect: function() { + return '#'; + } +} + +Object.extend(Enumerable, { + map: Enumerable.collect, + find: Enumerable.detect, + select: Enumerable.findAll, + member: Enumerable.include, + entries: Enumerable.toArray +}); +var $A = Array.from = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) { + return iterable.toArray(); + } else { + var results = []; + for (var i = 0; i < iterable.length; i++) + results.push(iterable[i]); + return results; + } +} + +Object.extend(Array.prototype, Enumerable); + +Array.prototype._reverse = Array.prototype.reverse; + +Object.extend(Array.prototype, { + _each: function(iterator) { + for (var i = 0; i < this.length; i++) + iterator(this[i]); + }, + + clear: function() { + this.length = 0; + return this; + }, + + first: function() { + return this[0]; + }, + + last: function() { + return this[this.length - 1]; + }, + + compact: function() { + return this.select(function(value) { + return value != undefined || value != null; + }); + }, + + flatten: function() { + return this.inject([], function(array, value) { + return array.concat(value.constructor == Array ? + value.flatten() : [value]); + }); + }, + + without: function() { + var values = $A(arguments); + return this.select(function(value) { + return !values.include(value); + }); + }, + + indexOf: function(object) { + for (var i = 0; i < this.length; i++) + if (this[i] == object) return i; + return -1; + }, + + reverse: function(inline) { + return (inline !== false ? this : this.toArray())._reverse(); + }, + + shift: function() { + var result = this[0]; + for (var i = 0; i < this.length - 1; i++) + this[i] = this[i + 1]; + this.length--; + return result; + }, + + inspect: function() { + return '[' + this.map(Object.inspect).join(', ') + ']'; + } +}); +var Hash = { + _each: function(iterator) { + for (key in this) { + var value = this[key]; + if (typeof value == 'function') continue; + + var pair = [key, value]; + pair.key = key; + pair.value = value; + iterator(pair); + } + }, + + keys: function() { + return this.pluck('key'); + }, + + values: function() { + return this.pluck('value'); + }, + + merge: function(hash) { + return $H(hash).inject($H(this), function(mergedHash, pair) { + mergedHash[pair.key] = pair.value; + return mergedHash; + }); + }, + + toQueryString: function() { + return this.map(function(pair) { + return pair.map(encodeURIComponent).join('='); + }).join('&'); + }, + + inspect: function() { + return '#'; + } +} + +function $H(object) { + var hash = Object.extend({}, object || {}); + Object.extend(hash, Enumerable); + Object.extend(hash, Hash); + return hash; +} +ObjectRange = Class.create(); +Object.extend(ObjectRange.prototype, Enumerable); +Object.extend(ObjectRange.prototype, { + initialize: function(start, end, exclusive) { + this.start = start; + this.end = end; + this.exclusive = exclusive; + }, + + _each: function(iterator) { + var value = this.start; + do { + iterator(value); + value = value.succ(); + } while (this.include(value)); + }, + + include: function(value) { + if (value < this.start) + return false; + if (this.exclusive) + return value < this.end; + return value <= this.end; + } +}); + +var $R = function(start, end, exclusive) { + return new ObjectRange(start, end, exclusive); +} + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')}, + function() {return new XMLHttpRequest()} + ) || false; + }, + + activeRequestCount: 0 +} + +Ajax.Responders = { + responders: [], + + _each: function(iterator) { + this.responders._each(iterator); + }, + + register: function(responderToAdd) { + if (!this.include(responderToAdd)) + this.responders.push(responderToAdd); + }, + + unregister: function(responderToRemove) { + this.responders = this.responders.without(responderToRemove); + }, + + dispatch: function(callback, request, transport, json) { + this.each(function(responder) { + if (responder[callback] && typeof responder[callback] == 'function') { + 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 = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + parameters: '' + } + Object.extend(this.options, options || {}); + }, + + responseIsSuccess: function() { + return this.transport.status == undefined + || this.transport.status == 0 + || (this.transport.status >= 200 && this.transport.status < 300); + }, + + responseIsFailure: function() { + return !this.responseIsSuccess(); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = Object.extend(new Ajax.Base(), { + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + this.request(url); + }, + + request: function(url) { + var parameters = this.options.parameters || ''; + if (parameters.length > 0) parameters += '&_='; + + try { + this.url = url; + if (this.options.method == 'get' && parameters.length > 0) + this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; + + Ajax.Responders.dispatch('onCreate', this, this.transport); + + this.transport.open(this.options.method, this.url, + this.options.asynchronous); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.setRequestHeaders(); + + var body = this.options.postBody ? this.options.postBody : parameters; + this.transport.send(this.options.method == 'post' ? body : null); + + } catch (e) { + this.dispatchException(e); + } + }, + + setRequestHeaders: function() { + var requestHeaders = + ['X-Requested-With', 'XMLHttpRequest', + 'X-Prototype-Version', Prototype.Version]; + + if (this.options.method == 'post') { + requestHeaders.push('Content-type', + 'application/x-www-form-urlencoded'); + + /* Force "Connection: close" for Mozilla browsers to work around + * a bug where XMLHttpReqeuest sends an incorrect Content-length + * header. See Mozilla Bugzilla #246651. + */ + if (this.transport.overrideMimeType) + requestHeaders.push('Connection', 'close'); + } + + if (this.options.requestHeaders) + requestHeaders.push.apply(requestHeaders, this.options.requestHeaders); + + for (var i = 0; i < requestHeaders.length; i += 2) + this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + header: function(name) { + try { + return this.transport.getResponseHeader(name); + } catch (e) {} + }, + + evalJSON: function() { + try { + return eval(this.header('X-JSON')); + } catch (e) {} + }, + + evalResponse: function() { + try { + return eval(this.transport.responseText); + } catch (e) { + this.dispatchException(e); + } + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + var transport = this.transport, json = this.evalJSON(); + + if (event == 'Complete') { + try { + (this.options['on' + this.transport.status] + || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] + || Prototype.emptyFunction)(transport, json); + } catch (e) { + this.dispatchException(e); + } + + if ((this.header('Content-type') || '').match(/^text\/javascript/i)) + this.evalResponse(); + } + + try { + (this.options['on' + event] || Prototype.emptyFunction)(transport, json); + Ajax.Responders.dispatch('on' + event, this, transport, json); + } catch (e) { + this.dispatchException(e); + } + + /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ + if (event == 'Complete') + this.transport.onreadystatechange = Prototype.emptyFunction; + }, + + dispatchException: function(exception) { + (this.options.onException || Prototype.emptyFunction)(this, exception); + Ajax.Responders.dispatch('onException', this, exception); + } +}); + +Ajax.Updater = Class.create(); + +Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { + initialize: function(container, url, options) { + this.containers = { + success: container.success ? $(container.success) : $(container), + failure: container.failure ? $(container.failure) : + (container.success ? null : $(container)) + } + + this.transport = Ajax.getTransport(); + this.setOptions(options); + + var onComplete = this.options.onComplete || Prototype.emptyFunction; + this.options.onComplete = (function(transport, object) { + this.updateContent(); + onComplete(transport, object); + }).bind(this); + + this.request(url); + }, + + updateContent: function() { + var receiver = this.responseIsSuccess() ? + this.containers.success : this.containers.failure; + var response = this.transport.responseText; + + if (!this.options.evalScripts) + response = response.stripScripts(); + + if (receiver) { + if (this.options.insertion) { + new this.options.insertion(receiver, response); + } else { + Element.update(receiver, response); + } + } + + if (this.responseIsSuccess()) { + if (this.onComplete) + setTimeout(this.onComplete.bind(this), 10); + } + } +}); + +Ajax.PeriodicalUpdater = Class.create(); +Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { + initialize: function(container, url, options) { + this.setOptions(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.onComplete = undefined; + clearTimeout(this.timer); + (this.onComplete || Prototype.emptyFunction).apply(this, arguments); + }, + + updateComplete: function(request) { + if (this.options.decay) { + this.decay = (request.responseText == this.lastText ? + this.decay * this.options.decay : 1); + + this.lastText = request.responseText; + } + this.timer = setTimeout(this.onTimerEvent.bind(this), + this.decay * this.frequency * 1000); + }, + + onTimerEvent: function() { + this.updater = new Ajax.Updater(this.container, this.url, this.options); + } +}); +document.getElementsByClassName = function(className, parentElement) { + var children = ($(parentElement) || document.body).getElementsByTagName('*'); + return $A(children).inject([], function(elements, child) { + if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) + elements.push(child); + return elements; + }); +} + +/*--------------------------------------------------------------------------*/ + +if (!window.Element) { + var Element = new Object(); +} + +Object.extend(Element, { + visible: function(element) { + return $(element).style.display != 'none'; + }, + + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + Element[Element.visible(element) ? 'hide' : 'show'](element); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + update: function(element, html) { + $(element).innerHTML = html.stripScripts(); + setTimeout(function() {html.evalScripts()}, 10); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + }, + + classNames: function(element) { + return new Element.ClassNames(element); + }, + + hasClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).include(className); + }, + + addClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).add(className); + }, + + removeClassName: function(element, className) { + if (!(element = $(element))) return; + return Element.classNames(element).remove(className); + }, + + // removes whitespace-only text node children + cleanWhitespace: function(element) { + element = $(element); + for (var i = 0; i < element.childNodes.length; i++) { + var node = element.childNodes[i]; + if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) + Element.remove(node); + } + }, + + empty: function(element) { + return $(element).innerHTML.match(/^\s*$/); + }, + + scrollTo: function(element) { + element = $(element); + var x = element.x ? element.x : element.offsetLeft, + y = element.y ? element.y : element.offsetTop; + window.scrollTo(x, y); + }, + + getStyle: function(element, style) { + element = $(element); + var value = element.style[style.camelize()]; + if (!value) { + if (document.defaultView && document.defaultView.getComputedStyle) { + var css = document.defaultView.getComputedStyle(element, null); + value = css ? css.getPropertyValue(style) : null; + } else if (element.currentStyle) { + value = element.currentStyle[style.camelize()]; + } + } + + if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) + if (Element.getStyle(element, 'position') == 'static') value = 'auto'; + + return value == 'auto' ? null : value; + }, + + setStyle: function(element, style) { + element = $(element); + for (name in style) + element.style[name.camelize()] = style[name]; + }, + + getDimensions: function(element) { + element = $(element); + if (Element.getStyle(element, 'display') != 'none') + return {width: element.offsetWidth, height: element.offsetHeight}; + + // All *Width and *Height properties give 0 on elements with display none, + // so enable the element temporarily + var els = element.style; + var originalVisibility = els.visibility; + var originalPosition = els.position; + els.visibility = 'hidden'; + els.position = 'absolute'; + els.display = ''; + var originalWidth = element.clientWidth; + var originalHeight = element.clientHeight; + els.display = 'none'; + els.position = originalPosition; + els.visibility = originalVisibility; + return {width: originalWidth, height: originalHeight}; + }, + + makePositioned: function(element) { + element = $(element); + var pos = Element.getStyle(element, 'position'); + if (pos == 'static' || !pos) { + element._madePositioned = true; + element.style.position = 'relative'; + // Opera returns the offset relative to the positioning context, when an + // element is position relative but top and left have not been defined + if (window.opera) { + element.style.top = 0; + element.style.left = 0; + } + } + }, + + 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 = ''; + } + }, + + makeClipping: function(element) { + element = $(element); + if (element._overflow) return; + element._overflow = element.style.overflow; + if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden') + element.style.overflow = 'hidden'; + }, + + undoClipping: function(element) { + element = $(element); + if (element._overflow) return; + element.style.overflow = element._overflow; + element._overflow = undefined; + } +}); + +var Toggle = new Object(); +Toggle.display = Element.toggle; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content.stripScripts(); + + if (this.adjacency && this.element.insertAdjacentHTML) { + try { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } catch (e) { + if (this.element.tagName.toLowerCase() == 'tbody') { + this.insertContent(this.contentFromAnonymousTable()); + } else { + throw e; + } + } + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.insertContent([this.range.createContextualFragment(this.content)]); + } + + setTimeout(function() {content.evalScripts()}, 10); + }, + + contentFromAnonymousTable: function() { + var div = document.createElement('div'); + div.innerHTML = '' + this.content + '
'; + return $A(div.childNodes[0].childNodes[0].childNodes); + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, this.element); + }).bind(this)); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function(fragments) { + fragments.reverse(false).each((function(fragment) { + this.element.insertBefore(fragment, this.element.firstChild); + }).bind(this)); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.appendChild(fragment); + }).bind(this)); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function(fragments) { + fragments.each((function(fragment) { + this.element.parentNode.insertBefore(fragment, + this.element.nextSibling); + }).bind(this)); + } +}); + +/*--------------------------------------------------------------------------*/ + +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(this.toArray().concat(classNameToAdd).join(' ')); + }, + + remove: function(classNameToRemove) { + if (!this.include(classNameToRemove)) return; + this.set(this.select(function(className) { + return className != classNameToRemove; + }).join(' ')); + }, + + toString: function() { + return this.toArray().join(' '); + } +} + +Object.extend(Element.ClassNames.prototype, Enumerable); +var Field = { + clear: function() { + for (var i = 0; i < arguments.length; i++) + $(arguments[i]).value = ''; + }, + + focus: function(element) { + $(element).focus(); + }, + + present: function() { + for (var i = 0; i < arguments.length; i++) + if ($(arguments[i]).value == '') return false; + return true; + }, + + select: function(element) { + $(element).select(); + }, + + activate: function(element) { + element = $(element); + element.focus(); + if (element.select) + element.select(); + } +} + +/*--------------------------------------------------------------------------*/ + +var Form = { + serialize: function(form) { + var elements = Form.getElements($(form)); + var queryComponents = new Array(); + + for (var i = 0; i < elements.length; i++) { + var queryComponent = Form.Element.serialize(elements[i]); + if (queryComponent) + queryComponents.push(queryComponent); + } + + return queryComponents.join('&'); + }, + + getElements: function(form) { + form = $(form); + var elements = new Array(); + + for (tagName in Form.Element.Serializers) { + var tagElements = form.getElementsByTagName(tagName); + for (var j = 0; j < tagElements.length; j++) + elements.push(tagElements[j]); + } + return elements; + }, + + getInputs: function(form, typeName, name) { + form = $(form); + var inputs = form.getElementsByTagName('input'); + + if (!typeName && !name) + return inputs; + + var matchingInputs = new Array(); + for (var i = 0; i < inputs.length; i++) { + var input = inputs[i]; + if ((typeName && input.type != typeName) || + (name && input.name != name)) + continue; + matchingInputs.push(input); + } + + return matchingInputs; + }, + + disable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.blur(); + element.disabled = 'true'; + } + }, + + enable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.disabled = ''; + } + }, + + findFirstElement: function(form) { + return Form.getElements(form).find(function(element) { + return element.type != 'hidden' && !element.disabled && + ['input', 'select', 'textarea'].include(element.tagName.toLowerCase()); + }); + }, + + focusFirstElement: function(form) { + Field.activate(Form.findFirstElement(form)); + }, + + reset: function(form) { + $(form).reset(); + } +} + +Form.Element = { + serialize: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) { + var key = encodeURIComponent(parameter[0]); + if (key.length == 0) return; + + if (parameter[1].constructor != Array) + parameter[1] = [parameter[1]]; + + return parameter[1].map(function(value) { + return key + '=' + encodeURIComponent(value); + }).join('&'); + } + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return parameter[1]; + } +} + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'submit': + case 'hidden': + case 'password': + case 'text': + return Form.Element.Serializers.textarea(element); + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + } + return false; + }, + + inputSelector: function(element) { + if (element.checked) + return [element.name, element.value]; + }, + + textarea: function(element) { + return [element.name, element.value]; + }, + + select: function(element) { + return Form.Element.Serializers[element.type == 'select-one' ? + 'selectOne' : 'selectMany'](element); + }, + + selectOne: function(element) { + var value = '', opt, index = element.selectedIndex; + if (index >= 0) { + opt = element.options[index]; + value = opt.value; + if (!value && !('value' in opt)) + value = opt.text; + } + return [element.name, value]; + }, + + selectMany: function(element) { + var value = new Array(); + for (var i = 0; i < element.length; i++) { + var opt = element.options[i]; + if (opt.selected) { + var optValue = opt.value; + if (!optValue && !('value' in opt)) + optValue = opt.text; + value.push(optValue); + } + } + return [element.name, value]; + } +} + +/*--------------------------------------------------------------------------*/ + +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); + +/*--------------------------------------------------------------------------*/ + +Abstract.EventObserver = function() {} +Abstract.EventObserver.prototype = { + 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() { + var elements = Form.getElements(this.element); + for (var i = 0; i < elements.length; i++) + this.registerCallback(elements[i]); + }, + + registerCallback: function(element) { + if (element.type) { + switch (element.type.toLowerCase()) { + case 'checkbox': + case 'radio': + Event.observe(element, 'click', this.onElementEvent.bind(this)); + break; + case 'password': + case 'text': + case 'textarea': + case 'select-one': + case 'select-multiple': + Event.observe(element, 'change', this.onElementEvent.bind(this)); + break; + } + } + } +} + +Form.Element.EventObserver = Class.create(); +Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.EventObserver = Class.create(); +Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { + getValue: function() { + return Form.serialize(this.element); + } +}); +if (!window.Event) { + var Event = new Object(); +} + +Object.extend(Event, { + KEY_BACKSPACE: 8, + KEY_TAB: 9, + KEY_RETURN: 13, + KEY_ESC: 27, + KEY_LEFT: 37, + KEY_UP: 38, + KEY_RIGHT: 39, + KEY_DOWN: 40, + KEY_DELETE: 46, + + element: function(event) { + return event.target || event.srcElement; + }, + + isLeftClick: function(event) { + return (((event.which) && (event.which == 1)) || + ((event.button) && (event.button == 1))); + }, + + pointerX: function(event) { + return event.pageX || (event.clientX + + (document.documentElement.scrollLeft || document.body.scrollLeft)); + }, + + pointerY: function(event) { + return event.pageY || (event.clientY + + (document.documentElement.scrollTop || document.body.scrollTop)); + }, + + stop: function(event) { + if (event.preventDefault) { + event.preventDefault(); + event.stopPropagation(); + } else { + event.returnValue = false; + event.cancelBubble = true; + } + }, + + // find the first node with the given tagName, starting from the + // node the event was triggered on; traverses the DOM upwards + findElement: function(event, tagName) { + var element = Event.element(event); + while (element.parentNode && (!element.tagName || + (element.tagName.toUpperCase() != tagName.toUpperCase()))) + element = element.parentNode; + return element; + }, + + observers: false, + + _observeAndCache: function(element, name, observer, useCapture) { + if (!this.observers) this.observers = []; + if (element.addEventListener) { + this.observers.push([element, name, observer, useCapture]); + element.addEventListener(name, observer, useCapture); + } else if (element.attachEvent) { + this.observers.push([element, name, observer, useCapture]); + element.attachEvent('on' + name, observer); + } + }, + + unloadCache: function() { + if (!Event.observers) return; + for (var i = 0; i < Event.observers.length; i++) { + Event.stopObserving.apply(this, Event.observers[i]); + Event.observers[i][0] = null; + } + Event.observers = false; + }, + + observe: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.attachEvent)) + name = 'keydown'; + + this._observeAndCache(element, name, observer, useCapture); + }, + + stopObserving: function(element, name, observer, useCapture) { + var element = $(element); + useCapture = useCapture || false; + + if (name == 'keypress' && + (navigator.appVersion.match(/Konqueror|Safari|KHTML/) + || element.detachEvent)) + name = 'keydown'; + + if (element.removeEventListener) { + element.removeEventListener(name, observer, useCapture); + } else if (element.detachEvent) { + element.detachEvent('on' + name, observer); + } + } +}); + +/* prevent memory leaks in IE */ +Event.observe(window, 'unload', Event.unloadCache, false); +var Position = { + // set to true if needed, warning: firefox performance problems + // NOT neeeded for page scrolling, only if draggable contained in + // scrollable elements + includeScrollOffsets: false, + + // must be called before calling withinIncludingScrolloffset, every time the + // page is scrolled + prepare: function() { + this.deltaX = window.pageXOffset + || document.documentElement.scrollLeft + || document.body.scrollLeft + || 0; + this.deltaY = window.pageYOffset + || document.documentElement.scrollTop + || document.body.scrollTop + || 0; + }, + + realOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.scrollTop || 0; + valueL += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [valueL, valueT]; + }, + + cumulativeOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [valueL, valueT]; + }, + + positionedOffset: function(element) { + var valueT = 0, valueL = 0; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + element = element.offsetParent; + if (element) { + p = Element.getStyle(element, 'position'); + if (p == 'relative' || p == 'absolute') break; + } + } while (element); + return [valueL, valueT]; + }, + + offsetParent: 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; + }, + + // caches x/y coordinate pair to use with overlap + within: function(element, x, y) { + if (this.includeScrollOffsets) + return this.withinIncludingScrolloffsets(element, x, y); + this.xcomp = x; + this.ycomp = y; + this.offset = this.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 = this.realOffset(element); + + this.xcomp = x + offsetcache[0] - this.deltaX; + this.ycomp = y + offsetcache[1] - this.deltaY; + this.offset = this.cumulativeOffset(element); + + return (this.ycomp >= this.offset[1] && + this.ycomp < this.offset[1] + element.offsetHeight && + this.xcomp >= this.offset[0] && + this.xcomp < this.offset[0] + element.offsetWidth); + }, + + // within must be called directly before + overlap: function(mode, element) { + if (!mode) return 0; + if (mode == 'vertical') + return ((this.offset[1] + element.offsetHeight) - this.ycomp) / + element.offsetHeight; + if (mode == 'horizontal') + return ((this.offset[0] + element.offsetWidth) - this.xcomp) / + element.offsetWidth; + }, + + clone: function(source, target) { + source = $(source); + target = $(target); + target.style.position = 'absolute'; + var offsets = this.cumulativeOffset(source); + target.style.top = offsets[1] + 'px'; + target.style.left = offsets[0] + 'px'; + target.style.width = source.offsetWidth + 'px'; + target.style.height = source.offsetHeight + 'px'; + }, + + page: function(forElement) { + var valueT = 0, valueL = 0; + + var element = forElement; + do { + valueT += element.offsetTop || 0; + valueL += element.offsetLeft || 0; + + // Safari fix + if (element.offsetParent==document.body) + if (Element.getStyle(element,'position')=='absolute') break; + + } while (element = element.offsetParent); + + element = forElement; + do { + valueT -= element.scrollTop || 0; + valueL -= element.scrollLeft || 0; + } while (element = element.parentNode); + + return [valueL, valueT]; + }, + + clone: function(source, target) { + var options = Object.extend({ + setLeft: true, + setTop: true, + setWidth: true, + setHeight: true, + offsetTop: 0, + offsetLeft: 0 + }, arguments[2] || {}) + + // find page position of source + source = $(source); + var p = Position.page(source); + + // find coordinate system to use + target = $(target); + var delta = [0, 0]; + var parent = null; + // delta [0,0] will do fine with position: fixed elements, + // position:absolute needs offsetParent deltas + if (Element.getStyle(target,'position') == 'absolute') { + parent = Position.offsetParent(target); + delta = Position.page(parent); + } + + // correct by body offsets (fixes Safari) + if (parent == document.body) { + delta[0] -= document.body.offsetLeft; + delta[1] -= document.body.offsetTop; + } + + // set position + if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px'; + if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px'; + if(options.setWidth) target.style.width = source.offsetWidth + 'px'; + if(options.setHeight) target.style.height = source.offsetHeight + 'px'; + }, + + absolutize: function(element) { + element = $(element); + if (element.style.position == 'absolute') return; + Position.prepare(); + + var offsets = Position.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';; + }, + + relativize: function(element) { + element = $(element); + if (element.style.position == 'relative') return; + Position.prepare(); + + 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; + } +} + +// Safari returns margins on body which is incorrect if the child is absolutely +// positioned. For performance reasons, redefine Position.cumulativeOffset for +// KHTML/WebKit only. +if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { + Position.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 [valueL, valueT]; + } +} \ No newline at end of file diff --git a/UI/MailerUI/Images/read-messages.png b/UI/WebServerResources/read-messages.png similarity index 100% rename from UI/MailerUI/Images/read-messages.png rename to UI/WebServerResources/read-messages.png diff --git a/UI/MailerUI/Images/search-messages.png b/UI/WebServerResources/search-messages.png similarity index 100% rename from UI/MailerUI/Images/search-messages.png rename to UI/WebServerResources/search-messages.png diff --git a/UI/MailerUI/Images/treeview_corner.gif b/UI/WebServerResources/treeview_corner.gif similarity index 100% rename from UI/MailerUI/Images/treeview_corner.gif rename to UI/WebServerResources/treeview_corner.gif diff --git a/UI/MailerUI/Images/treeview_corner_minus.gif b/UI/WebServerResources/treeview_corner_minus.gif similarity index 100% rename from UI/MailerUI/Images/treeview_corner_minus.gif rename to UI/WebServerResources/treeview_corner_minus.gif diff --git a/UI/MailerUI/Images/treeview_corner_plus.gif b/UI/WebServerResources/treeview_corner_plus.gif similarity index 100% rename from UI/MailerUI/Images/treeview_corner_plus.gif rename to UI/WebServerResources/treeview_corner_plus.gif diff --git a/UI/MailerUI/Images/treeview_junction.gif b/UI/WebServerResources/treeview_junction.gif similarity index 100% rename from UI/MailerUI/Images/treeview_junction.gif rename to UI/WebServerResources/treeview_junction.gif diff --git a/UI/MailerUI/Images/treeview_leaf.gif b/UI/WebServerResources/treeview_leaf.gif similarity index 100% rename from UI/MailerUI/Images/treeview_leaf.gif rename to UI/WebServerResources/treeview_leaf.gif diff --git a/UI/MailerUI/Images/treeview_leaf_corner.gif b/UI/WebServerResources/treeview_leaf_corner.gif similarity index 100% rename from UI/MailerUI/Images/treeview_leaf_corner.gif rename to UI/WebServerResources/treeview_leaf_corner.gif diff --git a/UI/MailerUI/Images/treeview_line.gif b/UI/WebServerResources/treeview_line.gif similarity index 100% rename from UI/MailerUI/Images/treeview_line.gif rename to UI/WebServerResources/treeview_line.gif diff --git a/UI/MailerUI/Images/treeview_minus.gif b/UI/WebServerResources/treeview_minus.gif similarity index 100% rename from UI/MailerUI/Images/treeview_minus.gif rename to UI/WebServerResources/treeview_minus.gif diff --git a/UI/MailerUI/Images/treeview_plus.gif b/UI/WebServerResources/treeview_plus.gif similarity index 100% rename from UI/MailerUI/Images/treeview_plus.gif rename to UI/WebServerResources/treeview_plus.gif diff --git a/UI/MailerUI/Images/treeview_space.gif b/UI/WebServerResources/treeview_space.gif similarity index 100% rename from UI/MailerUI/Images/treeview_space.gif rename to UI/WebServerResources/treeview_space.gif diff --git a/UI/Scheduler/images/week-view.png b/UI/WebServerResources/week-view.png similarity index 100% rename from UI/Scheduler/images/week-view.png rename to UI/WebServerResources/week-view.png diff --git a/UI/MailerUI/Images/write-message.png b/UI/WebServerResources/write-message.png similarity index 100% rename from UI/MailerUI/Images/write-message.png rename to UI/WebServerResources/write-message.png diff --git a/UI/Contacts/Images/write.png b/UI/WebServerResources/write.png similarity index 100% rename from UI/Contacts/Images/write.png rename to UI/WebServerResources/write.png