From f2d90fe0d3a54fd3950882f2b3f21019b12574f8 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Fri, 5 Jun 2009 14:02:34 +0000 Subject: [PATCH] replaced Farbtastic with jPicker, because of the license issues change license to Apache License v 2.0 git-svn-id: http://svg-edit.googlecode.com/svn/trunk@36 eee81c28-f429-11dd-99c0-75d572ba1ddd --- CHANGES | 9 +- COPYING | 339 -- LICENSE | 202 + README | 6 +- editor/farbtastic.css | 50 - editor/farbtastic.js | 348 -- editor/images/marker.png | Bin 652 -> 0 bytes editor/images/mask.png | Bin 2020 -> 0 bytes editor/images/wheel.png | Bin 11733 -> 0 bytes editor/jpicker/images/bar-blue-bl.png | Bin 0 -> 177 bytes editor/jpicker/images/bar-blue-br.png | Bin 0 -> 172 bytes editor/jpicker/images/bar-blue-tl.png | Bin 0 -> 175 bytes editor/jpicker/images/bar-blue-tr.png | Bin 0 -> 173 bytes editor/jpicker/images/bar-brightness.png | Bin 0 -> 263 bytes editor/jpicker/images/bar-green-bl.png | Bin 0 -> 177 bytes editor/jpicker/images/bar-green-br.png | Bin 0 -> 176 bytes editor/jpicker/images/bar-green-tl.png | Bin 0 -> 172 bytes editor/jpicker/images/bar-green-tr.png | Bin 0 -> 172 bytes editor/jpicker/images/bar-hue.png | Bin 0 -> 226 bytes editor/jpicker/images/bar-red-bl.png | Bin 0 -> 175 bytes editor/jpicker/images/bar-red-br.png | Bin 0 -> 179 bytes editor/jpicker/images/bar-red-tl.png | Bin 0 -> 406 bytes editor/jpicker/images/bar-red-tr.png | Bin 0 -> 172 bytes editor/jpicker/images/bar-saturation.png | Bin 0 -> 257 bytes editor/jpicker/images/map-blue-max.png | Bin 0 -> 612 bytes editor/jpicker/images/map-blue-min.png | Bin 0 -> 637 bytes editor/jpicker/images/map-brightness.png | Bin 0 -> 6305 bytes editor/jpicker/images/map-green-max.png | Bin 0 -> 634 bytes editor/jpicker/images/map-green-min.png | Bin 0 -> 3293 bytes editor/jpicker/images/map-hue.png | Bin 0 -> 15712 bytes editor/jpicker/images/map-red-max.png | Bin 0 -> 614 bytes editor/jpicker/images/map-red-min.png | Bin 0 -> 614 bytes .../jpicker/images/map-saturation-overlay.png | Bin 0 -> 38806 bytes editor/jpicker/images/map-saturation.png | Bin 0 -> 6260 bytes editor/jpicker/images/mappoint.gif | Bin 0 -> 93 bytes editor/jpicker/images/picker.gif | Bin 0 -> 146 bytes editor/jpicker/images/rangearrows.gif | Bin 0 -> 94 bytes editor/jpicker/jpicker.css | 188 + editor/jpicker/jpicker.js | 1510 ++++++ editor/jquery.js | 4365 ++++++++++++++++- editor/svg-editor.css | 16 - editor/svg-editor.html | 10 +- editor/svg-editor.js | 80 +- 43 files changed, 6315 insertions(+), 808 deletions(-) delete mode 100644 COPYING create mode 100644 LICENSE delete mode 100644 editor/farbtastic.css delete mode 100644 editor/farbtastic.js delete mode 100644 editor/images/marker.png delete mode 100644 editor/images/mask.png delete mode 100644 editor/images/wheel.png create mode 100644 editor/jpicker/images/bar-blue-bl.png create mode 100644 editor/jpicker/images/bar-blue-br.png create mode 100644 editor/jpicker/images/bar-blue-tl.png create mode 100644 editor/jpicker/images/bar-blue-tr.png create mode 100644 editor/jpicker/images/bar-brightness.png create mode 100644 editor/jpicker/images/bar-green-bl.png create mode 100644 editor/jpicker/images/bar-green-br.png create mode 100644 editor/jpicker/images/bar-green-tl.png create mode 100644 editor/jpicker/images/bar-green-tr.png create mode 100644 editor/jpicker/images/bar-hue.png create mode 100644 editor/jpicker/images/bar-red-bl.png create mode 100644 editor/jpicker/images/bar-red-br.png create mode 100644 editor/jpicker/images/bar-red-tl.png create mode 100644 editor/jpicker/images/bar-red-tr.png create mode 100644 editor/jpicker/images/bar-saturation.png create mode 100644 editor/jpicker/images/map-blue-max.png create mode 100644 editor/jpicker/images/map-blue-min.png create mode 100644 editor/jpicker/images/map-brightness.png create mode 100644 editor/jpicker/images/map-green-max.png create mode 100644 editor/jpicker/images/map-green-min.png create mode 100644 editor/jpicker/images/map-hue.png create mode 100644 editor/jpicker/images/map-red-max.png create mode 100644 editor/jpicker/images/map-red-min.png create mode 100644 editor/jpicker/images/map-saturation-overlay.png create mode 100644 editor/jpicker/images/map-saturation.png create mode 100644 editor/jpicker/images/mappoint.gif create mode 100644 editor/jpicker/images/picker.gif create mode 100644 editor/jpicker/images/rangearrows.gif create mode 100644 editor/jpicker/jpicker.css create mode 100644 editor/jpicker/jpicker.js diff --git a/CHANGES b/CHANGES index d043438a..4837483d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,9 +1,12 @@ 2.0.1 - ???? ??, ???? --------------------- -* added tooltips (patch by codedread) -* fix flyout menus (patch by codedread) +* added tooltips +* fix flyout menus * ask before clearing the drawing (suggested by martin.vidner) -* control group, fill and stroke opacity (suggested by coderead) +* control group, fill and stroke opacity +* fix flyouts when using color picker +* change license from GPLv2 to Apache License v2.0 +* replaced Farbtastic with jPicker, because of the license issues 2.0 - June 03, 2009 ------------------ diff --git a/COPYING b/COPYING deleted file mode 100644 index d511905c..00000000 --- a/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README b/README index e9b26c19..581857b9 100644 --- a/README +++ b/README @@ -16,6 +16,6 @@ jQuery Right-Click Plugin http://abeautifulsite.net/notebook/68 Copyright (c) 2008 Cory S.N. LaViska -Farbtastic -http://acko.net/dev/farbtastic -Copyright (c) 2007 Steven Wittens +jPicker +http://www.digitalmagicpro.com/jPicker/ +Copyright (c) 2009 Christopher T. Tillman diff --git a/editor/farbtastic.css b/editor/farbtastic.css deleted file mode 100644 index ece6184c..00000000 --- a/editor/farbtastic.css +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Farbtastic Color Picker 1.2 - * © 2008 Steven Wittens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -.farbtastic { - position: relative; -} -.farbtastic * { - position: absolute; - cursor: crosshair; -} -.farbtastic, .farbtastic .wheel { - width: 195px; - height: 195px; -} -.farbtastic .color, .farbtastic .overlay { - top: 47px; - left: 47px; - width: 101px; - height: 101px; -} -.farbtastic .wheel { - background: url('images/wheel.png') no-repeat; - width: 195px; - height: 195px; -} -.farbtastic .overlay { - background: url('images/mask.png') no-repeat; -} -.farbtastic .marker { - width: 17px; - height: 17px; - margin: -8px 0 0 -8px; - overflow: hidden; - background: url('images/marker.png') no-repeat; -} diff --git a/editor/farbtastic.js b/editor/farbtastic.js deleted file mode 100644 index c346bda4..00000000 --- a/editor/farbtastic.js +++ /dev/null @@ -1,348 +0,0 @@ -/** - * Farbtastic Color Picker 1.2 - * © 2008 Steven Wittens - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -jQuery.fn.farbtastic = function (callback) { - $.farbtastic(this, callback); - return this; -}; - -jQuery.farbtastic = function (container, callback) { - var container = $(container).get(0); - return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback)); -} - -jQuery._farbtastic = function (container, callback) { - // Store farbtastic object - var fb = this; - - // Insert markup - $(container).html('
'); - var e = $('.farbtastic', container); - fb.wheel = $('.wheel', container).get(0); - // Dimensions - fb.radius = 84; - fb.square = 100; - fb.width = 194; - - // Fix background PNGs in IE6 - if (navigator.appVersion.match(/MSIE [0-6]\./)) { - $('*', e).each(function () { - if (this.currentStyle.backgroundImage != 'none') { - var image = this.currentStyle.backgroundImage; - image = this.currentStyle.backgroundImage.substring(5, image.length - 2); - $(this).css({ - 'backgroundImage': 'none', - 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')" - }); - } - }); - } - - /** - * Link to the given element(s) or callback. - */ - fb.linkTo = function (callback) { - // Unbind previous nodes - if (typeof fb.callback == 'object') { - $(fb.callback).unbind('keyup', fb.updateValue); - } - - // Reset color - fb.color = null; - - // Bind callback or elements - if (typeof callback == 'function') { - fb.callback = callback; - } - else if (typeof callback == 'object' || typeof callback == 'string') { - fb.callback = $(callback); - fb.callback.bind('keyup', fb.updateValue); - if (fb.callback.get(0).value) { - fb.setColor(fb.callback.get(0).value); - } - } - return this; - } - fb.updateValue = function (event) { - if (this.value && this.value != fb.color) { - fb.setColor(this.value); - } - } - - /** - * Change color with HTML syntax #123456 - */ - fb.setColor = function (color) { - var unpack = fb.unpack(color); - if (fb.color != color && unpack) { - fb.rgb = unpack; - fb.color = fb.pack(unpack); - fb.hsl = fb.RGBToHSL(fb.rgb); - fb.updateDisplay(); - } - return this; - } - - /** - * Change color with HSL triplet [0..1, 0..1, 0..1] - */ - fb.setHSL = function (hsl) { - fb.hsl = hsl; - fb.rgb = fb.HSLToRGB(hsl); - fb.color = fb.pack(fb.rgb); - fb.updateDisplay(); - return this; - } - - ///////////////////////////////////////////////////// - - /** - * Retrieve the coordinates of the given event relative to the center - * of the widget. - */ - fb.widgetCoords = function (event) { - var x, y; - var el = event.target || event.srcElement; - var reference = fb.wheel; - - if (typeof event.offsetX != 'undefined') { - // Use offset coordinates and find common offsetParent - var pos = { x: event.offsetX, y: event.offsetY }; - - // Send the coordinates upwards through the offsetParent chain. - var e = el; - while (e) { - e.mouseX = pos.x; - e.mouseY = pos.y; - pos.x += e.offsetLeft; - pos.y += e.offsetTop; - e = e.offsetParent; - } - - // Look for the coordinates starting from the wheel widget. - var e = reference; - var offset = { x: 0, y: 0 } - while (e) { - if (typeof e.mouseX != 'undefined') { - x = e.mouseX - offset.x; - y = e.mouseY - offset.y; - break; - } - offset.x += e.offsetLeft; - offset.y += e.offsetTop; - e = e.offsetParent; - } - - // Reset stored coordinates - e = el; - while (e) { - e.mouseX = undefined; - e.mouseY = undefined; - e = e.offsetParent; - } - } - else { - // Use absolute coordinates - var pos = fb.absolutePosition(reference); - x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x; - y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y; - } - // Subtract distance to middle - return { x: x - fb.width / 2, y: y - fb.width / 2 }; - } - - /** - * Mousedown handler - */ - fb.mousedown = function (event) { - // Capture mouse - if (!document.dragging) { - $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup); - document.dragging = true; - } - - // Check which area is being dragged - var pos = fb.widgetCoords(event); - fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square; - - // Process - fb.mousemove(event); - return false; - } - - /** - * Mousemove handler - */ - fb.mousemove = function (event) { - // Get coordinates relative to color picker center - var pos = fb.widgetCoords(event); - - // Set new HSL parameters - if (fb.circleDrag) { - var hue = Math.atan2(pos.x, -pos.y) / 6.28; - if (hue < 0) hue += 1; - fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]); - } - else { - var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5)); - var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5)); - fb.setHSL([fb.hsl[0], sat, lum]); - } - return false; - } - - /** - * Mouseup handler - */ - fb.mouseup = function () { - // Uncapture mouse - $(document).unbind('mousemove', fb.mousemove); - $(document).unbind('mouseup', fb.mouseup); - document.dragging = false; - } - - /** - * Update the markers and styles - */ - fb.updateDisplay = function () { - // Markers - var angle = fb.hsl[0] * 6.28; - $('.h-marker', e).css({ - left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px', - top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px' - }); - - $('.sl-marker', e).css({ - left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px', - top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px' - }); - - // Saturation/Luminance gradient - $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5]))); - - // Linked elements or callback - if (typeof fb.callback == 'object') { - // Set background/foreground color - $(fb.callback).css({ - backgroundColor: fb.color, - color: fb.hsl[2] > 0.5 ? '#000' : '#fff' - }); - - // Change linked value - $(fb.callback).each(function() { - if (this.value && this.value != fb.color) { - this.value = fb.color; - } - }); - } - else if (typeof fb.callback == 'function') { - fb.callback.call(fb, fb.color); - } - } - - /** - * Get absolute position of element - */ - fb.absolutePosition = function (el) { - var r = { x: el.offsetLeft, y: el.offsetTop }; - // Resolve relative to offsetParent - if (el.offsetParent) { - var tmp = fb.absolutePosition(el.offsetParent); - r.x += tmp.x; - r.y += tmp.y; - } - return r; - }; - - /* Various color utility functions */ - fb.pack = function (rgb) { - var r = Math.round(rgb[0] * 255); - var g = Math.round(rgb[1] * 255); - var b = Math.round(rgb[2] * 255); - return '#' + (r < 16 ? '0' : '') + r.toString(16) + - (g < 16 ? '0' : '') + g.toString(16) + - (b < 16 ? '0' : '') + b.toString(16); - } - - fb.unpack = function (color) { - if (color.length == 7) { - return [parseInt('0x' + color.substring(1, 3)) / 255, - parseInt('0x' + color.substring(3, 5)) / 255, - parseInt('0x' + color.substring(5, 7)) / 255]; - } - else if (color.length == 4) { - return [parseInt('0x' + color.substring(1, 2)) / 15, - parseInt('0x' + color.substring(2, 3)) / 15, - parseInt('0x' + color.substring(3, 4)) / 15]; - } else if (color.substring(0,4) == 'rgb(') { - color = color.substring(4, color.length-1).split(','); - return [ parseInt(color[0])/255, parseInt(color[1])/255, parseInt(color[2])/255 ]; - } - } - - fb.HSLToRGB = function (hsl) { - var m1, m2, r, g, b; - var h = hsl[0], s = hsl[1], l = hsl[2]; - m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s; - m1 = l * 2 - m2; - return [this.hueToRGB(m1, m2, h+0.33333), - this.hueToRGB(m1, m2, h), - this.hueToRGB(m1, m2, h-0.33333)]; - } - - fb.hueToRGB = function (m1, m2, h) { - h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h); - if (h * 6 < 1) return m1 + (m2 - m1) * h * 6; - if (h * 2 < 1) return m2; - if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6; - return m1; - } - - fb.RGBToHSL = function (rgb) { - var min, max, delta, h, s, l; - var r = rgb[0], g = rgb[1], b = rgb[2]; - min = Math.min(r, Math.min(g, b)); - max = Math.max(r, Math.max(g, b)); - delta = max - min; - l = (min + max) / 2; - s = 0; - if (l > 0 && l < 1) { - s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l)); - } - h = 0; - if (delta > 0) { - if (max == r && max != g) h += (g - b) / delta; - if (max == g && max != b) h += (2 + (b - r) / delta); - if (max == b && max != r) h += (4 + (r - g) / delta); - h /= 6; - } - return [h, s, l]; - } - - // Install mousedown handler (the others are set on the document on-demand) - $('*', e).mousedown(fb.mousedown); - - // Init color - fb.setColor('#000000'); - - // Set linked elements/callback - if (callback) { - fb.linkTo(callback); - } -} diff --git a/editor/images/marker.png b/editor/images/marker.png deleted file mode 100644 index 3929bbb51dd950802bb9bf12a397d1ac1e140610..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 652 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 diff --git a/editor/jpicker/images/bar-blue-bl.png b/editor/jpicker/images/bar-blue-bl.png new file mode 100644 index 0000000000000000000000000000000000000000..1ffcb504c65771ff88e69d23844751151624321f GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84Ny_Ar;B4q#jQ7|4{|aXaIkEcyzBp|w|uN0C;tgPd3OD@ m)JURHrPll<*FH^BKfn-w=HK5kH{B?p@eH1>elF{r5}E*jR6#}n literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-blue-br.png b/editor/jpicker/images/bar-blue-br.png new file mode 100644 index 0000000000000000000000000000000000000000..c4264013f711235fa45e36df039980f07c1223e4 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84N#Gvr;B4q#jQ7|4S5+DIG8s~d~n~WLSfF^`?Gx3S#8oe fO+3o4WR+m3n#01QVzB5D&}0TrS3j3^P6-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84Ny^_r;B4q#jQ7|75NwpI9N6)-~7LyN6a?ob@a<~>!+XC kq;r~Rq+hy2l97#}@+k}Ft9vO|frc}9y85}Sb4q9e01nPT>;M1& literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-blue-tr.png b/editor/jpicker/images/bar-blue-tr.png new file mode 100644 index 0000000000000000000000000000000000000000..a25d44a10725797ecbb857e491e2c31201996468 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84N#H4r;B4q#jQ7|H}WzVa4>IB`1*hPVg411_g3F}_DXe= h&S~P&{!d&64EBbs+*b|u7XgiC@O1TaS?83{1ONn>K|25d literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-brightness.png b/editor/jpicker/images/bar-brightness.png new file mode 100644 index 0000000000000000000000000000000000000000..d17b0f01802e91abfa82035bff6d64779b284075 GIT binary patch literal 263 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3><7g*5;jICP0cM-O<;Pfnog#bJnhxK)z&& zYeY$Kep*R+Vo@rCV@iHfs)A>3VtQ&&YGO)d;mK4RprV=TQEkBvy7))z84z(4Xz5;Y4gQu&X%Q~loCIH+LS}Xtn literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-green-bl.png b/editor/jpicker/images/bar-green-bl.png new file mode 100644 index 0000000000000000000000000000000000000000..a7debb35a2f7065fc7937a92f5d6cb34c9133a54 GIT binary patch literal 177 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84Ny_Ar;B4q#jQ7|4{|aXaIkEcyzBp|w|uN0C;tiF`SaQ) mozp}k|EH6qPDjsUU}lJV`0wv7zED@7@eH1>elF{r5}E*PkwpRk literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-green-br.png b/editor/jpicker/images/bar-green-br.png new file mode 100644 index 0000000000000000000000000000000000000000..e077fb1f209f5a1d00b238bc4e4b8cbb85a0e754 GIT binary patch literal 176 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84Ny^#r;B4q#jQ7|H}WzVa4>IB`1t?y7xo)k)#a&b(R2S! mO^uvJEc$so#`2B&0fy4=ES#7Aa~}tq&fw|l=d#Wzp$P!RX+H-5 literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-green-tl.png b/editor/jpicker/images/bar-green-tl.png new file mode 100644 index 0000000000000000000000000000000000000000..6b4cb4003b1346ebfb21f76a7e2e2526102a0e04 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84N#Gvr;B4q#jQ7|4S5+DIG7DQKIB(cD9m|#-|tn9*R<3~ gqR~&?^$g4mm8)5J{@;nR1)9v@>FVdQ&MBb@02qxq(f|Me literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-green-tr.png b/editor/jpicker/images/bar-green-tr.png new file mode 100644 index 0000000000000000000000000000000000000000..245c106edacd8b07a2d0aa5dab009a5b7ac41351 GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84N#Gvr;B4q#jQ7|7xFSNa4;Kq{P_R$;lvl$wokrt{mTDS hn{-YSjpVftFxWb>a?elDJ^?hD!PC{xWt~$(696d~L9YM+ literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-hue.png b/editor/jpicker/images/bar-hue.png new file mode 100644 index 0000000000000000000000000000000000000000..549b719da1f3e0f2fe3d6ab16ca8f9d2ba6b01fd GIT binary patch literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v}!F-O<;Pfnog#bJnhxK)z&& zYeY$Kep*R+Vo@rCV@iHfs)A>3VtQ&&YGO)d;mK4RprR5_7srr_TW@YSay1wTupCtE z`uBf#-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84Ny^_r;B4q#jQ7|H*zunn6py3Rju6{1-oD!M-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84Ny_2r;B4q#jQ8DH}WzVaIkE2Px?RgB;N(sefN}OeARAO n`6o)W5sm%{h4XQL7EWL&VQ1kCk(XHqw1C0W)z4*}Q$iB}@&h() literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-red-tl.png b/editor/jpicker/images/bar-red-tl.png new file mode 100644 index 0000000000000000000000000000000000000000..a50a0f56287e4a37f10bac9fb7db45c2f909deab GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84N!-Lr;B4q#jQ6tt}9JoWN1s=Z@Y=}X7%(H9I5Y>j4nCs z_#gd1>Xqf+d!L`P-Fx(M<&*u|?9wuX!JmB5{srCa2fsJ{=h`P+qy59}gZ#n$tpA1n z1b^82K)z``OFY*;ff~IZyB`=IT;8;w(@wBP=f~;?`c3^T@?3TTd-N;(KdgHod+>JC zc9wjudjfm(DtterADqv!o-0mpkIs+94^$6!H`#O4>HnDffc4<#ru$s;g#WmG$UeBa zDV@cid!CSuW`)y-9S;l-E^cyX;pdhUveBq;DA@nN?%>|0YL;^DI@KNC1`!R7~Q2YZ{OS*~-}DemwqSo=Wg;MJzpEa6=11a!*xXb8t>?GT7z`VrZ{ Y$Pn;EY`WPqaL6-wy85}Sb4q9e09LM?=>Px# literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-red-tr.png b/editor/jpicker/images/bar-red-tr.png new file mode 100644 index 0000000000000000000000000000000000000000..2b91cc7d917c14a7b3e875fcf65df332b8474a8a GIT binary patch literal 172 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3>-{Amd)*h$v{f7#5JNMI6tkVJh3R1!7(L2 zDOJHUH!(dmC^a#qvhZZ84N#Gvr;B4q#jQ7|7xFSNa4;Kq{P_R$;lvl$wokrt{m*Kh h)0>D!pSCjbFjxn&a_^7!;RKq@;OXk;vd$@?2>=LFK?nc< literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/bar-saturation.png b/editor/jpicker/images/bar-saturation.png new file mode 100644 index 0000000000000000000000000000000000000000..047fb1664d4c6e4458d93a247db9e61583aaf864 GIT binary patch literal 257 zcmeAS@N?(olHy`uVBq!ia0vp^A`A?S3><7g*5;jICP0cM-O<;Pfnog#bJnhxK)z&& zYeY$Kep*R+Vo@rCV@iHfs)A>3VtQ&&YGO)d;mK4RprXm1E{-7;x8B?~OF(2@2v4JQBE& zSiEABh8A;|5?8xS*CEArnW7VLLW8TlVNu7Sg{Ky+;Nf_&fe{MqS$@UyU$_aB&-L1;Fyx1 zl&avFo0y&&l$w}QS$HzlhJk^J&C|s(q~g|_%Z!{14m`{o`R?t1dhURAgp;U9-X*`J zvSNMSIjRgS3``7+4Gazp3Jd}a98~8jFfh`_V1$!t=z5SP96&_%U_rPZ82%0nezXbx chWVli43;IV+)8Zwt}y_Cr>mdKI;Vst0M`FSZ~y=R literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/map-blue-min.png b/editor/jpicker/images/map-blue-min.png new file mode 100644 index 0000000000000000000000000000000000000000..5329ad29979ed95d1efe68335b28c1620a05d51a GIT binary patch literal 637 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 literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/map-green-max.png b/editor/jpicker/images/map-green-max.png new file mode 100644 index 0000000000000000000000000000000000000000..702eab8d125ecf82d6097a592ee799b1d2f9f895 GIT binary patch literal 634 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLm(wt;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$HzlhJk@e#?!?yq~g|_Ya4kR40sqE)h|5wo9?S6a)e7{;fJ|4 zjZdfFxz^Q@=5yBa{_plxEDa0}3*wB3``7+ROhlJu+z$DsH17?egOt1AR-hn z2h6|Ea9_rtvFiEOw>qp1;vBRIOt_EBNRFouv)vmQ8SdQVRM70>@C7C&22WQ%mvv4F FO#p`#SBC%q literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/map-green-min.png b/editor/jpicker/images/map-green-min.png new file mode 100644 index 0000000000000000000000000000000000000000..01b3f99d14d0f31aa7d44e224245a75f9eefb422 GIT binary patch literal 3293 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 literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/map-hue.png b/editor/jpicker/images/map-hue.png new file mode 100644 index 0000000000000000000000000000000000000000..eae13e9254cdde2ca6b69e0c897d51c94acb726d GIT binary patch literal 15712 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 Yl=bAn6H@A)L>f4K^4y7v<3#fR2SiI(T>t<8 literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/map-red-max.png b/editor/jpicker/images/map-red-max.png new file mode 100644 index 0000000000000000000000000000000000000000..ebabdb92a7dbd97bb41138331950bbb6fcd07ef5 GIT binary patch literal 614 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLm(wt;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$HzlhJk^J!_&nvq~g|_%Lh3b95|Q{a$K)J-Sz+V0m&f8gw@ub zGwpbuNbkjSPl6nU<~xS;7QFR1X%o>p><9Gzils e_#dRRNHAEIuyW^1#w-IS90pHUKbLh*2~7Y1y-3dh literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/map-red-min.png b/editor/jpicker/images/map-red-min.png new file mode 100644 index 0000000000000000000000000000000000000000..5ef601a42cdff8c11256e651672801fe1e60b198 GIT binary patch literal 614 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911L)MWvCLm(wt;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$HzlhJk^J!_&nvq~g|_%Lh3b95|Q{a(uhL>CoQw%;_Gijc z8SUO#$9N!+$$>$EL4bjSfrWvIfw6&s>RcuP8W{|CGA&&Xw4?!qs2(hE*Mm%EdB8%O d;QtZH$i^Tf!NTt$tDMOI1fH&bF6*2Ung9U%NR9vi literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/map-saturation-overlay.png b/editor/jpicker/images/map-saturation-overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..6b30e2ad7a2d8f88f6a0a349a70644848f0a9499 GIT binary patch literal 38806 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

