From: helge Date: Sun, 10 Jul 2005 22:01:40 +0000 (+0000) Subject: started WEPrototype library X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1890e3be6e06d044a6681d0e2ee3f4a6167559b2;p=sope started WEPrototype library git-svn-id: http://svn.opengroupware.org/SOPE/trunk@876 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/sope-appserver/NGObjWeb/DynamicElements/WOJavaScript.m b/sope-appserver/NGObjWeb/DynamicElements/WOJavaScript.m index e70fa0de..69510418 100644 --- a/sope-appserver/NGObjWeb/DynamicElements/WOJavaScript.m +++ b/sope-appserver/NGObjWeb/DynamicElements/WOJavaScript.m @@ -138,7 +138,7 @@ } /* add URL to script */ - if (self->scriptSource) { + if (self->scriptSource != nil) { st = [self->scriptSource stringValueInComponent:sComponent]; WOResponse_AddCString(_response, " src=\""); [_response appendContentHTMLAttributeValue:st]; diff --git a/sope-appserver/WEPrototype/COPYING b/sope-appserver/WEPrototype/COPYING new file mode 100644 index 00000000..2f599d85 --- /dev/null +++ b/sope-appserver/WEPrototype/COPYING @@ -0,0 +1,485 @@ +IMPORTANT NOTE: the prototype JavaScript source has a different license. + + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, 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 library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, 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 companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/sope-appserver/WEPrototype/COPYRIGHT b/sope-appserver/WEPrototype/COPYRIGHT new file mode 100644 index 00000000..cfb1b370 --- /dev/null +++ b/sope-appserver/WEPrototype/COPYRIGHT @@ -0,0 +1,7 @@ +Copyright (C) 2005 Helge Hess +Contact: helge.hess@opengroupware.org + +The JavaScript Prototype library sources are: +Copyright (c) 2005 Sam Stephenson + +Please see the LICENSE file in the prototype subdirectory. diff --git a/sope-appserver/WEPrototype/ChangeLog b/sope-appserver/WEPrototype/ChangeLog new file mode 100644 index 00000000..0913c9ba --- /dev/null +++ b/sope-appserver/WEPrototype/ChangeLog @@ -0,0 +1,5 @@ +2005-07-10 Helge Hess + + * imported Prototype library v1.2.0 + + * created project diff --git a/sope-appserver/WEPrototype/GNUmakefile b/sope-appserver/WEPrototype/GNUmakefile new file mode 100644 index 00000000..7209794a --- /dev/null +++ b/sope-appserver/WEPrototype/GNUmakefile @@ -0,0 +1,32 @@ +# GNUstep makefile + +-include ../../config.make +include $(GNUSTEP_MAKEFILES)/common.make +include ../Version +include ./Version + +LIBRARY_NAME = libWEPrototype +BUNDLE_NAME = WEPrototype +BUNDLE_EXTENSION = .wox +BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Library/WOxElemBuilders-$(MAJOR_VERSION).$(MINOR_VERSION)/ + +FHS_MANPAGES += doc/*.3 + +libWEPrototype_HEADER_FILES_DIR = . +libWEPrototype_HEADER_FILES_INSTALL_DIR = /WEPrototype + +libWEPrototype_HEADER_FILES = + +libWEPrototype_OBJC_FILES = \ + WEPrototypeScriptAction.m \ + WEPrototypeScript.m \ + WELiveLink.m \ + +WEPrototype_OBJC_FILES = WEPrototypeBundle.m +WEPrototype_PRINCIPAL_CLASS = WEPrototypeBundle + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/library.make +include $(GNUSTEP_MAKEFILES)/bundle.make +-include GNUmakefile.postamble +-include fhs.make diff --git a/sope-appserver/WEPrototype/GNUmakefile.postamble b/sope-appserver/WEPrototype/GNUmakefile.postamble new file mode 100644 index 00000000..694cce0a --- /dev/null +++ b/sope-appserver/WEPrototype/GNUmakefile.postamble @@ -0,0 +1,8 @@ +# postprocessing makefile + +WEPrototypeScript.jsm : prototype/prototype.js + sh js2m.sh $< $@ + touch WEPrototypeScript.m + +before-all :: WEPrototypeScript.jsm + diff --git a/sope-appserver/WEPrototype/GNUmakefile.preamble b/sope-appserver/WEPrototype/GNUmakefile.preamble new file mode 100644 index 00000000..433444d7 --- /dev/null +++ b/sope-appserver/WEPrototype/GNUmakefile.preamble @@ -0,0 +1,86 @@ +# compiler flags + + +ADDITIONAL_CPPFLAGS += \ + -Wall -DCOMPILE_FOR_GSTEP_MAKE=1 \ + -DSOPE_MAJOR_VERSION=$(MAJOR_VERSION) \ + -DSOPE_MINOR_VERSION=$(MINOR_VERSION) \ + -DWEP_SUBMINOR_VERSION=$(SUBMINOR_VERSION) + +ADDITIONAL_CPPFLAGS += -Wall +ADDITIONAL_INCLUDE_DIRS += \ + -I.. -I../.. -I../NGObjWeb \ + -I../../sope-core/NGStreams \ + -I../../sope-core/NGExtensions \ + -I../../sope-core \ + -I../../sope-xml + + +ifneq ($(GNUSTEP_BUILD_DIR),) +after-WEPrototype-all :: + @(cp bundle-info.plist \ + $(GNUSTEP_BUILD_DIR)/$(BUNDLE_NAME)$(BUNDLE_EXTENSION)) +else +after-WEPrototype-all :: + @(cd $(BUNDLE_NAME)$(BUNDLE_EXTENSION);\ + cp ../bundle-info.plist .) +endif + +libWEPrototype_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) +libWEPrototype_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION).$(SUBMINOR_VERSION) + +libWEPrototype_LIBRARIES_DEPEND_UPON += \ + -lNGObjWeb \ + -lNGMime \ + -lNGStreams -lNGExtensions -lEOControl \ + -lXmlRpc -lDOM -lSaxObjC + +ifneq ($(GNUSTEP_BUILD_DIR),) +RELBUILD_DIR_APPSERVER=$(GNUSTEP_BUILD_DIR)/.. +RELBUILD_DIR_MIME=$(GNUSTEP_BUILD_DIR)/../../sope-mime +RELBUILD_DIR_SxCore=$(GNUSTEP_BUILD_DIR)/../../sope-core +RELBUILD_DIR_SxXml=$(GNUSTEP_BUILD_DIR)/../../sope-xml + +ADDITIONAL_LIB_DIRS += \ + -L$(GNUSTEP_OBJ_DIR) \ + -L$(RELBUILD_DIR_APPSERVER)/NGObjWeb/$(GNUSTEP_OBJ_DIR_NAME) \ + -L$(RELBUILD_DIR_MIME)/$(GNUSTEP_OBJ_DIR_NAME) \ + -L$(RELBUILD_DIR_SxCore)/NGStreams/$(GNUSTEP_OBJ_DIR_NAME) \ + -L$(RELBUILD_DIR_SxCore)/NGExtensions/$(GNUSTEP_OBJ_DIR_NAME) \ + -L$(RELBUILD_DIR_SxCore)/EOControl/$(GNUSTEP_OBJ_DIR_NAME) \ + -L$(RELBUILD_DIR_SxXml)/XmlRpc/$(GNUSTEP_OBJ_DIR_NAME) \ + -L$(RELBUILD_DIR_SxXml)/DOM/$(GNUSTEP_OBJ_DIR_NAME) \ + -L$(RELBUILD_DIR_SxXml)/SaxObjC/$(GNUSTEP_OBJ_DIR_NAME) +else +ADDITIONAL_LIB_DIRS += \ + -L./$(GNUSTEP_OBJ_DIR) \ + -L../NGObjWeb/$(GNUSTEP_OBJ_DIR) \ + -L../../sope-mime/$(GNUSTEP_OBJ_DIR) \ + -L../../sope-core/NGStreams/$(GNUSTEP_OBJ_DIR) \ + -L../../sope-core/NGExtensions/$(GNUSTEP_OBJ_DIR) \ + -L../../sope-core/EOControl/$(GNUSTEP_OBJ_DIR) \ + -L../../sope-xml/XmlRpc/$(GNUSTEP_OBJ_DIR) \ + -L../../sope-xml/DOM/$(GNUSTEP_OBJ_DIR) \ + -L../../sope-xml/SaxObjC/$(GNUSTEP_OBJ_DIR) +endif + +WEPrototype_BUNDLE_LIBS += \ + -lWEPrototype \ + -lNGObjWeb \ + -lNGMime \ + -lNGStreams -lNGExtensions -lEOControl \ + -lXmlRpc -lDOM -lSaxObjC +WEPrototype_WOBUNDLE_LIBS += $(WEPrototype_BUNDLE_LIBS) + +ifneq ($(GNUSTEP_BUILD_DIR),) +WEPrototype_LIB_DIRS += -L$(GNUSTEP_OBJ_DIR) +else +WEPrototype_LIB_DIRS += -L./$(GNUSTEP_OBJ_DIR) +endif + +# Apple + +#ifeq ($(FOUNDATION_LIB),apple) +#libWEPrototype_PREBIND_ADDR="TODO TODO" +#libWEPrototype_LDFLAGS += -seg1addr $(libWEPrototype_PREBIND_ADDR) +#endif diff --git a/sope-appserver/WEPrototype/README b/sope-appserver/WEPrototype/README new file mode 100644 index 00000000..8a73d61a --- /dev/null +++ b/sope-appserver/WEPrototype/README @@ -0,0 +1,174 @@ +WEPrototype +=========== + +This framework contains dynamic elements wrapping and connecting the +excellent Prototype JavaScript library. + +http://api.rubyonrails.com/classes/ActionView/Helpers/JavaScriptHelper.html#M000394 + +Prototype functions +=================== + +Prototype +========= + +Prototype +- 'Version' property + +Class + .create() + +Abstract + +[Object] + .extend(otherobject) - copy properties of 'otherobject' to receiver + +[Function] + .bind(object) + .bindAsEventListener(object) + +[Number] + .toColorPart() + +Try + +PeriodicalExecuter + .initialize(callback, frequency) + .registerCallback() + .onTimerEvent + +$(...) +- run getElementById() for arguments +- return array for multiple, a single for one + + +Form +==== + +Field + .clear(...) - resolve names using $() and reset value + eg: Field.clear("sender", "from", "to") + .present(...) - check whether all elements have values + .focus(element) - lookup element using $() and focus + .select(element) - lookup element using $() and select + .activate(element) - lookup element using $() and focus+select + +Form + .serialize(form) + .getElements(form) + .disable(form) + .focusFirstElement(form) + .reset(form) + +Form.Element + .serialize(element) + .getValue(element) + +Form.Element.Serializers + +Abstract.TimedObserver + .initialize(element, frequency, callback) + +Form.Element.Observer : Abstract.TimedObserver + .getValue + +Form.Observer : Abstract.TimedObserver + .getValue + + +AJAX +==== + +Ajax.getTransport() +- return XMLHTTP object depending on browser + +Ajax.Base() + .setOptions(dict) + method - post + asynchronous - true + parameters - '' + +Ajax.Request() + - states: Uninitialized, Loading, Loaded, Interactive, Complete + .initialize(url, options) + +Ajax.Updater() + .initialize(container, url, options) + options: + - Base options + 'insertion' => function(container, responseText) => default: .innerHTML + + +Effects +======= +TODO + + +DOM +=== + +document.getElementsByClasName(className) + +Element + .toggle(...) - toggle style between "None" and "" + .hide(...) + .show(...) + .remove(elemName) - removed named element (lookup using $()) + .getHeight(elemName) + +Toggle + .display(..) - same like Element.toggle() + +Abstract.Insertion(adjacency) + .initialize(element, content) + +Insertion.Before : Abstract.Insertion + +Insertion.Top : Abstract.Insertion + +Insertion.Bottom : Abstract.Insertion + +Insertion.After : Abstract.Insertion + + +Compat +====== +TODO + + +RoR +=== +
+ + + (leave url ») + + +link_to_remote word, + :url => { :action => "action" }, + 404 => "alert('Not found...? Wrong URL...?')", + :failure => "alert('HTTP Error ' + request.status + '!')" + + +link_to_remove + :url + :update + :update => "emails" + or + :update => { :success => "posts", :failure => "error" } + :position + - :before, :top, :bottom, :after + Callbacks + :complete + :loading + :loaded + :interactive + :failure + :confirm - add confirmation dialog + :condition + :before - before request is initiated + :after - after request was initiated and before :loading diff --git a/sope-appserver/WEPrototype/Version b/sope-appserver/WEPrototype/Version new file mode 100644 index 00000000..ee9b5f97 --- /dev/null +++ b/sope-appserver/WEPrototype/Version @@ -0,0 +1,5 @@ +# version file + +SUBMINOR_VERSION:=1 + +# v4.5.1 requires libNGObjWeb v4.5.170 diff --git a/sope-appserver/WEPrototype/WELiveLink.m b/sope-appserver/WEPrototype/WELiveLink.m new file mode 100644 index 00000000..b1a657bf --- /dev/null +++ b/sope-appserver/WEPrototype/WELiveLink.m @@ -0,0 +1,212 @@ +/* + Copyright (C) 2005 Helge Hess + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#import + +/* + WELiveLink + + Inspired by the link_to_remote() RoR function. +*/ + +@interface WELiveLink : WODynamicElement +{ + WOAssociation *string; + WOAssociation *updateID; + WOAssociation *position; + + WOAssociation *actionClass; + WOAssociation *directActionName; + WOAssociation *href; + + WOAssociation *confirmText; + + WOElement *template; +} + +@end + +#include "WEPrototypeScript.h" +#include "common.h" + +@implementation WELiveLink + +- (id)initWithName:(NSString *)_name + associations:(NSDictionary *)_config + template:(WOElement *)_tmp +{ + if ((self = [super initWithName:_name associations:_config template:_tmp])) { + self->template = [_tmp retain]; + + self->string = WEPExtGetProperty(_config, @"string"); + self->updateID = WEPExtGetProperty(_config, @"updateID"); + self->position = WEPExtGetProperty(_config, @"position"); + self->actionClass = WEPExtGetProperty(_config, @"actionClass"); + self->directActionName = WEPExtGetProperty(_config, @"directActionName"); + self->href = WEPExtGetProperty(_config, @"href"); + self->confirmText = WEPExtGetProperty(_config, @"confirmText"); + } + return self; +} + +- (void)dealloc { + [self->updateID release]; + [self->position release]; + [self->actionClass release]; + [self->directActionName release]; + [self->href release]; + [self->confirmText release]; + [self->string release]; + [self->template release]; + [super dealloc]; +} + +/* generating response */ + +- (NSString *)linkInContext:(WOContext *)_ctx { + if (self->directActionName != nil) { + NSString *ac, *da; + + ac = [self->actionClass stringValueInComponent:[_ctx component]]; + da = [self->directActionName stringValueInComponent:[_ctx component]]; + + if ([ac length] > 0) + da = [[ac stringByAppendingString:@"/"] stringByAppendingString:da]; + + return [_ctx directActionURLForActionNamed:da queryDictionary:nil]; + } + + if (self->href != nil) + return [self->href stringValueInComponent:[_ctx component]]; + + [self logWithFormat:@"ERROR: no binding for link!"]; + return nil; +} + +- (void)appendJavaScriptToResponse:(WOResponse *)_response + inContext:(WOContext *)_ctx +{ + /* + new Ajax.Updater('time_div', + '/hello_world/say_when', + {insertion:Insertion.After, asynchronous:true}); + return false; + */ + WOComponent *sComponent; + NSString *s; + BOOL closeBracket = NO, isDOM = NO; + + sComponent = [_ctx component]; + + /* check for confirm panel */ + + s = [self->confirmText stringValueInComponent:sComponent]; + if ([s length] > 0) { + [_response appendContentString:@"if (confirm('"]; + [_response appendContentHTMLAttributeValue:s]; + [_response appendContentString:@"')) { "]; + closeBracket = YES; + } + + /* whether to update an element */ + + s = [self->updateID stringValueInComponent:sComponent]; + if ([s length] > 0) { + [_response appendContentString:@"new Ajax.Updater('"]; + [_response appendContentHTMLAttributeValue:s]; + [_response appendContentString:@"', '"]; + isDOM = YES; + } + else { + [_response appendContentString:@"new Ajax.Request('"]; + } + + /* Link */ + + if ((s = [self linkInContext:_ctx]) != nil) + [_response appendContentHTMLAttributeValue:s]; + [_response appendContentString:@"'"]; + + /* parameters */ + + [_response appendContentString:@", {"]; + + if (isDOM) { + s = [self->position stringValueInComponent:sComponent]; + if ([s length] > 0) { + [_response appendContentString:@"insertion: Insertion."]; + [_response appendContentString:[s capitalizedString]]; + [_response appendContentString:@", "]; + } + } + + [_response appendContentString:@"asynchronous: true }"]; + + /* close function */ + + [_response appendContentString:@");"]; + + /* close confirm panel if */ + + if (closeBracket) [_response appendContentString:@"}"]; + + /* always: do not follow link target */ + [_response appendContentString:@" return false;"]; +} + +- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { + NSString *s; + + /* first ensure that prototype is loaded */ + [WEPrototypeScript appendToResponse:_response inContext:_ctx]; + + /* start link tag */ + + [_response appendContentString:@"otherTagString != nil) { + [_response appendContentString:@" "]; + s = [self->otherTagString stringValueInComponent:[_ctx component]]; + [_response appendContentString:s]; + } + [_response appendContentString:@">"]; + + /* generate content */ + + if ((s = [self->string stringValueInComponent:[_ctx component]]) != nil) + [_response appendContentHTMLString:s]; + + [self->template appendToResponse:_response inContext:_ctx]; + + /* close anker */ + [_response appendContentString:@""]; +} + +@end /* WELiveLink */ diff --git a/sope-appserver/WEPrototype/WEPrototypeBundle.m b/sope-appserver/WEPrototype/WEPrototypeBundle.m new file mode 100644 index 00000000..c6a6328b --- /dev/null +++ b/sope-appserver/WEPrototype/WEPrototypeBundle.m @@ -0,0 +1,28 @@ +/* + Copyright (C) 2005 Helge Hess + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#import + +@interface WEPrototypeBundle : NSObject +@end + +@implementation WEPrototypeBundle +@end /* WEPrototypeBundle */ diff --git a/sope-appserver/WEPrototype/WEPrototypeElemBuilder.m b/sope-appserver/WEPrototype/WEPrototypeElemBuilder.m new file mode 100644 index 00000000..7125f19e --- /dev/null +++ b/sope-appserver/WEPrototype/WEPrototypeElemBuilder.m @@ -0,0 +1,66 @@ +/* + Copyright (C) 2005 Helge Hess + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#include + +/* + This builder builds various elements from the WEPrototype library. + + All tags are mapped into the namespace (XMLNS_OD_BIND). + + Supported tags: +*/ + +@interface WEPrototypeElemBuilder : WOxTagClassElemBuilder +{ +} + +@end + +#include +#include "common.h" + +@implementation WEPrototypeElemBuilder + +- (Class)classForElement:(id)_element { + NSString *tagName; + unsigned tl; + unichar c1; + + if (![[_element namespaceURI] isEqualToString:XMLNS_OD_BIND]) + return Nil; + + tagName = [_element tagName]; + if ((tl = [tagName length]) < 2) + return Nil; + + c1 = [tagName characterAtIndex:0]; + + switch (c1) { + case 'l': + if ([tagName isEqualToString:@"live-link"]) + return NSClassFromString(@"WELiveLink"); + default: + return Nil; + } +} + +@end /* WEPrototypeElemBuilder */ diff --git a/sope-appserver/WEPrototype/WEPrototypeScript.api b/sope-appserver/WEPrototype/WEPrototypeScript.api new file mode 100644 index 00000000..f9b25fe3 --- /dev/null +++ b/sope-appserver/WEPrototype/WEPrototypeScript.api @@ -0,0 +1,4 @@ + + + + diff --git a/sope-appserver/WEPrototype/WEPrototypeScript.h b/sope-appserver/WEPrototype/WEPrototypeScript.h new file mode 100644 index 00000000..d97443e7 --- /dev/null +++ b/sope-appserver/WEPrototype/WEPrototypeScript.h @@ -0,0 +1,49 @@ +/* + Copyright (C) 2005 Helge Hess + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#ifndef __WEPrototypeScript_H__ +#define __WEPrototypeScript_H__ + +#import + +/* + WEPrototypeScript + + Generates a link to the direct action which delivers the prototype.js file. + + The method is also exposed as a class method so that other methods can + trigger it. It will generate its content only once (protected by a context + variable). +*/ + +@class WOContext, WOResponse; + +@interface WEPrototypeScript : WODynamicElement +{ +} + ++ (BOOL)wasDeliveredInContext:(WOContext *)_ctx; ++ (void)markDeliveredInContext:(WOContext *)_ctx; ++ (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx; + +@end + +#endif /* __WEPrototypeScript_H__ */ diff --git a/sope-appserver/WEPrototype/WEPrototypeScript.jsm b/sope-appserver/WEPrototype/WEPrototypeScript.jsm new file mode 100644 index 00000000..e752dbe1 --- /dev/null +++ b/sope-appserver/WEPrototype/WEPrototypeScript.jsm @@ -0,0 +1,695 @@ +/* automatically generated from prototype/prototype.js, do not edit ! */ +@"/* Prototype: an object-oriented Javascript library, version 1.2.0\n" +@" * (c) 2005 Sam Stephenson \n" +@" *\n" +@" * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff\n" +@" * against the source tree, available from the Prototype darcs repository. \n" +@" *\n" +@" * Prototype is freely distributable under the terms of an MIT-style license.\n" +@" *\n" +@" * For details, see the Prototype web site: http://prototype.conio.net/\n" +@" *\n" +@"/*--------------------------------------------------------------------------*/\n" +@"var Prototype = {\n" +@" Version: '1.2.0'\n" +@"}\n" +@"var Class = {\n" +@" create: function() {\n" +@" return function() { \n" +@" this.initialize.apply(this, arguments);\n" +@" }\n" +@" }\n" +@"}\n" +@"var Abstract = new Object();\n" +@"Object.prototype.extend = function(object) {\n" +@" for (property in object) {\n" +@" this[property] = object[property];\n" +@" }\n" +@" return this;\n" +@"}\n" +@"Function.prototype.bind = function(object) {\n" +@" var method = this;\n" +@" return function() {\n" +@" method.apply(object, arguments);\n" +@" }\n" +@"}\n" +@"Function.prototype.bindAsEventListener = function(object) {\n" +@" var method = this;\n" +@" return function(event) {\n" +@" method.call(object, event || window.event);\n" +@" }\n" +@"}\n" +@"Number.prototype.toColorPart = function() {\n" +@" var digits = this.toString(16);\n" +@" if (this < 16) return '0' + digits;\n" +@" return digits;\n" +@"}\n" +@"var Try = {\n" +@" these: function() {\n" +@" var returnValue;\n" +@" \n" +@" for (var i = 0; i < arguments.length; i++) {\n" +@" var lambda = arguments[i];\n" +@" try {\n" +@" returnValue = lambda();\n" +@" break;\n" +@" } catch (e) {}\n" +@" }\n" +@" \n" +@" return returnValue;\n" +@" }\n" +@"}\n" +@"/*--------------------------------------------------------------------------*/\n" +@"var PeriodicalExecuter = Class.create();\n" +@"PeriodicalExecuter.prototype = {\n" +@" initialize: function(callback, frequency) {\n" +@" this.callback = callback;\n" +@" this.frequency = frequency;\n" +@" this.currentlyExecuting = false;\n" +@" \n" +@" this.registerCallback();\n" +@" },\n" +@" \n" +@" registerCallback: function() {\n" +@" setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);\n" +@" },\n" +@" \n" +@" onTimerEvent: function() {\n" +@" if (!this.currentlyExecuting) {\n" +@" try { \n" +@" this.currentlyExecuting = true;\n" +@" this.callback(); \n" +@" } finally { \n" +@" this.currentlyExecuting = false;\n" +@" }\n" +@" }\n" +@" \n" +@" this.registerCallback();\n" +@" }\n" +@"}\n" +@"/*--------------------------------------------------------------------------*/\n" +@"function $() {\n" +@" var elements = new Array();\n" +@" \n" +@" for (var i = 0; i < arguments.length; i++) {\n" +@" var element = arguments[i];\n" +@" if (typeof element == 'string')\n" +@" element = document.getElementById(element);\n" +@" if (arguments.length == 1) \n" +@" return element;\n" +@" \n" +@" elements.push(element);\n" +@" }\n" +@" \n" +@" return elements;\n" +@"}\n" +@"/*--------------------------------------------------------------------------*/\n" +@"if (!Array.prototype.push) {\n" +@" Array.prototype.push = function() {\n" +@" var startLength = this.length;\n" +@" for (var i = 0; i < arguments.length; i++)\n" +@" this[startLength + i] = arguments[i];\n" +@" return this.length;\n" +@" }\n" +@"}\n" +@"if (!Function.prototype.apply) {\n" +@" // Based on code from http://www.youngpup.net/\n" +@" Function.prototype.apply = function(object, parameters) {\n" +@" var parameterStrings = new Array();\n" +@" if (!object) object = window;\n" +@" if (!parameters) parameters = new Array();\n" +@" \n" +@" for (var i = 0; i < parameters.length; i++)\n" +@" parameterStrings[i] = 'x[' + i + ']';\n" +@" \n" +@" object.__apply__ = this;\n" +@" var result = eval('obj.__apply__(' + \n" +@" parameterStrings[i].join(', ') + ')');\n" +@" object.__apply__ = null;\n" +@" \n" +@" return result;\n" +@" }\n" +@"}\n" +@"/*--------------------------------------------------------------------------*/\n" +@"var Ajax = {\n" +@" getTransport: function() {\n" +@" return Try.these(\n" +@" function() {return new ActiveXObject('Msxml2.XMLHTTP')},\n" +@" function() {return new ActiveXObject('Microsoft.XMLHTTP')},\n" +@" function() {return new XMLHttpRequest()}\n" +@" ) || false;\n" +@" },\n" +@" \n" +@" emptyFunction: function() {}\n" +@"}\n" +@"Ajax.Base = function() {};\n" +@"Ajax.Base.prototype = {\n" +@" setOptions: function(options) {\n" +@" this.options = {\n" +@" method: 'post',\n" +@" asynchronous: true,\n" +@" parameters: ''\n" +@" }.extend(options || {});\n" +@" }\n" +@"}\n" +@"Ajax.Request = Class.create();\n" +@"Ajax.Request.Events = \n" +@" ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];\n" +@"Ajax.Request.prototype = (new Ajax.Base()).extend({\n" +@" initialize: function(url, options) {\n" +@" this.transport = Ajax.getTransport();\n" +@" this.setOptions(options);\n" +@" \n" +@" try {\n" +@" if (this.options.method == 'get')\n" +@" url += '?' + this.options.parameters + '&_=';\n" +@" \n" +@" this.transport.open(this.options.method, url, true);\n" +@" \n" +@" if (this.options.asynchronous) {\n" +@" this.transport.onreadystatechange = this.onStateChange.bind(this);\n" +@" setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);\n" +@" }\n" +@" \n" +@" this.transport.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n" +@" this.transport.setRequestHeader('X-Prototype-Version', Prototype.Version);\n" +@" if (this.options.method == 'post') {\n" +@" this.transport.setRequestHeader('Connection', 'close');\n" +@" this.transport.setRequestHeader('Content-type',\n" +@" 'application/x-www-form-urlencoded');\n" +@" }\n" +@" \n" +@" this.transport.send(this.options.method == 'post' ? \n" +@" this.options.parameters + '&_=' : null);\n" +@" \n" +@" } catch (e) {\n" +@" } \n" +@" },\n" +@" \n" +@" onStateChange: function() {\n" +@" var readyState = this.transport.readyState;\n" +@" if (readyState != 1)\n" +@" this.respondToReadyState(this.transport.readyState);\n" +@" },\n" +@" \n" +@" respondToReadyState: function(readyState) {\n" +@" var event = Ajax.Request.Events[readyState];\n" +@" (this.options['on' + event] || Ajax.emptyFunction)(this.transport);\n" +@" }\n" +@"});\n" +@"Ajax.Updater = Class.create();\n" +@"Ajax.Updater.prototype = (new Ajax.Base()).extend({\n" +@" initialize: function(container, url, options) {\n" +@" this.container = $(container);\n" +@" this.setOptions(options);\n" +@" \n" +@" if (this.options.asynchronous) {\n" +@" this.onComplete = this.options.onComplete;\n" +@" this.options.onComplete = this.updateContent.bind(this);\n" +@" }\n" +@" \n" +@" this.request = new Ajax.Request(url, this.options);\n" +@" \n" +@" if (!this.options.asynchronous)\n" +@" this.updateContent();\n" +@" },\n" +@" \n" +@" updateContent: function() {\n" +@" if (this.options.insertion) {\n" +@" new this.options.insertion(this.container,\n" +@" this.request.transport.responseText);\n" +@" } else {\n" +@" this.container.innerHTML = this.request.transport.responseText;\n" +@" }\n" +@" if (this.onComplete) {\n" +@" setTimeout((function() {this.onComplete(this.request)}).bind(this), 10);\n" +@" }\n" +@" }\n" +@"});\n" +@"/*--------------------------------------------------------------------------*/\n" +@"var Field = {\n" +@" clear: function() {\n" +@" for (var i = 0; i < arguments.length; i++)\n" +@" $(arguments[i]).value = '';\n" +@" },\n" +@" focus: function(element) {\n" +@" $(element).focus();\n" +@" },\n" +@" \n" +@" present: function() {\n" +@" for (var i = 0; i < arguments.length; i++)\n" +@" if ($(arguments[i]).value == '') return false;\n" +@" return true;\n" +@" },\n" +@" \n" +@" select: function(element) {\n" +@" $(element).select();\n" +@" },\n" +@" \n" +@" activate: function(element) {\n" +@" $(element).focus();\n" +@" $(element).select();\n" +@" }\n" +@"}\n" +@"/*--------------------------------------------------------------------------*/\n" +@"var Form = {\n" +@" serialize: function(form) {\n" +@" var elements = Form.getElements($(form));\n" +@" var queryComponents = new Array();\n" +@" \n" +@" for (var i = 0; i < elements.length; i++) {\n" +@" var queryComponent = Form.Element.serialize(elements[i]);\n" +@" if (queryComponent)\n" +@" queryComponents.push(queryComponent);\n" +@" }\n" +@" \n" +@" return queryComponents.join('&');\n" +@" },\n" +@" \n" +@" getElements: function(form) {\n" +@" form = $(form);\n" +@" var elements = new Array();\n" +@" for (tagName in Form.Element.Serializers) {\n" +@" var tagElements = form.getElementsByTagName(tagName);\n" +@" for (var j = 0; j < tagElements.length; j++)\n" +@" elements.push(tagElements[j]);\n" +@" }\n" +@" return elements;\n" +@" },\n" +@" \n" +@" disable: function(form) {\n" +@" var elements = Form.getElements(form);\n" +@" for (var i = 0; i < elements.length; i++) {\n" +@" var element = elements[i];\n" +@" element.blur();\n" +@" element.disable = 'true';\n" +@" }\n" +@" },\n" +@" focusFirstElement: function(form) {\n" +@" form = $(form);\n" +@" var elements = Form.getElements(form);\n" +@" for (var i = 0; i < elements.length; i++) {\n" +@" var element = elements[i];\n" +@" if (element.type != 'hidden' && !element.disabled) {\n" +@" Field.activate(element);\n" +@" break;\n" +@" }\n" +@" }\n" +@" },\n" +@" reset: function(form) {\n" +@" $(form).reset();\n" +@" }\n" +@"}\n" +@"Form.Element = {\n" +@" serialize: function(element) {\n" +@" element = $(element);\n" +@" var method = element.tagName.toLowerCase();\n" +@" var parameter = Form.Element.Serializers[method](element);\n" +@" \n" +@" if (parameter)\n" +@" return encodeURIComponent(parameter[0]) + '=' + \n" +@" encodeURIComponent(parameter[1]); \n" +@" },\n" +@" \n" +@" getValue: function(element) {\n" +@" element = $(element);\n" +@" var method = element.tagName.toLowerCase();\n" +@" var parameter = Form.Element.Serializers[method](element);\n" +@" \n" +@" if (parameter) \n" +@" return parameter[1];\n" +@" }\n" +@"}\n" +@"Form.Element.Serializers = {\n" +@" input: function(element) {\n" +@" switch (element.type.toLowerCase()) {\n" +@" case 'hidden':\n" +@" case 'password':\n" +@" case 'text':\n" +@" return Form.Element.Serializers.textarea(element);\n" +@" case 'checkbox': \n" +@" case 'radio':\n" +@" return Form.Element.Serializers.inputSelector(element);\n" +@" }\n" +@" return false;\n" +@" },\n" +@" inputSelector: function(element) {\n" +@" if (element.checked)\n" +@" return [element.name, element.value];\n" +@" },\n" +@" textarea: function(element) {\n" +@" return [element.name, element.value];\n" +@" },\n" +@" select: function(element) {\n" +@" var index = element.selectedIndex;\n" +@" var value = element.options[index].value || element.options[index].text;\n" +@" return [element.name, (index >= 0) ? value : ''];\n" +@" }\n" +@"}\n" +@"/*--------------------------------------------------------------------------*/\n" +@"var $F = Form.Element.getValue;\n" +@"/*--------------------------------------------------------------------------*/\n" +@"Abstract.TimedObserver = function() {}\n" +@"Abstract.TimedObserver.prototype = {\n" +@" initialize: function(element, frequency, callback) {\n" +@" this.frequency = frequency;\n" +@" this.element = $(element);\n" +@" this.callback = callback;\n" +@" \n" +@" this.lastValue = this.getValue();\n" +@" this.registerCallback();\n" +@" },\n" +@" \n" +@" registerCallback: function() {\n" +@" setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);\n" +@" },\n" +@" \n" +@" onTimerEvent: function() {\n" +@" var value = this.getValue();\n" +@" if (this.lastValue != value) {\n" +@" this.callback(this.element, value);\n" +@" this.lastValue = value;\n" +@" }\n" +@" \n" +@" this.registerCallback();\n" +@" }\n" +@"}\n" +@"Form.Element.Observer = Class.create();\n" +@"Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({\n" +@" getValue: function() {\n" +@" return Form.Element.getValue(this.element);\n" +@" }\n" +@"});\n" +@"Form.Observer = Class.create();\n" +@"Form.Observer.prototype = (new Abstract.TimedObserver()).extend({\n" +@" getValue: function() {\n" +@" return Form.serialize(this.element);\n" +@" }\n" +@"});\n" +@"/*--------------------------------------------------------------------------*/\n" +@"document.getElementsByClassName = function(className) {\n" +@" var children = document.getElementsByTagName('*') || document.all;\n" +@" var elements = new Array();\n" +@" \n" +@" for (var i = 0; i < children.length; i++) {\n" +@" var child = children[i];\n" +@" var classNames = child.className.split(' ');\n" +@" for (var j = 0; j < classNames.length; j++) {\n" +@" if (classNames[j] == className) {\n" +@" elements.push(child);\n" +@" break;\n" +@" }\n" +@" }\n" +@" }\n" +@" \n" +@" return elements;\n" +@"}\n" +@"/*--------------------------------------------------------------------------*/\n" +@"var Element = {\n" +@" toggle: function() {\n" +@" for (var i = 0; i < arguments.length; i++) {\n" +@" var element = $(arguments[i]);\n" +@" element.style.display = \n" +@" (element.style.display == 'none' ? '' : 'none');\n" +@" }\n" +@" },\n" +@" hide: function() {\n" +@" for (var i = 0; i < arguments.length; i++) {\n" +@" var element = $(arguments[i]);\n" +@" element.style.display = 'none';\n" +@" }\n" +@" },\n" +@" show: function() {\n" +@" for (var i = 0; i < arguments.length; i++) {\n" +@" var element = $(arguments[i]);\n" +@" element.style.display = '';\n" +@" }\n" +@" },\n" +@" remove: function(element) {\n" +@" element = $(element);\n" +@" element.parentNode.removeChild(element);\n" +@" },\n" +@" \n" +@" getHeight: function(element) {\n" +@" element = $(element);\n" +@" return element.offsetHeight; \n" +@" }\n" +@"}\n" +@"var Toggle = new Object();\n" +@"Toggle.display = Element.toggle;\n" +@"/*--------------------------------------------------------------------------*/\n" +@"Abstract.Insertion = function(adjacency) {\n" +@" this.adjacency = adjacency;\n" +@"}\n" +@"Abstract.Insertion.prototype = {\n" +@" initialize: function(element, content) {\n" +@" this.element = $(element);\n" +@" this.content = content;\n" +@" \n" +@" if (this.adjacency && this.element.insertAdjacentHTML) {\n" +@" this.element.insertAdjacentHTML(this.adjacency, this.content);\n" +@" } else {\n" +@" this.range = this.element.ownerDocument.createRange();\n" +@" if (this.initializeRange) this.initializeRange();\n" +@" this.fragment = this.range.createContextualFragment(this.content);\n" +@" this.insertContent();\n" +@" }\n" +@" }\n" +@"}\n" +@"var Insertion = new Object();\n" +@"Insertion.Before = Class.create();\n" +@"Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({\n" +@" initializeRange: function() {\n" +@" this.range.setStartBefore(this.element);\n" +@" },\n" +@" \n" +@" insertContent: function() {\n" +@" this.element.parentNode.insertBefore(this.fragment, this.element);\n" +@" }\n" +@"});\n" +@"Insertion.Top = Class.create();\n" +@"Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({\n" +@" initializeRange: function() {\n" +@" this.range.selectNodeContents(this.element);\n" +@" this.range.collapse(true);\n" +@" },\n" +@" \n" +@" insertContent: function() { \n" +@" this.element.insertBefore(this.fragment, this.element.firstChild);\n" +@" }\n" +@"});\n" +@"Insertion.Bottom = Class.create();\n" +@"Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({\n" +@" initializeRange: function() {\n" +@" this.range.selectNodeContents(this.element);\n" +@" this.range.collapse(this.element);\n" +@" },\n" +@" \n" +@" insertContent: function() {\n" +@" this.element.appendChild(this.fragment);\n" +@" }\n" +@"});\n" +@"Insertion.After = Class.create();\n" +@"Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({\n" +@" initializeRange: function() {\n" +@" this.range.setStartAfter(this.element);\n" +@" },\n" +@" \n" +@" insertContent: function() {\n" +@" this.element.parentNode.insertBefore(this.fragment, \n" +@" this.element.nextSibling);\n" +@" }\n" +@"});\n" +@"/*--------------------------------------------------------------------------*/\n" +@"var Effect = new Object();\n" +@"Effect.Highlight = Class.create();\n" +@"Effect.Highlight.prototype = {\n" +@" initialize: function(element) {\n" +@" this.element = $(element);\n" +@" this.start = 153;\n" +@" this.finish = 255;\n" +@" this.current = this.start;\n" +@" this.fade();\n" +@" },\n" +@" \n" +@" fade: function() {\n" +@" if (this.isFinished()) return;\n" +@" if (this.timer) clearTimeout(this.timer);\n" +@" this.highlight(this.element, this.current);\n" +@" this.current += 17;\n" +@" this.timer = setTimeout(this.fade.bind(this), 250);\n" +@" },\n" +@" \n" +@" isFinished: function() {\n" +@" return this.current > this.finish;\n" +@" },\n" +@" \n" +@" highlight: function(element, current) {\n" +@" element.style.backgroundColor = \"#ffff\" + current.toColorPart();\n" +@" }\n" +@"}\n" +@"Effect.Fade = Class.create();\n" +@"Effect.Fade.prototype = {\n" +@" initialize: function(element) {\n" +@" this.element = $(element);\n" +@" this.start = 100;\n" +@" this.finish = 0;\n" +@" this.current = this.start;\n" +@" this.fade();\n" +@" },\n" +@" \n" +@" fade: function() {\n" +@" if (this.isFinished()) { this.element.style.display = 'none'; return; }\n" +@" if (this.timer) clearTimeout(this.timer);\n" +@" this.setOpacity(this.element, this.current);\n" +@" this.current -= 10;\n" +@" this.timer = setTimeout(this.fade.bind(this), 50);\n" +@" },\n" +@" \n" +@" isFinished: function() {\n" +@" return this.current <= this.finish;\n" +@" },\n" +@" \n" +@" setOpacity: function(element, opacity) {\n" +@" opacity = (opacity == 100) ? 99.999 : opacity;\n" +@" element.style.filter = \"alpha(opacity:\"+opacity+\")\";\n" +@" element.style.opacity = opacity/100 /*//*/;\n" +@" }\n" +@"}\n" +@"Effect.Scale = Class.create();\n" +@"Effect.Scale.prototype = {\n" +@" initialize: function(element, percent) {\n" +@" this.element = $(element);\n" +@" this.startScale = 1.0;\n" +@" this.startHeight = this.element.offsetHeight;\n" +@" this.startWidth = this.element.offsetWidth;\n" +@" this.currentHeight = this.startHeight;\n" +@" this.currentWidth = this.startWidth;\n" +@" this.finishScale = (percent/100) /*//*/;\n" +@" if (this.element.style.fontSize==\"\") this.sizeEm = 1.0;\n" +@" if (this.element.style.fontSize.indexOf(\"em\")>0)\n" +@" this.sizeEm = parseFloat(this.element.style.fontSize);\n" +@" if(this.element.effect_scale) {\n" +@" clearTimeout(this.element.effect_scale.timer);\n" +@" this.startScale = this.element.effect_scale.currentScale;\n" +@" this.startHeight = this.element.effect_scale.startHeight;\n" +@" this.startWidth = this.element.effect_scale.startWidth;\n" +@" if(this.element.effect_scale.sizeEm) \n" +@" this.sizeEm = this.element.effect_scale.sizeEm; \n" +@" }\n" +@" this.element.effect_scale = this;\n" +@" this.currentScale = this.startScale;\n" +@" this.factor = this.finishScale - this.startScale;\n" +@" this.options = arguments[2] || {}; \n" +@" this.scale();\n" +@" },\n" +@" \n" +@" scale: function() {\n" +@" if (this.isFinished()) { \n" +@" this.setDimensions(this.element, this.startWidth*this.finishScale, this.startHeight*this.finishScale);\n" +@" if(this.sizeEm) this.element.style.fontSize = this.sizeEm*this.finishScale + \"em\";\n" +@" if(this.options.complete) this.options.complete(this);\n" +@" return; \n" +@" }\n" +@" if (this.timer) clearTimeout(this.timer);\n" +@" if (this.options.step) this.options.step(this);\n" +@" this.setDimensions(this.element, this.currentWidth, this.currentHeight);\n" +@" if(this.sizeEm) this.element.style.fontSize = this.sizeEm*this.currentScale + \"em\";\n" +@" this.currentScale += (this.factor/10) /*//*/;\n" +@" this.currentWidth = this.startWidth * this.currentScale;\n" +@" this.currentHeight = this.startHeight * this.currentScale;\n" +@" this.timer = setTimeout(this.scale.bind(this), 50);\n" +@" },\n" +@" \n" +@" isFinished: function() {\n" +@" return (this.factor < 0) ? \n" +@" this.currentScale <= this.finishScale : this.currentScale >= this.finishScale;\n" +@" },\n" +@" \n" +@" setDimensions: function(element, width, height) {\n" +@" element.style.width = width + 'px';\n" +@" element.style.height = height + 'px';\n" +@" }\n" +@"}\n" +@"Effect.Squish = Class.create();\n" +@"Effect.Squish.prototype = {\n" +@" initialize: function(element) {\n" +@" this.element = $(element);\n" +@" new Effect.Scale(this.element, 1, { complete: this.hide.bind(this) } );\n" +@" },\n" +@" hide: function() {\n" +@" this.element.style.display = 'none';\n" +@" } \n" +@"}\n" +@"Effect.Puff = Class.create();\n" +@"Effect.Puff.prototype = {\n" +@" initialize: function(element) {\n" +@" this.element = $(element);\n" +@" this.opacity = 100;\n" +@" this.startTop = this.element.top || this.element.offsetTop;\n" +@" this.startLeft = this.element.left || this.element.offsetLeft;\n" +@" new Effect.Scale(this.element, 200, { step: this.fade.bind(this), complete: this.hide.bind(this) } );\n" +@" },\n" +@" fade: function(effect) {\n" +@" topd = (((effect.currentScale)*effect.startHeight) - effect.startHeight)/2;\n" +@" leftd = (((effect.currentScale)*effect.startWidth) - effect.startWidth)/2;\n" +@" this.element.style.position='absolute';\n" +@" this.element.style.top = this.startTop-topd + \"px\";\n" +@" this.element.style.left = this.startLeft-leftd + \"px\";\n" +@" this.opacity -= 10;\n" +@" this.setOpacity(this.element, this.opacity); \n" +@" if(navigator.appVersion.indexOf('AppleWebKit')>0) this.element.innerHTML += ''; //force redraw on safari\n" +@" },\n" +@" hide: function() {\n" +@" this.element.style.display = 'none';\n" +@" },\n" +@" setOpacity: function(element, opacity) {\n" +@" opacity = (opacity == 100) ? 99.999 : opacity;\n" +@" element.style.filter = \"alpha(opacity:\"+opacity+\")\";\n" +@" element.style.opacity = opacity/100 /*//*/;\n" +@" }\n" +@"}\n" +@"Effect.Appear = Class.create();\n" +@"Effect.Appear.prototype = {\n" +@" initialize: function(element) {\n" +@" this.element = $(element);\n" +@" this.start = 0;\n" +@" this.finish = 100;\n" +@" this.current = this.start;\n" +@" this.fade();\n" +@" },\n" +@" \n" +@" fade: function() {\n" +@" if (this.isFinished()) return;\n" +@" if (this.timer) clearTimeout(this.timer);\n" +@" this.setOpacity(this.element, this.current);\n" +@" this.current += 10;\n" +@" this.timer = setTimeout(this.fade.bind(this), 50);\n" +@" },\n" +@" \n" +@" isFinished: function() {\n" +@" return this.current > this.finish;\n" +@" },\n" +@" \n" +@" setOpacity: function(element, opacity) {\n" +@" opacity = (opacity == 100) ? 99.999 : opacity;\n" +@" element.style.filter = \"alpha(opacity:\"+opacity+\")\";\n" +@" element.style.opacity = opacity/100 /*//*/;\n" +@" element.style.display = '';\n" +@" }\n" +@"}\n" +@"Effect.ContentZoom = Class.create();\n" +@"Effect.ContentZoom.prototype = {\n" +@" initialize: function(element, percent) {\n" +@" this.element = $(element);\n" +@" if (this.element.style.fontSize==\"\") this.sizeEm = 1.0;\n" +@" if (this.element.style.fontSize.indexOf(\"em\")>0)\n" +@" this.sizeEm = parseFloat(this.element.style.fontSize);\n" +@" if(this.element.effect_contentzoom) {\n" +@" this.sizeEm = this.element.effect_contentzoom.sizeEm;\n" +@" }\n" +@" this.element.effect_contentzoom = this;\n" +@" this.element.style.fontSize = this.sizeEm*(percent/100) + \"em\" /*//*/;\n" +@" if(navigator.appVersion.indexOf('AppleWebKit')>0) { this.element.scrollTop -= 1; };\n" +@" }\n" +@"}\n" diff --git a/sope-appserver/WEPrototype/WEPrototypeScript.m b/sope-appserver/WEPrototype/WEPrototypeScript.m new file mode 100644 index 00000000..c9ec1d4c --- /dev/null +++ b/sope-appserver/WEPrototype/WEPrototypeScript.m @@ -0,0 +1,59 @@ +/* + Copyright (C) 2005 Helge Hess + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#include "WEPrototypeScript.h" +#include "common.h" + +@implementation WEPrototypeScript + +static NSString *WEPrototypeScriptKey = @"WEPrototypeScriptKey"; + +/* generating response */ + ++ (BOOL)wasDeliveredInContext:(WOContext *)_ctx { + return [[_ctx objectForKey:WEPrototypeScriptKey] boolValue]; +} + ++ (void)markDeliveredInContext:(WOContext *)_ctx { + [_ctx setObject:@"YES" forKey:WEPrototypeScriptKey]; +} + ++ (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { + NSString *url; + + if ([self wasDeliveredInContext:_ctx]) + return; + + url = [_ctx directActionURLForActionNamed:@"WEPrototypeScriptAction/default" + queryDictionary:nil]; + + [_response appendContentString:@""]; + + [self markDeliveredInContext:_ctx]; +} + +- (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx { + [[self class] appendToResponse:_response inContext:_ctx]; +} + +@end /* WEPrototypeScript */ diff --git a/sope-appserver/WEPrototype/WEPrototypeScriptAction.m b/sope-appserver/WEPrototype/WEPrototypeScriptAction.m new file mode 100644 index 00000000..38ad677b --- /dev/null +++ b/sope-appserver/WEPrototype/WEPrototypeScriptAction.m @@ -0,0 +1,68 @@ +/* + Copyright (C) 2005 Helge Hess + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#import + +@interface WEPrototypeScriptAction : WODirectAction +@end + +#include "common.h" + +@implementation WEPrototypeScriptAction + +static NSString *etag = nil; +static NSString *script = +#include "WEPrototypeScript.jsm" + ; + ++ (void)initialize { + if (etag == nil) { + etag = [[NSString alloc] initWithFormat:@"\"sope/%i.%i-wep/%03i\"", + SOPE_MAJOR_VERSION, SOPE_MINOR_VERSION, + WEP_SUBMINOR_VERSION]; + } +} + +- (id)defaultAction { + WOResponse *r; + NSString *s; + + r = [[self context] response]; + [r setHeader:@"application/x-javascript" forKey:@"content-type"]; + [r setHeader:etag forKey:@"etag"]; + + /* check preconditions */ + + s = [[[self context] request] headerForKey:@"if-none-match"]; + if ([s rangeOfString:etag].length > 0) { + /* client already has the proper entity */ + [r setStatus:304 /* Not Modified */]; + return r; + } + + /* send script */ + + [r setStatus:200 /* OK */]; + [r appendContentString:script]; + return r; +} + +@end /* WEPrototypeScriptAction */ diff --git a/sope-appserver/WEPrototype/bundle-info.plist b/sope-appserver/WEPrototype/bundle-info.plist new file mode 100644 index 00000000..e1fa8f41 --- /dev/null +++ b/sope-appserver/WEPrototype/bundle-info.plist @@ -0,0 +1,23 @@ +{ + requires = { + bundleManagerVersion = 1; + + classes = ( + { name = NSObject; } + ); + }; + + provides = { + WOxElemBuilder = ( + { name = "WEPrototypeElemBuilder"; }, + ); + + WODynamicElements = ( + { name = "WELiveLink"; }, + ); + + classes = ( + { name = "WEPrototypeElemBuilder"; }, + ); + }; +} diff --git a/sope-appserver/WEPrototype/common.h b/sope-appserver/WEPrototype/common.h new file mode 100644 index 00000000..b2ad6cf4 --- /dev/null +++ b/sope-appserver/WEPrototype/common.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2005 Helge Hess + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#ifndef __WEPrototype_common_H__ +#define __WEPrototype_common_H__ + +#import + +#include +#include + +#if NeXT_Foundation_LIBRARY || APPLE_Foundation_LIBRARY +# include +#endif + +static inline id WEPExtGetProperty(NSDictionary *_set, NSString *_name) { + id propValue = [_set objectForKey:_name]; + + if (propValue != nil) { + propValue = [propValue retain]; + [(NSMutableDictionary *)_set removeObjectForKey:_name]; + } + return propValue; +} + +#endif /* __WEPrototype_common_H__ */ diff --git a/sope-appserver/WEPrototype/fhs.make b/sope-appserver/WEPrototype/fhs.make new file mode 100644 index 00000000..c5ed2134 --- /dev/null +++ b/sope-appserver/WEPrototype/fhs.make @@ -0,0 +1,55 @@ +# postprocessing + +# FHS support (this is a hack and is going to be done by gstep-make!) + +ifneq ($(FHS_INSTALL_ROOT),) + +FHS_INCLUDE_DIR=$(FHS_INSTALL_ROOT)/include/ +FHS_LIB_DIR=$(FHS_INSTALL_ROOT)/lib/ +FHS_BIN_DIR=$(FHS_INSTALL_ROOT)/bin/ +FHS_WOx_DIR=$(FHS_LIB_DIR)sope-$(MAJOR_VERSION).$(MINOR_VERSION)/wox-builders/ +FHS_MAN_DIR=$(FHS_INSTALL_ROOT)/man + +NONFHS_LIBDIR="$(GNUSTEP_LIBRARIES)/$(GNUSTEP_TARGET_LDIR)/" +NONFHS_LIBNAME="$(LIBRARY_NAME)$(LIBRARY_NAME_SUFFIX)$(SHARED_LIBEXT)" + + +fhs-header-dirs :: + $(MKDIRS) $(FHS_INCLUDE_DIR)$(libWEPrototype_HEADER_FILES_INSTALL_DIR) + +fhs-wox-dirs :: + $(MKDIRS) $(FHS_WOx_DIR) + +fhs-man-dirs :: + $(MKDIRS) $(FHS_MAN_DIR) + +move-headers-to-fhs :: fhs-header-dirs + @echo "moving headers to $(FHS_INCLUDE_DIR) .." + mv $(GNUSTEP_HEADERS)$(libWEPrototype_HEADER_FILES_INSTALL_DIR)/*.h \ + $(FHS_INCLUDE_DIR)$(libWEPrototype_HEADER_FILES_INSTALL_DIR)/ + +move-libs-to-fhs :: + @echo "moving libs to $(FHS_LIB_DIR) .." + mv $(NONFHS_LIBDIR)/$(NONFHS_LIBNAME)* $(FHS_LIB_DIR)/ + +move-bundles-to-fhs :: fhs-wox-dirs + @echo "moving bundles $(BUNDLE_INSTALL_DIR) to $(FHS_WOx_DIR) .." + for i in $(BUNDLE_NAME); do \ + j="$(FHS_WOx_DIR)/$${i}$(BUNDLE_EXTENSION)"; \ + if test -d $$j; then rm -r $$j; fi; \ + mv "$(BUNDLE_INSTALL_DIR)/$${i}$(BUNDLE_EXTENSION)" $$j; \ + done + +move-to-fhs :: move-headers-to-fhs move-libs-to-fhs move-bundles-to-fhs + +install-fhs-manpages :: fhs-man-dirs + @echo "installing manpages in $(FHS_MAN_DIR) ..." + for i in $(FHS_MANPAGES); do \ + msection="$(FHS_MAN_DIR)/man`echo -n $$i | tail -c 1`"; \ + $(MKDIRS) $$msection; \ + $(INSTALL_DATA) $$i $$msection; \ + done + +after-install :: install-fhs-manpages move-to-fhs + +endif diff --git a/sope-appserver/WEPrototype/js2m.sh b/sope-appserver/WEPrototype/js2m.sh new file mode 100755 index 00000000..c1b77372 --- /dev/null +++ b/sope-appserver/WEPrototype/js2m.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +jsfile=$1 +mfile=$2 + +if [ "x${jsfile}" = "x" ]; then + echo "usage: $0 " + exit 1; +fi +if [ "x${mfile}" = "x" ]; then + echo "usage: $0 " + exit 1; +fi + +if [ ! -f $jsfile ]; then + echo "$0: file '${jsfile}' can't be found !" + exit 2; +fi + +echo "transforming ${jsfile} to ${mfile} .." + +IFS=" +" +replaceto='\\"' + +SEDCMD=sed +ECHOCMD=echo + +$ECHOCMD >$mfile "/* automatically generated from ${jsfile}, do not edit ! */" +for i in `${SEDCMD} "s|\\"|$replaceto|g" <${jsfile}`; do + $ECHOCMD -n >>$mfile "@\"" + $ECHOCMD -n >>$mfile "${i}" + $ECHOCMD >>$mfile "\\n\"" +done diff --git a/sope-appserver/WEPrototype/prototype/AUTHORS b/sope-appserver/WEPrototype/prototype/AUTHORS new file mode 100644 index 00000000..77456177 --- /dev/null +++ b/sope-appserver/WEPrototype/prototype/AUTHORS @@ -0,0 +1,6 @@ +Creator and maintainer +* Sam Stephenson -- http://conio.net/ +--- +* Thomas Fuchs -- http://mir.aculo.us/ +* David Heinemeier Hansson -- http://www.loudthinking.com/ +* Matthew McCray -- http://www.mattmccray.com/ diff --git a/sope-appserver/WEPrototype/prototype/LICENSE b/sope-appserver/WEPrototype/prototype/LICENSE new file mode 100644 index 00000000..45ac2509 --- /dev/null +++ b/sope-appserver/WEPrototype/prototype/LICENSE @@ -0,0 +1,16 @@ +Copyright (c) 2005 Sam Stephenson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sope-appserver/WEPrototype/prototype/README b/sope-appserver/WEPrototype/prototype/README new file mode 100644 index 00000000..c09679aa --- /dev/null +++ b/sope-appserver/WEPrototype/prototype/README @@ -0,0 +1,52 @@ += Prototype +==== An object-oriented Javascript library + +(c) 2005 Sam Stephenson (mailto:sam@conio.net) + +Prototype is a Javascript library that aims to ease development of dynamic web applications. Its development is driven heavily by the Ruby on Rails framework, but it can be used in any environment. + +=== Targeted platforms + +Prototype currently targets the following platforms: + +* Microsoft Internet Explorer for Windows, version 6.0 and higher +* Mozilla Firefox 1.0/Mozilla 1.7 and higher +* Apple Safari 1.2 and higher + +== Using Prototype + +To use Prototype in your application, download the latest release from the Prototype web site (http://prototype.conio.net/) and copy dist/prototype.js to a suitable location. Then include it in your HTML like so: + + + +=== Building Prototype from source + +prototype.js is a composite file generated from many source files in the src/ directory. To build Prototype, you'll need: + +* a copy of the Prototype source tree, either from a distribution tarball or + from the darcs repository (see below) +* Ruby 1.8.2 or higher (http://www.ruby-lang.org/) +* Rake -- Ruby Make (http://rake.rubyforge.org/) +* RDoc, if your Ruby distribution does not include it +* darcs 1.0.1 or higher (http://abridgegame.org/darcs/; static binaries + available at http://www.scannedinavian.org/DarcsWiki/CategoryBinaries) + +From the root Prototype directory, + +* rake generate_dist_prototype will run script/make-dist.rb, + which preprocesses the Prototype source and generates the single-file + dist/prototype.js. +* rake generate_dist_tarball will run the aforementioned task and + create a distribution tarball of your current darcs repository with + darcs dist. (rake dist, or just rake, can be used + for this, too.) + +== Contributing to Prototype + +You'll need the tools mentioned above. Modify the files in src/, add tests in test/ if possible, generate a new dist file, and record the changes with darcs record -al. Then email patches to mailto:sam@conio.net using darcs send. + +== Documentation + +Prototype is embarrassingly lacking in documentation. (The source code should be fairly easy to comprehend; I'm committed to using a clean style with meaningful identifiers. But I know that only goes so far.) + +Much of the problem is that there is no easy way to document it from within the source code itself. I've tried JSDoc[http://jsdoc.sf.net/] and a Perl script included with JsUnit[http://www.edwardh.com/jsunit/]; neither groks Prototype's hash-style class definitions or inheritance scheme. Making them work would require major changes, and I don't have the time for that right now. diff --git a/sope-appserver/WEPrototype/prototype/prototype.js b/sope-appserver/WEPrototype/prototype/prototype.js new file mode 100644 index 00000000..dd5c9b0f --- /dev/null +++ b/sope-appserver/WEPrototype/prototype/prototype.js @@ -0,0 +1,764 @@ +/* Prototype: an object-oriented Javascript library, version 1.2.0 + * (c) 2005 Sam Stephenson + * + * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff + * against the source tree, available from the Prototype darcs repository. + * + * Prototype is freely distributable under the terms of an MIT-style license. + * + * For details, see the Prototype web site: http://prototype.conio.net/ + * +/*--------------------------------------------------------------------------*/ + +var Prototype = { + Version: '1.2.0' +} + +var Class = { + create: function() { + return function() { + this.initialize.apply(this, arguments); + } + } +} + +var Abstract = new Object(); + +Object.prototype.extend = function(object) { + for (property in object) { + this[property] = object[property]; + } + return this; +} + +Function.prototype.bind = function(object) { + var method = this; + return function() { + method.apply(object, arguments); + } +} + +Function.prototype.bindAsEventListener = function(object) { + var method = this; + return function(event) { + method.call(object, event || window.event); + } +} + +Number.prototype.toColorPart = function() { + var digits = this.toString(16); + if (this < 16) return '0' + digits; + return digits; +} + +var Try = { + these: function() { + var returnValue; + + for (var i = 0; i < arguments.length; i++) { + var lambda = arguments[i]; + try { + returnValue = lambda(); + break; + } catch (e) {} + } + + return returnValue; + } +} + +/*--------------------------------------------------------------------------*/ + +var PeriodicalExecuter = Class.create(); +PeriodicalExecuter.prototype = { + initialize: function(callback, frequency) { + this.callback = callback; + this.frequency = frequency; + this.currentlyExecuting = false; + + this.registerCallback(); + }, + + registerCallback: function() { + setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + if (!this.currentlyExecuting) { + try { + this.currentlyExecuting = true; + this.callback(); + } finally { + this.currentlyExecuting = false; + } + } + + this.registerCallback(); + } +} + +/*--------------------------------------------------------------------------*/ + +function $() { + var elements = new Array(); + + for (var i = 0; i < arguments.length; i++) { + var element = arguments[i]; + if (typeof element == 'string') + element = document.getElementById(element); + + if (arguments.length == 1) + return element; + + elements.push(element); + } + + return elements; +} + +/*--------------------------------------------------------------------------*/ + +if (!Array.prototype.push) { + Array.prototype.push = function() { + var startLength = this.length; + for (var i = 0; i < arguments.length; i++) + this[startLength + i] = arguments[i]; + return this.length; + } +} + +if (!Function.prototype.apply) { + // Based on code from http://www.youngpup.net/ + Function.prototype.apply = function(object, parameters) { + var parameterStrings = new Array(); + if (!object) object = window; + if (!parameters) parameters = new Array(); + + for (var i = 0; i < parameters.length; i++) + parameterStrings[i] = 'x[' + i + ']'; + + object.__apply__ = this; + var result = eval('obj.__apply__(' + + parameterStrings[i].join(', ') + ')'); + object.__apply__ = null; + + return result; + } +} + +/*--------------------------------------------------------------------------*/ + +var Ajax = { + getTransport: function() { + return Try.these( + function() {return new ActiveXObject('Msxml2.XMLHTTP')}, + function() {return new ActiveXObject('Microsoft.XMLHTTP')}, + function() {return new XMLHttpRequest()} + ) || false; + }, + + emptyFunction: function() {} +} + +Ajax.Base = function() {}; +Ajax.Base.prototype = { + setOptions: function(options) { + this.options = { + method: 'post', + asynchronous: true, + parameters: '' + }.extend(options || {}); + } +} + +Ajax.Request = Class.create(); +Ajax.Request.Events = + ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; + +Ajax.Request.prototype = (new Ajax.Base()).extend({ + initialize: function(url, options) { + this.transport = Ajax.getTransport(); + this.setOptions(options); + + try { + if (this.options.method == 'get') + url += '?' + this.options.parameters + '&_='; + + this.transport.open(this.options.method, url, true); + + if (this.options.asynchronous) { + this.transport.onreadystatechange = this.onStateChange.bind(this); + setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10); + } + + this.transport.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + this.transport.setRequestHeader('X-Prototype-Version', Prototype.Version); + + if (this.options.method == 'post') { + this.transport.setRequestHeader('Connection', 'close'); + this.transport.setRequestHeader('Content-type', + 'application/x-www-form-urlencoded'); + } + + this.transport.send(this.options.method == 'post' ? + this.options.parameters + '&_=' : null); + + } catch (e) { + } + }, + + onStateChange: function() { + var readyState = this.transport.readyState; + if (readyState != 1) + this.respondToReadyState(this.transport.readyState); + }, + + respondToReadyState: function(readyState) { + var event = Ajax.Request.Events[readyState]; + (this.options['on' + event] || Ajax.emptyFunction)(this.transport); + } +}); + +Ajax.Updater = Class.create(); +Ajax.Updater.prototype = (new Ajax.Base()).extend({ + initialize: function(container, url, options) { + this.container = $(container); + this.setOptions(options); + + if (this.options.asynchronous) { + this.onComplete = this.options.onComplete; + this.options.onComplete = this.updateContent.bind(this); + } + + this.request = new Ajax.Request(url, this.options); + + if (!this.options.asynchronous) + this.updateContent(); + }, + + updateContent: function() { + if (this.options.insertion) { + new this.options.insertion(this.container, + this.request.transport.responseText); + } else { + this.container.innerHTML = this.request.transport.responseText; + } + + if (this.onComplete) { + setTimeout((function() {this.onComplete(this.request)}).bind(this), 10); + } + } +}); + +/*--------------------------------------------------------------------------*/ + +var Field = { + clear: function() { + for (var i = 0; i < arguments.length; i++) + $(arguments[i]).value = ''; + }, + + focus: function(element) { + $(element).focus(); + }, + + present: function() { + for (var i = 0; i < arguments.length; i++) + if ($(arguments[i]).value == '') return false; + return true; + }, + + select: function(element) { + $(element).select(); + }, + + activate: function(element) { + $(element).focus(); + $(element).select(); + } +} + +/*--------------------------------------------------------------------------*/ + +var Form = { + serialize: function(form) { + var elements = Form.getElements($(form)); + var queryComponents = new Array(); + + for (var i = 0; i < elements.length; i++) { + var queryComponent = Form.Element.serialize(elements[i]); + if (queryComponent) + queryComponents.push(queryComponent); + } + + return queryComponents.join('&'); + }, + + getElements: function(form) { + form = $(form); + var elements = new Array(); + + for (tagName in Form.Element.Serializers) { + var tagElements = form.getElementsByTagName(tagName); + for (var j = 0; j < tagElements.length; j++) + elements.push(tagElements[j]); + } + return elements; + }, + + disable: function(form) { + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + element.blur(); + element.disable = 'true'; + } + }, + + focusFirstElement: function(form) { + form = $(form); + var elements = Form.getElements(form); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + if (element.type != 'hidden' && !element.disabled) { + Field.activate(element); + break; + } + } + }, + + reset: function(form) { + $(form).reset(); + } +} + +Form.Element = { + serialize: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return encodeURIComponent(parameter[0]) + '=' + + encodeURIComponent(parameter[1]); + }, + + getValue: function(element) { + element = $(element); + var method = element.tagName.toLowerCase(); + var parameter = Form.Element.Serializers[method](element); + + if (parameter) + return parameter[1]; + } +} + +Form.Element.Serializers = { + input: function(element) { + switch (element.type.toLowerCase()) { + case 'hidden': + case 'password': + case 'text': + return Form.Element.Serializers.textarea(element); + case 'checkbox': + case 'radio': + return Form.Element.Serializers.inputSelector(element); + } + return false; + }, + + inputSelector: function(element) { + if (element.checked) + return [element.name, element.value]; + }, + + textarea: function(element) { + return [element.name, element.value]; + }, + + select: function(element) { + var index = element.selectedIndex; + var value = element.options[index].value || element.options[index].text; + return [element.name, (index >= 0) ? value : '']; + } +} + +/*--------------------------------------------------------------------------*/ + +var $F = Form.Element.getValue; + +/*--------------------------------------------------------------------------*/ + +Abstract.TimedObserver = function() {} +Abstract.TimedObserver.prototype = { + initialize: function(element, frequency, callback) { + this.frequency = frequency; + this.element = $(element); + this.callback = callback; + + this.lastValue = this.getValue(); + this.registerCallback(); + }, + + registerCallback: function() { + setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000); + }, + + onTimerEvent: function() { + var value = this.getValue(); + if (this.lastValue != value) { + this.callback(this.element, value); + this.lastValue = value; + } + + this.registerCallback(); + } +} + +Form.Element.Observer = Class.create(); +Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({ + getValue: function() { + return Form.Element.getValue(this.element); + } +}); + +Form.Observer = Class.create(); +Form.Observer.prototype = (new Abstract.TimedObserver()).extend({ + getValue: function() { + return Form.serialize(this.element); + } +}); + + +/*--------------------------------------------------------------------------*/ + +document.getElementsByClassName = function(className) { + var children = document.getElementsByTagName('*') || document.all; + var elements = new Array(); + + for (var i = 0; i < children.length; i++) { + var child = children[i]; + var classNames = child.className.split(' '); + for (var j = 0; j < classNames.length; j++) { + if (classNames[j] == className) { + elements.push(child); + break; + } + } + } + + return elements; +} + +/*--------------------------------------------------------------------------*/ + +var Element = { + toggle: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = + (element.style.display == 'none' ? '' : 'none'); + } + }, + + hide: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = 'none'; + } + }, + + show: function() { + for (var i = 0; i < arguments.length; i++) { + var element = $(arguments[i]); + element.style.display = ''; + } + }, + + remove: function(element) { + element = $(element); + element.parentNode.removeChild(element); + }, + + getHeight: function(element) { + element = $(element); + return element.offsetHeight; + } +} + +var Toggle = new Object(); +Toggle.display = Element.toggle; + +/*--------------------------------------------------------------------------*/ + +Abstract.Insertion = function(adjacency) { + this.adjacency = adjacency; +} + +Abstract.Insertion.prototype = { + initialize: function(element, content) { + this.element = $(element); + this.content = content; + + if (this.adjacency && this.element.insertAdjacentHTML) { + this.element.insertAdjacentHTML(this.adjacency, this.content); + } else { + this.range = this.element.ownerDocument.createRange(); + if (this.initializeRange) this.initializeRange(); + this.fragment = this.range.createContextualFragment(this.content); + this.insertContent(); + } + } +} + +var Insertion = new Object(); + +Insertion.Before = Class.create(); +Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({ + initializeRange: function() { + this.range.setStartBefore(this.element); + }, + + insertContent: function() { + this.element.parentNode.insertBefore(this.fragment, this.element); + } +}); + +Insertion.Top = Class.create(); +Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({ + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(true); + }, + + insertContent: function() { + this.element.insertBefore(this.fragment, this.element.firstChild); + } +}); + +Insertion.Bottom = Class.create(); +Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({ + initializeRange: function() { + this.range.selectNodeContents(this.element); + this.range.collapse(this.element); + }, + + insertContent: function() { + this.element.appendChild(this.fragment); + } +}); + +Insertion.After = Class.create(); +Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({ + initializeRange: function() { + this.range.setStartAfter(this.element); + }, + + insertContent: function() { + this.element.parentNode.insertBefore(this.fragment, + this.element.nextSibling); + } +}); + +/*--------------------------------------------------------------------------*/ + +var Effect = new Object(); + +Effect.Highlight = Class.create(); +Effect.Highlight.prototype = { + initialize: function(element) { + this.element = $(element); + this.start = 153; + this.finish = 255; + this.current = this.start; + this.fade(); + }, + + fade: function() { + if (this.isFinished()) return; + if (this.timer) clearTimeout(this.timer); + this.highlight(this.element, this.current); + this.current += 17; + this.timer = setTimeout(this.fade.bind(this), 250); + }, + + isFinished: function() { + return this.current > this.finish; + }, + + highlight: function(element, current) { + element.style.backgroundColor = "#ffff" + current.toColorPart(); + } +} + + +Effect.Fade = Class.create(); +Effect.Fade.prototype = { + initialize: function(element) { + this.element = $(element); + this.start = 100; + this.finish = 0; + this.current = this.start; + this.fade(); + }, + + fade: function() { + if (this.isFinished()) { this.element.style.display = 'none'; return; } + if (this.timer) clearTimeout(this.timer); + this.setOpacity(this.element, this.current); + this.current -= 10; + this.timer = setTimeout(this.fade.bind(this), 50); + }, + + isFinished: function() { + return this.current <= this.finish; + }, + + setOpacity: function(element, opacity) { + opacity = (opacity == 100) ? 99.999 : opacity; + element.style.filter = "alpha(opacity:"+opacity+")"; + element.style.opacity = opacity/100 /*//*/; + } +} + +Effect.Scale = Class.create(); +Effect.Scale.prototype = { + initialize: function(element, percent) { + this.element = $(element); + this.startScale = 1.0; + this.startHeight = this.element.offsetHeight; + this.startWidth = this.element.offsetWidth; + this.currentHeight = this.startHeight; + this.currentWidth = this.startWidth; + this.finishScale = (percent/100) /*//*/; + if (this.element.style.fontSize=="") this.sizeEm = 1.0; + if (this.element.style.fontSize.indexOf("em")>0) + this.sizeEm = parseFloat(this.element.style.fontSize); + if(this.element.effect_scale) { + clearTimeout(this.element.effect_scale.timer); + this.startScale = this.element.effect_scale.currentScale; + this.startHeight = this.element.effect_scale.startHeight; + this.startWidth = this.element.effect_scale.startWidth; + if(this.element.effect_scale.sizeEm) + this.sizeEm = this.element.effect_scale.sizeEm; + } + this.element.effect_scale = this; + this.currentScale = this.startScale; + this.factor = this.finishScale - this.startScale; + this.options = arguments[2] || {}; + this.scale(); + }, + + scale: function() { + if (this.isFinished()) { + this.setDimensions(this.element, this.startWidth*this.finishScale, this.startHeight*this.finishScale); + if(this.sizeEm) this.element.style.fontSize = this.sizeEm*this.finishScale + "em"; + if(this.options.complete) this.options.complete(this); + return; + } + if (this.timer) clearTimeout(this.timer); + if (this.options.step) this.options.step(this); + this.setDimensions(this.element, this.currentWidth, this.currentHeight); + if(this.sizeEm) this.element.style.fontSize = this.sizeEm*this.currentScale + "em"; + this.currentScale += (this.factor/10) /*//*/; + this.currentWidth = this.startWidth * this.currentScale; + this.currentHeight = this.startHeight * this.currentScale; + this.timer = setTimeout(this.scale.bind(this), 50); + }, + + isFinished: function() { + return (this.factor < 0) ? + this.currentScale <= this.finishScale : this.currentScale >= this.finishScale; + }, + + setDimensions: function(element, width, height) { + element.style.width = width + 'px'; + element.style.height = height + 'px'; + } +} + +Effect.Squish = Class.create(); +Effect.Squish.prototype = { + initialize: function(element) { + this.element = $(element); + new Effect.Scale(this.element, 1, { complete: this.hide.bind(this) } ); + }, + hide: function() { + this.element.style.display = 'none'; + } +} + +Effect.Puff = Class.create(); +Effect.Puff.prototype = { + initialize: function(element) { + this.element = $(element); + this.opacity = 100; + this.startTop = this.element.top || this.element.offsetTop; + this.startLeft = this.element.left || this.element.offsetLeft; + new Effect.Scale(this.element, 200, { step: this.fade.bind(this), complete: this.hide.bind(this) } ); + }, + fade: function(effect) { + topd = (((effect.currentScale)*effect.startHeight) - effect.startHeight)/2; + leftd = (((effect.currentScale)*effect.startWidth) - effect.startWidth)/2; + this.element.style.position='absolute'; + this.element.style.top = this.startTop-topd + "px"; + this.element.style.left = this.startLeft-leftd + "px"; + this.opacity -= 10; + this.setOpacity(this.element, this.opacity); + if(navigator.appVersion.indexOf('AppleWebKit')>0) this.element.innerHTML += ''; //force redraw on safari + }, + hide: function() { + this.element.style.display = 'none'; + }, + setOpacity: function(element, opacity) { + opacity = (opacity == 100) ? 99.999 : opacity; + element.style.filter = "alpha(opacity:"+opacity+")"; + element.style.opacity = opacity/100 /*//*/; + } +} + +Effect.Appear = Class.create(); +Effect.Appear.prototype = { + initialize: function(element) { + this.element = $(element); + this.start = 0; + this.finish = 100; + this.current = this.start; + this.fade(); + }, + + fade: function() { + if (this.isFinished()) return; + if (this.timer) clearTimeout(this.timer); + this.setOpacity(this.element, this.current); + this.current += 10; + this.timer = setTimeout(this.fade.bind(this), 50); + }, + + isFinished: function() { + return this.current > this.finish; + }, + + setOpacity: function(element, opacity) { + opacity = (opacity == 100) ? 99.999 : opacity; + element.style.filter = "alpha(opacity:"+opacity+")"; + element.style.opacity = opacity/100 /*//*/; + element.style.display = ''; + } +} + +Effect.ContentZoom = Class.create(); +Effect.ContentZoom.prototype = { + initialize: function(element, percent) { + this.element = $(element); + if (this.element.style.fontSize=="") this.sizeEm = 1.0; + if (this.element.style.fontSize.indexOf("em")>0) + this.sizeEm = parseFloat(this.element.style.fontSize); + if(this.element.effect_contentzoom) { + this.sizeEm = this.element.effect_contentzoom.sizeEm; + } + this.element.effect_contentzoom = this; + this.element.style.fontSize = this.sizeEm*(percent/100) + "em" /*//*/; + if(navigator.appVersion.indexOf('AppleWebKit')>0) { this.element.scrollTop -= 1; }; + } +} diff --git a/sope-appserver/samples/TestPrototype/ChangeLog b/sope-appserver/samples/TestPrototype/ChangeLog new file mode 100644 index 00000000..a6b5dd01 --- /dev/null +++ b/sope-appserver/samples/TestPrototype/ChangeLog @@ -0,0 +1,4 @@ +2005-07-10 Helge Hess + + * created ChangeLog / project + diff --git a/sope-appserver/samples/TestPrototype/GNUmakefile b/sope-appserver/samples/TestPrototype/GNUmakefile new file mode 100644 index 00000000..371142d2 --- /dev/null +++ b/sope-appserver/samples/TestPrototype/GNUmakefile @@ -0,0 +1,13 @@ +# GNUstep makefile + +-include ../../../config.make +include $(GNUSTEP_MAKEFILES)/common.make + +WOAPP_NAME = TestPrototype + +TestPrototype_OBJC_FILES += TestPrototype.m Main.m +TestPrototype_COMPONENTS += Main.wo + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/woapp.make +-include GNUmakefile.postamble diff --git a/sope-appserver/samples/TestPrototype/GNUmakefile.preamble b/sope-appserver/samples/TestPrototype/GNUmakefile.preamble new file mode 100644 index 00000000..11f67096 --- /dev/null +++ b/sope-appserver/samples/TestPrototype/GNUmakefile.preamble @@ -0,0 +1,16 @@ +# compile settings + +APPSERVER="../.." + +ADDITIONAL_LIB_DIRS += \ + -L$(APPSERVER)/WEPrototype/$(GNUSTEP_OBJ_DIR) \ + -L$(APPSERVER)/NGObjWeb/$(GNUSTEP_OBJ_DIR) \ + +# static references required for Mach linker + +ADDITIONAL_TOOL_LIBS += \ + -lWEPrototype \ + -lEOControl \ + -lDOM -lXmlRpc -lSaxObjC + +ADDITIONAL_LIB_DIRS += -L/usr/local/lib -L/usr/lib diff --git a/sope-appserver/samples/TestPrototype/Main.m b/sope-appserver/samples/TestPrototype/Main.m new file mode 100644 index 00000000..37eefb04 --- /dev/null +++ b/sope-appserver/samples/TestPrototype/Main.m @@ -0,0 +1,98 @@ +/* + Copyright (C) 2005 SKYRIX Software AG + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#include + +@class NSArray; + +@interface Main : WOComponent +{ + NSArray *items; + id item; +} + +@end + +#include "common.h" + +@implementation Main + +- (id)initWithContext:(id)_ctx { + if ((self = [super initWithContext:_ctx])) { + NSMutableArray *ma; + int i; + + ma = [[NSMutableArray alloc] init]; + for (i = 0; i < 1000; i++) { + char buf[16]; + NSString *s; + sprintf(buf, "%i", i); + s = [[NSString alloc] initWithCString:buf]; + [ma addObject:s]; + [s release]; + } + self->items = ma; + } + return self; +} + +- (void)dealloc { + [self->items release]; + [self->item release]; + [super dealloc]; +} + +/* accessors */ + +- (void)setItem:(id)_item { + ASSIGN(self->item, _item); +} +- (id)item { + return self->item; +} + +- (NSArray *)list { + return self->items; +} + +/* actions */ + +- (id)sayWhenAction { + WOResponse *r = [[self context] response]; + + [r appendContentString:@"