xJ+J@JSzZ0-rkVy1U|7z_aiaJ zYuBgAqjO#9$z$T-oIXwmof^C2$;} zKhnF25Tu#Nfn3Vy=Y+NUg&V}VkxU#88|D<=VR9?A6_O~)D-S^0J-l8#igHI$UKV>_ za4v&$1KM~idf5w@ZnpPA2peg1lj+$!44!&v(bmd-@t@^iWfBRJ{Z57r)nac9@W%k( zywq0m^51nRU0eMod4;(85hDP+)pLoXvHRAmmL5G<|20%DLLJ69X}NJzcA6RfA-L+6 z2Y0z7J4TgrNc@i3FFp1cD#Vn9zqtLHKEK78BViVq^(1(wJ zkx7&~?3il3e)b{aWJ(4PK}SXE=!2QPZUZcyG~2%qRJg#)jClF!_)(dK+P$;t-DEnk6r6{EOU_<`8y9Ny=d-tkIA)x1v4*x53$(Tn*L@CKNLdq*nF zrN&~Tn?FyHt7rF=A9PX>b+-HK;ij(Mc;{o8nA&MM5zhzG{D)d<>edDVwp6*ibL-qeiwMN4Mct& z%-LjA1G=w#VST?f?u7XS7ZU zia8*Xl$zk|@V`Mef+~zZg{q-KoCP3Mbvh8KH%zpI>^4Evn(Dflj6LM(E|xQESsX(@fZ&TGV&d4r_2rE(Te_M;@+ek;*TLoWowcuR?z_HTe1 zoY@F@E1%Lh(ielk%a-+X1}SSxD9+r{W?oJwrgrXii)dHPxjkWU@xAX1*Io1Kv`sv~ zWUb!DR>(T~w&RTgN(-|9h|^78KXfJZ(H6}$`|a#7o_!1Ox|iZuo!q@PfmGGLmD(sf zk;8S{8M6B-$(dVgMqHV$^KaGt-11B~DVs^Uj@3VY46uA!x|4Qm+;zpLI>*7)v~``a z-Htg;xX$i1Xi)Ei5447j!XcbY$Z237yXkWRHHloN$1C$qM|rO8JpRy4^X4M1HY)&n z-p*TvQ$TW3NGyAMMCM8ehX;sbmTCKMvUqc-&q@b&6-7VR+PfW&;a)%3-gb!1ED&*WW@NAi0RAo>Pyhe` literal 0 HcmV?d00001 diff --git a/editor/jpicker/images/picker.gif b/editor/jpicker/images/picker.gif new file mode 100644 index 0000000000000000000000000000000000000000..374d891042f22ff5c23eed3148b6ae5fe2cfdb1c GIT binary patch literal 146 zcmZ?wbhEHblw^=#Sj56`S)_gx__~2Yh?c=8>m+y){r~YPZmz!j+@QWJ- rTTkXiR9;#Y7Lm*_bDc!X*~6o0ZXGB7YP=m6OaAbAEReG$Etr{7jLaE9#b t7GCi1!@Slr$13Nmrlsthrg<&Q@Rwb&_w{c(pZ$t6RH$3jv4DZW8UXTXBuxMS literal 0 HcmV?d00001 diff --git a/editor/jpicker/jpicker.css b/editor/jpicker/jpicker.css new file mode 100644 index 00000000..ca61bc47 --- /dev/null +++ b/editor/jpicker/jpicker.css @@ -0,0 +1,188 @@ +/*[compact]*/ +.jPicker_Picker { + display: inline-block; + height: 24px; /* change this value if using a different sized color picker icon */ + position: relative; /* make this element an absolute positioning container */ + text-align: left; /* make the zero width children position to the left of container */ + width: 25px; /* change this value if using a different sized color picker icon */ +} +.jPicker_Color { + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + width: 100%; +} +.jPicker_Icon { + background-repeat: no-repeat; + cursor: pointer; + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + width: 100%; +} +.jPicker_Container { + display: none; + z-index: 10; /* make sure container draws above color picker icon in Firefox/Safari/Chrome/Opera/etc. - + IE calculates z-index so this won't work - we will hide all color picker icons placed after the selected one in code when shown in IE */ +} +.jPicker_table { + background-color: #efefef; + border: 1px outset #666; + font-family: Arial, Helvetica, Sans-Serif; + font-size: 12px; + height: 320px; + margin: 0px; + padding: 5px; + width: 560px; +} +.jPicker_table td { + margin: 0px; + padding: 0px; + vertical-align: top; +} +.jPicker_MoveBar { + background-color: #dddddd; + border: 1px outset #aaa; + cursor: move; + height: 12px; +} +.jPicker_ColorMap { + border: 2px inset #eee; + cursor: crosshair; + height: 260px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 256px later */ + margin: 12px 5px; + overflow: hidden; /* hide the overdraw of the Color Map icon when at edge of viewing box */ + padding: 0px; + position: relative; /* make this element an absolute positioning container */ + width: 260px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 256px later */ +} +div[class="jPicker_ColorMap"] { + height: 256px; /* correct to 256px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ + width: 256px; /* correct to 256px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ +} +.jPicker_ColorMap_l1, .jPicker_ColorMap_l2 { + background-repeat: no-repeat; + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + width: 100%; +} +.jPicker_ColorMap_l1 { + background-color: #000000; + background-image: none; +} +.jPicker_ColorMap_l2 { + background-color: transparent; +} +.jPicker_ColorMap_Arrow { + display: block; + position: absolute; +} +.jPicker_ColorBar { + border: 2px inset #eee; + cursor: n-resize; + height: 260px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 256px later */ + margin: 12px 10px; + padding: 0px; + position: relative; + width: 24px; /* IE 6 incorrectly draws border inside the width and height instead of outside - We will fix this to 20px later */ +} +div[class="jPicker_ColorBar"] { + height: 256px; /* correct to 256px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ + width: 20px; /* correct to 20px for browsers that support the "[class="xxx"]" selector (IE7+,Firefox,Safari,Chrome,Opera,etc.) */ +} +.jPicker_ColorBar_l1, .jPicker_ColorBar_l2, .jPicker_ColorBar_l3, .jPicker_ColorBar_l4 { + background-repeat: no-repeat; + display: block; + height: 100%; + left: 0px; + position: absolute; + top: 0px; + width: 100%; +} +.jPicker_ColorBar_l1, .jPicker_ColorBar_l2, .jPicker_ColorBar_l3 { + background-color: transparent; + background-image: none; +} +.jPicker_ColorBar_l4 { + background-color: transparent; +} +.jPicker_ColorBar_Arrow { + display: block; + left: -10px; /* (arrow width / 2) - (element width / 2) - position arrows' center in elements' center */ + position: absolute; +} +.jPicker_Preview { + font-size: x-small; + text-align: center; +} +.jPicker_Preview div { + border: 2px inset #eee; + height: 62px; + margin: 0px auto; + padding: 0px; + width: 62px; +} +.jPicker_Preview div span { + border: 1px solid #000; + display: block; + height: 30px; + margin: 0px auto; + padding: 0px; + width: 60px; +} +.jPicker_Preview div span.jPicker_Active { + border-bottom-width: 0px; +} +.jPicker_Preview div span.jPicker_Current { + border-top-width: 0px; + cursor: pointer; +} +.jPicker_OkCancel { + text-align: center; + width: 120px; +} +.jPicker_OkCancel input { + width: 100px; +} +.jPicker_OkCancel input.jPicker_Ok { + margin: 12px 0px 5px 0px; +} +.jPicker_Spacer { + height: 10px; +} +.jPicker_RadioText { + background-color: #fff; + border: 1px inset #aaa; + margin: 0px 0px 0px 5px; + width: 30px; +} +.jPicker_EnterHex { + text-align: right; +} +.jPicker_Hex { + background-color: #fff; + border: 1px inset #aaa; + margin: 0px 19px 0px 5px; + width: 50px; +} +.jPicker_Grid { + text-align: center; +} +.jPicker_QuickColor { + border: 1px inset #aaa; + cursor: pointer; + display: block; + float: left; + height: 12px; + line-height: 12px; + margin: 2px 3px 1px 3px; + padding: 0px; + width: 12px; +} diff --git a/editor/jpicker/jpicker.js b/editor/jpicker/jpicker.js new file mode 100644 index 00000000..7392cb16 --- /dev/null +++ b/editor/jpicker/jpicker.js @@ -0,0 +1,1510 @@ +/* + * jPicker 1.0.2 + * + * jQuery Plugin for Photoshop style color picker + * + * Copyright (c) 2009 Christopher T. Tillman + * Digital Magic Productions, Inc. (http://www.digitalmagicpro.com/) + * MIT style license, FREE to use, alter, copy, sell, and especially ENHANCE + * + * Painstakingly ported from John Dyers' excellent work on his own color picker based on the Prototype framework. + * + * John Dyers' website: (http://johndyer.name) + * Color Picker page: (http://johndyer.name/post/2007/09/PhotoShop-like-JavaScript-Color-Picker.aspx) + * + */ +(function($) +{ + var Slider = // encapsulate slider functionality for the ColorMap and ColorBar - could be useful to use a jQuery UI draggable for this with certain extensions + function(id, options) + { + var $this = this, // private properties, methods, and events - keep these variables and classes invisible to outside code + bar = $('#' + id), // 1D or 2D area used for dragging + arrow = $('#' + id + '_Arrow'), // the arrow image image to drag + barMouseDown = // bind the mousedown to the bar not the arrow for quick snapping to the clicked location + function(e) + { + setValuesFromMousePosition(e); + // Bind mousemove and mouseup event to the document so it responds when dragged of of the bar - we will unbind these when on mouseup to save processing + $(document).bind('mousemove', docMouseMove).bind('mouseup', docMouseUp); + e.stopPropagation(); + e.preventDefault(); // don't try to select anything or drag the image to the desktop + return false; + }, + docMouseMove = // set the values as the mouse moves + function(e) + { + setValuesFromMousePosition(e); + e.stopPropagation(); + e.preventDefault(); + return false; + }, + docMouseUp = // unbind the document events - they aren't needed when not dragging + function(e) + { + $(document).unbind('mouseup', docMouseUp).unbind('mousemove', docMouseMove); + e.stopPropagation(); + e.preventDefault(); + return false; + }, + setValuesFromMousePosition = // calculate mouse position and set value within the current range + function(e) + { + var offset = bar.offset(), // lets not calculate this more than once + x = e.pageX - offset.left - parseInt(bar.css('border-left-width')), + y = e.pageY - offset.top - parseInt(bar.css('border-top-width')), + barW = bar.w, // local copies for YUI compressor + barH = bar.h, + newX, + newY; + // keep the arrow within the bounds of the bar + if (x < 0) x = 0; + else if (x > barW) x = barW; + if (y < 0) y = 0; + else if (y > barH) y = barH; + // we will use Math.floor for ALL conversion to pixel lengths - parseInt takes a string as input so it boxes the number into a string THEN converts it + // number.toFixed(0) spends time processing rounding which when dealing with imprecise pixels is unnecessary + newX = Math.floor(x / barW * $this.mxX); + newY = Math.floor(y / barH * $this.mxY); + $this.x = newX; + $this.y = newY; + // if x or y have no range, set it to 1D dragging + if ($this.mxX == $this.mnX) x = 0; + if ($this.mxY == $this.mnY) y = 0; + // set the arrow position + $this.setArrowPosition(x, y); + // check if this.valuesChanged is a function and execute it if it is + $.isFunction($this.valuesChanged) && $this.valuesChanged($this); + }; + $.extend(true, $this, // public properties, methods, and event - these we need to access from other controls + { + settings: options, // we'll set map and arrow dimensions and image sources + x: 0, // this is the calculated x value based on the x range and mouse position + y: 0, // this is the calculated y value based on the y range and mouse position + mnX: 0, // set the min x value + mxX: 0, // set the max x value + mnY: 100, // set the min y value + mxY: 100, // set the max y value + valuesChanged: $.isFunction(arguments[2]) && arguments[2] || null, // pass this argument or assign the variable to register for callbacks + setPositioningVariables: + function(e) + { + var map = $this.settings.map; // local copy for YUI compressor + bar.w = map && map.width || bar.width(); + bar.h = map && map.height || bar.height(); + $this.MinX = 0; + $this.MinY = 0; + $this.MaxX = bar.w; + $this.MaxY = bar.h; + }, + setArrowPositionFromValues: + function(e) + { + $this.setPositioningVariables(); + var arrowOffsetX = 0, + arrowOffsetY = 0, + // local copies for YUI compressor + mnX = $this.mnX, + mxX = $this.mxX, + mnY = $this.mnY, + mxY = $this.mxY, + x = $this.x, + y = $this.y; + if (mnX != mxX) // range is greater than zero + { + // constrain to bounds + if (x == mnX) arrowOffsetX = 0; + else if (x == mxX) arrowOffsetX = bar.w; + else // set arrow x position + { + if (mnX < 1) mxX += Math.abs(mnX) + 1; + if (x < 1) x += 1; + arrowOffsetX = x / mxX * bar.w; + if (parseInt(arrowOffsetX) == (mxX - 1)) arrowOffsetX = mxX; + else arrowOffsetX = parseInt(arrowOffsetX); + if (mnX < 1) arrowOffsetX -= Math.abs(mnX) - 1; + } + } + if (mnY != mxY) // range is greater than zero + { + // constrain to bounds + if (y == mnY) arrowOffsetY = 0; + else if (y == mxY) arrowOffsetY = bar.h; + else // set arrow y position + { + if (mnY < 1) mxY += Math.abs(mnY) + 1; + if (y < 1) y += 1; + arrowOffsetY = y / mxY * bar.h; + if (parseInt(arrowOffsetY) == (mxY - 1)) arrowOffsetY = mxY; + else arrowOffsetY = parseInt(arrowOffsetY); + if (mnY < 1) arrowOffsetY -= Math.abs(mnY) - 1; + } + } + // set the arrow position based on these offsets + $this.setArrowPosition(arrowOffsetX, arrowOffsetY); + }, + setArrowPosition: + function(offsetX, offsetY) + { + var barW = bar.w, // local copies for YUI compressor + barH = bar.h, + arrowW = arrow.w, + arrowH = arrow.h; + // constrain arrow to bar x + if (offsetX < 0) offsetX = 0; + else if (offsetX > barW) offsetX = barW; + // constrain arrow to bar y + if (offsetY < 0) offsetY = 0; + else if (offsetY > barH) offsetY = barH; + // if arrow width is greater than bar width, center arrow and prevent horizontal dragging + if (arrowW > barW) offsetX = (barW >> 1) - (arrowW >> 1); // number >> 1 - superfast bitwise divide by two and truncate (move bits over one bit discarding lowest) + else offsetX -= arrowW >> 1; + // if arrow height is greater than bar height, center arrow and prevent vertical dragging + if (arrowH > barH) offsetY = (barH >> 1) - (arrowH >> 1); + else offsetY -= arrowH >> 1; + // set the elements offsets + arrow.css({ left: offsetX + 'px', top: offsetY + 'px' }); + }, + destroy: + function() + { + // unbind all possible events and null objects + $(document).unbind('mouseup', docMouseUp).unbind('mousemove', docMouseMove); + bar.unbind('mousedown', barMouseDown); + bar = null; + arrow = null; + $this.valuesChanged = null; + } + }); + // initialize this control + arrow.src = $this.settings.arrow && $this.settings.arrow.image; + arrow.w = $this.settings.arrow && $this.settings.arrow.width || arrow.width(); + arrow.h = $this.settings.arrow && $this.settings.arrow.height || arrow.height(); + $this.setPositioningVariables(); + // bind mousedown event + bar.bind('mousedown', barMouseDown); + $this.setArrowPositionFromValues(); + // first callback to set initial values + $.isFunction($this.valuesChanged) && $this.valuesChanged($this); + }, + ColorValuePicker = // controls for all the input elements for the typing in color values + function(id) + { + var $this = this, // private properties and methods + hsvKeyUp = // hue, saturation, or brightness input box key up - validate value and set color + function(e) + { + if (e.target.value == '') return; + validateHsv(e); + $this.setValuesFromHsv(); + $.isFunction($this.valuesChanged) && $this.valuesChanged($this); + }, + rgbKeyUp = // red, green, or blue input box key up - validate and set color + function(e) + { + if (e.target.value == '') return; + validateRgb(e); + $this.setValuesFromRgb(); + $.isFunction($this.valuesChanged) && $this.valuesChanged($this); + }, + hsvBlur = // hue, saturation, or brightness input box blur - reset to original if value empty + function(e) + { + if (e.target.value == '') $this.setValuesFromRgb(); + }, + rgbBlur = // red, green, or blue input box blur - reset to original value if empty + function(e) + { + if (e.target.value == '') $this.setValuesFromHsv(); + }, + hexKeyUp = // hex input box key up - validate and set color + function(e) + { + if (e.target.value == '') return; + validateHex(e); + $this.setValuesFromHex(); + $.isFunction($this.valuesChanged) && $this.valuesChanged($this); + }, + hexBlur = // hex input box blur - reset to original value if empty + function(e) + { + if (e.target.value == '') $this.setValuesFromHsv(); + }, + validateRgb = // validate rgb values + function(e) + { + if (!validateKey(e)) return e; + fields.red.val(setValueInRange(fields.red.val(), 0, 255)); + fields.green.val(setValueInRange(fields.green.val(), 0, 255)); + fields.blue.val(setValueInRange(fields.blue.val(), 0, 255)); + }, + validateHsv = // validate hsv values + function(e) + { + if (!validateKey(e)) return e; + fields.hue.val(setValueInRange(fields.hue.val(), 0, 360)); + fields.saturation.val(setValueInRange(fields.saturation.val(), 0, 100)); + fields.value.val(setValueInRange(fields.value.val(), 0, 100)); + }, + validateHex = // validate hex value + function(e) + { + if (!validateKey(e)) return e; + fields.hex.val(fields.hex.val().replace(/[^a-fA-F0-9]/g, '0').toLowerCase().substring(0, 6)); + }, + validateKey = // validate key + function(e) + { + switch(e.keyCode) + { + case 9: + case 16: + case 29: + case 37: + case 38: + case 40: + return false; + case 'c'.charCodeAt(): + case 'v'.charCodeAt(): + if (e.ctrlKey) return false; + } + return true; + }, + setValueInRange = // constrain value within range + function(value, min, max) + { + if (value == '' || isNaN(value)) return min; + value = parseInt(value); + if (value > max) return max; + if (value < min) return min; + return value; + }; + $.extend(true, $this, // public properties and methods + { + color: new Color(), + fields: + { + hue: $('#' + id + '_jPicker_Hue'), + saturation: $('#' + id + '_jPicker_Saturation'), + value: $('#' + id + '_jPicker_Brightness'), + red: $('#' + id + '_jPicker_Red'), + green: $('#' + id + '_jPicker_Green'), + blue: $('#' + id + '_jPicker_Blue'), + hex: $('#' + id + '_jPicker_Hex') + }, + valuesChanged: $.isFunction(arguments[1]) && arguments[1] || null, + bindedHexKeyUp: // binded input element key up + function(e) + { + hexKeyUp(e); + }, + setValuesFromRgb: // set values when rgb changes + function() + { + color.fromRgb(fields.red.val(), fields.green.val(), fields.blue.val()); + fields.hex.val(color.hex); + fields.hue.val(color.h); + fields.saturation.val(color.s); + fields.value.val(color.v); + }, + setValuesFromHsv: // set values when hsv changes + function() + { + color.fromHsv(fields.hue.val(), fields.saturation.val(), fields.value.val()); + fields.hex.val(color.hex); + fields.red.val(color.r); + fields.green.val(color.g); + fields.blue.val(color.b); + }, + setValuesFromHex: // set values when hex changes + function() + { + color.fromHex(fields.hex.val()); + fields.red.val(color.r); + fields.green.val(color.g); + fields.blue.val(color.b); + fields.hue.val(color.h); + fields.saturation.val(color.s); + fields.value.val(color.v); + }, + destroy: + function() + { + // unbind all events and null objects + fields.hue.add(fields.saturation).add(fields.value).unbind('keyup', events.hsvKeyUp).unbind('blur', hsvBlur); + fields.red.add(fields.green).add(fields.blue).unbind('keyup', events.rgbKeyUp).unbind('blur', rgbBlur); + fields.hex.unbind('keyup', $this.hexKeyUp); + fields = null; + color = null; + $this.valuesChanged = null; + } + }); + var fields = $this.fields, color = $this.color; // local copies for YUI compressor + fields.hue.add(fields.saturation).add(fields.value).bind('keyup', hsvKeyUp).bind('blur', hsvBlur); + fields.red.add(fields.green).add(fields.blue).bind('keyup', rgbKeyUp).bind('blur', rgbBlur); + fields.hex.bind('keyup', hexKeyUp); + if (fields.hex.val() != '') + { + color.fromHex(fields.hex.val()); + $this.setValuesFromHex(); + } + }; + $.jPicker = + { + List: [], // array holding references to each active instance of the control + getListElementById: // retrieve the jPicker object by the initiating objects id + function(id) + { + var List = $.jPicker.List; + for (i = 0; i < List.length; i++) if (List[i].id == id) return List[i]; + return null; + }, + Color: // color object - we will be able to assign by any color space type or retrieve any color space info + // we want this public so we can optionally assign new color objects to initial values using inputs other than a string hex value (also supported) + function(init) + { + var $this = this; + $.extend(true, $this, // public properties and methods + { + r: 0, // Red + g: 0, // Green + b: 0, // Blue + h: 0, // Hue + s: 0, // Saturation + v: 0, // Brightness + hex: '', // Hex + fromRgb: + function(r, g, b) + { + var $this = this; + $this.r = r; + $this.g = g; + $this.b = b; + var newHsv = ColorMethods.rgbToHsv($this); + $this.h = newHsv.h; + $this.s = newHsv.s; + $this.v = newHsv.v; + $this.hex = ColorMethods.rgbToHex($this); + }, + fromHsv: + function(h, s, v) + { + var $this = this; + $this.h = h; + $this.s = s; + $this.v = v; + var newRgb = ColorMethods.hsvToRgb($this); + $this.r = newRgb.r; + $this.g = newRgb.g; + $this.b = newRgb.b; + $this.hex = ColorMethods.rgbToHex(newRgb); + }, + fromHex: + function(hex) + { + var $this = this; + $this.hex = hex; + var newRgb = ColorMethods.hexToRgb(hex); + $this.r = newRgb.r; + $this.g = newRgb.g; + $this.b = newRgb.b; + var newHsv = ColorMethods.rgbToHsv(newRgb); + $this.h = newHsv.h; + $this.s = newHsv.s; + $this.v = newHsv.v; + $this.hex = ColorMethods.rgbToHex(newRgb); + } + }); + if (init) + { + if (init.hex) $this.fromHex(init.hex); + else if (init.r) $this.fromRgb(init.r, init.g, init.b); + else if (init.h) $this.fromHsv(init.h, init.s, init.v); + } + }, + ColorMethods: // color conversion methods - make public to give use to external scripts + { + hexToRgb: + function(hex) + { + hex = this.validateHex(hex); + var r = '00', g = '00', b = '00'; + if (hex.length == 6) + { + r = hex.substring(0, 2); + g = hex.substring(2, 4); + b = hex.substring(4, 6); + } + else + { + if (hex.length > 4) + { + r = hex.substring(4, hex.length); + hex = hex.substring(0, 4); + } + if (hex.length > 2) + { + g = hex.substring(2, hex.length); + hex = hex.substring(0, 2); + } + if (hex.length > 0) b = hex.substring(0, hex.length); + } + return { r: this.hexToInt(r), g: this.hexToInt(g), b: this.hexToInt(b) }; + }, + validateHex: + function(hex) + { + hex = hex.toLowerCase().replace(/[^a-f0-9]/g, '0'); + if (hex.length > 6) hex = hex.substring(0, 6); + return hex; + }, + rgbToHex: + function(rgb) + { + return this.intToHex(rgb.r) + this.intToHex(rgb.g) + this.intToHex(rgb.b); + }, + intToHex: + function(dec) + { + var result = parseInt(dec).toString(16); + if (result.length == 1) result = ('0' + result); + return result.toLowerCase(); + }, + hexToInt: + function(hex) + { + return parseInt(hex, 16); + }, + rgbToHsv: + function(rgb) + { + var r = rgb.r / 255, g = rgb.g / 255, b = rgb.b / 255, hsv = { h: 0, s: 0, v: 0 }, min = 0, max = 0, delta; + if (r >= g && r >= b) + { + max = r; + min = g > b ? b : g; + } + else if (g >= b && g >= r) + { + max = g; + min = r > b ? b : r; + } + else + { + max = b; + min = g > r ? r : g; + } + hsv.v = max; + hsv.s = max ? (max - min) / max : 0; + if (!hsv.s) hsv.h = 0; + else + { + delta = max - min; + if (r == max) hsv.h = (g - b) / delta; + else if (g == max) hsv.h = 2 + (b - r) / delta; + else hsv.h = 4 + (r - g) / delta; + hsv.h = parseInt(hsv.h * 60); + if (hsv.h < 0) hsv.h += 360; + } + hsv.s = parseInt(hsv.s * 100); + hsv.v = parseInt(hsv.v * 100); + return hsv; + }, + hsvToRgb: + function(hsv) + { + var rgb = { r: 0, g: 0, b: 0 }, h = hsv.h, s = hsv.s, v = hsv.v; + if (s == 0) + { + if (v == 0) rgb.r = rgb.g = rgb.b = 0; + else rgb.r = rgb.g = rgb.b = parseInt(v * 255 / 100); + } + else + { + if (h == 360) h = 0; + h /= 60; + s = s / 100; + v = v / 100; + var i = parseInt(h), + f = h - i, + p = v * (1 - s), + q = v * (1 - (s * f)), + t = v * (1 - (s * (1 - f))); + switch (i) + { + case 0: + rgb.r = v; + rgb.g = t; + rgb.b = p; + break; + case 1: + rgb.r = q; + rgb.g = v; + rgb.b = p; + break; + case 2: + rgb.r = p; + rgb.g = v; + rgb.b = t; + break; + case 3: + rgb.r = p; + rgb.g = q; + rgb.b = v; + break; + case 4: + rgb.r = t; + rgb.g = p; + rgb.b = v; + break; + case 5: + rgb.r = v; + rgb.g = p; + rgb.b = q; + break; + } + rgb.r = parseInt(rgb.r * 255); + rgb.g = parseInt(rgb.g * 255); + rgb.b = parseInt(rgb.b * 255); + } + return rgb; + } + } + }; + var Color = $.jPicker.Color, List = $.jPicker.List, ColorMethods = $.jPicker.ColorMethods; // local copies for YUI compressor + $.fn.jPicker = + function(options) + { + var $arguments = arguments; + return this.each( + function() + { + var $this = $(this), id = $this.attr('id'), $settings = $.extend(true, {}, $.fn.jPicker.defaults, options); // local copies for YUI compressor + if (!id) + { + alert('Container element must have an id attribute to maintain unique id strings for sub-elements.'); + return; + } + if ($this.get(0).nodeName.toLowerCase() == 'input') // Add color picker icon if binding to an input element and bind the events to the input + { + $.extend(true, $settings, + { + window: + { + bindToInput: true, + input: $this + } + }); + if (ColorMethods.validateHex($this.val())) + { + $settings.color.active = new Color({ hex: $this.val() }); + $settings.color.current = new Color({ hex: $this.val() }); + } + $this.after('   '); + } + else // Basic control binding for inline use - You will need to override the liveCallback or commitCallback function to retrieve results + { + $settings.window.draggable = false; + $settings.window.liveUpdate = false; + } + var isLessThanIE7 = parseFloat(navigator.appVersion.split('MSIE')[1]) < 7 && document.body.filters, // needed to run the AlphaImageLoader function for IE6 + colorMapL1 = null, // different layers of colorMap and colorBar + colorMapL2 = null, + colorBarL1 = null, + colorBarL2 = null, + colorBarL3 = null, + colorBarL4 = null, + container = null, + hue = null, // radio buttons + saturation = null, + value = null, + red = null, + green = null, + blue = null, + colorMap = null, // color maps + colorBar = null, + colorPicker = null, + elementStartX = null, // Used to record the starting css positions for dragging the control + elementStartY = null, + pageStartX = null, // Used to record the mousedown coordinates for dragging the control + pageStartY = null, + activeColor = null, // color boxes above the radio buttons + currentColor = null, + okButton = null, + cancelButton = null, + grid = null, // preset colors grid + colorBox = null, // colorBox for popup button + colorIcon = null, // colorIcon popup icon + moveBar = null, // drag bar + setColorMode = // set color mode and update visuals for the new color mode + function(colorMode) + { + color.active = colorPicker.color; + var active = color.active, // local copies for YUI compressor + clientPath = images.clientPath, + resetImage = + function(img) + { + setAlpha(img, 100); + img.css({ backgroundColor: '', backgroundImage: 'none', filter: '' }); + }; + resetImage(colorMapL1); // reset images + resetImage(colorMapL2); + resetImage(colorBarL1); + resetImage(colorBarL2); + resetImage(colorBarL3); + resetImage(colorBarL4); + hue.add(saturation).add(value).add(red).add(green).add(blue).removeAttr('checked'); + switch (colorMode) + { + case 'h': + hue.attr('checked', true); + colorMapL1.css({ backgroundColor: '#' + active.hex }); + colorMapL2.css({ backgroundColor: 'transparent' }); + setImg(colorMapL2, clientPath + 'map-hue.png'); + setAlpha(colorMapL2, 100); + setImg(colorBarL4, clientPath + 'bar-hue.png'); + colorMap.mxX = 100; + colorMap.mxY = 100; + colorBar.mxY = 360; + break; + case 's': + saturation.attr('checked', true); + setImg(colorMapL1, clientPath + 'map-saturation.png'); + setImg(colorMapL2, clientPath + 'map-saturation-overlay.png'); + setAlpha(colorMapL2, 0); + setBG(colorBarL3, active.hex); + setImg(colorBarL4, clientPath + 'bar-saturation.png'); + colorMap.mxX = 360; + colorMap.mxY = 100; + colorBar.mxY = 100; + break; + case 'v': + value.attr('checked', true); + setBG(colorMapL1, '000'); + setImg(colorMapL2, clientPath + 'map-brightness.png'); + colorBarL3.css({ backgroundColor: '#' + active.hex }); + setImg(colorBarL4, clientPath + 'bar-brightness.png'); + colorMap.mxX = 360; + colorMap.mxY = 100; + colorBar.mxY = 100; + break; + case 'r': + red.attr('checked', true); + setImg(colorMapL2, clientPath + 'map-red-max.png'); + setImg(colorMapL1, clientPath + 'map-red-min.png'); + setImg(colorBarL4, clientPath + 'bar-red-tl.png'); + setImg(colorBarL3, clientPath + 'bar-red-tr.png'); + setImg(colorBarL2, clientPath + 'bar-red-br.png'); + setImg(colorBarL1, clientPath + 'bar-red-bl.png'); + break; + case 'g': + green.attr('checked', true); + setImg(colorMapL2, clientPath + 'map-green-max.png'); + setImg(colorMapL1, clientPath + 'map-green-min.png'); + setImg(colorBarL4, clientPath + 'bar-green-tl.png'); + setImg(colorBarL3, clientPath + 'bar-green-tr.png'); + setImg(colorBarL2, clientPath + 'bar-green-br.png'); + setImg(colorBarL1, clientPath + 'bar-green-bl.png'); + break; + case 'b': + blue.attr('checked', true); + setImg(colorMapL2, clientPath + 'map-blue-max.png'); + setImg(colorMapL1, clientPath + 'map-blue-min.png'); + setImg(colorBarL4, clientPath + 'bar-blue-tl.png'); + setImg(colorBarL3, clientPath + 'bar-blue-tr.png'); + setImg(colorBarL2, clientPath + 'bar-blue-br.png'); + setImg(colorBarL1, clientPath + 'bar-blue-bl.png'); + break; + default: + throw ('Invalid Mode'); + break; + } + switch (colorMode) + { + case 'h': + case 's': + case 'v': + colorMap.mnX = 1; + colorMap.mnY = 1; + colorBar.mnY = 1; + break; + case 'r': + case 'g': + case 'b': + colorMap.mnX = 0; + colorMap.mnY = 0; + colorBar.mnY = 0; + colorMap.mxX = 255; + colorMap.mxY = 255; + colorBar.mxY = 255; + break; + } + color.mode = colorMode; + positionMapAndBarArrows(); + updateMapVisuals(); + updateBarVisuals(); + if (window.bindToInput && window.liveUpdate) + { + window.input.val(active.hex).css( + { + backgroundColor: '#' + active.hex, + color: active.v > 75 ? '#000000' : '#ffffff' + }); + colorBox.css({ backgroundColor: '#' + active.hex }); + } + $.isFunction($this.liveCallback) && $this.liveCallback(active); + }, + textValuesChanged = // Update color when user changes text values + function() + { + positionMapAndBarArrows(); + updateVisuals(); + color.active = colorPicker.color; + var active = color.active; // local copy for YUI compressor + if (window.bindToInput && window.liveUpdate) + { + window.input.val(colorPicker.fields.hex.val()).css( + { + backgroundColor: '#' + active.hex, + color: active.v > 75 ? '#000000' : '#ffffff' + }); + colorBox.css({ backgroundColor: '#' + active.hex }); + } + $.isFunction($this.liveCallback) && $this.liveCallback(active); + }, + mapValueChanged = // user has dragged the ColorMap pointer + function() + { + if (!colorPicker || !colorMap || !colorBar) return; + color.active = colorPicker.color; + var fields = colorPicker.fields, // local copies for YUI compressor + active = color.active; + switch (color.mode) + { + case 'h': + fields.saturation.val(colorMap.x); + fields.value.val(100 - colorMap.y); + break; + case 's': + fields.hue.val(colorMap.x); + fields.value.val(100 - colorMap.y); + break; + case 'v': + fields.hue.val(colorMap.x); + fields.saturation.val(100 - colorMap.y); + break; + case 'r': + fields.blue.val(colorMap.x); + fields.green.val(255 - colorMap.y); + break; + case 'g': + fields.blue.val(colorMap.x); + fields.red.val(255 - colorMap.y); + break; + case 'b': + fields.red.val(colorMap.x); + fields.green.val(255 - colorMap.y); + break; + } + switch (color.mode) + { + case 'h': + case 's': + case 'v': + colorPicker.setValuesFromHsv(); + break; + case 'r': + case 'g': + case 'b': + colorPicker.setValuesFromRgb(); + break; + } + updateVisuals(); + if (window.bindToInput && window.liveUpdate) + { + window.input.val(active.hex).css( + { + backgroundColor: '#' + active.hex, + color: active.v > 75 ? '#000000' : '#ffffff' + }); + colorBox.css({ backgroundColor: '#' + active.hex }); + } + $.isFunction($this.liveCallback) && $this.liveCallback(active); + }, + barValueChanged = // user has dragged the ColorBar slider + function() + { + if (!colorPicker || !colorMap || !colorBar) return; + color.active = colorPicker.color; + var fields = colorPicker.fields, // local copies for YUI compressor + active = color.active; + switch (color.mode) + { + case 'h': + fields.hue.val(360 - colorBar.y); + break; + case 's': + fields.saturation.val(100 - colorBar.y); + break; + case 'v': + fields.value.val(100 - colorBar.y); + break; + case 'r': + fields.red.val(255 - colorBar.y); + break; + case 'g': + fields.green.val(255 - colorBar.y); + break; + case 'b': + fields.blue.val(255 - colorBar.y); + break; + } + switch (color.mode) + { + case 'h': + case 's': + case 'v': + colorPicker.setValuesFromHsv(); + break; + case 'r': + case 'g': + case 'b': + colorPicker.setValuesFromRgb(); + break; + } + updateVisuals(); + if (window.bindToInput && window.liveUpdate) + { + window.input.val(active.hex).css( + { + backgroundColor: '#' + active.hex, + color: active.v > 75 ? '#000000' : '#ffffff' + }); + colorBox.css({ backgroundColor: '#' + active.hex }); + } + $.isFunction($this.liveCallback) && $this.liveCallback(active); + }, + positionMapAndBarArrows = // position map and bar arrows to match current color + function() + { + color.active = colorPicker.color; + var sliderValue = 0, + active = color.active; // local copy for YUI compressor + switch ($this.settings.color.mode) + { + case 'h': + sliderValue = 360 - active.h; + break; + case 's': + sliderValue = 100 - active.s; + break; + case 'v': + sliderValue = 100 - active.v; + break; + case 'r': + sliderValue = 255 - active.r; + break; + case 'g': + sliderValue = 255 - active.g; + break; + case 'b': + sliderValue = 255 - active.b; + break; + } + colorBar.y = sliderValue; + colorBar.setArrowPositionFromValues(); + var mapX = 0, mapY = 0; + switch ($this.settings.color.mode) + { + case 'h': + mapX = active.s; + mapY = 100 - active.v; + break; + case 's': + mapX = active.h; + mapY = 100 - active.v; + break; + case 'v': + mapX = active.h; + mapY = 100 - active.s; + break; + case 'r': + mapX = active.b; + mapY = 256 - active.g; + break; + case 'g': + mapX = active.b; + mapY = 256 - active.r; + break; + case 'b': + mapX = active.r; + mapY = 256 - active.g; + break; + } + colorMap.x = mapX; + colorMap.y = mapY; + colorMap.setArrowPositionFromValues(); + }, + updateVisuals = + function() + { + updatePreview(); + updateMapVisuals(); + updateBarVisuals(); + }, + updatePreview = + function() + { + try + { + activeColor.css({ backgroundColor: '#' + colorPicker.color.hex }); + } + catch (e) { } + }, + updateMapVisuals = + function() + { + if (!color || !colorPicker) return; + color.active = colorPicker.color; + var active = color.active; // local copy for YUI compressor + switch (color.mode) + { + case 'h': + var newColor = new Color({ h: active.h, s: 100, v: 100 }); + setBG(colorMapL1, newColor.hex); + break; + case 's': + setAlpha(colorMapL2, 100 - active.s); + break; + case 'v': + setAlpha(colorMapL2, active.v); + break; + case 'r': + setAlpha(colorMapL2, active.r / 256 * 100); + break; + case 'g': + setAlpha(colorMapL2, active.g / 256 * 100); + break; + case 'b': + setAlpha(colorMapL2, active.b / 256 * 100); + break; + } + }, + updateBarVisuals = + function() + { + if (!color || !colorPicker) return; + color.active = colorPicker.color; + var active = color.active, // local copy for YUI compressor + mode = color.mode, + fields = colorPicker.fields; + switch (mode) + { + case 'h': + break; + case 's': + var saturatedColor = new Color({ h: active.h, s: 100, v: active.v }); + setBG(colorBarL3, saturatedColor.hex); + break; + case 'v': + var valueColor = new Color({ h: active.h, s: active.s, v: 100 }); + setBG(colorBarL3, valueColor.hex); + break; + case 'r': + case 'g': + case 'b': + var hValue = 0, vValue = 0; + if (mode == 'r') + { + hValue = fields.blue.val(); + vValue = fields.green.val(); + } + else if (mode == 'g') + { + hValue = fields.blue.val(); + vValue = fields.red.val(); + } + else if (mode == 'b') + { + hValue = fields.red.val(); + vValue = fields.green.val(); + } + var horzPer = hValue / 256 * 100, vertPer = vValue / 256 * 100, horzPerRev = (256 - hValue) / 256 * 100, vertPerRev = (256 - vValue) / 256 * 100; + setAlpha(colorBarL4, vertPer > horzPerRev ? horzPerRev : vertPer); + setAlpha(colorBarL3, vertPer > horzPer ? horzPer : vertPer); + setAlpha(colorBarL2, vertPerRev > horzPer ? horzPer : vertPerRev); + setAlpha(colorBarL1, vertPerRev > horzPerRev ? horzPerRev : vertPerRev); + break; + } + }, + setBG = + function(el, c) + { + try + { + el.css({ backgroundColor: '#' + c }); + } + catch (e) { } + }, + setImg = + function(img, src) + { + if (src.indexOf('png') && this.isLessThanIE7) + { + img.attr('pngSrc', src); + img.css({ backgroundImage: 'none', filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\')' }); + } + else img.css({ backgroundImage: 'url(' + src + ')' }); + }, + setAlpha = + function(obj, alpha) + { + if (alpha == 0) + { + obj.css({ display: 'none' }); + return; + } + else if (alpha < 100) + { + obj.css({ display: '' }); + if (this.isLessThanIE7) + { + var src = obj.attr('pngSrc'); + if (src != null && src.indexOf('map-hue') == -1) + obj.css({ filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\') progid:DXImageTransform.Microsoft.Alpha(opacity=' + alpha + ')' }); + } + else obj.css({ opacity: alpha / 100 }); + } + else if (alpha == 100) // IE7 still will not combine 8-bit PNG translucency AND element opacity without drawing errors + // Even opacity:1.0 (or filter:Alpha(opacity=100)) causes issues, so remove it if opaque + { + obj.css({ display: '' }); + if (this.isLessThanIE7) + { + var src = obj.attr('pngSrc'); + if (src != null && src.indexOf('map-hue') == -1) obj.css({ filter: 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'' + src + '\')' }); + } + else obj.css({ opacity: '' }); + } + }, + revertColor = // revert color to original color when opened + function() + { + colorPicker.fields.hex.val(color.current.hex); + colorPicker.setValuesFromHex(); + $.isFunction(colorPicker.valuesChanged) && colorPicker.valuesChanged(colorPicker); + }, + radioClicked = + function(e) + { + setColorMode(e.target.value); + }, + currentClicked = + function() + { + revertColor(); + }, + cancelClicked = + function() + { + revertColor(); + window.bindToInput && $this.hide(); + $.isFunction($this.cancelCallback) && $this.cancelCallback(); + }, + commitColor = // commit the color changes + function() + { + var active = color.active; // local copies for YUI compressor + color.current = new Color({ hex: active.hex }); + currentColor.css({ backgroundColor: '#' + active.hex }); + if (window.bindToInput) + { + window.input.val(active.hex).css( + { + backgroundColor: '#' + active.hex, + color: active.v > 75 ? '#000000' : '#ffffff' + }); + colorBox.css({ backgroundColor: '#' + active.hex }); + } + $.isFunction($this.commitCallback) && $this.commitCallback(active); + }, + okClicked = + function() + { + commitColor(); + window.bindToInput && $this.hide(); + }, + colorIconClicked = + function() + { + $this.show(); + }, + moveBarMouseDown = + function(e) + { + var element = window.element, // local copies for YUI compressor + page = window.page; + elementStartX = parseInt(container.css('left')); + elementStartY = parseInt(container.css('top')); + pageStartX = e.pageX; + pageStartY = e.pageY; + // bind events to document to move window - we will unbind these on mouseup + $(document).bind('mousemove', documentMouseMove).bind('mouseup', documentMouseUp); + e.stopPropagation(); + e.preventDefault(); // prevent attempted dragging of the column + return false; + }, + documentMouseMove = + function(e) + { + container.css({ left: elementStartX - (pageStartX - e.pageX) + 'px', top: elementStartY - (pageStartY - e.pageY) + 'px' }); + e.stopPropagation(); + e.preventDefault(); + return false; + }, + documentMouseUp = + function(e) + { + $(document).unbind('mousemove', documentMouseMove).unbind('mouseup', documentMouseUp); + e.stopPropagation(); + e.preventDefault(); + return false; + }, + bindedHexKeyUp = + function(e) + { + colorPicker.fields.hex.val($this.settings.window.input.val()); + colorPicker.bindedHexKeyUp(e); + }, + quickPickClicked = + function(e) + { + colorPicker.fields.hex.val(color.quickList[e.data.i].hex); + colorPicker.setValuesFromHex(); + $.isFunction(colorPicker.valuesChanged) && colorPicker.valuesChanged(colorPicker); + }; + $.extend(true, $this, // pulic properties, methods, and callbacks + { + id: $this.attr('id'), + settings: $settings, + color: null, + icon: null, + commitCallback: $.isFunction($arguments[1]) && $arguments[1] || null, // commitCallback function can be overridden to return the selected color to a method you specify when the user clicks "OK" + liveCallback: $.isFunction($arguments[2]) && $arguments[2] || null, // liveCallback function can be overridden to return the selected color to a method you specify in live mode (continuous update) + cancelCallback: $.isFunction($arguments[3]) && $arguments[3] || null, // cancelCallback function can be overridden to a method you specify when the user clicks "Cancel" + show: + function() + { + if (document.all) // In IE, due to calculated z-index values, we need to hide all color picker icons that appear later in the source code than this one + { + var foundthis = false; + for (i = 0; i < List.length; i++) + { + if (foundthis) List[i].color.add(List[i].icon).css({ display: 'none' }); + if (List[i].id == $this.id) foundthis = true; + } + } + color.current = new Color({ hex: color.active.hex }); + currentColor.css({ backgroundColor: '#' + color.active.hex }); + container.css({ display: 'block' }); + colorMap.setPositioningVariables(); + colorBar.setPositioningVariables(); + positionMapAndBarArrows(); + }, + hide: + function() + { + if (document.all) // In IE, show the previously hidden color picker icons again + { + var foundthis = false; + for (i = 0; i < List.length; i++) + { + if (foundthis) List[i].color.add(List[i].icon).css({ display: 'block' }); + if (List[i].id == $this.id) foundthis = true; + } + } + container.css({ display: 'none' }); + }, + destroy: // destroys this control entirely, removing all events and objects, and removing itself from the List + function() + { + if (window.bindToInput) + { + colorIcon = $('#' + $this.id + '_jPicker_Icon').unbind('click', colorIconClicked); + window.input.unbind('keyup', bindedHexKeyUp).unbind('change', bindedHexKeyUp); + } + hue.add(saturation).add(value).add(red).add(green).add(blue).unbind('click', radioClicked); + currentColor.unbind('click', currentClicked); + cancelButton.unbind('click', cancelClicked); + okButton.unbind('click', okClicked); + if (window.draggable) moveBar.unbind('mousedown', moveBarMouseDown); + if (color.quickList && color.quickList.length > 0) + for (i = 0; i < color.quickList.length; i++) + $('#' + $this.id + '_jPicker_Grid_' + i, container).unbind('click', quickPickClicked); + hue = null; + saturation = null; + value = null; + red = null; + green = null; + blue = null; + colorMapL1 = null; + colorMapL2 = null; + colorBarL1 = null; + colorBarL2 = null; + colorBarL3 = null; + colorBarL4 = null; + activeColor = null; + currentColor = null; + okButton = null; + cancelButton = null; + grid = null; + $this.color = null; + $this.icon = null; + colorMap.destroy(); + colorMap = null; + colorBar.destroy(); + colorBar = null; + colorPicker.destroy(); + colorPicker = null; + $this.commitCallback = null; + $this.cancelCallback = null; + $this.liveCallback = null; + container.html(''); + for (i = 0; i < List.length; i++) if (List[i].id == $this.id) List.splice(i, 1); + } + }); + var images = $this.settings.images, // local copies for YUI compressor + window = $this.settings.window, + color = $this.settings.color; + container = window.bindToInput ? $('#' + id + '_jPicker_Container') : $this; + if (window.bindToInput) + container.css( // positions must be set and display set to absolute before source code injection or IE will size the container to fit the window + { + left: window.position.x == 'left' ? '-535px' : window.position.x == 'center' ? '-268px' : window.position.x == 'right' ? '0px' : window.position.x == 'screenCenter' ? + (($(document).width() >> 1) - 268) - $('#' + id + '_jPicker_Picker').offset().left + 'px' : window.position.x, + position: 'absolute', + top: window.position.y == 'top' ? '-320px' : window.position.y == 'center' ? '-148px' : window.position.y == 'bottom' ? '25px' : window.position.y + }); + // if default colors are hex strings, change them to color objects + if ((typeof (color.active)).toString().toLowerCase() == 'string') color.active = new Color({ hex: color.active.substring(1) }); + if ((typeof (color.current)).toString().toLowerCase() == 'string') color.current = new Color({ hex: color.current.substring(1) }); + // inject html source code - we are using a single table for this control - I know tables are considered bad, but it takes care of equal height columns and + // this control really is tabular data, so I believe it is the right move + container.html('' + (window.draggable ? '' : '') + '
  
    
new
  
current

 
°
%
%
 
#:
'); + // initialize the objects to the source code just injected + hue = $('#' + $this.id + '_jPicker_HueRadio', container); + saturation = $('#' + $this.id + '_jPicker_SaturationRadio', container); + value = $('#' + $this.id + '_jPicker_BrightnessRadio', container); + red = $('#' + $this.id + '_jPicker_RedRadio', container); + green = $('#' + $this.id + '_jPicker_GreenRadio', container); + blue = $('#' + $this.id + '_jPicker_BlueRadio', container); + colorMapL1 = $('#' + $this.id + '_jPicker_ColorMap_l1', container); + colorMapL2 = $('#' + $this.id + '_jPicker_ColorMap_l2', container); + colorBarL1 = $('#' + $this.id + '_jPicker_ColorBar_l1', container); + colorBarL2 = $('#' + $this.id + '_jPicker_ColorBar_l2', container); + colorBarL3 = $('#' + $this.id + '_jPicker_ColorBar_l3', container); + colorBarL4 = $('#' + $this.id + '_jPicker_ColorBar_l4', container); + activeColor = $('#' + $this.id + '_jPicker_Active', container).css({ backgroundColor: '#' + color.active.hex }); + currentColor = $('#' + $this.id + '_jPicker_Current', container).css({ backgroundColor: '#' + color.current.hex }); + okButton = $('#' + $this.id + '_jPicker_Ok', container); + cancelButton = $('#' + $this.id + '_jPicker_Cancel', container); + grid = $('#' + $this.id + '_jPicker_Grid', container); + $this.color = $('#' + $this.id + '_jPicker_Color'); + $this.icon = $('#' + $this.id + '_jPicker_Icon'); + // create color pickers and maps + colorPicker = new ColorValuePicker($this.id, textValuesChanged); + colorMap = new Slider($this.id + '_jPicker_ColorMap', + { + map: + { + width: images.colorMap.width, + height: images.colorMap.height + }, + arrow: + { + image: images.clientPath + images.colorMap.arrow.file, + width: images.colorMap.arrow.width, + height: images.colorMap.arrow.height + } + }, + mapValueChanged); + colorBar = new Slider($this.id + '_jPicker_ColorBar', + { + map: + { + width: images.colorBar.width, + height: images.colorBar.height + }, + arrow: + { + image: images.clientPath + images.colorBar.arrow.file, + width: images.colorBar.arrow.width, + height: images.colorBar.arrow.height + } + }, + barValueChanged); + // bind to input + if (window.bindToInput) + { + colorBox = $('#' + $this.id + '_jPicker_Color').css({ backgroundColor: '#' + color.current.hex }); + colorIcon = $('#' + $this.id + '_jPicker_Icon').css( + { + backgroundImage: 'url(' + images.clientPath + images.picker.file + ')' + }).bind('click', colorIconClicked); + window.input.bind('keyup', bindedHexKeyUp).bind('change', bindedHexKeyUp); + } + hue.add(saturation).add(value).add(red).add(green).add(blue).bind('click', radioClicked); + currentColor.bind('click', currentClicked); + cancelButton.bind('click', cancelClicked); + okButton.bind('click', okClicked); + if (window.draggable) moveBar = $('#' + $this.id + '_jPicker_MoveBar', container).bind('mousedown', moveBarMouseDown); + // initialize quick list + if (color.quickList && color.quickList.length > 0) + { + grid.html(''); + for (i = 0; i < color.quickList.length; i++) + { + /* if default colors are hex strings, change them to color objects */ + if ((typeof (color.quickList[i])).toString().toLowerCase() == 'string') color.quickList[i] = new Color({ hex: color.quickList[i].substring(1) }); + grid.append(' '); + $('#' + $this.id + '_jPicker_Grid_' + i, container).css({ backgroundColor: '#' + color.quickList[i].hex }).bind('click', { i: i }, quickPickClicked); + } + } + setColorMode(color.mode); + colorPicker.fields.hex.val(colorBar.hex); + colorPicker.setValuesFromHex(); + positionMapAndBarArrows(); + updateVisuals(); + commitColor(); + $.isFunction($this.commitCallback) && $this.commitCallback(color.current); + if (!window.bindToInput) $this.show(); + List.push($this); + }); + }; + $.fn.jPicker.defaults = /* jPicker defaults - you can change anything in this section (such as the clientPath to your images) without fear of breaking the program */ + { + window: + { + position: + { + x: 'screenCenter', /* acceptable values "left", "center", "right", "screenCenter", or relative px value */ + y: 'top' /* acceptable values "top", "bottom", "center", or relative px value */ + }, + draggable: true, /* set to false automatically if not binded to an input element */ + liveUpdate: true /* set false if you want the user to have to click "OK" before the binded input box updates values */ + }, + color: + { + mode: 'h', /* acceptabled values "h" (hue), "s" (saturation), "v" (brightness), "r" (red), "g" (green), "b" (blue) */ + current: new Color({ hex: 'ffffff' }), /* acceptable values are any declared $.jPicker.Color object or string HEX value (e.g. #ffc000) INCLUDING the "#" prefix */ + active: new Color({ hex: 'ffc000' }), /* acceptable values are any declared $.jPicker.Color object or string HEX value (e.g. #ffc000) INCLUDING the "#" prefix */ + quickList: /* the quick pick color list */ + [ + new Color({ h: 360, s: 33, v: 100 }), /* acceptable values are any declared $.jPicker.Color object or string HEX value (e.g. #ffc000) INCLUDING the "#" prefix */ + new Color({ h: 360, s: 66, v: 100 }), + new Color({ h: 360, s: 100, v: 100 }), + new Color({ h: 360, s: 100, v: 75 }), + new Color({ h: 360, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 100 }), + new Color({ h: 30, s: 33, v: 100 }), + new Color({ h: 30, s: 66, v: 100 }), + new Color({ h: 30, s: 100, v: 100 }), + new Color({ h: 30, s: 100, v: 75 }), + new Color({ h: 30, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 90 }), + new Color({ h: 60, s: 33, v: 100 }), + new Color({ h: 60, s: 66, v: 100 }), + new Color({ h: 60, s: 100, v: 100 }), + new Color({ h: 60, s: 100, v: 75 }), + new Color({ h: 60, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 80 }), + new Color({ h: 90, s: 33, v: 100 }), + new Color({ h: 90, s: 66, v: 100 }), + new Color({ h: 90, s: 100, v: 100 }), + new Color({ h: 90, s: 100, v: 75 }), + new Color({ h: 90, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 70 }), + new Color({ h: 120, s: 33, v: 100 }), + new Color({ h: 120, s: 66, v: 100 }), + new Color({ h: 120, s: 100, v: 100 }), + new Color({ h: 120, s: 100, v: 75 }), + new Color({ h: 120, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 60 }), + new Color({ h: 150, s: 33, v: 100 }), + new Color({ h: 150, s: 66, v: 100 }), + new Color({ h: 150, s: 100, v: 100 }), + new Color({ h: 150, s: 100, v: 75 }), + new Color({ h: 150, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 50 }), + new Color({ h: 180, s: 33, v: 100 }), + new Color({ h: 180, s: 66, v: 100 }), + new Color({ h: 180, s: 100, v: 100 }), + new Color({ h: 180, s: 100, v: 75 }), + new Color({ h: 180, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 40 }), + new Color({ h: 210, s: 33, v: 100 }), + new Color({ h: 210, s: 66, v: 100 }), + new Color({ h: 210, s: 100, v: 100 }), + new Color({ h: 210, s: 100, v: 75 }), + new Color({ h: 210, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 30 }), + new Color({ h: 240, s: 33, v: 100 }), + new Color({ h: 240, s: 66, v: 100 }), + new Color({ h: 240, s: 100, v: 100 }), + new Color({ h: 240, s: 100, v: 75 }), + new Color({ h: 240, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 20 }), + new Color({ h: 270, s: 33, v: 100 }), + new Color({ h: 270, s: 66, v: 100 }), + new Color({ h: 270, s: 100, v: 100 }), + new Color({ h: 270, s: 100, v: 75 }), + new Color({ h: 270, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 10 }), + new Color({ h: 300, s: 33, v: 100 }), + new Color({ h: 300, s: 66, v: 100 }), + new Color({ h: 300, s: 100, v: 100 }), + new Color({ h: 300, s: 100, v: 75 }), + new Color({ h: 300, s: 100, v: 50 }), + new Color({ h: 180, s: 0, v: 0 }), + new Color({ h: 330, s: 33, v: 100 }), + new Color({ h: 330, s: 66, v: 100 }), + new Color({ h: 330, s: 100, v: 100 }), + new Color({ h: 330, s: 100, v: 75 }), + new Color({ h: 330, s: 100, v: 50 }) + ] + }, + images: + { + clientPath: '/jPicker/images/', /* Path to image files */ + colorMap: + { + width: 256, + height: 256, + arrow: + { + file: 'mappoint.gif', /* ColorMap arrow icon */ + width: 15, + height: 15 + } + }, + colorBar: + { + width: 20, + height: 256, + arrow: + { + file: 'rangearrows.gif', /* ColorBar arrow icon */ + width: 40, + height: 9 + } + }, + picker: + { + file: 'picker.gif', /* Color Picker icon */ + width: 25, + height: 24 + } + } + }; +})(jQuery); \ No newline at end of file diff --git a/editor/jquery.js b/editor/jquery.js index b1ae21d8..92635743 100644 --- a/editor/jquery.js +++ b/editor/jquery.js @@ -1,4 +1,4 @@ -/* +/*! * jQuery JavaScript Library v1.3.2 * http://jquery.com/ * @@ -9,11 +9,4368 @@ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) * Revision: 6246 */ -(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div