The time is "]; + [r appendContentString:[[NSCalendarDate date] description]]; + [r appendContentString:@"

"]; + + return r; +} + +/* response generation */ + +- (void)appendToResponse:(WOResponse *)_r inContext:(WOContext *)_ctx { + NSDate *s; + + s = [NSDate date]; + [super appendToResponse:_r inContext:_ctx]; + printf("duration: %.3f\n", [[NSDate date] timeIntervalSinceDate:s]); +} + +@end /* Main */ diff --git a/sope-appserver/samples/TestPrototype/Main.wo/Main.html b/sope-appserver/samples/TestPrototype/Main.wo/Main.html new file mode 100644 index 00000000..0e2cb301 --- /dev/null +++ b/sope-appserver/samples/TestPrototype/Main.wo/Main.html @@ -0,0 +1,17 @@ + + + Test WEPrototype + + <#Prototype/> + + + +

Test WEPrototype

+ +
+ I don't have the time, but + <#TimeLink>click here + and I will look it up. +
+ + diff --git a/sope-appserver/samples/TestPrototype/Main.wo/Main.wod b/sope-appserver/samples/TestPrototype/Main.wo/Main.wod new file mode 100644 index 00000000..aa10fb9f --- /dev/null +++ b/sope-appserver/samples/TestPrototype/Main.wo/Main.wod @@ -0,0 +1,15 @@ +// bind template to controller + +Prototype: WEPrototypeScript {} + +TimeLink: WELiveLink { + updateID = "time_div"; + position = "after"; + actionClass = "Main"; + directActionName = "sayWhen"; + confirmText = "Really update time?"; +} + +AppName: WOString { + value = application.name; +} \ No newline at end of file diff --git a/sope-appserver/samples/TestPrototype/TestPrototype.m b/sope-appserver/samples/TestPrototype/TestPrototype.m new file mode 100644 index 00000000..499feff9 --- /dev/null +++ b/sope-appserver/samples/TestPrototype/TestPrototype.m @@ -0,0 +1,47 @@ +/* + Copyright (C) 2005 SKYRIX Software AG + + This file is part of SOPE. + + SOPE is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOPE 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with SOPE; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#include + +@interface TestPrototype : WOApplication +{ +} + +@end + +#include "common.h" + +@implementation TestPrototype +@end /* TestPrototype */ + +int main(int argc, char **argv, char **env) { + NSAutoreleasePool *pool; + + pool = [[NSAutoreleasePool alloc] init]; +#if LIB_FOUNDATION_LIBRARY + [NSProcessInfo initializeWithArguments:argv count:argc environment:env]; +#endif + + WOApplicationMain(@"TestPrototype", argc, (void*)argv); + + [pool release]; + return 0; +} diff --git a/sope-appserver/samples/TestPrototype/common.h b/sope-appserver/samples/TestPrototype/common.h new file mode 100644 index 00000000..13127494 --- /dev/null +++ b/sope-appserver/samples/TestPrototype/common.h @@ -0,0 +1,3 @@ + +#import +#include