","
"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); -/* +(function(){ + +var + // Will speed up references to window, and allows munging its name. + window = this, + // Will speed up references to undefined, and allows munging its name. + undefined, + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + // Map over the $ in case of overwrite + _$ = window.$, + + jQuery = window.jQuery = window.$ = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context ); + }, + + // A simple way to check for HTML strings or ID strings + // (both of which we optimize for) + quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/, + // Is it a simple selector + isSimple = /^.[^:#\[\.,]*$/; + +jQuery.fn = jQuery.prototype = { + init: function( selector, context ) { + // Make sure that a selection was provided + selector = selector || document; + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this[0] = selector; + this.length = 1; + this.context = selector; + return this; + } + // Handle HTML strings + if ( typeof selector === "string" ) { + // Are we dealing with HTML string or an ID? + var match = quickExpr.exec( selector ); + + // Verify a match, and that no context was specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) + selector = jQuery.clean( [ match[1] ], context ); + + // HANDLE: $("#id") + else { + var elem = document.getElementById( match[3] ); + + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem && elem.id != match[3] ) + return jQuery().find( selector ); + + // Otherwise, we inject the element directly into the jQuery object + var ret = jQuery( elem || [] ); + ret.context = document; + ret.selector = selector; + return ret; + } + + // HANDLE: $(expr, [context]) + // (which is just equivalent to: $(content).find(expr) + } else + return jQuery( context ).find( selector ); + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) + return jQuery( document ).ready( selector ); + + // Make sure that old selector state is passed along + if ( selector.selector && selector.context ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return this.setArray(jQuery.isArray( selector ) ? + selector : + jQuery.makeArray(selector)); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.3.2", + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num === undefined ? + + // Return a 'clean' array + Array.prototype.slice.call( this ) : + + // Return just the object + this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + // Build a new jQuery matched element set + var ret = jQuery( elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) + ret.selector = this.selector + (this.selector ? " " : "") + selector; + else if ( name ) + ret.selector = this.selector + "." + name + "(" + selector + ")"; + + // Return the newly-formed element set + return ret; + }, + + // Force the current matched set of elements to become + // the specified array of elements (destroying the stack in the process) + // You should use pushStack() in order to do this, but maintain the stack + setArray: function( elems ) { + // Resetting the length to 0, then using the native Array push + // is a super-fast way to populate an object with array-like properties + this.length = 0; + Array.prototype.push.apply( this, elems ); + + return this; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem && elem.jquery ? elem[0] : elem + , this ); + }, + + attr: function( name, value, type ) { + var options = name; + + // Look for the case where we're accessing a style value + if ( typeof name === "string" ) + if ( value === undefined ) + return this[0] && jQuery[ type || "attr" ]( this[0], name ); + + else { + options = {}; + options[ name ] = value; + } + + // Check to see if we're setting style values + return this.each(function(i){ + // Set all the styles + for ( name in options ) + jQuery.attr( + type ? + this.style : + this, + name, jQuery.prop( this, options[ name ], type, i, name ) + ); + }); + }, + + css: function( key, value ) { + // ignore negative width and height values + if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) + value = undefined; + return this.attr( key, value, "curCSS" ); + }, + + text: function( text ) { + if ( typeof text !== "object" && text != null ) + return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); + + var ret = ""; + + jQuery.each( text || this, function(){ + jQuery.each( this.childNodes, function(){ + if ( this.nodeType != 8 ) + ret += this.nodeType != 1 ? + this.nodeValue : + jQuery.fn.text( [ this ] ); + }); + }); + + return ret; + }, + + wrapAll: function( html ) { + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).clone(); + + if ( this[0].parentNode ) + wrap.insertBefore( this[0] ); + + wrap.map(function(){ + var elem = this; + + while ( elem.firstChild ) + elem = elem.firstChild; + + return elem; + }).append(this); + } + + return this; + }, + + wrapInner: function( html ) { + return this.each(function(){ + jQuery( this ).contents().wrapAll( html ); + }); + }, + + wrap: function( html ) { + return this.each(function(){ + jQuery( this ).wrapAll( html ); + }); + }, + + append: function() { + return this.domManip(arguments, true, function(elem){ + if (this.nodeType == 1) + this.appendChild( elem ); + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function(elem){ + if (this.nodeType == 1) + this.insertBefore( elem, this.firstChild ); + }); + }, + + before: function() { + return this.domManip(arguments, false, function(elem){ + this.parentNode.insertBefore( elem, this ); + }); + }, + + after: function() { + return this.domManip(arguments, false, function(elem){ + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + }, + + end: function() { + return this.prevObject || jQuery( [] ); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: [].push, + sort: [].sort, + splice: [].splice, + + find: function( selector ) { + if ( this.length === 1 ) { + var ret = this.pushStack( [], "find", selector ); + ret.length = 0; + jQuery.find( selector, this[0], ret ); + return ret; + } else { + return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){ + return jQuery.find( selector, elem ); + })), "find", selector ); + } + }, + + clone: function( events ) { + // Do the clone + var ret = this.map(function(){ + if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { + // IE copies events bound via attachEvent when + // using cloneNode. Calling detachEvent on the + // clone will also remove the events from the orignal + // In order to get around this, we use innerHTML. + // Unfortunately, this means some modifications to + // attributes in IE that are actually only stored + // as properties will not be copied (such as the + // the name attribute on an input). + var html = this.outerHTML; + if ( !html ) { + var div = this.ownerDocument.createElement("div"); + div.appendChild( this.cloneNode(true) ); + html = div.innerHTML; + } + + return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0]; + } else + return this.cloneNode(true); + }); + + // Copy the events from the original to the clone + if ( events === true ) { + var orig = this.find("*").andSelf(), i = 0; + + ret.find("*").andSelf().each(function(){ + if ( this.nodeName !== orig[i].nodeName ) + return; + + var events = jQuery.data( orig[i], "events" ); + + for ( var type in events ) { + for ( var handler in events[ type ] ) { + jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); + } + } + + i++; + }); + } + + // Return the cloned set + return ret; + }, + + filter: function( selector ) { + return this.pushStack( + jQuery.isFunction( selector ) && + jQuery.grep(this, function(elem, i){ + return selector.call( elem, i ); + }) || + + jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ + return elem.nodeType === 1; + }) ), "filter", selector ); + }, + + closest: function( selector ) { + var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null, + closer = 0; + + return this.map(function(){ + var cur = this; + while ( cur && cur.ownerDocument ) { + if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) { + jQuery.data(cur, "closest", closer); + return cur; + } + cur = cur.parentNode; + closer++; + } + }); + }, + + not: function( selector ) { + if ( typeof selector === "string" ) + // test special case where just one selector is passed in + if ( isSimple.test( selector ) ) + return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); + else + selector = jQuery.multiFilter( selector, this ); + + var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; + return this.filter(function() { + return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; + }); + }, + + add: function( selector ) { + return this.pushStack( jQuery.unique( jQuery.merge( + this.get(), + typeof selector === "string" ? + jQuery( selector ) : + jQuery.makeArray( selector ) + ))); + }, + + is: function( selector ) { + return !!selector && jQuery.multiFilter( selector, this ).length > 0; + }, + + hasClass: function( selector ) { + return !!selector && this.is( "." + selector ); + }, + + val: function( value ) { + if ( value === undefined ) { + var elem = this[0]; + + if ( elem ) { + if( jQuery.nodeName( elem, 'option' ) ) + return (elem.attributes.value || {}).specified ? elem.value : elem.text; + + // We need to handle select boxes special + if ( jQuery.nodeName( elem, "select" ) ) { + var index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type == "select-one"; + + // Nothing was selected + if ( index < 0 ) + return null; + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + if ( option.selected ) { + // Get the specifc value for the option + value = jQuery(option).val(); + + // We don't need an array for one selects + if ( one ) + return value; + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + } + + // Everything else, we just grab the value + return (elem.value || "").replace(/\r/g, ""); + + } + + return undefined; + } + + if ( typeof value === "number" ) + value += ''; + + return this.each(function(){ + if ( this.nodeType != 1 ) + return; + + if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) + this.checked = (jQuery.inArray(this.value, value) >= 0 || + jQuery.inArray(this.name, value) >= 0); + + else if ( jQuery.nodeName( this, "select" ) ) { + var values = jQuery.makeArray(value); + + jQuery( "option", this ).each(function(){ + this.selected = (jQuery.inArray( this.value, values ) >= 0 || + jQuery.inArray( this.text, values ) >= 0); + }); + + if ( !values.length ) + this.selectedIndex = -1; + + } else + this.value = value; + }); + }, + + html: function( value ) { + return value === undefined ? + (this[0] ? + this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : + null) : + this.empty().append( value ); + }, + + replaceWith: function( value ) { + return this.after( value ).remove(); + }, + + eq: function( i ) { + return this.slice( i, +i + 1 ); + }, + + slice: function() { + return this.pushStack( Array.prototype.slice.apply( this, arguments ), + "slice", Array.prototype.slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function(elem, i){ + return callback.call( elem, i, elem ); + })); + }, + + andSelf: function() { + return this.add( this.prevObject ); + }, + + domManip: function( args, table, callback ) { + if ( this[0] ) { + var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), + scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), + first = fragment.firstChild; + + if ( first ) + for ( var i = 0, l = this.length; i < l; i++ ) + callback.call( root(this[i], first), this.length > 1 || i > 0 ? + fragment.cloneNode(true) : fragment ); + + if ( scripts ) + jQuery.each( scripts, evalScript ); + } + + return this; + + function root( elem, cur ) { + return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? + (elem.getElementsByTagName("tbody")[0] || + elem.appendChild(elem.ownerDocument.createElement("tbody"))) : + elem; + } + } +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +function evalScript( i, elem ) { + if ( elem.src ) + jQuery.ajax({ + url: elem.src, + async: false, + dataType: "script" + }); + + else + jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); + + if ( elem.parentNode ) + elem.parentNode.removeChild( elem ); +} + +function now(){ + return +new Date; +} + +jQuery.extend = jQuery.fn.extend = function() { + // copy reference to target object + var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) + target = {}; + + // extend jQuery itself if only one argument is passed + if ( length == i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) + // Extend the base object + for ( var name in options ) { + var src = target[ name ], copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) + continue; + + // Recurse if we're merging object values + if ( deep && copy && typeof copy === "object" && !copy.nodeType ) + target[ name ] = jQuery.extend( deep, + // Never move original objects, clone them + src || ( copy.length != null ? [ ] : { } ) + , copy ); + + // Don't bring in undefined values + else if ( copy !== undefined ) + target[ name ] = copy; + + } + + // Return the modified object + return target; +}; + +// exclude the following css properties to add px +var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, + // cache defaultView + defaultView = document.defaultView || {}, + toString = Object.prototype.toString; + +jQuery.extend({ + noConflict: function( deep ) { + window.$ = _$; + + if ( deep ) + window.jQuery = _jQuery; + + return jQuery; + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return toString.call(obj) === "[object Function]"; + }, + + isArray: function( obj ) { + return toString.call(obj) === "[object Array]"; + }, + + // check if an element is in a (or is an) XML document + isXMLDoc: function( elem ) { + return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || + !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument ); + }, + + // Evalulates a script in a global context + globalEval: function( data ) { + if ( data && /\S/.test(data) ) { + // Inspired by code by Andrea Giammarchi + // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html + var head = document.getElementsByTagName("head")[0] || document.documentElement, + script = document.createElement("script"); + + script.type = "text/javascript"; + if ( jQuery.support.scriptEval ) + script.appendChild( document.createTextNode( data ) ); + else + script.text = data; + + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709). + head.insertBefore( script, head.firstChild ); + head.removeChild( script ); + } + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); + }, + + // args is for internal usage only + each: function( object, callback, args ) { + var name, i = 0, length = object.length; + + if ( args ) { + if ( length === undefined ) { + for ( name in object ) + if ( callback.apply( object[ name ], args ) === false ) + break; + } else + for ( ; i < length; ) + if ( callback.apply( object[ i++ ], args ) === false ) + break; + + // A special, fast, case for the most common use of each + } else { + if ( length === undefined ) { + for ( name in object ) + if ( callback.call( object[ name ], name, object[ name ] ) === false ) + break; + } else + for ( var value = object[0]; + i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} + } + + return object; + }, + + prop: function( elem, value, type, i, name ) { + // Handle executable functions + if ( jQuery.isFunction( value ) ) + value = value.call( elem, i ); + + // Handle passing in a number to a CSS property + return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ? + value + "px" : + value; + }, + + className: { + // internal only, use addClass("class") + add: function( elem, classNames ) { + jQuery.each((classNames || "").split(/\s+/), function(i, className){ + if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) + elem.className += (elem.className ? " " : "") + className; + }); + }, + + // internal only, use removeClass("class") + remove: function( elem, classNames ) { + if (elem.nodeType == 1) + elem.className = classNames !== undefined ? + jQuery.grep(elem.className.split(/\s+/), function(className){ + return !jQuery.className.has( classNames, className ); + }).join(" ") : + ""; + }, + + // internal only, use hasClass("class") + has: function( elem, className ) { + return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; + } + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var old = {}; + // Remember the old values, and insert the new ones + for ( var name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + callback.call( elem ); + + // Revert the old values + for ( var name in options ) + elem.style[ name ] = old[ name ]; + }, + + css: function( elem, name, force, extra ) { + if ( name == "width" || name == "height" ) { + var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; + + function getWH() { + val = name == "width" ? elem.offsetWidth : elem.offsetHeight; + + if ( extra === "border" ) + return; + + jQuery.each( which, function() { + if ( !extra ) + val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; + if ( extra === "margin" ) + val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; + else + val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; + }); + } + + if ( elem.offsetWidth !== 0 ) + getWH(); + else + jQuery.swap( elem, props, getWH ); + + return Math.max(0, Math.round(val)); + } + + return jQuery.curCSS( elem, name, force ); + }, + + curCSS: function( elem, name, force ) { + var ret, style = elem.style; + + // We need to handle opacity special in IE + if ( name == "opacity" && !jQuery.support.opacity ) { + ret = jQuery.attr( style, "opacity" ); + + return ret == "" ? + "1" : + ret; + } + + // Make sure we're using the right name for getting the float value + if ( name.match( /float/i ) ) + name = styleFloat; + + if ( !force && style && style[ name ] ) + ret = style[ name ]; + + else if ( defaultView.getComputedStyle ) { + + // Only "float" is needed here + if ( name.match( /float/i ) ) + name = "float"; + + name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); + + var computedStyle = defaultView.getComputedStyle( elem, null ); + + if ( computedStyle ) + ret = computedStyle.getPropertyValue( name ); + + // We should always get a number back from opacity + if ( name == "opacity" && ret == "" ) + ret = "1"; + + } else if ( elem.currentStyle ) { + var camelCase = name.replace(/\-(\w)/g, function(all, letter){ + return letter.toUpperCase(); + }); + + ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { + // Remember the original values + var left = style.left, rsLeft = elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + elem.runtimeStyle.left = elem.currentStyle.left; + style.left = ret || 0; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + elem.runtimeStyle.left = rsLeft; + } + } + + return ret; + }, + + clean: function( elems, context, fragment ) { + context = context || document; + + // !context.createElement fails in IE with an error but returns typeof 'object' + if ( typeof context.createElement === "undefined" ) + context = context.ownerDocument || context[0] && context[0].ownerDocument || document; + + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { + var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); + if ( match ) + return [ context.createElement( match[1] ) ]; + } + + var ret = [], scripts = [], div = context.createElement("div"); + + jQuery.each(elems, function(i, elem){ + if ( typeof elem === "number" ) + elem += ''; + + if ( !elem ) + return; + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ + return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? + all : + front + ">"; + }); + + // Trim whitespace, otherwise indexOf won't work as expected + var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); + + var wrap = + // option or optgroup + !tags.indexOf("", "" ] || + + !tags.indexOf("", "" ] || + + tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && + [ 1, "", "
" ] || + + !tags.indexOf("", "" ] || + + // matched above + (!tags.indexOf("", "" ] || + + !tags.indexOf("", "" ] || + + // IE can't serialize and - + SVG-edit demo @@ -15,11 +15,7 @@
-
-
- - -
+
diff --git a/editor/svg-editor.js b/editor/svg-editor.js index 6a925849..c697c31a 100644 --- a/editor/svg-editor.js +++ b/editor/svg-editor.js @@ -1,5 +1,4 @@ var palette = ["#000000","#202020","#404040","#606060","#808080","#a0a0a0","#c0c0c0","#e0e0e0","#ffffff","#800000","#ff0000","#808000","#ffff00","#008000","#00ff00","#008080","#00ffff","#000080","#0000ff","#800080","#ff00ff","#2b0000","#550000","#800000","#aa0000","#d40000","#ff0000","#ff2a2a","#ff5555","#ff8080","#ffaaaa","#ffd5d5","#280b0b","#501616","#782121","#a02c2c","#c83737","#d35f5f","#de8787","#e9afaf","#f4d7d7","#241c1c","#483737","#6c5353","#916f6f","#ac9393","#c8b7b7","#e3dbdb","#2b1100","#552200","#803300","#aa4400","#d45500","#ff6600","#ff7f2a","#ff9955","#ffb380","#ffccaa","#ffe6d5","#28170b","#502d16","#784421","#a05a2c","#c87137","#d38d5f","#deaa87","#e9c6af","#f4e3d7","#241f1c","#483e37","#6c5d53","#917c6f","#ac9d93","#c8beb7","#e3dedb","#2b2200","#554400","#806600","#aa8800","#d4aa00","#ffcc00","#ffd42a","#ffdd55","#ffe680","#ffeeaa","#fff6d5","#28220b","#504416","#786721","#a0892c","#c8ab37","#d3bc5f","#decd87","#e9ddaf","#f4eed7","#24221c","#484537","#6c6753","#918a6f","#aca793","#c8c4b7","#e3e2db","#222b00","#445500","#668000","#88aa00","#aad400","#ccff00","#d4ff2a","#ddff55","#e5ff80","#eeffaa","#f6ffd5","#22280b","#445016","#677821","#89a02c","#abc837","#bcd35f","#cdde87","#dde9af","#eef4d7","#22241c","#454837","#676c53","#8a916f","#a7ac93","#c4c8b7","#e2e3db","#112b00","#225500","#338000","#44aa00","#55d400","#66ff00","#7fff2a","#99ff55","#b3ff80","#ccffaa","#e5ffd5","#17280b","#2d5016","#447821","#5aa02c","#71c837","#8dd35f","#aade87","#c6e9af","#e3f4d7","#1f241c","#3e4837","#5d6c53","#7c916f","#9dac93","#bec8b7","#dee3db","#002b00","#005500","#008000","#00aa00","#00d400","#00ff00","#2aff2a","#55ff55","#80ff80","#aaffaa","#d5ffd5","#0b280b","#165016","#217821","#2ca02c","#37c837","#5fd35f","#87de87","#afe9af","#d7f4d7","#1c241c","#374837","#536c53","#6f916f","#93ac93","#b7c8b7","#dbe3db","#002b11","#005522","#008033","#00aa44","#00d455","#00ff66","#2aff80","#55ff99","#80ffb3","#aaffcc","#d5ffe6","#0b2817","#16502d","#217844","#2ca05a","#37c871","#5fd38d","#87deaa","#afe9c6","#d7f4e3","#1c241f","#37483e","#536c5d","#6f917c","#93ac9d","#b7c8be","#dbe3de","#002b22","#005544","#008066","#00aa88","#00d4aa","#00ffcc","#2affd5","#55ffdd","#80ffe6","#aaffee","#d5fff6","#0b2822","#165044","#217867","#2ca089","#37c8ab","#5fd3bc","#87decd","#afe9dd","#d7f4ee","#1c2422","#374845","#536c67","#6f918a","#93aca7","#b7c8c4","#dbe3e2","#00222b","#004455","#006680","#0088aa","#00aad4","#00ccff","#2ad4ff","#55ddff","#80e5ff","#aaeeff","#d5f6ff","#0b2228","#164450","#216778","#2c89a0","#37abc8","#5fbcd3","#87cdde","#afdde9","#d7eef4","#1c2224","#374548","#53676c","#6f8a91","#93a7ac","#b7c4c8","#dbe2e3","#00112b","#002255","#003380","#0044aa","#0055d4","#0066ff","#2a7fff","#5599ff","#80b3ff","#aaccff","#d5e5ff","#0b1728","#162d50","#214478","#2c5aa0","#3771c8","#5f8dd3","#87aade","#afc6e9","#d7e3f4","#1c1f24","#373e48","#535d6c","#6f7c91","#939dac","#b7bec8","#dbdee3","#00002b","#000055","#000080","#0000aa","#0000d4","#0000ff","#2a2aff","#5555ff","#8080ff","#aaaaff","#d5d5ff","#0b0b28","#161650","#212178","#2c2ca0","#3737c8","#5f5fd3","#8787de","#afafe9","#d7d7f4","#1c1c24","#373748","#53536c","#6f6f91","#9393ac","#b7b7c8","#dbdbe3","#11002b","#220055","#330080","#4400aa","#5500d4","#6600ff","#7f2aff","#9955ff","#b380ff","#ccaaff","#e5d5ff","#170b28","#2d1650","#442178","#5a2ca0","#7137c8","#8d5fd3","#aa87de","#c6afe9","#e3d7f4","#1f1c24","#3e3748","#5d536c","#7c6f91","#9d93ac","#beb7c8","#dedbe3","#22002b","#440055","#660080","#8800aa","#aa00d4","#cc00ff","#d42aff","#dd55ff","#e580ff","#eeaaff","#f6d5ff","#220b28","#441650","#672178","#892ca0","#ab37c8","#bc5fd3","#cd87de","#ddafe9","#eed7f4","#221c24","#453748","#67536c","#8a6f91","#a793ac","#c4b7c8","#e2dbe3","#2b0022","#550044","#800066","#aa0088","#d400aa","#ff00cc","#ff2ad4","#ff55dd","#ff80e5","#ffaaee","#ffd5f6","#280b22","#501644","#782167","#a02c89","#c837ab","#d35fbc","#de87cd","#e9afdd","#f4d7ee","#241c22","#483745","#6c5367","#916f8a","#ac93a7","#c8b7c4","#e3dbe2","#2b0011","#550022","#800033","#aa0044","#d40055","#ff0066","#ff2a7f","#ff5599","#ff80b2","#ffaacc","#ffd5e5","#280b17","#50162d","#782144","#a02c5a","#c83771","#d35f8d","#de87aa","#e9afc6","#f4d7e3","#241c1f","#48373e","#6c535d","#916f7c","#ac939d","#c8b7be","#e3dbde"] -var picker = null; $(document).ready(function(){ var str = '
' @@ -8,6 +7,7 @@ $(document).ready(function(){ }); $('#palette').append(str); + var pos = $('#tools_rect_show').position(); $('#tools_rect').css({'left': pos.left+2, 'top': pos.top+2}); pos = $('#tools_ellipse_show').position(); @@ -126,59 +126,63 @@ $(document).ready(function(){ SvgCanvas.serialize(serializeHandler); }); - $('#fill_color').click(function(){ + var colorPicker = function(elem) { $('.tools_flyout').hide(); - var color = $(this).css('background-color'); - if (color == 'transparent') color = '#ffffff'; - picker.setColor(color); - picker.mode = 'fill'; - pos = $(this).position(); - $('#color_pick').css({'left': pos.left, 'top': pos.top}).show(); + var oldbg = elem.css('background'); + var color = elem.css('background-color'); + if (color == 'transparent') { + } else { + if (color.length == 7 && color[0] == '#') { // #hheexx notation + color = new $.jPicker.Color( { hex: color.substring(1,7) } ); + } else if (color.substring(0,4) == 'rgb(' && color[color.length-1] == ')') { // rgb(r,g,b) notation + var rgb = color.substring(4,color.length-1).split(','); + color = new $.jPicker.Color({ r: rgb[0], g: rgb[1], b: rgb[2] }); + } else { + color = new $.jPicker.Color({ hex: 'ffffff' }); + } + } + var pos = elem.position(); + picker = 'stroke'; + $('#color_picker').css({'left': pos.left, 'top': pos.top}).jPicker({ + images: { clientPath: "jpicker/images/" }, + color: { active: color } + }, function(color){ + elem.css('background', '#' + this.settings.color.active.hex); + if (elem.attr('id') == 'stroke_color') { + SvgCanvas.setStrokeColor('#' + this.settings.color.active.hex); + } else if (elem.attr('id') == 'fill_color') { + SvgCanvas.setFillColor('#' + this.settings.color.active.hex); + } + $('#color_picker').hide(); + } + , null, function(){ + elem.css('background', oldbg); + $('#color_picker').hide(); + }); + } + + $('#fill_color').click(function(){ + colorPicker($(this)); }); $('#stroke_color').click(function(){ - $('.tools_flyout').hide(); - var color = $(this).css('background-color'); - if (color == 'transparent') color = '#ffffff'; - picker.setColor(color); - picker.mode = 'stroke'; - pos = $(this).position(); - $('#color_pick').css({'left': pos.left, 'top': pos.top}).show(); + colorPicker($(this)); }); - $('#color_pick_ok').click(function(){ - $('#color_pick').hide(); - if (picker.mode == 'stroke') { - $('#stroke_color').css('background', picker.color); - SvgCanvas.setStrokeColor(picker.color); - } - if (picker.mode == 'fill') { - $('#fill_color').css('background', picker.color); - SvgCanvas.setFillColor(picker.color); - } - }); - - picker = $.farbtastic('#color_pick_wheel', function(){ - $('#color_pick_text').attr('value', this.color); - }); - - $('#color_pick_text').keyup(function(){ - picker.setColor($(this).attr('value')); - }); - - // This hides any flyouts and then shows the rect flyout + // this hides any flyouts and then shows the rect flyout $('#tools_rect_show').click(function(){ $('.tools_flyout').hide(); $('#tools_rect').show(); }); - // This hides any flyouts and then shows the circle flyout + // this hides any flyouts and then shows the circle flyout $('#tools_ellipse_show').click(function(){ $('.tools_flyout').hide(); $('#tools_ellipse').show(); }); + }) -function serializeHandler(svg) { +var serializeHandler = function(svg) { alert(svg); }