From: Radek Czajka Date: Wed, 28 Dec 2011 15:47:40 +0000 (+0100) Subject: ios version X-Git-Url: https://git.mdrn.pl/wl-mobile.git/commitdiff_plain/b9acd6c8b2300a76624900cd19f9e40e59ff3f7b?hp=bff5852b5ee1320a6eaf4256570784bbc024496f ios version --- diff --git a/.classpath b/.classpath deleted file mode 100644 index 1a630a7..0000000 --- a/.classpath +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/.gitignore b/.gitignore index 90786c8..e1a2565 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,4 @@ .pydevproject .settings - - +.DS_Store diff --git a/AndroidManifest.xml b/AndroidManifest.xml deleted file mode 100644 index 9e15f71..0000000 --- a/AndroidManifest.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/COPYING b/COPYING deleted file mode 100644 index a871fcf..0000000 --- a/COPYING +++ /dev/null @@ -1,662 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - 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 -them 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. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If 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 convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. - diff --git a/Classes/AppDelegate.h b/Classes/AppDelegate.h new file mode 100644 index 0000000..369da83 --- /dev/null +++ b/Classes/AppDelegate.h @@ -0,0 +1,29 @@ +// +// AppDelegate.h +// wl-mobi +// +// Created by FNP on 10/19/11. +// Copyright __MyCompanyName__ 2011. All rights reserved. +// + +#import +#ifdef PHONEGAP_FRAMEWORK + #import +#else + #import "PhoneGapDelegate.h" +#endif + +@interface AppDelegate : PhoneGapDelegate { + + NSString* invokeString; +} + +// invoke string is passed to your app on launch, this is only valid if you +// edit wl-mobi.plist to add a protocol +// a simple tutorial can be found here : +// http://iphonedevelopertips.com/cocoa/launching-your-own-application-via-a-custom-url-scheme.html + +@property (copy) NSString* invokeString; + +@end + diff --git a/Classes/AppDelegate.m b/Classes/AppDelegate.m new file mode 100644 index 0000000..bd627b3 --- /dev/null +++ b/Classes/AppDelegate.m @@ -0,0 +1,130 @@ +// +// AppDelegate.m +// wl-mobi +// +// Created by FNP on 10/19/11. +// Copyright __MyCompanyName__ 2011. All rights reserved. +// + +#import "AppDelegate.h" +#ifdef PHONEGAP_FRAMEWORK + #import +#else + #import "PhoneGapViewController.h" +#endif + +@implementation AppDelegate + +@synthesize invokeString; + +- (id) init +{ + /** If you need to do any extra app-specific initialization, you can do it here + * -jm + **/ + return [super init]; +} + +/** + * This is main kick off after the app inits, the views and Settings are setup here. (preferred - iOS4 and up) + */ +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + + NSArray *keyArray = [launchOptions allKeys]; + if ([launchOptions objectForKey:[keyArray objectAtIndex:0]]!=nil) + { + NSURL *url = [launchOptions objectForKey:[keyArray objectAtIndex:0]]; + self.invokeString = [url absoluteString]; + NSLog(@"wl-mobi launchOptions = %@",url); + } + + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +// this happens while we are running ( in the background, or from within our own app ) +// only valid if wl-mobi.plist specifies a protocol to handle +- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url +{ + // must call super so all plugins will get the notification, and their handlers will be called + // super also calls into javascript global function 'handleOpenURL' + return [super application:application handleOpenURL:url]; +} + +-(id) getCommandInstance:(NSString*)className +{ + /** You can catch your own commands here, if you wanted to extend the gap: protocol, or add your + * own app specific protocol to it. -jm + **/ + return [super getCommandInstance:className]; +} + +/** + Called when the webview finishes loading. This stops the activity view and closes the imageview + */ +- (void)webViewDidFinishLoad:(UIWebView *)theWebView +{ + // only valid if wl-mobi.plist specifies a protocol to handle + if(self.invokeString) + { + // this is passed before the deviceready event is fired, so you can access it in js when you receive deviceready + NSString* jsString = [NSString stringWithFormat:@"var invokeString = \"%@\";", self.invokeString]; + [theWebView stringByEvaluatingJavaScriptFromString:jsString]; + } + return [ super webViewDidFinishLoad:theWebView ]; +} + +- (void)webViewDidStartLoad:(UIWebView *)theWebView +{ + return [ super webViewDidStartLoad:theWebView ]; +} + +/** + * Fail Loading With Error + * Error - If the webpage failed to load display an error with the reason. + */ +- (void)webView:(UIWebView *)theWebView didFailLoadWithError:(NSError *)error +{ + return [ super webView:theWebView didFailLoadWithError:error ]; +} + + +/** + * Start Loading Request + * This is where most of the magic happens... We take the request(s) and process the response. + * From here we can re direct links and other protocalls to different internal methods. + */ +- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType +{ + NSURL *url = [request URL]; + + // Intercept the external http requests and forward to Safari.app + // Otherwise forward to the PhoneGap WebView + if ([[url scheme] isEqualToString:@"http"] || [[url scheme] isEqualToString:@"https"]) { + [[UIApplication sharedApplication] openURL:url]; + return NO; + } + else { + return [ super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType ]; + } +} + + + +- (BOOL) execute:(InvokedUrlCommand*)command +{ + return [ super execute:command]; +} + +- (void)dealloc +{ + [ super dealloc ]; +} + + ++ (NSString*) startPage +{ + return @"WolneLektury.html"; +} + +@end diff --git a/NOTICE b/NOTICE deleted file mode 100644 index 73a186e..0000000 --- a/NOTICE +++ /dev/null @@ -1,19 +0,0 @@ - - WolneLektury-Mobile - - Copyright © 2011 Fundacja Nowoczesna Polska - - Author: Radek Czajka - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . diff --git a/PhoneGap.plist b/PhoneGap.plist new file mode 100644 index 0000000..39c98ef --- /dev/null +++ b/PhoneGap.plist @@ -0,0 +1,59 @@ + + + + + DetectPhoneNumber + + TopActivityIndicator + gray + EnableLocation + + EnableAcceleration + + EnableViewportScale + + AutoHideSplashScreen + + ShowSplashScreenSpinner + + MediaPlaybackRequiresUserAction + + AllowInlineMediaPlayback + + ExternalHosts + + wolnelektury.pl + www.wolnelektury.pl + static.wolnelektury.pl + + Plugins + + NativeControls + NativeControls + com.phonegap.accelerometer + PGAccelerometer + com.phonegap.camera + PGCamera + com.phonegap.connection + PGConnection + com.phonegap.contacts + PGContacts + com.phonegap.debugconsole + PGDebugConsole + com.phonegap.file + PGFile + com.phonegap.filetransfer + PGFileTransfer + com.phonegap.geolocation + PGLocation + com.phonegap.notification + PGNotification + com.phonegap.media + PGSound + com.phonegap.mediacapture + PGCapture + com.phonegap.splashscreen + PGSplashScreen + + + diff --git a/PhoneGapBuildSettings.xcconfig b/PhoneGapBuildSettings.xcconfig new file mode 100644 index 0000000..83badbb --- /dev/null +++ b/PhoneGapBuildSettings.xcconfig @@ -0,0 +1,8 @@ +// +// PhoneGap.xcconfig +// wl-mobi +// + +// Override this to use your project specific PHONEGAPLIB. +// You can base it off the current project path, $(PROJECT_DIR) +PHONEGAPLIB = $(PHONEGAPLIB) \ No newline at end of file diff --git a/Plugins/NativeControls/NativeControls.h b/Plugins/NativeControls/NativeControls.h new file mode 100644 index 0000000..31976ce --- /dev/null +++ b/Plugins/NativeControls/NativeControls.h @@ -0,0 +1,59 @@ +// +// NativeControls.h +// +// +// Created by Jesse MacFadyen on 10-02-03. +// MIT Licensed + +// Originally this code was developed my Michael Nachbaur +// Formerly -> PhoneGap :: UIControls.h +// Created by Michael Nachbaur on 13/04/09. +// Copyright 2009 Decaf Ninja Software. All rights reserved. + +#import +#import +#import +#import +#ifdef PHONEGAP_FRAMEWORK +#import +#else +#import "PGPlugin.h" +#endif + +@interface NativeControls : PGPlugin { + UITabBar* tabBar; + NSMutableDictionary* tabBarItems; + + UIToolbar* toolBar; + UIBarButtonItem* toolBarTitle; + NSMutableArray* toolBarItems; + + CGRect originalWebViewBounds; +} + +/* Tab Bar methods + */ +- (void)createTabBar:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)showTabBar:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)hideTabBar:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)showTabBarItems:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)createTabBarItem:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)updateTabBarItem:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)selectTabBarItem:(NSArray*)arguments withDict:(NSDictionary*)options; + + + +/* Tool Bar methods + */ +- (void)createToolBar:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)resetToolBar:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)setToolBarTitle:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)createToolBarItem:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)showToolBar:(NSArray*)arguments withDict:(NSDictionary*)options; +- (void)hideToolBar:(NSArray*)arguments withDict:(NSDictionary*)options; +/* ActionSheet + */ +- (void)createActionSheet:(NSArray*)arguments withDict:(NSDictionary*)options; + + +@end \ No newline at end of file diff --git a/Plugins/NativeControls/NativeControls.js b/Plugins/NativeControls/NativeControls.js new file mode 100644 index 0000000..6e6d3c3 --- /dev/null +++ b/Plugins/NativeControls/NativeControls.js @@ -0,0 +1,309 @@ +// JS :::::::: + +/* + // This code is adapted from the work of: + // Created by Michael Nachbaur on 13/04/09. + // Copyright 2009 Decaf Ninja Software. All rights reserved. + // MIT licensed + */ + +/** + * This class exposes mobile phone interface controls to JavaScript, such as + * native tab and tool bars, etc. + * @constructor + */ +function NativeControls() { + this.tabBarTag = 0; + this.toolBarIndexes = 0; + + this.tabBarCallbacks = {}; + this.toolBarCallbacks = {}; + + this.tappedToolBarItem = null; + this.selectedTabBarItem = null; +} + +/** + * Create a native tab bar that can have tab buttons added to it which can respond to events. + */ +NativeControls.prototype.createTabBar = function() { + PhoneGap.exec("NativeControls.createTabBar"); +}; + +/** + * Show a tab bar. The tab bar has to be created first. + * @param {Object} [options] Options indicating how the tab bar should be shown: + * - \c height integer indicating the height of the tab bar (default: \c 49) + * - \c position specifies whether the tab bar will be placed at the \c top or \c bottom of the screen (default: \c bottom) + */ +NativeControls.prototype.showTabBar = function(options) { + if (!options) options = {'position' : 'bottom'}; + PhoneGap.exec("NativeControls.showTabBar", options); +}; + +/** + * Hide a tab bar. The tab bar has to be created first. + */ +NativeControls.prototype.hideTabBar = function(animate) { + if (animate == undefined || animate == null) + animate = true; + PhoneGap.exec("NativeControls.hideTabBar", { animate: animate }); +}; + +/** + * Create a new tab bar item for use on a previously created tab bar. Use ::showTabBarItems to show the new item on the tab bar. + * + * If the supplied image name is one of the labels listed below, then this method will construct a tab button + * using the standard system buttons. Note that if you use one of the system images, that the \c title you supply will be ignored. + * + * Tab Buttons + * - tabButton:More + * - tabButton:Favorites + * - tabButton:Featured + * - tabButton:TopRated + * - tabButton:Recents + * - tabButton:Contacts + * - tabButton:History + * - tabButton:Bookmarks + * - tabButton:Search + * - tabButton:Downloads + * - tabButton:MostRecent + * - tabButton:MostViewed + * @param {String} name internal name to refer to this tab by + * @param {String} [title] title text to show on the tab, or null if no text should be shown + * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown + * @param {Object} [options] Options for customizing the individual tab item + * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden + */ +NativeControls.prototype.createTabBarItem = function(name, label, image, options) { + + var tag = this.tabBarTag++; + if (options && 'onSelect' in options && typeof(options['onSelect']) == 'function') { + this.tabBarCallbacks[tag] = {'onSelect':options.onSelect,'name':name}; + //delete options.onSelect; + } + + PhoneGap.exec("NativeControls.createTabBarItem", name, label, image, tag, options); +}; + +/** + * Update an existing tab bar item to change its badge value. + * @param {String} name internal name used to represent this item when it was created + * @param {Object} options Options for customizing the individual tab item + * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden + */ +NativeControls.prototype.updateTabBarItem = function(name, options) { + if (!options) options = {}; + PhoneGap.exec("NativeControls.updateTabBarItem", name, options); +}; + +/** + * Show previously created items on the tab bar + * @param {String} arguments... the item names to be shown + * @param {Object} [options] dictionary of options, notable options including: + * - \c animate indicates that the items should animate onto the tab bar + * @see createTabBarItem + * @see createTabBar + */ +NativeControls.prototype.showTabBarItems = function() { + var parameters = [ "NativeControls.showTabBarItems" ]; + for (var i = 0; i < arguments.length; i++) { + parameters.push(arguments[i]); + } + PhoneGap.exec.apply(this, parameters); +}; + + +/** + * Function to detect currently selected tab bar item + * @see createTabBarItem + * @see showTabBarItems + */ +NativeControls.prototype.getSelectedTabBarItem = function() { + return this.selectedTabBarItem; +}; + + +/** + * Manually select an individual tab bar item, or nil for deselecting a currently selected tab bar item. + * @param {String} tabName the name of the tab to select, or null if all tabs should be deselected + * @see createTabBarItem + * @see showTabBarItems + */ +NativeControls.prototype.selectTabBarItem = function(tab) { + PhoneGap.exec("NativeControls.selectTabBarItem", tab); +}; + +/** + * Function called when a tab bar item has been selected. + * @param {Number} tag the tag number for the item that has been selected + */ +NativeControls.prototype.tabBarItemSelected = function(tag) +{ + this.selectedTabBarItem = tag; + if (typeof(this.tabBarCallbacks[tag].onSelect) == 'function') + this.tabBarCallbacks[tag].onSelect(this.tabBarCallbacks[tag].name); +}; + + + + +/** + * Create a toolbar. + */ +NativeControls.prototype.createToolBar = function() +{ + PhoneGap.exec("NativeControls.createToolBar"); +}; +/** + * Function called when a tab bar item has been selected. + * @param {String} title the title to set within the toolbar + */ +NativeControls.prototype.setToolBarTitle = function(title) +{ + PhoneGap.exec("NativeControls.setToolBarTitle", title); +}; +/* + * Added by Emile khattar: emile818@gmail.com emile@sign.al + * @ 2011-07-08 , 5.00 AM + */ +/** + * Set toolBarItems = nil; + */ +NativeControls.prototype.resetToolBar = function() { + PhoneGap.exec("NativeControls.resetToolBar"); +}; +/** + * Hide the tool bar + * @brief hide the tool bar + */ +NativeControls.prototype.hideToolBar = function() { + PhoneGap.exec("NativeControls.hideToolBar"); +}; + +/** + * Show the tool bar ( re-render elements ) + * @brief Show the tool bar + */ +NativeControls.prototype.showToolBar = function() { + PhoneGap.exec("NativeControls.showToolBar"); +}; + +/** + * Set the toolbar title + * @param: title + */ +NativeControls.prototype.setToolBarTitle = function(title) { + PhoneGap.exec("NativeControls.setToolBarTitle" , title ); +}; + + +/** + * Create a new tool bar button item for use on a previously created tool bar. Use ::showToolBar to show the new item on the tool bar. + * + * If the supplied image name is one of the labels listed below, then this method will construct a button + * using the standard system buttons. Note that if you use one of the system images, that the title you supply will be ignored. + * + * Tool Bar Buttons + * UIBarButtonSystemItemDone + * UIBarButtonSystemItemCancel + * UIBarButtonSystemItemEdit + * UIBarButtonSystemItemSave + * UIBarButtonSystemItemAdd + * UIBarButtonSystemItemFlexibleSpace + * UIBarButtonSystemItemFixedSpace + * UIBarButtonSystemItemCompose + * UIBarButtonSystemItemReply + * UIBarButtonSystemItemAction + * UIBarButtonSystemItemOrganize + * UIBarButtonSystemItemBookmarks + * UIBarButtonSystemItemSearch + * UIBarButtonSystemItemRefresh + * UIBarButtonSystemItemStop + * UIBarButtonSystemItemCamera + * UIBarButtonSystemItemTrash + * UIBarButtonSystemItemPlay + * UIBarButtonSystemItemPause + * UIBarButtonSystemItemRewind + * UIBarButtonSystemItemFastForward + * UIBarButtonSystemItemUndo, // iOS 3.0 and later + * UIBarButtonSystemItemRedo, // iOS 3.0 and later + * UIBarButtonSystemItemPageCurl, // iOS 4.0 and later + * @param {String} name internal name to refer to this tab by + * @param {String} [title] title text to show on the button, or null if no text should be shown + * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown + * @param {Object} [options] Options for customizing the individual tab item [no option available at this time - this is for future proofing] + * + */ +NativeControls.prototype.createToolBarItem = function(name , title , image , options) { + var toolBarIndex = this.toolBarIndexes++; + if (options && 'onTap' in options && typeof(options['onTap']) == 'function') { + this.toolBarCallbacks[toolBarIndex] = {'onTap':options.onTap,'name':name}; + //delete options.onSelect; + } + //modify the NativeControls.m to change the options quickly + // the instance name on the plugin can be passed with option for now it is hardcode in objc // Emile + PhoneGap.exec("NativeControls.createToolBarItem" , name , title , image , options ); +}; + +/** + * Function called when a tool bar item has been tapped. + * @param {Number} tag the tag number for the item that has been selected + */ +NativeControls.prototype.toolBarButtonTapped = function(tag) +{ + this.tappedToolBarItem = tag; + if (typeof(this.toolBarCallbacks[tag].onTap) == 'function') + this.toolBarCallbacks[tag].onTap(this.toolBarCallbacks[tag].name); +}; + + + + + +NativeControls.prototype.createActionSheet = function(buttonTitles,actionSheetTitle,cancelButtonIndex,destructiveButtonIndex) +{ + var options = {}; + + if(actionSheetTitle != null) + { + options.title = actionSheetTitle; + } + if(cancelButtonIndex != null) + { + options.cancelButtonIndex = cancelButtonIndex; + } + if(destructiveButtonIndex != null) + { + options.destructiveButtonIndex = destructiveButtonIndex; + } + + var params = [ "NativeControls.createActionSheet",options ]; + for (var i = 0; i < buttonTitles.length; i++) + { + params.push(buttonTitles[i]); + } + PhoneGap.exec.apply(this, params); + + this.actionSheetDelegate = {}; + return this.actionSheetDelegate; +} + + +NativeControls.prototype._onActionSheetDismissed = function(index) +{ + this.actionSheetDelegate.onActionSheetDismissed(index); +} + + + +NativeControls.prototype.setStatusBarVisibilty = function(bHide) +{ + PhoneGap.exec("StatusBar.setHidden",bHide); +} + + +if(!window.plugins) + window.plugins = {}; + + window.plugins.nativeControls = new NativeControls(); diff --git a/Plugins/NativeControls/NativeControls.m b/Plugins/NativeControls/NativeControls.m new file mode 100644 index 0000000..8f89c6d --- /dev/null +++ b/Plugins/NativeControls/NativeControls.m @@ -0,0 +1,704 @@ +// +// NativeControls.h +// +// +// Created by Jesse MacFadyen on 10-02-03. +// MIT Licensed + +// Originally this code was developed my Michael Nachbaur +// Formerly -> PhoneGap :: UIControls.h +// Created by Michael Nachbaur on 13/04/09. +// Copyright 2009 Decaf Ninja Software. All rights reserved. + +#import "NativeControls.h" + +#import + +@implementation NativeControls +#ifndef __IPHONE_3_0 +@synthesize webView; +#endif + +-(PGPlugin*) initWithWebView:(UIWebView*)theWebView +{ + self = (NativeControls*)[super initWithWebView:theWebView]; + if (self) + { + tabBarItems = [[NSMutableDictionary alloc] initWithCapacity:5]; + originalWebViewBounds = theWebView.bounds; + } + return self; +} + +- (void)dealloc +{ + if (tabBar) + [tabBar release]; + + if (toolBar) + { + [toolBarTitle release]; + [toolBarItems release]; + [toolBar release]; + } + + [super dealloc]; +} + +#pragma mark - +#pragma mark TabBar + +/** + * Create a native tab bar at either the top or the bottom of the display. + * @brief creates a tab bar + * @param arguments unused + * @param options unused + */ +- (void)createTabBar:(NSArray*)arguments withDict:(NSDictionary*)options +{ + tabBar = [UITabBar new]; + [tabBar sizeToFit]; + tabBar.delegate = self; + tabBar.multipleTouchEnabled = NO; + tabBar.autoresizesSubviews = YES; + tabBar.hidden = YES; + tabBar.userInteractionEnabled = YES; + tabBar.opaque = YES; + + self.webView.superview.autoresizesSubviews = YES; + + [ self.webView.superview addSubview:tabBar]; +} + +/** + * Show the tab bar after its been created. + * @brief show the tab bar + * @param arguments unused + * @param options used to indicate options for where and how the tab bar should be placed + * - \c height integer indicating the height of the tab bar (default: \c 49) + * - \c position specifies whether the tab bar will be placed at the \c top or \c bottom of the screen (default: \c bottom) + */ +- (void)showTabBar:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!tabBar) + [self createTabBar:nil withDict:nil]; + + // if we are calling this again when its shown, reset + if (!tabBar.hidden) { + return; + } + + CGFloat height = 0.0f; + BOOL atBottom = YES; + + // CGRect offsetRect = [ [UIApplication sharedApplication] statusBarFrame]; + + if (options) + { + height = [[options objectForKey:@"height"] floatValue]; + atBottom = [[options objectForKey:@"position"] isEqualToString:@"bottom"]; + } + if(height == 0) + { + height = 49.0f; + atBottom = YES; + } + + tabBar.hidden = NO; + CGRect webViewBounds = originalWebViewBounds; + CGRect tabBarBounds; + + NSNotification* notif = [NSNotification notificationWithName:@"PGLayoutSubviewAdded" object:tabBar]; + [[NSNotificationQueue defaultQueue] enqueueNotification:notif postingStyle: NSPostASAP]; + + if (atBottom) + { + tabBarBounds = CGRectMake( + webViewBounds.origin.x, + webViewBounds.origin.y + webViewBounds.size.height - height, + webViewBounds.size.width, + height + ); + webViewBounds = CGRectMake( + webViewBounds.origin.x, + webViewBounds.origin.y, + webViewBounds.size.width, + webViewBounds.size.height - height + ); + } + else + { + tabBarBounds = CGRectMake( + webViewBounds.origin.x, + webViewBounds.origin.y, + webViewBounds.size.width, + height + ); + webViewBounds = CGRectMake( + webViewBounds.origin.x, + webViewBounds.origin.y + height, + webViewBounds.size.width, + webViewBounds.size.height - height + ); + } + + [tabBar setFrame:tabBarBounds]; + + + [self.webView setFrame:webViewBounds]; +} + +/** + * Hide the tab bar + * @brief hide the tab bar + * @param arguments unused + * @param options unused + */ +- (void)hideTabBar:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!tabBar) + [self createTabBar:nil withDict:nil]; + tabBar.hidden = YES; + + NSNotification* notif = [NSNotification notificationWithName:@"PGLayoutSubviewRemoved" object:tabBar]; + [[NSNotificationQueue defaultQueue] enqueueNotification:notif postingStyle: NSPostASAP]; + + + [self.webView setFrame:originalWebViewBounds]; +} + +/** + * Create a new tab bar item for use on a previously created tab bar. Use ::showTabBarItems to show the new item on the tab bar. + * + * If the supplied image name is one of the labels listed below, then this method will construct a tab button + * using the standard system buttons. Note that if you use one of the system images, that the \c title you supply will be ignored. + * - Tab Buttons + * - tabButton:More + * - tabButton:Favorites + * - tabButton:Featured + * - tabButton:TopRated + * - tabButton:Recents + * - tabButton:Contacts + * - tabButton:History + * - tabButton:Bookmarks + * - tabButton:Search + * - tabButton:Downloads + * - tabButton:MostRecent + * - tabButton:MostViewed + * @brief create a tab bar item + * @param arguments Parameters used to create the tab bar + * -# \c name internal name to refer to this tab by + * -# \c title title text to show on the tab, or null if no text should be shown + * -# \c image image filename or internal identifier to show, or null if now image should be shown + * -# \c tag unique number to be used as an internal reference to this button + * @param options Options for customizing the individual tab item + * - \c badge value to display in the optional circular badge on the item; if nil or unspecified, the badge will be hidden + */ +- (void)createTabBarItem:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!tabBar) + [self createTabBar:nil withDict:nil]; + + NSString *name = [arguments objectAtIndex:0]; + NSString *title = [arguments objectAtIndex:1]; + NSString *imageName = [arguments objectAtIndex:2]; + int tag = [[arguments objectAtIndex:3] intValue]; + + UITabBarItem *item = nil; + if ([imageName length] > 0) { + UIBarButtonSystemItem systemItem = -1; + if ([imageName isEqualToString:@"tabButton:More"]) systemItem = UITabBarSystemItemMore; + if ([imageName isEqualToString:@"tabButton:Favorites"]) systemItem = UITabBarSystemItemFavorites; + if ([imageName isEqualToString:@"tabButton:Featured"]) systemItem = UITabBarSystemItemFeatured; + if ([imageName isEqualToString:@"tabButton:TopRated"]) systemItem = UITabBarSystemItemTopRated; + if ([imageName isEqualToString:@"tabButton:Recents"]) systemItem = UITabBarSystemItemRecents; + if ([imageName isEqualToString:@"tabButton:Contacts"]) systemItem = UITabBarSystemItemContacts; + if ([imageName isEqualToString:@"tabButton:History"]) systemItem = UITabBarSystemItemHistory; + if ([imageName isEqualToString:@"tabButton:Bookmarks"]) systemItem = UITabBarSystemItemBookmarks; + if ([imageName isEqualToString:@"tabButton:Search"]) systemItem = UITabBarSystemItemSearch; + if ([imageName isEqualToString:@"tabButton:Downloads"]) systemItem = UITabBarSystemItemDownloads; + if ([imageName isEqualToString:@"tabButton:MostRecent"]) systemItem = UITabBarSystemItemMostRecent; + if ([imageName isEqualToString:@"tabButton:MostViewed"]) systemItem = UITabBarSystemItemMostViewed; + if (systemItem != -1) + item = [[UITabBarItem alloc] initWithTabBarSystemItem:systemItem tag:tag]; + } + + if (item == nil) { + item = [[UITabBarItem alloc] initWithTitle:title image:[UIImage imageNamed:imageName] tag:tag]; + } + + if ([options objectForKey:@"badge"]) + item.badgeValue = [options objectForKey:@"badge"]; + + [tabBarItems setObject:item forKey:name]; + [item release]; +} + + +/** + * Update an existing tab bar item to change its badge value. + * @brief update the badge value on an existing tab bar item + * @param arguments Parameters used to identify the tab bar item to update + * -# \c name internal name used to represent this item when it was created + * @param options Options for customizing the individual tab item + * - \c badge value to display in the optional circular badge on the item; if nil or unspecified, the badge will be hidden + */ +- (void)updateTabBarItem:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!tabBar) + [self createTabBar:nil withDict:nil]; + + NSString *name = [arguments objectAtIndex:0]; + UITabBarItem *item = [tabBarItems objectForKey:name]; + if (item) + item.badgeValue = [options objectForKey:@"bad ge"]; +} + + +/** + * Show previously created items on the tab bar + * @brief show a list of tab bar items + * @param arguments the item names to be shown + * @param options dictionary of options, notable options including: + * - \c animate indicates that the items should animate onto the tab bar + * @see createTabBarItem + * @see createTabBar + */ +- (void)showTabBarItems:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!tabBar) + [self createTabBar:nil withDict:nil]; + + int i, count = [arguments count]; + NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:count]; + for (i = 0; i < count; i++) { + NSString *itemName = [arguments objectAtIndex:i]; + UITabBarItem *item = [tabBarItems objectForKey:itemName]; + if (item) + [items addObject:item]; + } + + BOOL animateItems = NO; + if ([options objectForKey:@"animate"]) + animateItems = [(NSString*)[options objectForKey:@"animate"] boolValue]; + [tabBar setItems:items animated:animateItems]; + [items release]; +} + +/** + * Manually select an individual tab bar item, or nil for deselecting a currently selected tab bar item. + * @brief manually select a tab bar item + * @param arguments the name of the tab bar item to select + * @see createTabBarItem + * @see showTabBarItems + */ +- (void)selectTabBarItem:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!tabBar) + [self createTabBar:nil withDict:nil]; + + NSString *itemName = [arguments objectAtIndex:0]; + UITabBarItem *item = [tabBarItems objectForKey:itemName]; + if (item) + tabBar.selectedItem = item; + else + tabBar.selectedItem = nil; +} + + +- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item +{ + NSString * jsCallBack = [NSString stringWithFormat:@"window.plugins.nativeControls.tabBarItemSelected(%d);", item.tag]; + [self.webView stringByEvaluatingJavaScriptFromString:jsCallBack]; +} + +#pragma mark - +#pragma mark ToolBar + + +/*********************************************************************************/ +- (void)createToolBar:(NSArray*)arguments withDict:(NSDictionary*)options +{ + CGFloat height = 45.0f; + BOOL atTop = YES; + UIBarStyle style = UIBarStyleBlackOpaque; + + NSDictionary* toolBarSettings = options;//[settings objectForKey:@"ToolBarSettings"]; + if (toolBarSettings) + { + if ([toolBarSettings objectForKey:@"height"]) + height = [[toolBarSettings objectForKey:@"height"] floatValue]; + + if ([toolBarSettings objectForKey:@"position"]) + atTop = [[toolBarSettings objectForKey:@"position"] isEqualToString:@"top"]; + +#pragma unused(atTop) + + NSString *styleStr = [toolBarSettings objectForKey:@"style"]; + if ([styleStr isEqualToString:@"Default"]) + style = UIBarStyleDefault; + else if ([styleStr isEqualToString:@"BlackOpaque"]) + style = UIBarStyleBlackOpaque; + else if ([styleStr isEqualToString:@"BlackTranslucent"]) + style = UIBarStyleBlackTranslucent; + } + + CGRect webViewBounds = self.webView.bounds; + CGRect toolBarBounds = CGRectMake( + webViewBounds.origin.x, + webViewBounds.origin.y - 1.0f, + webViewBounds.size.width, + height + ); + webViewBounds = CGRectMake( + webViewBounds.origin.x, + webViewBounds.origin.y + height, + webViewBounds.size.width, + webViewBounds.size.height - height + ); + toolBar = [[UIToolbar alloc] initWithFrame:toolBarBounds]; + [toolBar sizeToFit]; + toolBar.hidden = NO; + toolBar.multipleTouchEnabled = NO; + toolBar.autoresizesSubviews = YES; + toolBar.userInteractionEnabled = YES; + toolBar.barStyle = style; + + + [toolBar setFrame:toolBarBounds]; + [self.webView setFrame:webViewBounds]; + + [self.webView.superview addSubview:toolBar]; +} + +- (void)resetToolBar:(NSArray*)arguments withDict:(NSDictionary*)options +{ + NSLog(@"about to reset toolBarItems"); + toolBarItems = nil; + /* + if (toolBarItems) + { + [toolBarItems release]; + } + */ +} + +/** + * Hide the tool bar + * @brief hide the tool bar + * @param arguments unused + * @param options unused + */ +- (void)hideToolBar:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!toolBar) + [self createToolBar:nil withDict:nil]; + toolBar.hidden = YES; + + NSNotification* notif = [NSNotification notificationWithName:@"PGLayoutSubviewRemoved" object:toolBar]; + [[NSNotificationQueue defaultQueue] enqueueNotification:notif postingStyle: NSPostASAP]; + + + [self.webView setFrame:originalWebViewBounds]; +} + + +- (void)setToolBarTitle:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!toolBar) + [self createToolBar:nil withDict:nil]; + + NSString *title = [arguments objectAtIndex:0]; + + + if (!toolBarTitle) { + NSLog(@"not : %@", title); + toolBarTitle = [[UIBarButtonItem alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:self action:@selector(toolBarTitleClicked)]; + } else { + NSLog(@"is: %@", title); + toolBarTitle.title = title; + } +} + +/** + * Create a new tool bar button item for use on a previously created tool bar. Use ::showToolBar to show the new item on the tool bar. + * + * If the supplied image name is one of the labels listed below, then this method will construct a button + * using the standard system buttons. Note that if you use one of the system images, that the title you supply will be ignored. + * + * Tool Bar Buttons + * UIBarButtonSystemItemDone + * UIBarButtonSystemItemCancel + * UIBarButtonSystemItemEdit + * UIBarButtonSystemItemSave + * UIBarButtonSystemItemAdd + * UIBarButtonSystemItemFlexibleSpace + * UIBarButtonSystemItemFixedSpace + * UIBarButtonSystemItemCompose + * UIBarButtonSystemItemReply + * UIBarButtonSystemItemAction + * UIBarButtonSystemItemOrganize + * UIBarButtonSystemItemBookmarks + * UIBarButtonSystemItemSearch + * UIBarButtonSystemItemRefresh + * UIBarButtonSystemItemStop + * UIBarButtonSystemItemCamera + * UIBarButtonSystemItemTrash + * UIBarButtonSystemItemPlay + * UIBarButtonSystemItemPause + * UIBarButtonSystemItemRewind + * UIBarButtonSystemItemFastForward + * UIBarButtonSystemItemUndo, // iOS 3.0 and later + * UIBarButtonSystemItemRedo, // iOS 3.0 and later + * UIBarButtonSystemItemPageCurl, // iOS 4.0 and later + * @param {String} name internal name to refer to this tab by + * @param {String} [title] title text to show on the button, or null if no text should be shown + * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown + * @param {Object} [options] Options for customizing the individual tab item [no option available at this time - this is for future proofing] + * + */ +- (void)createToolBarItem:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!toolBar) + { + [self createToolBar:nil withDict:nil]; + } + + if (!toolBarItems) + { + toolBarItems = [[NSMutableArray alloc] initWithCapacity:1]; + } + + NSString *tagId = [arguments objectAtIndex:0]; + NSString *title = [arguments objectAtIndex:1]; + NSString *imageName; + if (arguments.count >= 2) + { + imageName = [arguments objectAtIndex:2]; + } + + NSString *style; + + if (arguments.count >= 4) + { + style = [arguments objectAtIndex:3]; + } + else + { + style = @"UIBarButtonItemStylePlain"; + } + + + UIBarButtonItemStyle useStyle; + + if ([style isEqualToString:@"UIBarButtonItemStyleBordered"]) + { + useStyle = UIBarButtonItemStyleBordered; + } + else if ([style isEqualToString:@"UIBarButtonItemStyleDone"]) + { + useStyle = UIBarButtonItemStyleDone; + } + else + { + useStyle = UIBarButtonItemStylePlain; + } + + UIBarButtonItem *item = nil; + if ([imageName length] > 0) + { + UIBarButtonSystemItem systemItem; + if ([imageName isEqualToString:@"UIBarButtonSystemItemDone"]) + { + systemItem = UIBarButtonSystemItemDone; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemCancel"]) + { + systemItem = UIBarButtonSystemItemCancel; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemEdit"]) + { + systemItem = UIBarButtonSystemItemEdit; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemSave"]) + { + systemItem = UIBarButtonSystemItemSave; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemAdd"]) + { + systemItem = UIBarButtonSystemItemAdd; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemFlexibleSpace"]) + { + systemItem = UIBarButtonSystemItemFlexibleSpace; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemFixedSpace"]) + { + systemItem = UIBarButtonSystemItemFixedSpace; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemCompose"]) + { + systemItem = UIBarButtonSystemItemCompose; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemReply"]) + { + systemItem = UIBarButtonSystemItemReply; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemAction"]) + { + systemItem = UIBarButtonSystemItemAction; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemOrganize"]) + { + systemItem = UIBarButtonSystemItemOrganize; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemBookmarks"]) + { + systemItem = UIBarButtonSystemItemBookmarks; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemSearch"]) + { + systemItem = UIBarButtonSystemItemSearch; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemRefresh"]) + { + systemItem = UIBarButtonSystemItemRefresh; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemStop"]) + { + systemItem = UIBarButtonSystemItemStop; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemCamera"]) + { + systemItem = UIBarButtonSystemItemCamera; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemTrash"]) + { + systemItem = UIBarButtonSystemItemTrash; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemPlay"]) + { + systemItem = UIBarButtonSystemItemPlay; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemPause"]) + { + systemItem = UIBarButtonSystemItemPause; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemRewind"]) + { + systemItem = UIBarButtonSystemItemRewind; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemFastForward"]) + { + systemItem = UIBarButtonSystemItemFastForward; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemUndo"]) + { + systemItem = UIBarButtonSystemItemUndo; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemRedo"]) + { + systemItem = UIBarButtonSystemItemRedo; + } + else if ([imageName isEqualToString:@"UIBarButtonSystemItemPageCurl"]) + { + systemItem = UIBarButtonSystemItemPageCurl; + } + + if (systemItem) + { + item = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:systemItem target:self action:@selector(toolBarButtonTapped:)]; + if ([imageName isEqualToString:@"UIBarButtonSystemItemFixedSpace"]) + { + item.width = 14; + } + } + else + { + item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:imageName] style:useStyle target:self action:@selector(toolBarButtonTapped:)]; + } + } + else + { + item = [[UIBarButtonItem alloc] initWithTitle:title style:useStyle target:self action:@selector(toolBarButtonTapped:)]; + } + + + [toolBarItems insertObject:item atIndex:[tagId intValue]]; + [item release]; +} + +- (void)showToolBar:(NSArray*)arguments withDict:(NSDictionary*)options +{ + if (!toolBar) + { + [self createToolBar:nil withDict:nil]; + } + + [toolBar setItems:toolBarItems animated:NO]; +} + +- (void) toolBarButtonTapped:(UIBarButtonItem *)button +{ + int count = 0; + + for (UIBarButtonItem* currentButton in toolBarItems) + { + if (currentButton == button) { + NSString * jsCallBack = [NSString stringWithFormat:@"window.plugins.nativeControls.toolBarButtonTapped(%d);", count]; + [self.webView stringByEvaluatingJavaScriptFromString:jsCallBack]; + return; + } + + count++; + } +} + +#pragma mark - +#pragma mark ActionSheet + +- (void)createActionSheet:(NSArray*)arguments withDict:(NSDictionary*)options +{ + + NSString* title = [options objectForKey:@"title"]; + + + UIActionSheet* actionSheet = [ [UIActionSheet alloc ] + initWithTitle:title + delegate:self + cancelButtonTitle:nil + destructiveButtonTitle:nil + otherButtonTitles:nil + ]; + + int count = [arguments count]; + for(int n = 0; n < count; n++) + { + [ actionSheet addButtonWithTitle:[arguments objectAtIndex:n]]; + } + + if([options objectForKey:@"cancelButtonIndex"]) + { + actionSheet.cancelButtonIndex = [[options objectForKey:@"cancelButtonIndex"] intValue]; + } + if([options objectForKey:@"destructiveButtonIndex"]) + { + actionSheet.destructiveButtonIndex = [[options objectForKey:@"destructiveButtonIndex"] intValue]; + } + + actionSheet.actionSheetStyle = UIActionSheetStyleBlackTranslucent;//UIActionSheetStyleBlackOpaque; + [actionSheet showInView:self.webView.superview]; + [actionSheet release]; + +} + + +- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + NSString * jsCallBack = [NSString stringWithFormat:@"window.plugins.nativeControls._onActionSheetDismissed(%d);", buttonIndex]; + [self.webView stringByEvaluatingJavaScriptFromString:jsCallBack]; +} + + + +@end \ No newline at end of file diff --git a/Plugins/README b/Plugins/README new file mode 100644 index 0000000..438840d --- /dev/null +++ b/Plugins/README @@ -0,0 +1 @@ +Put the .h and .m files of your plugin here. The .js files of your plugin belong in the www folder. \ No newline at end of file diff --git a/Resources/icons/icon-72.png b/Resources/icons/icon-72.png new file mode 100755 index 0000000..9db5b55 Binary files /dev/null and b/Resources/icons/icon-72.png differ diff --git a/Resources/icons/icon.png b/Resources/icons/icon.png new file mode 100755 index 0000000..2566dcb Binary files /dev/null and b/Resources/icons/icon.png differ diff --git a/Resources/icons/icon@2x.png b/Resources/icons/icon@2x.png new file mode 100755 index 0000000..37328fe Binary files /dev/null and b/Resources/icons/icon@2x.png differ diff --git a/Resources/splash/Default-Landscape.png b/Resources/splash/Default-Landscape.png new file mode 100755 index 0000000..897e098 Binary files /dev/null and b/Resources/splash/Default-Landscape.png differ diff --git a/Resources/splash/Default-Portrait.png b/Resources/splash/Default-Portrait.png new file mode 100755 index 0000000..42cf2a6 Binary files /dev/null and b/Resources/splash/Default-Portrait.png differ diff --git a/Resources/splash/Default.png b/Resources/splash/Default.png new file mode 100755 index 0000000..da87cce Binary files /dev/null and b/Resources/splash/Default.png differ diff --git a/Resources/splash/Default@2x.png b/Resources/splash/Default@2x.png new file mode 100755 index 0000000..15db6a4 Binary files /dev/null and b/Resources/splash/Default@2x.png differ diff --git a/Wolne Lektury b/Wolne Lektury new file mode 100644 index 0000000..e69de29 diff --git a/Wolne Lektury.xcodeproj/fnp.mode1v3 b/Wolne Lektury.xcodeproj/fnp.mode1v3 new file mode 100644 index 0000000..62e5fbd --- /dev/null +++ b/Wolne Lektury.xcodeproj/fnp.mode1v3 @@ -0,0 +1,1990 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + DefaultDescriptionKey + DockingSystemVisible + + Extension + mode1v3 + FavBarConfig + + PBXProjectModuleGUID + 98DF31FE144EDB8D001381F0 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.mode1v3 + MajorVersion + 33 + MinorVersion + 0 + Name + Default + Notifications + + OpenEditors + + + Content + + PBXProjectModuleGUID + 98E0622E145879DF008FCAF3 + PBXProjectModuleLabel + style.css + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 98E0622F145879DF008FCAF3 + PBXProjectModuleLabel + style.css + _historyCapacity + 0 + bookmark + 984B12AA14AB6F46004BF082 + history + + 984B103914AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {658, 576}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 622 161 658 617 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 98B7EBAE1491163B000EE462 + PBXProjectModuleLabel + view.js + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 98B7EBAF1491163B000EE462 + PBXProjectModuleLabel + view.js + _historyCapacity + 0 + bookmark + 984B12AC14AB6F46004BF082 + history + + 984B103C14AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {658, 576}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 223 118 658 617 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 984B10EC14AB6716004BF082 + PBXProjectModuleLabel + menu.js + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 984B10ED14AB6716004BF082 + PBXProjectModuleLabel + menu.js + _historyCapacity + 0 + bookmark + 984B12AE14AB6F46004BF082 + history + + 984B10EE14AB6716004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {658, 576}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 607 161 658 617 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 984B103E14AB4E96004BF082 + PBXProjectModuleLabel + main.js + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 984B103F14AB4E96004BF082 + PBXProjectModuleLabel + main.js + _historyCapacity + 0 + bookmark + 984B12B014AB6F46004BF082 + history + + 984B104014AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {658, 576}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 354 148 658 617 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 98E0622A145879DF008FCAF3 + PBXProjectModuleLabel + book_text.css + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 98E0622B145879DF008FCAF3 + PBXProjectModuleLabel + book_text.css + _historyCapacity + 0 + bookmark + 984B12B214AB6F46004BF082 + history + + 984B103614AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {658, 576}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 575 156 658 617 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 984B104214AB4E96004BF082 + PBXProjectModuleLabel + PhoneGap.plist + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 984B104314AB4E96004BF082 + PBXProjectModuleLabel + PhoneGap.plist + _historyCapacity + 0 + bookmark + 984B12B414AB6F46004BF082 + history + + 984B104514AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {750, 461}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 61 228 750 502 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 98B602FA144F0D5200E746E6 + PBXProjectModuleLabel + AppDelegate.h + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 98B602FB144F0D5200E746E6 + PBXProjectModuleLabel + AppDelegate.h + _historyCapacity + 0 + bookmark + 984B12B514AB6F46004BF082 + history + + 984B104614AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {750, 461}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 15 271 750 502 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 98DF3515144F0095001381F0 + PBXProjectModuleLabel + main.m + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 98DF3516144F0095001381F0 + PBXProjectModuleLabel + main.m + _historyCapacity + 0 + bookmark + 984B12B614AB6F46004BF082 + history + + 984B104714AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {750, 461}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 107 187 750 502 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 98DF3512144F0095001381F0 + PBXProjectModuleLabel + AppDelegate.m + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 98DF3513144F0095001381F0 + PBXProjectModuleLabel + AppDelegate.m + _historyCapacity + 0 + bookmark + 984B12B714AB6F46004BF082 + history + + 984B104814AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {750, 461}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 130 166 750 502 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 984B104914AB4E96004BF082 + PBXProjectModuleLabel + filerepo.js + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 984B104A14AB4E96004BF082 + PBXProjectModuleLabel + filerepo.js + _historyCapacity + 0 + bookmark + 984B12B814AB6F46004BF082 + history + + 984B104B14AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {658, 576}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 394 150 658 617 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 98DF3409144EE6D2001381F0 + PBXProjectModuleLabel + catalogue.js + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 98DF340A144EE6D2001381F0 + PBXProjectModuleLabel + catalogue.js + _historyCapacity + 0 + bookmark + 984B12B914AB6F46004BF082 + history + + 984B104D14AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {750, 461}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 273 224 750 502 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 984B104E14AB4E96004BF082 + PBXProjectModuleLabel + history.js + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 984B104F14AB4E96004BF082 + PBXProjectModuleLabel + history.js + _historyCapacity + 0 + bookmark + 984B12BA14AB6F46004BF082 + history + + 984B105014AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {658, 576}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 471 147 658 617 0 0 1280 778 + + + + Content + + PBXProjectModuleGUID + 98DF3405144EE6D2001381F0 + PBXProjectModuleLabel + dbput.js + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 98DF3406144EE6D2001381F0 + PBXProjectModuleLabel + dbput.js + _historyCapacity + 0 + bookmark + 984B12BC14AB6F46004BF082 + history + + 984B105214AB4E96004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + Geometry + + Frame + {{0, 20}, {750, 461}} + PBXModuleWindowStatusBarHidden2 + + RubberWindowFrame + 61 229 750 502 0 0 1280 778 + + + + PerspectiveWidths + + -1 + -1 + + Perspectives + + + ChosenToolbarItems + + active-combo-popup + action + NSToolbarFlexibleSpaceItem + debugger-enable-breakpoints + build-and-go + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProjectWithEditor + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 98DF335B144EE40D001381F0 + 984B0F4214AB25C9004BF082 + 984B0F4314AB25C9004BF082 + 301BF52D109A57CC0062928A + 080E96DDFE201D6D7F000001 + 307C750510C5A3420062BCA9 + 98B602E2144F0C4200E746E6 + 29B97315FDCFA39411CA2CEA + 29B97317FDCFA39411CA2CEA + 308D052D1370CCF300D202BF + 308D05311370CCF300D202BF + 29B97323FDCFA39411CA2CEA + 19C28FACFE9D520D11CA2CBB + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 3 + 1 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 573}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 591}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + -1 146 1280 632 0 0 1280 778 + + Module + PBXSmartGroupTreeModule + Proportion + 203pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20306471E060097A5F4 + PBXProjectModuleLabel + WolneLektury + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CE0B20406471E060097A5F4 + PBXProjectModuleLabel + WolneLektury + _historyCapacity + 0 + bookmark + 984B12A814AB6F46004BF082 + history + + 98DF33E2144EE6D2001381F0 + 98B7EA83149103F1000EE462 + 98B7EAFD14910675000EE462 + 98B7EAFE14910675000EE462 + 98B7EB0314910675000EE462 + 98B7EB0414910675000EE462 + 98B7EB0514910675000EE462 + 98B7EB0614910675000EE462 + 98B7EB0714910675000EE462 + 98B7EB0814910675000EE462 + 98B7EB0914910675000EE462 + 98B7EB8914911229000EE462 + 98B7EBA31491163B000EE462 + 98B7EBA41491163B000EE462 + 98B7EBA61491163B000EE462 + 98B7EBA71491163B000EE462 + 98B7EBA81491163B000EE462 + 98B7EBA91491163B000EE462 + 984B102614AB4E96004BF082 + 984B102714AB4E96004BF082 + 984B102814AB4E96004BF082 + 984B102914AB4E96004BF082 + 984B102A14AB4E96004BF082 + 984B102B14AB4E96004BF082 + 984B102C14AB4E96004BF082 + 984B102D14AB4E96004BF082 + 984B102E14AB4E96004BF082 + 984B103014AB4E96004BF082 + 984B106C14AB4EFB004BF082 + + + SplitCount + 1 + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {1072, 363}} + RubberWindowFrame + -1 146 1280 632 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 363pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CE0B20506471E060097A5F4 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{0, 368}, {1072, 223}} + RubberWindowFrame + -1 146 1280 632 0 0 1280 778 + + Module + XCDetailModule + Proportion + 223pt + + + Proportion + 1072pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDetailModule + + TableOfContents + + 984B106E14AB4EFB004BF082 + 1CE0B1FE06471DED0097A5F4 + 984B106F14AB4EFB004BF082 + 1CE0B20306471E060097A5F4 + 1CE0B20506471E060097A5F4 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.morph + IsVertical + 0 + Layout + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C08E77C0454961000C914BD + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + + PBXProjectModuleGUID + 11E0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 186 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 1C37FABC05509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {186, 337}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 1 + XCSharingToken + com.apple.Xcode.GFSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {203, 355}} + GroupTreeTableConfiguration + + MainColumn + 186 + + RubberWindowFrame + 373 269 690 397 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 100% + + + Name + Morph + PreferredWidth + 300 + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + + TableOfContents + + 11E0B1FE06471DED0097A5F4 + + ToolbarConfiguration + xcode.toolbar.config.default.shortV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecificationMode1.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + The Default Workspace in this version of Xcode now includes support to hide and show the detail view (what has been referred to as the "Metro-Morph" feature). You must discard your current Default Workspace settings and update to the latest Default Workspace in order to gain this feature. Do you wish to update to the latest Workspace defaults for project '%@'? + WindowJustification + 5 + WindowOrderList + + 1CD10A99069EF8BA00B06720 + 98DF31FF144EDB8D001381F0 + 98DF3405144EE6D2001381F0 + 984B104E14AB4E96004BF082 + 98DF3409144EE6D2001381F0 + 984B104914AB4E96004BF082 + 98DF3512144F0095001381F0 + 98DF3515144F0095001381F0 + 98B602FA144F0D5200E746E6 + 984B104214AB4E96004BF082 + 98E0622A145879DF008FCAF3 + 984B103E14AB4E96004BF082 + 1C78EAAD065D492600B07095 + 984B10EC14AB6716004BF082 + 98B7EBAE1491163B000EE462 + 98E0622E145879DF008FCAF3 + /Users/fnp/wl-mobi/Wolne Lektury.xcodeproj + + WindowString + -1 146 1280 632 0 0 1280 778 + WindowToolsV3 + + + FirstTimeWindowDisplayed + + Identifier + windowTool.build + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {500, 218}} + RubberWindowFrame + 394 219 500 500 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{0, 223}, {500, 236}} + RubberWindowFrame + 394 219 500 500 0 0 1280 778 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 459pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + + TableOfContents + + 98DF31FF144EDB8D001381F0 + 984B107C14AB4EFB004BF082 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowContentMinSize + 486 300 + WindowString + 394 219 500 500 0 0 1280 778 + WindowToolGUID + 98DF31FF144EDB8D001381F0 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debugger + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {316, 203}} + {{316, 0}, {378, 203}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 203}} + {{0, 203}, {694, 178}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 381}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 148 + + Frame + {{316, 0}, {378, 203}} + RubberWindowFrame + 267 301 694 422 0 0 1280 778 + + RubberWindowFrame + 267 301 694 422 0 0 1280 778 + + Module + PBXDebugSessionModule + Proportion + 381pt + + + Proportion + 381pt + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + + TableOfContents + + 1CD10A99069EF8BA00B06720 + 984B107D14AB4EFB004BF082 + 1C162984064C10D400B95A72 + 984B107E14AB4EFB004BF082 + 984B107F14AB4EFB004BF082 + 984B108014AB4EFB004BF082 + 984B108114AB4EFB004BF082 + 984B108214AB4EFB004BF082 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 267 301 694 422 0 0 1280 778 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.find + IsVertical + + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + + StatusBarVisibility + + + GeometryConfiguration + + Frame + {{0, 0}, {781, 212}} + RubberWindowFrame + 105 217 781 470 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 212pt + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{0, 217}, {781, 212}} + RubberWindowFrame + 105 217 781 470 0 0 1280 778 + + Module + PBXProjectFindModule + Proportion + 212pt + + + Proportion + 429pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + + TableOfContents + + 1C530D57069F1CE1000CFCEE + 98B602EA144F0C5200E746E6 + 98B602EB144F0C5200E746E6 + 1CDD528C0622207200134675 + 1CD0528E0623707200166675 + + WindowString + 105 217 781 470 0 0 1280 778 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + + + + Identifier + MENUSEPARATOR + + + FirstTimeWindowDisplayed + + Identifier + windowTool.debuggerConsole + IsVertical + + Layout + + + Dock + + + BecomeActive + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {650, 209}} + RubberWindowFrame + 514 169 650 250 0 0 1280 778 + + Module + PBXDebugCLIModule + Proportion + 209pt + + + Proportion + 209pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + + TableOfContents + + 1C78EAAD065D492600B07095 + 984B109214AB4F1D004BF082 + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 514 169 650 250 0 0 1280 778 + WindowToolGUID + 1C78EAAD065D492600B07095 + WindowToolIsVisible + + + + FirstTimeWindowDisplayed + + Identifier + windowTool.snapshots + IsVertical + + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 98DF3239144EDDA2001381F0 + PBXProjectModuleLabel + Snapshots + + GeometryConfiguration + + Frame + {{0, 0}, {300, 509}} + RubberWindowFrame + 129 194 300 550 0 0 1280 778 + + Module + XCSnapshotModule + Proportion + 509pt + + + Proportion + 509pt + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + + TableOfContents + + 98DF323A144EDDA2001381F0 + 98DF323B144EDDA2001381F0 + 98DF3239144EDDA2001381F0 + + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 129 194 300 550 0 0 1280 778 + WindowToolGUID + 98DF323A144EDDA2001381F0 + WindowToolIsVisible + + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.0950012207031 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scm + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 100% + + + Proportion + 100% + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {374, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {630, 331}} + MembersFrame + {{0, 105}, {374, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 97 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 385 179 630 352 0 0 1440 878 + + Module + PBXClassBrowserModule + Proportion + 332pt + + + Proportion + 332pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C0AD2AF069F1E9B00FABCE6 + 1C0AD2B0069F1E9B00FABCE6 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 385 179 630 352 0 0 1440 878 + WindowToolGUID + 1C0AD2AF069F1E9B00FABCE6 + WindowToolIsVisible + 0 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/Wolne Lektury.xcodeproj/fnp.pbxuser b/Wolne Lektury.xcodeproj/fnp.pbxuser new file mode 100644 index 0000000..c528161 --- /dev/null +++ b/Wolne Lektury.xcodeproj/fnp.pbxuser @@ -0,0 +1,1085 @@ +// !$*UTF8*$! +{ + 1D3623240D0F684500981E51 /* AppDelegate.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {705, 430}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 646}"; + sepNavWindowFrame = "{{15, 215}, {750, 558}}"; + }; + }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {782, 1807}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 749}"; + sepNavWindowFrame = "{{130, 110}, {750, 558}}"; + }; + }; + 1D6058900D05DD3D006BFB54 /* Wolne Lektury */ = { + activeExec = 0; + executables = ( + 9879B548144ED51F0012352D /* Wolne Lektury */, + ); + }; + 29B97313FDCFA39411CA2CEA /* Project object */ = { + activeBuildConfigurationName = Debug; + activeExecutable = 9879B548144ED51F0012352D /* Wolne Lektury */; + activeTarget = 1D6058900D05DD3D006BFB54 /* Wolne Lektury */; + addToTargets = ( + 1D6058900D05DD3D006BFB54 /* Wolne Lektury */, + ); + codeSenseManager = 9879B567144ED5290012352D /* Code sense */; + executables = ( + 9879B548144ED51F0012352D /* Wolne Lektury */, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXBookmarksDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXBookmarksDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 200, + 200, + 151, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXBookmarksDataSource_LocationID, + PBXBookmarksDataSource_NameID, + PBXBookmarksDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 22, + 300, + 721, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXExecutablesDataSource_ActiveFlagID, + PBXExecutablesDataSource_NameID, + PBXExecutablesDataSource_CommentsID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = 1; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 833, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID; + PBXFileTableDataSourceColumnWidthsKey = ( + 200, + 847, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFindDataSource_MessageID, + PBXFindDataSource_LocationID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXSymbolsDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXSymbolsDataSource_SymbolNameID; + PBXFileTableDataSourceColumnWidthsKey = ( + 16, + 200, + 50, + 773, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXSymbolsDataSource_SymbolTypeIconID, + PBXSymbolsDataSource_SymbolNameID, + PBXSymbolsDataSource_SymbolTypeID, + PBXSymbolsDataSource_ReferenceNameID, + ); + }; + PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 793, + 60, + 20, + 48, + 43, + 43, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXTargetDataSource_PrimaryAttribute, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 346771179; + PBXWorkspaceStateSaveDate = 346771179; + }; + perUserProjectItems = { + 984B102614AB4E96004BF082 /* PBXTextBookmark */ = 984B102614AB4E96004BF082 /* PBXTextBookmark */; + 984B102714AB4E96004BF082 /* PBXTextBookmark */ = 984B102714AB4E96004BF082 /* PBXTextBookmark */; + 984B102814AB4E96004BF082 /* PBXTextBookmark */ = 984B102814AB4E96004BF082 /* PBXTextBookmark */; + 984B102914AB4E96004BF082 /* PlistBookmark */ = 984B102914AB4E96004BF082 /* PlistBookmark */; + 984B102A14AB4E96004BF082 /* PBXTextBookmark */ = 984B102A14AB4E96004BF082 /* PBXTextBookmark */; + 984B102B14AB4E96004BF082 /* PBXTextBookmark */ = 984B102B14AB4E96004BF082 /* PBXTextBookmark */; + 984B102C14AB4E96004BF082 /* PlistBookmark */ = 984B102C14AB4E96004BF082 /* PlistBookmark */; + 984B102D14AB4E96004BF082 /* PBXTextBookmark */ = 984B102D14AB4E96004BF082 /* PBXTextBookmark */; + 984B102E14AB4E96004BF082 /* PBXBookmark */ = 984B102E14AB4E96004BF082 /* PBXBookmark */; + 984B103014AB4E96004BF082 /* PBXTextBookmark */ = 984B103014AB4E96004BF082 /* PBXTextBookmark */; + 984B103614AB4E96004BF082 /* PBXTextBookmark */ = 984B103614AB4E96004BF082 /* PBXTextBookmark */; + 984B103914AB4E96004BF082 /* PBXTextBookmark */ = 984B103914AB4E96004BF082 /* PBXTextBookmark */; + 984B103C14AB4E96004BF082 /* PBXTextBookmark */ = 984B103C14AB4E96004BF082 /* PBXTextBookmark */; + 984B104014AB4E96004BF082 /* PBXTextBookmark */ = 984B104014AB4E96004BF082 /* PBXTextBookmark */; + 984B104514AB4E96004BF082 /* PlistBookmark */ = 984B104514AB4E96004BF082 /* PlistBookmark */; + 984B104614AB4E96004BF082 /* PBXTextBookmark */ = 984B104614AB4E96004BF082 /* PBXTextBookmark */; + 984B104714AB4E96004BF082 /* PBXTextBookmark */ = 984B104714AB4E96004BF082 /* PBXTextBookmark */; + 984B104814AB4E96004BF082 /* PBXTextBookmark */ = 984B104814AB4E96004BF082 /* PBXTextBookmark */; + 984B104B14AB4E96004BF082 /* PBXTextBookmark */ = 984B104B14AB4E96004BF082 /* PBXTextBookmark */; + 984B104D14AB4E96004BF082 /* PBXTextBookmark */ = 984B104D14AB4E96004BF082 /* PBXTextBookmark */; + 984B105014AB4E96004BF082 /* PBXTextBookmark */ = 984B105014AB4E96004BF082 /* PBXTextBookmark */; + 984B105214AB4E96004BF082 /* PBXTextBookmark */ = 984B105214AB4E96004BF082 /* PBXTextBookmark */; + 984B106C14AB4EFB004BF082 /* PBXTextBookmark */ = 984B106C14AB4EFB004BF082 /* PBXTextBookmark */; + 984B10EE14AB6716004BF082 /* PBXTextBookmark */ = 984B10EE14AB6716004BF082 /* PBXTextBookmark */; + 984B12A814AB6F46004BF082 /* PBXTextBookmark */ = 984B12A814AB6F46004BF082 /* PBXTextBookmark */; + 984B12AA14AB6F46004BF082 /* PBXTextBookmark */ = 984B12AA14AB6F46004BF082 /* PBXTextBookmark */; + 984B12AC14AB6F46004BF082 /* PBXTextBookmark */ = 984B12AC14AB6F46004BF082 /* PBXTextBookmark */; + 984B12AE14AB6F46004BF082 /* PBXTextBookmark */ = 984B12AE14AB6F46004BF082 /* PBXTextBookmark */; + 984B12B014AB6F46004BF082 /* PBXTextBookmark */ = 984B12B014AB6F46004BF082 /* PBXTextBookmark */; + 984B12B214AB6F46004BF082 /* PBXTextBookmark */ = 984B12B214AB6F46004BF082 /* PBXTextBookmark */; + 984B12B414AB6F46004BF082 /* PlistBookmark */ = 984B12B414AB6F46004BF082 /* PlistBookmark */; + 984B12B514AB6F46004BF082 /* PBXTextBookmark */ = 984B12B514AB6F46004BF082 /* PBXTextBookmark */; + 984B12B614AB6F46004BF082 /* PBXTextBookmark */ = 984B12B614AB6F46004BF082 /* PBXTextBookmark */; + 984B12B714AB6F46004BF082 /* PBXTextBookmark */ = 984B12B714AB6F46004BF082 /* PBXTextBookmark */; + 984B12B814AB6F46004BF082 /* PBXTextBookmark */ = 984B12B814AB6F46004BF082 /* PBXTextBookmark */; + 984B12B914AB6F46004BF082 /* PBXTextBookmark */ = 984B12B914AB6F46004BF082 /* PBXTextBookmark */; + 984B12BA14AB6F46004BF082 /* PBXTextBookmark */ = 984B12BA14AB6F46004BF082 /* PBXTextBookmark */; + 984B12BC14AB6F46004BF082 /* PBXTextBookmark */ = 984B12BC14AB6F46004BF082 /* PBXTextBookmark */; + 98B7EA83149103F1000EE462 /* PBXTextBookmark */ = 98B7EA83149103F1000EE462 /* PBXTextBookmark */; + 98B7EAFD14910675000EE462 /* PBXTextBookmark */ = 98B7EAFD14910675000EE462 /* PBXTextBookmark */; + 98B7EAFE14910675000EE462 /* PBXTextBookmark */ = 98B7EAFE14910675000EE462 /* PBXTextBookmark */; + 98B7EB0314910675000EE462 /* PBXBookmark */ = 98B7EB0314910675000EE462 /* PBXBookmark */; + 98B7EB0414910675000EE462 /* PBXBookmark */ = 98B7EB0414910675000EE462 /* PBXBookmark */; + 98B7EB0514910675000EE462 /* PBXBookmark */ = 98B7EB0514910675000EE462 /* PBXBookmark */; + 98B7EB0614910675000EE462 /* PBXBookmark */ = 98B7EB0614910675000EE462 /* PBXBookmark */; + 98B7EB0714910675000EE462 /* PBXBookmark */ = 98B7EB0714910675000EE462 /* PBXBookmark */; + 98B7EB0814910675000EE462 /* PBXBookmark */ = 98B7EB0814910675000EE462 /* PBXBookmark */; + 98B7EB0914910675000EE462 /* PBXBookmark */ = 98B7EB0914910675000EE462 /* PBXBookmark */; + 98B7EB8914911229000EE462 /* PBXTextBookmark */ = 98B7EB8914911229000EE462 /* PBXTextBookmark */; + 98B7EBA31491163B000EE462 /* PBXTextBookmark */ = 98B7EBA31491163B000EE462 /* PBXTextBookmark */; + 98B7EBA41491163B000EE462 /* PBXTextBookmark */ = 98B7EBA41491163B000EE462 /* PBXTextBookmark */; + 98B7EBA61491163B000EE462 /* PBXTextBookmark */ = 98B7EBA61491163B000EE462 /* PBXTextBookmark */; + 98B7EBA71491163B000EE462 /* PBXTextBookmark */ = 98B7EBA71491163B000EE462 /* PBXTextBookmark */; + 98B7EBA81491163B000EE462 /* PBXTextBookmark */ = 98B7EBA81491163B000EE462 /* PBXTextBookmark */; + 98B7EBA91491163B000EE462 /* PBXTextBookmark */ = 98B7EBA91491163B000EE462 /* PBXTextBookmark */; + 98DF33E2144EE6D2001381F0 /* PBXTextBookmark */ = 98DF33E2144EE6D2001381F0 /* PBXTextBookmark */; + }; + sourceControlManager = 9879B566144ED5290012352D /* Source Control */; + userBuildSettings = { + }; + }; + 29B97316FDCFA39411CA2CEA /* main.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {691, 430}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 364}"; + sepNavWindowFrame = "{{107, 131}, {750, 558}}"; + }; + }; + 3053AC6E109B7857006FCFE7 /* VERSION */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1011, 316}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 13}"; + }; + }; + 307D28A1123043350040C0FA /* PhoneGapBuildSettings.xcconfig */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1011, 316}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 193}"; + sepNavWindowFrame = "{{15, 100}, {658, 673}}"; + }; + }; + 30E1352610E2C1420031B30D /* PhoneGap.plist */ = { + uiCtxt = { + sepNavWindowFrame = "{{61, 172}, {750, 558}}"; + }; + }; + 32CA4F630368D1EE00C91783 /* wl_mobi-Prefix.pch */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1011, 316}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 183}"; + sepNavWindowFrame = "{{15, 100}, {658, 673}}"; + }; + }; + 8D1107310486CEB800E47090 /* wl_mobi-Info.plist */ = { + uiCtxt = { + sepNavWindowFrame = "{{15, 100}, {658, 673}}"; + }; + }; + 98458DA21450E96400C96A53 /* catalogue.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = catalogue.js; + path = "/Users/fnp/wl-mobi/www/js/catalogue.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {768, 5304}}"; + sepNavSelRange = "{1358, 0}"; + sepNavVisRange = "{0, 955}"; + sepNavWindowFrame = "{{273, 168}, {750, 558}}"; + }; + }; + 984B102614AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98E06229145879DF008FCAF3 /* filerepo.js */; + name = "filerepo.js: 50"; + rLen = 0; + rLoc = 1423; + rType = 0; + vrLen = 538; + vrLoc = 1024; + }; + 984B102714AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 32CA4F630368D1EE00C91783 /* wl_mobi-Prefix.pch */; + name = "wl_mobi-Prefix.pch: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 183; + vrLoc = 0; + }; + 984B102814AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 29B97316FDCFA39411CA2CEA /* main.m */; + name = "main.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 364; + vrLoc = 0; + }; + 984B102914AB4E96004BF082 /* PlistBookmark */ = { + isa = PlistBookmark; + fRef = 8D1107310486CEB800E47090 /* wl_mobi-Info.plist */; + fallbackIsa = PBXBookmark; + isK = 0; + kPath = ( + CFBundleIconFiles, + ); + name = "/Users/fnp/wl-mobi/wl_mobi-Info.plist"; + rLen = 0; + rLoc = 9223372036854775808; + }; + 984B102A14AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 3053AC6E109B7857006FCFE7 /* VERSION */; + name = "VERSION: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 13; + vrLoc = 0; + }; + 984B102B14AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 307D28A1123043350040C0FA /* PhoneGapBuildSettings.xcconfig */; + name = "PhoneGapBuildSettings.xcconfig: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 193; + vrLoc = 0; + }; + 984B102C14AB4E96004BF082 /* PlistBookmark */ = { + isa = PlistBookmark; + fRef = 30E1352610E2C1420031B30D /* PhoneGap.plist */; + fallbackIsa = PBXBookmark; + isK = 0; + kPath = ( + EnableViewportScale, + ); + name = "/Users/fnp/wl-mobi/PhoneGap.plist"; + rLen = 0; + rLoc = 9223372036854775808; + }; + 984B102D14AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98B7EBB41491163B000EE462 /* book_text.css */; + name = "book_text.css: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 496; + vrLoc = 0; + }; + 984B102E14AB4E96004BF082 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 984B102F14AB4E96004BF082 /* icon-BookText.png */; + }; + 984B102F14AB4E96004BF082 /* icon-BookText.png */ = { + isa = PBXFileReference; + lastKnownFileType = image.png; + name = "icon-BookText.png"; + path = "/Users/fnp/wl-mobi/www/img/icon-BookText.png"; + sourceTree = ""; + }; + 984B103014AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98E06231145879DF008FCAF3 /* style.css */; + name = "style.css: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 462; + vrLoc = 0; + }; + 984B103214AB4E96004BF082 /* WolneLektury.html */ = { + isa = PBXFileReference; + lastKnownFileType = text.html; + name = WolneLektury.html; + path = "/Users/fnp/wl-mobi/www/WolneLektury.html"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1011, 533}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{16, 1330}"; + }; + }; + 984B103614AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B103714AB4E96004BF082 /* book_text.css */; + name = "book_text.css: 10"; + rLen = 0; + rLoc = 255; + rType = 0; + vrLen = 908; + vrLoc = 0; + }; + 984B103714AB4E96004BF082 /* book_text.css */ = { + isa = PBXFileReference; + lastKnownFileType = text.css; + name = book_text.css; + path = "/Users/fnp/wl-mobi/www/css/book_text.css"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 2938}}"; + sepNavSelRange = "{255, 0}"; + sepNavVisRange = "{0, 886}"; + }; + }; + 984B103914AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B103A14AB4E96004BF082 /* style.css */; + name = "style.css: 163"; + rLen = 0; + rLoc = 2369; + rType = 0; + vrLen = 819; + vrLoc = 0; + }; + 984B103A14AB4E96004BF082 /* style.css */ = { + isa = PBXFileReference; + lastKnownFileType = text.css; + name = style.css; + path = "/Users/fnp/wl-mobi/www/css/style.css"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 2795}}"; + sepNavSelRange = "{1028, 0}"; + sepNavVisRange = "{646, 599}"; + }; + }; + 984B103C14AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B103D14AB4E96004BF082 /* view.js */; + name = "view.js: 20"; + rLen = 0; + rLoc = 459; + rType = 0; + vrLen = 908; + vrLoc = 199; + }; + 984B103D14AB4E96004BF082 /* view.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = view.js; + path = "/Users/fnp/wl-mobi/www/js/view.js"; + sourceTree = ""; + }; + 984B104014AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B104114AB4E96004BF082 /* main.js */; + name = "main.js: 63"; + rLen = 0; + rLoc = 1457; + rType = 0; + vrLen = 905; + vrLoc = 666; + }; + 984B104114AB4E96004BF082 /* main.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = main.js; + path = "/Users/fnp/wl-mobi/www/js/main.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 936}}"; + sepNavSelRange = "{760, 0}"; + sepNavVisRange = "{309, 903}"; + }; + }; + 984B104514AB4E96004BF082 /* PlistBookmark */ = { + isa = PlistBookmark; + fRef = 30E1352610E2C1420031B30D /* PhoneGap.plist */; + fallbackIsa = PBXBookmark; + isK = 0; + kPath = ( + EnableViewportScale, + ); + name = "/Users/fnp/wl-mobi/PhoneGap.plist"; + rLen = 0; + rLoc = 9223372036854775808; + }; + 984B104614AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 1D3623240D0F684500981E51 /* AppDelegate.h */; + name = "AppDelegate.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 646; + vrLoc = 0; + }; + 984B104714AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 29B97316FDCFA39411CA2CEA /* main.m */; + name = "main.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 364; + vrLoc = 0; + }; + 984B104814AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; + name = "AppDelegate.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 749; + vrLoc = 0; + }; + 984B104B14AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98E06229145879DF008FCAF3 /* filerepo.js */; + name = "filerepo.js: 76"; + rLen = 0; + rLoc = 2162; + rType = 0; + vrLen = 1275; + vrLoc = 0; + }; + 984B104D14AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98458DA21450E96400C96A53 /* catalogue.js */; + name = "catalogue.js: 57"; + rLen = 0; + rLoc = 1358; + rType = 0; + vrLen = 955; + vrLoc = 0; + }; + 984B105014AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B105114AB4E96004BF082 /* history.js */; + name = "history.js: 32"; + rLen = 0; + rLoc = 839; + rType = 0; + vrLen = 956; + vrLoc = 90; + }; + 984B105114AB4E96004BF082 /* history.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = history.js; + path = "/Users/fnp/wl-mobi/www/js/history.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 1352}}"; + sepNavSelRange = "{839, 0}"; + sepNavVisRange = "{90, 948}"; + }; + }; + 984B105214AB4E96004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B105314AB4E96004BF082 /* dbput.js */; + name = "dbput.js: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 822; + vrLoc = 0; + }; + 984B105314AB4E96004BF082 /* dbput.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = dbput.js; + path = "/Users/fnp/wl-mobi/www/js/dbput.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {691, 494}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 822}"; + sepNavWindowFrame = "{{61, 173}, {750, 558}}"; + }; + }; + 984B106C14AB4EFB004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B103214AB4E96004BF082 /* WolneLektury.html */; + name = "WolneLektury.html: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1410; + vrLoc = 16; + }; + 984B10EE14AB6716004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98B7EBA51491163B000EE462 /* menu.js */; + name = "menu.js: 25"; + rLen = 0; + rLoc = 1209; + rType = 0; + vrLen = 1516; + vrLoc = 248; + }; + 984B12A814AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B12A914AB6F46004BF082 /* WolneLektury.html */; + name = "WolneLektury.html: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 1410; + vrLoc = 16; + }; + 984B12A914AB6F46004BF082 /* WolneLektury.html */ = { + isa = PBXFileReference; + name = WolneLektury.html; + path = "/Users/fnp/wl-mobi/www/WolneLektury.html"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1011, 533}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{16, 1410}"; + }; + }; + 984B12AA14AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B12AB14AB6F46004BF082 /* style.css */; + name = "style.css: 59"; + rLen = 0; + rLoc = 1028; + rType = 0; + vrLen = 637; + vrLoc = 646; + }; + 984B12AB14AB6F46004BF082 /* style.css */ = { + isa = PBXFileReference; + name = style.css; + path = "/Users/fnp/wl-mobi/www/css/style.css"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 2795}}"; + sepNavSelRange = "{1028, 0}"; + sepNavVisRange = "{646, 637}"; + sepNavWindowFrame = "{{622, 105}, {658, 673}}"; + }; + }; + 984B12AC14AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B12AD14AB6F46004BF082 /* view.js */; + name = "view.js: 428"; + rLen = 10; + rLoc = 11532; + rType = 0; + vrLen = 905; + vrLoc = 984; + }; + 984B12AD14AB6F46004BF082 /* view.js */ = { + isa = PBXFileReference; + name = view.js; + path = "/Users/fnp/wl-mobi/www/js/view.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {964, 6474}}"; + sepNavSelRange = "{11532, 10}"; + sepNavVisRange = "{984, 905}"; + sepNavWindowFrame = "{{223, 62}, {658, 673}}"; + }; + }; + 984B12AE14AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B12AF14AB6F46004BF082 /* menu.js */; + name = "menu.js: 68"; + rLen = 0; + rLoc = 2417; + rType = 0; + vrLen = 1574; + vrLoc = 0; + }; + 984B12AF14AB6F46004BF082 /* menu.js */ = { + isa = PBXFileReference; + name = menu.js; + path = "/Users/fnp/wl-mobi/www/js/menu.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {999, 923}}"; + sepNavSelRange = "{2417, 0}"; + sepNavVisRange = "{0, 1574}"; + sepNavWindowFrame = "{{607, 105}, {658, 673}}"; + }; + }; + 984B12B014AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B12B114AB6F46004BF082 /* main.js */; + name = "main.js: 32"; + rLen = 0; + rLoc = 760; + rType = 0; + vrLen = 937; + vrLoc = 309; + }; + 984B12B114AB6F46004BF082 /* main.js */ = { + isa = PBXFileReference; + name = main.js; + path = "/Users/fnp/wl-mobi/www/js/main.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 936}}"; + sepNavSelRange = "{760, 0}"; + sepNavVisRange = "{309, 937}"; + sepNavWindowFrame = "{{354, 92}, {658, 673}}"; + }; + }; + 984B12B214AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B12B314AB6F46004BF082 /* book_text.css */; + name = "book_text.css: 10"; + rLen = 0; + rLoc = 255; + rType = 0; + vrLen = 908; + vrLoc = 0; + }; + 984B12B314AB6F46004BF082 /* book_text.css */ = { + isa = PBXFileReference; + name = book_text.css; + path = "/Users/fnp/wl-mobi/www/css/book_text.css"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 2938}}"; + sepNavSelRange = "{255, 0}"; + sepNavVisRange = "{0, 908}"; + sepNavWindowFrame = "{{575, 100}, {658, 673}}"; + }; + }; + 984B12B414AB6F46004BF082 /* PlistBookmark */ = { + isa = PlistBookmark; + fRef = 30E1352610E2C1420031B30D /* PhoneGap.plist */; + fallbackIsa = PBXBookmark; + isK = 0; + kPath = ( + EnableViewportScale, + ); + name = "/Users/fnp/wl-mobi/PhoneGap.plist"; + rLen = 0; + rLoc = 9223372036854775807; + }; + 984B12B514AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 1D3623240D0F684500981E51 /* AppDelegate.h */; + name = "AppDelegate.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 646; + vrLoc = 0; + }; + 984B12B614AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 29B97316FDCFA39411CA2CEA /* main.m */; + name = "main.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 364; + vrLoc = 0; + }; + 984B12B714AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; + name = "AppDelegate.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 749; + vrLoc = 0; + }; + 984B12B814AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98E06229145879DF008FCAF3 /* filerepo.js */; + name = "filerepo.js: 76"; + rLen = 0; + rLoc = 2162; + rType = 0; + vrLen = 1275; + vrLoc = 0; + }; + 984B12B914AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98458DA21450E96400C96A53 /* catalogue.js */; + name = "catalogue.js: 57"; + rLen = 0; + rLoc = 1358; + rType = 0; + vrLen = 955; + vrLoc = 0; + }; + 984B12BA14AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B12BB14AB6F46004BF082 /* history.js */; + name = "history.js: 32"; + rLen = 0; + rLoc = 839; + rType = 0; + vrLen = 956; + vrLoc = 90; + }; + 984B12BB14AB6F46004BF082 /* history.js */ = { + isa = PBXFileReference; + name = history.js; + path = "/Users/fnp/wl-mobi/www/js/history.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 1352}}"; + sepNavSelRange = "{839, 0}"; + sepNavVisRange = "{90, 956}"; + sepNavWindowFrame = "{{471, 91}, {658, 673}}"; + }; + }; + 984B12BC14AB6F46004BF082 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 984B12BD14AB6F46004BF082 /* dbput.js */; + name = "dbput.js: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 822; + vrLoc = 0; + }; + 984B12BD14AB6F46004BF082 /* dbput.js */ = { + isa = PBXFileReference; + name = dbput.js; + path = "/Users/fnp/wl-mobi/www/js/dbput.js"; + sourceTree = ""; + }; + 9879B548144ED51F0012352D /* Wolne Lektury */ = { + isa = PBXExecutable; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + breakpointsEnabled = 0; + configStateDict = { + }; + customDataFormattersEnabled = 1; + dataTipCustomDataFormattersEnabled = 1; + dataTipShowTypeColumn = 1; + dataTipSortType = 0; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = "Wolne Lektury"; + savedGlobals = { + }; + showTypeColumn = 0; + sourceDirectories = ( + ); + }; + 9879B566144ED5290012352D /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + repositoryNamesForRoots = { + "" = ""; + }; + }; + }; + 9879B567144ED5290012352D /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + 98B602E3144F0C4200E746E6 /* NativeControls.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1011, 897}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 639}"; + }; + }; + 98B602E4144F0C4200E746E6 /* NativeControls.js */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1011, 4199}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{17, 640}"; + sepNavWindowFrame = "{{38, 194}, {750, 558}}"; + }; + }; + 98B602E5144F0C4200E746E6 /* NativeControls.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1011, 9269}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRange = "{0, 579}"; + }; + }; + 98B7EA83149103F1000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98B7EA84149103F1000EE462 /* Wolne Lektury */; + name = "Wolne Lektury: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 0; + vrLoc = 0; + }; + 98B7EA84149103F1000EE462 /* Wolne Lektury */ = { + isa = PBXFileReference; + lastKnownFileType = text; + name = "Wolne Lektury"; + path = "/Users/fnp/wl-mobi/Wolne Lektury"; + sourceTree = ""; + }; + 98B7EAFD14910675000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98B602E5144F0C4200E746E6 /* NativeControls.m */; + name = "NativeControls.m: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 579; + vrLoc = 0; + }; + 98B7EAFE14910675000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98B602E4144F0C4200E746E6 /* NativeControls.js */; + name = "NativeControls.js: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 640; + vrLoc = 17; + }; + 98B7EB0314910675000EE462 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 308D05301370CCF300D202BF /* icon@2x.png */; + }; + 98B7EB0414910675000EE462 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 308D052F1370CCF300D202BF /* icon.png */; + }; + 98B7EB0514910675000EE462 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 308D052E1370CCF300D202BF /* icon-72.png */; + }; + 98B7EB0614910675000EE462 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 308D05351370CCF300D202BF /* Default@2x.png */; + }; + 98B7EB0714910675000EE462 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 308D05341370CCF300D202BF /* Default.png */; + }; + 98B7EB0814910675000EE462 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 308D05331370CCF300D202BF /* Default-Portrait.png */; + }; + 98B7EB0914910675000EE462 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = 308D05321370CCF300D202BF /* Default-Landscape.png */; + }; + 98B7EB8914911229000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98E06227145879DF008FCAF3 /* main.js */; + name = "main.js: 24"; + rLen = 0; + rLoc = 537; + rType = 0; + vrLen = 544; + vrLoc = 210; + }; + 98B7EBA31491163B000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98458DA21450E96400C96A53 /* catalogue.js */; + name = "catalogue.js: 162"; + rLen = 0; + rLoc = 4437; + rType = 0; + vrLen = 508; + vrLoc = 4158; + }; + 98B7EBA41491163B000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98B7EBA51491163B000EE462 /* menu.js */; + name = "menu.js: 40"; + rLen = 0; + rLoc = 1655; + rType = 0; + vrLen = 726; + vrLoc = 1073; + }; + 98B7EBA51491163B000EE462 /* menu.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = menu.js; + path = "/Users/fnp/wl-mobi/www/js/menu.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {999, 923}}"; + sepNavSelRange = "{2417, 0}"; + sepNavVisRange = "{0, 1535}"; + }; + }; + 98B7EBA61491163B000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98DF33F2144EE6D2001381F0 /* view.js */; + name = "view.js: 461"; + rLen = 0; + rLoc = 12327; + rType = 0; + vrLen = 598; + vrLoc = 12144; + }; + 98B7EBA71491163B000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98B602E3144F0C4200E746E6 /* NativeControls.h */; + name = "NativeControls.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 639; + vrLoc = 0; + }; + 98B7EBA81491163B000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; + name = "AppDelegate.m: 90"; + rLen = 0; + rLoc = 2732; + rType = 0; + vrLen = 468; + vrLoc = 0; + }; + 98B7EBA91491163B000EE462 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 1D3623240D0F684500981E51 /* AppDelegate.h */; + name = "AppDelegate.h: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 578; + vrLoc = 68; + }; + 98B7EBB41491163B000EE462 /* book_text.css */ = { + isa = PBXFileReference; + lastKnownFileType = text.css; + name = book_text.css; + path = "/Users/fnp/wl-mobi/www/css/book_text.css"; + sourceTree = ""; + }; + 98DF33E2144EE6D2001381F0 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 98DF33E3144EE6D2001381F0 /* menuinterface.js */; + name = "menuinterface.js: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 733; + vrLoc = 0; + }; + 98DF33E3144EE6D2001381F0 /* menuinterface.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = menuinterface.js; + path = "/Users/fnp/wl-mobi/www/js/menuinterface.js"; + sourceTree = ""; + }; + 98DF33F2144EE6D2001381F0 /* view.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = view.js; + path = "/Users/fnp/wl-mobi/www/js/view.js"; + sourceTree = ""; + }; + 98E06227145879DF008FCAF3 /* main.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = main.js; + path = "/Users/fnp/wl-mobi/www/js/main.js"; + sourceTree = ""; + }; + 98E06229145879DF008FCAF3 /* filerepo.js */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.javascript; + name = filerepo.js; + path = "/Users/fnp/wl-mobi/www/js/filerepo.js"; + sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {614, 1703}}"; + sepNavSelRange = "{2162, 0}"; + sepNavVisRange = "{0, 1275}"; + sepNavWindowFrame = "{{394, 94}, {658, 673}}"; + }; + }; + 98E06231145879DF008FCAF3 /* style.css */ = { + isa = PBXFileReference; + lastKnownFileType = text.css; + name = style.css; + path = "/Users/fnp/wl-mobi/www/css/style.css"; + sourceTree = ""; + }; +} diff --git a/Wolne Lektury.xcodeproj/project.pbxproj b/Wolne Lektury.xcodeproj/project.pbxproj new file mode 100755 index 0000000..48e6138 --- /dev/null +++ b/Wolne Lektury.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* AppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; + 301BF552109A68D80062928A /* libPhoneGap.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF535109A57CC0062928A /* libPhoneGap.a */; }; + 301BF5B5109A6A2B0062928A /* AddressBook.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B4109A6A2B0062928A /* AddressBook.framework */; }; + 301BF5B7109A6A2B0062928A /* AddressBookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */; }; + 301BF5B9109A6A2B0062928A /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */; }; + 301BF5BB109A6A2B0062928A /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BA109A6A2B0062928A /* AVFoundation.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 301BF5BD109A6A2B0062928A /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BC109A6A2B0062928A /* CFNetwork.framework */; }; + 301BF5BF109A6A2B0062928A /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5BE109A6A2B0062928A /* CoreLocation.framework */; }; + 301BF5C1109A6A2B0062928A /* MediaPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */; }; + 301BF5C3109A6A2B0062928A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C2109A6A2B0062928A /* QuartzCore.framework */; }; + 301BF5C5109A6A2B0062928A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */; }; + 3053AC6F109B7857006FCFE7 /* VERSION in Resources */ = {isa = PBXBuildFile; fileRef = 3053AC6E109B7857006FCFE7 /* VERSION */; }; + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */; }; + 307D28A2123043360040C0FA /* PhoneGapBuildSettings.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 307D28A1123043350040C0FA /* PhoneGapBuildSettings.xcconfig */; }; + 308D05371370CCF300D202BF /* icon-72.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052E1370CCF300D202BF /* icon-72.png */; }; + 308D05381370CCF300D202BF /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D052F1370CCF300D202BF /* icon.png */; }; + 308D05391370CCF300D202BF /* icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05301370CCF300D202BF /* icon@2x.png */; }; + 308D053A1370CCF300D202BF /* Default-Landscape.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05321370CCF300D202BF /* Default-Landscape.png */; }; + 308D053B1370CCF300D202BF /* Default-Portrait.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05331370CCF300D202BF /* Default-Portrait.png */; }; + 308D053C1370CCF300D202BF /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05341370CCF300D202BF /* Default.png */; }; + 308D053D1370CCF300D202BF /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 308D05351370CCF300D202BF /* Default@2x.png */; }; + 30E1352710E2C1420031B30D /* PhoneGap.plist in Resources */ = {isa = PBXBuildFile; fileRef = 30E1352610E2C1420031B30D /* PhoneGap.plist */; }; + 30E5649213A7FCAF007403D8 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30E5649113A7FCAF007403D8 /* CoreMedia.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 98B602E6144F0C4200E746E6 /* NativeControls.js in Sources */ = {isa = PBXBuildFile; fileRef = 98B602E4144F0C4200E746E6 /* NativeControls.js */; }; + 98B602E7144F0C4200E746E6 /* NativeControls.m in Sources */ = {isa = PBXBuildFile; fileRef = 98B602E5144F0C4200E746E6 /* NativeControls.m */; }; + 98DF3370144EE40D001381F0 /* www in Resources */ = {isa = PBXBuildFile; fileRef = 98DF335B144EE40D001381F0 /* www */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 301BF534109A57CC0062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* PhoneGapLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = D2AAC07E0554694100DB518D; + remoteInfo = PhoneGapLib; + }; + 301BF550109A68C00062928A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* PhoneGapLib.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = D2AAC07D0554694100DB518D; + remoteInfo = PhoneGapLib; + }; + 30E47BC2136F595F00DBB853 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* PhoneGapLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 303258D8136B2C9400982B63; + remoteInfo = PhoneGap; + }; + 9879B550144ED51F0012352D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 301BF52D109A57CC0062928A /* PhoneGapLib.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 686357A9141002F100DF4CF2; + remoteInfo = PhoneGapLibTests; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 98DF3300144EE25A001381F0 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = www; + dstSubfolderSpec = 7; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 98DF3307144EE28A001381F0 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = www; + dstSubfolderSpec = 7; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* Wolne Lektury.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Wolne Lektury.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 301BF52D109A57CC0062928A /* PhoneGapLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = PhoneGapLib.xcodeproj; sourceTree = PHONEGAPLIB; }; + 301BF5B4109A6A2B0062928A /* AddressBook.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBook.framework; path = System/Library/Frameworks/AddressBook.framework; sourceTree = SDKROOT; }; + 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; }; + 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 301BF5BA109A6A2B0062928A /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 301BF5BC109A6A2B0062928A /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 301BF5BE109A6A2B0062928A /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; }; + 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MediaPlayer.framework; path = System/Library/Frameworks/MediaPlayer.framework; sourceTree = SDKROOT; }; + 301BF5C2109A6A2B0062928A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 3053AC6E109B7857006FCFE7 /* VERSION */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = VERSION; sourceTree = PHONEGAPLIB; }; + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; + 307D28A1123043350040C0FA /* PhoneGapBuildSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = PhoneGapBuildSettings.xcconfig; sourceTree = ""; }; + 308D052E1370CCF300D202BF /* icon-72.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon-72.png"; sourceTree = ""; }; + 308D052F1370CCF300D202BF /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; + 308D05301370CCF300D202BF /* icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "icon@2x.png"; sourceTree = ""; }; + 308D05321370CCF300D202BF /* Default-Landscape.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Landscape.png"; sourceTree = ""; }; + 308D05331370CCF300D202BF /* Default-Portrait.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-Portrait.png"; sourceTree = ""; }; + 308D05341370CCF300D202BF /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; + 308D05351370CCF300D202BF /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; + 30E1352610E2C1420031B30D /* PhoneGap.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = PhoneGap.plist; sourceTree = ""; }; + 30E5649113A7FCAF007403D8 /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; + 32CA4F630368D1EE00C91783 /* wl_mobi-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "wl_mobi-Prefix.pch"; sourceTree = ""; }; + 8D1107310486CEB800E47090 /* wl_mobi-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "wl_mobi-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; + 98B602E3144F0C4200E746E6 /* NativeControls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeControls.h; sourceTree = ""; }; + 98B602E4144F0C4200E746E6 /* NativeControls.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = NativeControls.js; sourceTree = ""; }; + 98B602E5144F0C4200E746E6 /* NativeControls.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NativeControls.m; sourceTree = ""; }; + 98DF335B144EE40D001381F0 /* www */ = {isa = PBXFileReference; explicitFileType = folder; path = www; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 301BF552109A68D80062928A /* libPhoneGap.a in Frameworks */, + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, + 301BF5B5109A6A2B0062928A /* AddressBook.framework in Frameworks */, + 301BF5B7109A6A2B0062928A /* AddressBookUI.framework in Frameworks */, + 301BF5B9109A6A2B0062928A /* AudioToolbox.framework in Frameworks */, + 301BF5BB109A6A2B0062928A /* AVFoundation.framework in Frameworks */, + 301BF5BD109A6A2B0062928A /* CFNetwork.framework in Frameworks */, + 301BF5BF109A6A2B0062928A /* CoreLocation.framework in Frameworks */, + 301BF5C1109A6A2B0062928A /* MediaPlayer.framework in Frameworks */, + 301BF5C3109A6A2B0062928A /* QuartzCore.framework in Frameworks */, + 301BF5C5109A6A2B0062928A /* SystemConfiguration.framework in Frameworks */, + 305D5FD1115AB8F900A74A75 /* MobileCoreServices.framework in Frameworks */, + 30E5649213A7FCAF007403D8 /* CoreMedia.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* AppDelegate.h */, + 1D3623250D0F684500981E51 /* AppDelegate.m */, + ); + path = Classes; + sourceTree = SOURCE_ROOT; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* Wolne Lektury.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 98DF335B144EE40D001381F0 /* www */, + 301BF52D109A57CC0062928A /* PhoneGapLib.xcodeproj */, + 080E96DDFE201D6D7F000001 /* Classes */, + 307C750510C5A3420062BCA9 /* Plugins */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 32CA4F630368D1EE00C91783 /* wl_mobi-Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 308D052D1370CCF300D202BF /* icons */, + 308D05311370CCF300D202BF /* splash */, + 30E1352610E2C1420031B30D /* PhoneGap.plist */, + 3053AC6E109B7857006FCFE7 /* VERSION */, + 8D1107310486CEB800E47090 /* wl_mobi-Info.plist */, + 307D28A1123043350040C0FA /* PhoneGapBuildSettings.xcconfig */, + ); + name = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 288765FC0DF74451002DB57D /* CoreGraphics.framework */, + 301BF5B4109A6A2B0062928A /* AddressBook.framework */, + 301BF5B6109A6A2B0062928A /* AddressBookUI.framework */, + 301BF5B8109A6A2B0062928A /* AudioToolbox.framework */, + 301BF5BA109A6A2B0062928A /* AVFoundation.framework */, + 301BF5BC109A6A2B0062928A /* CFNetwork.framework */, + 301BF5BE109A6A2B0062928A /* CoreLocation.framework */, + 301BF5C0109A6A2B0062928A /* MediaPlayer.framework */, + 301BF5C2109A6A2B0062928A /* QuartzCore.framework */, + 301BF5C4109A6A2B0062928A /* SystemConfiguration.framework */, + 305D5FD0115AB8F900A74A75 /* MobileCoreServices.framework */, + 30E5649113A7FCAF007403D8 /* CoreMedia.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 301BF52E109A57CC0062928A /* Products */ = { + isa = PBXGroup; + children = ( + 301BF535109A57CC0062928A /* libPhoneGap.a */, + 30E47BC3136F595F00DBB853 /* PhoneGap.framework */, + 9879B551144ED51F0012352D /* PhoneGapLibTests.octest */, + ); + name = Products; + sourceTree = ""; + }; + 307C750510C5A3420062BCA9 /* Plugins */ = { + isa = PBXGroup; + children = ( + 98B602E2144F0C4200E746E6 /* NativeControls */, + ); + path = Plugins; + sourceTree = SOURCE_ROOT; + }; + 308D052D1370CCF300D202BF /* icons */ = { + isa = PBXGroup; + children = ( + 308D052E1370CCF300D202BF /* icon-72.png */, + 308D052F1370CCF300D202BF /* icon.png */, + 308D05301370CCF300D202BF /* icon@2x.png */, + ); + name = icons; + path = Resources/icons; + sourceTree = ""; + }; + 308D05311370CCF300D202BF /* splash */ = { + isa = PBXGroup; + children = ( + 308D05321370CCF300D202BF /* Default-Landscape.png */, + 308D05331370CCF300D202BF /* Default-Portrait.png */, + 308D05341370CCF300D202BF /* Default.png */, + 308D05351370CCF300D202BF /* Default@2x.png */, + ); + name = splash; + path = Resources/splash; + sourceTree = ""; + }; + 98B602E2144F0C4200E746E6 /* NativeControls */ = { + isa = PBXGroup; + children = ( + 98B602E3144F0C4200E746E6 /* NativeControls.h */, + 98B602E4144F0C4200E746E6 /* NativeControls.js */, + 98B602E5144F0C4200E746E6 /* NativeControls.m */, + ); + path = NativeControls; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* Wolne Lektury */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Wolne Lektury" */; + buildPhases = ( + 304B58A110DAC018002A0835 /* Touch www folder */, + 1D60588D0D05DD3D006BFB54 /* Resources */, + 98DF3300144EE25A001381F0 /* CopyFiles */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + 98DF3307144EE28A001381F0 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 301BF551109A68C00062928A /* PBXTargetDependency */, + ); + name = "Wolne Lektury"; + productName = "wl-mobi"; + productReference = 1D6058910D05DD3D006BFB54 /* Wolne Lektury.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Wolne Lektury" */; + compatibilityVersion = "Xcode 3.1"; + developmentRegion = English; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + es, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 301BF52E109A57CC0062928A /* Products */; + ProjectRef = 301BF52D109A57CC0062928A /* PhoneGapLib.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* Wolne Lektury */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + 301BF535109A57CC0062928A /* libPhoneGap.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libPhoneGap.a; + remoteRef = 301BF534109A57CC0062928A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 30E47BC3136F595F00DBB853 /* PhoneGap.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = PhoneGap.framework; + remoteRef = 30E47BC2136F595F00DBB853 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + 9879B551144ED51F0012352D /* PhoneGapLibTests.octest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = PhoneGapLibTests.octest; + remoteRef = 9879B550144ED51F0012352D /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3053AC6F109B7857006FCFE7 /* VERSION in Resources */, + 30E1352710E2C1420031B30D /* PhoneGap.plist in Resources */, + 307D28A2123043360040C0FA /* PhoneGapBuildSettings.xcconfig in Resources */, + 308D05371370CCF300D202BF /* icon-72.png in Resources */, + 308D05381370CCF300D202BF /* icon.png in Resources */, + 308D05391370CCF300D202BF /* icon@2x.png in Resources */, + 308D053A1370CCF300D202BF /* Default-Landscape.png in Resources */, + 308D053B1370CCF300D202BF /* Default-Portrait.png in Resources */, + 308D053C1370CCF300D202BF /* Default.png in Resources */, + 308D053D1370CCF300D202BF /* Default@2x.png in Resources */, + 98DF3370144EE40D001381F0 /* www in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 304B58A110DAC018002A0835 /* Touch www folder */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Touch www folder"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "touch -cm ${PROJECT_DIR}/www"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* AppDelegate.m in Sources */, + 98B602E6144F0C4200E746E6 /* NativeControls.js in Sources */, + 98B602E7144F0C4200E746E6 /* NativeControls.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 301BF551109A68C00062928A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = PhoneGapLib; + targetProxy = 301BF550109A68C00062928A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "wl_mobi-Prefix.pch"; + INFOPLIST_FILE = "wl_mobi-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + PRODUCT_NAME = "Wolne Lektury"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "wl_mobi-Prefix.pch"; + INFOPLIST_FILE = "wl_mobi-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + PRODUCT_NAME = "Wolne Lektury"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 307D28A1123043350040C0FA /* PhoneGapBuildSettings.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvmgcc42; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak_library", + /usr/lib/libSystem.B.dylib, + "-all_load", + "-Obj-C", + ); + PREBINDING = NO; + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = "\"$(PHONEGAPLIB)/Classes/JSON\" \"$(PHONEGAPLIB)/Classes\""; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 307D28A1123043350040C0FA /* PhoneGapBuildSettings.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_VERSION = com.apple.compilers.llvmgcc42; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 3.0; + OTHER_LDFLAGS = ( + "-weak_framework", + UIKit, + "-weak_framework", + AVFoundation, + "-weak_framework", + CoreMedia, + "-weak_library", + /usr/lib/libSystem.B.dylib, + "-all_load", + "-Obj-C", + ); + PREBINDING = NO; + SDKROOT = iphoneos; + SKIP_INSTALL = NO; + USER_HEADER_SEARCH_PATHS = "\"$(PHONEGAPLIB)/Classes/JSON\" \"$(PHONEGAPLIB)/Classes\""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "Wolne Lektury" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "Wolne Lektury" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/assets/www/css/book_text.css b/assets/www/css/book_text.css deleted file mode 100644 index 9fd9eac..0000000 --- a/assets/www/css/book_text.css +++ /dev/null @@ -1,229 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -#book-text { - font-size: .9em; - line-height: 1.5em; - margin: 0; -} - -#book-text a { - color: blue; - text-decoration: none; -} - -.night-mode #book-text a { - color: #88f; -} - - -/* ================================== */ -/* = Header with logo and menu = */ -/* ================================== */ -#book-text #toc, #themes, #nota_red, #info { - display: none; -} - -/* =================================================== */ -/* = Common elements: headings, paragraphs and lines = */ -/* =================================================== */ -#book-text h1 { - font-size: 2.5em; - margin: 1.5em 0; - text-align: center; - line-height: 1.5em; - font-weight: bold; -} - -#book-text h2 { - font-size: 1.7em; - margin: 1.5em 0 0; - font-weight: bold; - line-height: 1.5em; -} - -#book-text h3 { - font-size: 1.4em; - margin: 1.5em 0 0; - font-weight: normal; - line-height: 1.5em; -} - -#book-text h4 { - font-size: 1em; - margin: 1.5em 0 0; - line-height: 1.5em; -} - -#book-text p { - margin: 0; -} - -/* ======================== */ -/* = Footnotes and themes = */ -/* ======================== */ -#book-text .theme-begin { - display:none; -} - -#book-text .annotation { - font-style: normal; - font-weight: normal; - font-size: 12px; - padding-left: 2px; - position: relative; - top: -4px; -} - -#book-text #footnotes { - margin-top: 3em; -} - -#book-text #footnotes .annotation { - display: block; - float: left; - width: 2.5em; - clear: both; -} - -#book-text #footnotes div { - margin: 1.5em 0 0 0; -} - -#book-text #footnotes p, #footnotes ul { - margin-left: 2.5em; - font-size: 0.875em; -} - -#book-text #footnotes .permalink { - font-size: .75em; -} - -#book-text blockquote { - font-size: 0.875em; - margin: 0 0 0 1em; -} - -/* ============= */ -/* = Numbering = */ -/* ============= */ -#book-text .anchor{display:none;} - -/* =================== */ -/* = Custom elements = */ -/* =================== */ -#book-text span.author { - font-size: 0.5em; - display: block; - line-height: 1.5em; - margin-bottom: 0.25em; -} - -#book-text span.collection { - font-size: 0.375em; - display: block; - line-height: 1.5em; - margin-bottom: -0.25em; -} - -#book-text span.subtitle { - font-size: 0.5em; - display: block; - line-height: 1.5em; - margin-top: -0.25em; -} - -#book-text span.translator { - font-size: 0.375em; - display: block; - line-height: 1.5em; - margin-top: 0.25em; -} - -#book-text div.didaskalia { - font-style: italic; - margin: 0.5em 0 0 1.5em; -} - -#book-text div.kwestia { - margin: 0.5em 0 0; -} - -#book-text div.stanza { - margin: 1.5em 0 0; -} - -#book-text div.kwestia div.stanza { - margin: 0; -} - -#book-text p.paragraph { - text-align: justify; - margin: 1.5em 0 0; -} - -#book-text p.motto { - text-align: justify; - font-style: italic; - margin: 1.5em 0 0; -} - -#book-text p.motto_podpis { - font-size: 0.875em; - text-align: right; -} - -#book-text div.fragment { - border-bottom: 0.1em solid #999; - padding-bottom: 1.5em; -} - -#book-text div.note p, div.dedication p, div.note p.paragraph, div.dedication p.paragraph { - text-align: right; - font-style: italic; -} - -#book-text hr.spacer { - height: 3em; - visibility: hidden; -} - -#book-text hr.spacer-line { - margin: 1.5em 0; - border: none; - border-bottom: 0.1em solid #000; -} - -#book-text p.spacer-asterisk { - padding: 0; - margin: 1.5em 0; - text-align: center; -} - -#book-text div.person-list ol { - list-style: none; - padding: 0 0 0 1.5em; -} - -#book-text p.place-and-time { - font-style: italic; -} - -#book-text em.math, em.foreign-word, em.book-title, em.didaskalia { - font-style: italic; -} - -#book-text em.author-emphasis { - letter-spacing: 0.1em; -} - -#book-text em.person { - font-style: normal; - font-variant: small-caps; -} - -#book-text .verse:after { - content: "\feff"; -} diff --git a/assets/www/css/style.css b/assets/www/css/style.css deleted file mode 100644 index 89dc0c2..0000000 --- a/assets/www/css/style.css +++ /dev/null @@ -1,148 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -body { - padding: 0; - margin: 0; - background: white; - font-family: verdana, arial, helvetica, sans-serif; -} - -.night-mode, .night-mode #search { - color: #ddd; - background: #222; -} -.night-mode a { - color: #fff; -} - -.spinner { - margin-top: 4em; - text-align: center; -} -@-webkit-keyframes rotate { - from { - -webkit-transform: rotate(0deg); - } - to { - -webkit-transform: rotate(360deg); - } -} -.spinner img { - -webkit-animation-name: rotate; - -webkit-animation-duration: 4s; - -webkit-animation-iteration-count: 10; - -webkit-animation-direction: right; - -webkit-animation-timing-function:linear; -} -#spinnertext { - margin-top: 2em; - font-size: .7em; -} - -#cover { - width: 100%; -} - -#searchbox { - font-size: 1.25em; - background: #84bf2a; - padding: 5px; - display: none; -} -#search { - border: none; - width: 100%; - padding: 5px 0 5px 0; -} -#swrap { - margin-right:85px; -} -#searchbutton { - width:80px; - float:right; -} -#content { - padding: 10px; -} -.button { - display: block; - background: #ddd; - font-size: 1.25em; - padding: .5em; - margin-bottom: .5em; - border-radius: 8px; - -webkit-border-radius: 8px; - color: #295158; -} -.button img { - margin-right: .5em; - vertical-align: middle; -} -.button .sub { - font-size: .7em; -} -.button .note { - font-size: .5em; - text-align: right; -} -.button img { - float:left; -} -.button .label { - margin-left: 32px; -} - -.button-Book { - background: #ccc; -} -.button-BookText { - background: #ccc; -} -.delete { - float: right; - width: 24px; - - background: #464646; - font-size: 1.25em; - padding: .5em; - margin-bottom: .5em; - border-radius: 8px; - -webkit-border-radius: 8px; - color: white; - text-align: center; -} - -h1 .subheader { - display:block; - font-size: 70%; -} -.upper { - text-transform: capitalize; -} - - -.footer { - font-size: 0.75em; - text-align: center; -} - -.clr { - clear: both; -} - - -.info dt { - display: inline; - font-weight: bold; -} - -.info dd { - display: inline; - margin: 0; -} -.info img { - max-width: 100%; -} \ No newline at end of file diff --git a/assets/www/img/cc-by-sa.png b/assets/www/img/cc-by-sa.png deleted file mode 100644 index 12c70b6..0000000 Binary files a/assets/www/img/cc-by-sa.png and /dev/null differ diff --git a/assets/www/img/cover.jpg b/assets/www/img/cover.jpg deleted file mode 100644 index 343c352..0000000 Binary files a/assets/www/img/cover.jpg and /dev/null differ diff --git a/assets/www/img/icon-Book.png b/assets/www/img/icon-Book.png deleted file mode 100644 index 3c18284..0000000 Binary files a/assets/www/img/icon-Book.png and /dev/null differ diff --git a/assets/www/img/icon-BookText.png b/assets/www/img/icon-BookText.png deleted file mode 100644 index 60d38ee..0000000 Binary files a/assets/www/img/icon-BookText.png and /dev/null differ diff --git a/assets/www/img/icon-Bookmarks.png b/assets/www/img/icon-Bookmarks.png deleted file mode 100644 index 4cb6b9c..0000000 Binary files a/assets/www/img/icon-Bookmarks.png and /dev/null differ diff --git a/assets/www/img/icon-Last.png b/assets/www/img/icon-Last.png deleted file mode 100644 index 81d1b46..0000000 Binary files a/assets/www/img/icon-Last.png and /dev/null differ diff --git a/assets/www/img/icon-Tag.png b/assets/www/img/icon-Tag.png deleted file mode 100644 index db88d3a..0000000 Binary files a/assets/www/img/icon-Tag.png and /dev/null differ diff --git a/assets/www/img/logo-fnp.png b/assets/www/img/logo-fnp.png deleted file mode 100644 index 8720140..0000000 Binary files a/assets/www/img/logo-fnp.png and /dev/null differ diff --git a/assets/www/img/logo-wl.png b/assets/www/img/logo-wl.png deleted file mode 100644 index a18e950..0000000 Binary files a/assets/www/img/logo-wl.png and /dev/null differ diff --git a/assets/www/img/procent.png b/assets/www/img/procent.png deleted file mode 100644 index 2e0d73e..0000000 Binary files a/assets/www/img/procent.png and /dev/null differ diff --git a/assets/www/img/spinner.png b/assets/www/img/spinner.png deleted file mode 100644 index bad5a12..0000000 Binary files a/assets/www/img/spinner.png and /dev/null differ diff --git a/assets/www/index.html b/assets/www/index.html deleted file mode 100644 index fe6e17c..0000000 --- a/assets/www/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - Wolne Lektury - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - - -
- - \ No newline at end of file diff --git a/assets/www/js/catalogue.js b/assets/www/js/catalogue.js deleted file mode 100644 index 44f8e80..0000000 --- a/assets/www/js/catalogue.js +++ /dev/null @@ -1,375 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -var DB_VER = '0.9.15'; - -var WL_INITIAL = WL + '/media/api/mobile/initial/initial.db'; -var WL_UPDATE = WL + '/api/changes/SINCE.json?book_fields=author,html,parent,parent_number,sort_key,title' + - '&tag_fields=books,category,name,sort_key' + - '&tag_categories=author,epoch,genre,kind'; - - - -var categories = {'author': 'autor', - 'epoch': 'epoka', - 'genre': 'gatunek', - 'kind': 'rodzaj', - 'theme': 'motyw' - } - -// FIXME: htmlescape strings! - - -// for preparing sql statements -// use like: -// var s = new Sql("INSERT ... '{0}', '{1}' ..."; -// s.prepare("abc", ...) -var Sql = function(scheme) { - var self = this; - self.text = scheme; - - self.sql_escape = function(term) { - return term.toString().replace("'", "''"); - }; - - self.prepare = function() { - var args = arguments; - return self.text.replace(/{(\d+)}/g, function(match, number) { - return self.sql_escape(args[parseInt(number)]); - }); - } -}; - - -var Catalogue = new function() { - /* API for database */ - - var self = this; - self.db = null; - - this.init = function(success, error) { - console.log('Catalogue.init'); - - self.updateDB(function() { - self.db = window.openDatabase("wolnelektury", "1.0", "WL Catalogue", 1); - if (self.db) { - /*var regexp = { - onFunctionCall: function(val) { - var re = new RegExp(val.getString(0)); - if (val.getString(1).match(re)) - return 1; - else - return 0; - } - }; - self.db.createFunction("REGEXP", 2, regexp);*/ - - success && success(); - } else { - error && error('Nie mogę otworzyć bazy danych: ' + err); - } - - }, function(err) { - error && error('Błąd migracji: ' + err); - }); - }; - - self.sqlSanitize = function(term) { - return term.toString().replace("'", "''"); - }; - - - /* check if DB needs updating and upload a fresh copy, if so */ - this.updateDB = function(success, error) { - var has_ver = window.localStorage.getItem('db_ver'); - if (has_ver == DB_VER) { - console.log('db ok, skipping') - success && success(); - return; - } - - var done = function() { - FileRepo.clear(); - window.localStorage.setItem('db_ver', DB_VER); - console.log('db updated'); - success && success(); - }; - - // db initialize - // this is Android-specific for now - self.upload_db_android(done, error); - }; - - - this.upload_db_android = function(success, error) { - console.log('upload db for Android 2.x+'); - - var dbname = "wolnelektury"; - var db = window.openDatabase(dbname, "1.0", "WL Catalogue", 500000); - if (db) { - console.log('db created successfully'); - DBPut.fetch(WL_INITIAL, function(data) { - console.log('db fetch successful'); - success && success(); - }, function(data) { - error && error('Błąd podczas pobierania bazy danych: ' + data); - }); - } else { - error && error('Błąd podczas inicjowania bazy danych: ' + data); - } - }; - - - this.withState = function(callback) { - self.db.transaction(function(tx) { - tx.executeSql("SELECT * FROM state", [], - function(tx, results) { - if (results.rows.length) { - callback(results.rows.item(0)); - } - else { - callback({last_checked: 0}); - } - }); - }); - }; - - - this.withBook = function(id, callback, error) { - console.log('withBook '+id) - self.db.transaction(function(tx) { - tx.executeSql("SELECT * FROM book WHERE id="+id, [], - function(tx, results) { - if (results.rows.length) { - callback(results.rows.item(0)); - } - else { - error && error(); - } - }); - }); - }; - - this.withBooks = function(ids, callback) { - console.log('withBooks ' + ids) - self.db.transaction(function(tx) { - tx.executeSql("SELECT * FROM book WHERE id IN ("+ids+") ORDER BY sort_key", [], - function(tx, results) { - var items = []; - var count = results.rows.length; - for (var i=0; i 0) { - var url = self.viewStack.pop(); - console.log('History.goBack: ' + url); - View.enter(url); - } - else { - console.log('History: exiting'); - navigator.app.exitApp(); - } - }; - - - self.lastRead = function() { - var last_read = window.localStorage.getItem('History.last_ids'); - try { - return last_read.split(';'); - } catch (err) { - return []; - } - }; - - self.addRead = function(id, offset) { - id = "" + id; // this should check if int - console.log("History.addRead: " + id); - var last_read = self.lastRead(); - var lastly = last_read.indexOf(id); - if (lastly != -1) { - last_read.splice(lastly, 1); - } - while (last_read.length >= 10) { - last_read.pop(); - } - last_read.unshift(id); - window.localStorage.setItem('History.last_ids', last_read.join(';')); - } - - - self.bookmarks = function() { - var bookmarks = window.localStorage.getItem('History.bookmarks'); - try { - return JSON.parse(bookmarks) || []; - } catch (err) { - return []; - } - }; - - self.addBookmark = function(name) { - var id=(new Date).getTime(); - console.log("History.addBookmark: " + id); - - var bms = self.bookmarks(); - bms.unshift({ - id: id, - name: name, - title: View.currentTitle, - view: View.currentView, - par: View.currentPar, - offset: currentOffset() - }); - window.localStorage.setItem('History.bookmarks', JSON.stringify(bms)); - } - - self.deleteBookmark = function(id) { - console.log("History.deleteBookmark: " + id); - var bms = self.bookmarks(); - for (b in bms) { - if (bms[b].id == id) { - bms.splice(b, 1); - } - } - window.localStorage.setItem('History.bookmarks', JSON.stringify(bms)); - View.onBookmarkChange(); - } -} diff --git a/assets/www/js/links.js b/assets/www/js/links.js deleted file mode 100644 index 3a7465a..0000000 --- a/assets/www/js/links.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -var Links = new function() { - var self = this; - - self.href = function(view, par) { - return view+"/"+par; - }; - - self.button = function(view, par, text, offset) { - offset = offset || 0; - var html = "
"; - icon = view; - if (icon != 'Book' && icon != 'Bookmarks' && icon != 'BookText' && - icon != 'Last' && icon != 'Tag') { - icon = 'Tag'; - } - html += ""; - html += "
" + text + "
"; - html += "
"; - html += "
\n"; - return html; - }; - - self.bookLink = function(book) { - var target = 'Book'; - var note = ''; - - if (book.html_file) { - // this assumes that either book has a html XOR it has children - target = 'BookText'; - note = "
"; - if (book._local) - note += 'Pobrane'; - else { - note += book.pretty_size; - } - note += "
"; - } - - return self.button(target, book.id, - "
" + book.authors + "
" + - book.title + note); - }; - - self.deleteButton = function(id) { - return "
x
"; - }; -} diff --git a/assets/www/js/main.js b/assets/www/js/main.js deleted file mode 100644 index f3a1eee..0000000 --- a/assets/www/js/main.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -var WL = 'http://www.wolnelektury.pl'; - - -// disable debugging -console.log = function(text) {}; - - -function onLoad() { - console.log('onLoad'); - document.addEventListener("deviceready", onDeviceReady, false); -} - -function onDeviceReady() { - console.log('onDeviceReady'); - var error = function(err) { alert(err); }; - - FileRepo.init(function() { - console.log('after FileRepo.init'); - Catalogue.init(function() { - console.log('after catalogue.init'); - History.init(function() { - console.log('after history.init'); - View.init(function() { - Menu.init(function() { - Catalogue.sync(function() { - Catalogue.updateLocal(); - }, error); - }, error); - }, error); - }, error); - }, error); - }); -} - - -var currentOffset = function() { - var scr = document.body.scrollTop; - var h = document.getElementById('nothing').offsetTop; - return scr/h;document.getElementById('nothing') -}; - -var setOffset = function(offset) { - var h = document.getElementById('nothing').offsetTop; - scroll(0, h*offset); -}; - - -var prettySize = function(size) { - if (!size) return ""; - var units = ['B', 'KiB', 'MiB', 'GiB']; - size = size; - var unit = units.shift(); - while (size > 1000 && units.length) { - size /= 1024; - unit = units.shift(); - } - if (size < 10) { - return Math.round(size*10)/10 + ' ' + unit; - } - return Math.round(size) + ' ' + unit; -}; diff --git a/assets/www/js/menu.js b/assets/www/js/menu.js deleted file mode 100644 index 9fea371..0000000 --- a/assets/www/js/menu.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -var Menu = new function() { - var self = this; - var infoView = "ProjectInfo"; - - self.init = function() { - window.MenuInterface.setNightMode(View.getNightMode()); - }; - - self.start = function() { - History.visit(''); - }; - - self.info = function() { - History.visit(self.infoView + '/' + View.currentPar); - }; - - self.bookmark = function() { - var name = prompt('Nazwa zakładki'); - if (name != null) - History.addBookmark(name); - }; - - self.toggleNightMode = function() { - View.toggleNightMode(); - window.MenuInterface.setNightMode(View.getNightMode()); - }; - - self.setInfoButton = function(view, label, enabled) { - self.infoView = view; - window.MenuInterface.setInfoButton(label, enabled); - }; -} diff --git a/assets/www/js/menuinterface.js b/assets/www/js/menuinterface.js deleted file mode 100644 index 596f859..0000000 --- a/assets/www/js/menuinterface.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -/** - * - * @return Object literal singleton instance of MenuInterface - */ -var MenuInterface = { - /** - * @param asset Path to the asset (relative to assets dir) - * @param target Path to DB file (relative to app db files dir) - * @param overwrite - * @param win Success callback - * @param fail Error callback - */ - setInfoButton: function(label, enabled, win, fail) { - if (enabled == false) enabled = "false"; - else enabled = "true"; - return PhoneGap.exec( - win, - fail, - "MenuInterface", - "setInfoButton", - [label, enabled] - ); - }, - setNightMode: function(enabled, win, fail) { - if (enabled == false) enabled = "false"; - else enabled = "true"; - return PhoneGap.exec( - win, - fail, - "MenuInterface", - "setNightMode", - [enabled] - ); - }, -}; - diff --git a/assets/www/js/phonegap-1.0.0.js b/assets/www/js/phonegap-1.0.0.js deleted file mode 100644 index 751c52c..0000000 --- a/assets/www/js/phonegap-1.0.0.js +++ /dev/null @@ -1,4367 +0,0 @@ -/* - * PhoneGap is available under *either* the terms of the modified BSD license *or* the - * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. - * - * Copyright (c) 2005-2010, Nitobi Software Inc. - * Copyright (c) 2010-2011, IBM Corporation - */ - -if (typeof PhoneGap === "undefined") { - -/** - * The order of events during page load and PhoneGap startup is as follows: - * - * onDOMContentLoaded Internal event that is received when the web page is loaded and parsed. - * window.onload Body onload event. - * onNativeReady Internal event that indicates the PhoneGap native side is ready. - * onPhoneGapInit Internal event that kicks off creation of all PhoneGap JavaScript objects (runs constructors). - * onPhoneGapReady Internal event fired when all PhoneGap JavaScript objects have been created - * onPhoneGapInfoReady Internal event fired when device properties are available - * onDeviceReady User event fired to indicate that PhoneGap is ready - * onResume User event fired to indicate a start/resume lifecycle event - * onPause User event fired to indicate a pause lifecycle event - * onDestroy Internal event fired when app is being destroyed (User should use window.onunload event, not this one). - * - * The only PhoneGap events that user code should register for are: - * onDeviceReady - * onResume - * - * Listeners can be registered as: - * document.addEventListener("deviceready", myDeviceReadyListener, false); - * document.addEventListener("resume", myResumeListener, false); - * document.addEventListener("pause", myPauseListener, false); - */ - -if (typeof(DeviceInfo) !== 'object') { - var DeviceInfo = {}; -} - -/** - * This represents the PhoneGap API itself, and provides a global namespace for accessing - * information about the state of PhoneGap. - * @class - */ -var PhoneGap = { - queue: { - ready: true, - commands: [], - timer: null - } -}; - -/** - * List of resource files loaded by PhoneGap. - * This is used to ensure JS and other files are loaded only once. - */ -PhoneGap.resources = {base: true}; - -/** - * Determine if resource has been loaded by PhoneGap - * - * @param name - * @return - */ -PhoneGap.hasResource = function(name) { - return PhoneGap.resources[name]; -}; - -/** - * Add a resource to list of loaded resources by PhoneGap - * - * @param name - */ -PhoneGap.addResource = function(name) { - PhoneGap.resources[name] = true; -}; - -/** - * Custom pub-sub channel that can have functions subscribed to it - * @constructor - */ -PhoneGap.Channel = function (type) -{ - this.type = type; - this.handlers = {}; - this.guid = 0; - this.fired = false; - this.enabled = true; -}; - -/** - * Subscribes the given function to the channel. Any time that - * Channel.fire is called so too will the function. - * Optionally specify an execution context for the function - * and a guid that can be used to stop subscribing to the channel. - * Returns the guid. - */ -PhoneGap.Channel.prototype.subscribe = function(f, c, g) { - // need a function to call - if (f === null) { return; } - - var func = f; - if (typeof c === "object" && typeof f === "function") { func = PhoneGap.close(c, f); } - - g = g || func.observer_guid || f.observer_guid || this.guid++; - func.observer_guid = g; - f.observer_guid = g; - this.handlers[g] = func; - return g; -}; - -/** - * Like subscribe but the function is only called once and then it - * auto-unsubscribes itself. - */ -PhoneGap.Channel.prototype.subscribeOnce = function(f, c) { - var g = null; - var _this = this; - var m = function() { - f.apply(c || null, arguments); - _this.unsubscribe(g); - }; - if (this.fired) { - if (typeof c === "object" && typeof f === "function") { f = PhoneGap.close(c, f); } - f.apply(this, this.fireArgs); - } else { - g = this.subscribe(m); - } - return g; -}; - -/** - * Unsubscribes the function with the given guid from the channel. - */ -PhoneGap.Channel.prototype.unsubscribe = function(g) { - if (typeof g === "function") { g = g.observer_guid; } - this.handlers[g] = null; - delete this.handlers[g]; -}; - -/** - * Calls all functions subscribed to this channel. - */ -PhoneGap.Channel.prototype.fire = function(e) { - if (this.enabled) { - var fail = false; - var item, handler, rv; - for (item in this.handlers) { - if (this.handlers.hasOwnProperty(item)) { - handler = this.handlers[item]; - if (typeof handler === "function") { - rv = (handler.apply(this, arguments) === false); - fail = fail || rv; - } - } - } - this.fired = true; - this.fireArgs = arguments; - return !fail; - } - return true; -}; - -/** - * Calls the provided function only after all of the channels specified - * have been fired. - */ -PhoneGap.Channel.join = function(h, c) { - var i = c.length; - var f = function() { - if (!(--i)) { - h(); - } - }; - var len = i; - var j; - for (j=0; j - * - * @param name The plugin name - * @param obj The plugin object - */ -PhoneGap.addPlugin = function(name, obj) { - if (!window.plugins[name]) { - window.plugins[name] = obj; - } - else { - console.log("Error: Plugin "+name+" already exists."); - } -}; - -/** - * onDOMContentLoaded channel is fired when the DOM content - * of the page has been parsed. - */ -PhoneGap.onDOMContentLoaded = new PhoneGap.Channel('onDOMContentLoaded'); - -/** - * onNativeReady channel is fired when the PhoneGap native code - * has been initialized. - */ -PhoneGap.onNativeReady = new PhoneGap.Channel('onNativeReady'); - -/** - * onPhoneGapInit channel is fired when the web page is fully loaded and - * PhoneGap native code has been initialized. - */ -PhoneGap.onPhoneGapInit = new PhoneGap.Channel('onPhoneGapInit'); - -/** - * onPhoneGapReady channel is fired when the JS PhoneGap objects have been created. - */ -PhoneGap.onPhoneGapReady = new PhoneGap.Channel('onPhoneGapReady'); - -/** - * onPhoneGapInfoReady channel is fired when the PhoneGap device properties - * has been set. - */ -PhoneGap.onPhoneGapInfoReady = new PhoneGap.Channel('onPhoneGapInfoReady'); - -/** - * onPhoneGapConnectionReady channel is fired when the PhoneGap connection properties - * has been set. - */ -PhoneGap.onPhoneGapConnectionReady = new PhoneGap.Channel('onPhoneGapConnectionReady'); - -/** - * onResume channel is fired when the PhoneGap native code - * resumes. - */ -PhoneGap.onResume = new PhoneGap.Channel('onResume'); - -/** - * onPause channel is fired when the PhoneGap native code - * pauses. - */ -PhoneGap.onPause = new PhoneGap.Channel('onPause'); - -/** - * onDestroy channel is fired when the PhoneGap native code - * is destroyed. It is used internally. - * Window.onunload should be used by the user. - */ -PhoneGap.onDestroy = new PhoneGap.Channel('onDestroy'); -PhoneGap.onDestroy.subscribeOnce(function() { - PhoneGap.shuttingDown = true; -}); -PhoneGap.shuttingDown = false; - -// _nativeReady is global variable that the native side can set -// to signify that the native code is ready. It is a global since -// it may be called before any PhoneGap JS is ready. -if (typeof _nativeReady !== 'undefined') { PhoneGap.onNativeReady.fire(); } - -/** - * onDeviceReady is fired only after all PhoneGap objects are created and - * the device properties are set. - */ -PhoneGap.onDeviceReady = new PhoneGap.Channel('onDeviceReady'); - - -// Array of channels that must fire before "deviceready" is fired -PhoneGap.deviceReadyChannelsArray = [ PhoneGap.onPhoneGapReady, PhoneGap.onPhoneGapInfoReady, PhoneGap.onPhoneGapConnectionReady]; - -// Hashtable of user defined channels that must also fire before "deviceready" is fired -PhoneGap.deviceReadyChannelsMap = {}; - -/** - * Indicate that a feature needs to be initialized before it is ready to be used. - * This holds up PhoneGap's "deviceready" event until the feature has been initialized - * and PhoneGap.initComplete(feature) is called. - * - * @param feature {String} The unique feature name - */ -PhoneGap.waitForInitialization = function(feature) { - if (feature) { - var channel = new PhoneGap.Channel(feature); - PhoneGap.deviceReadyChannelsMap[feature] = channel; - PhoneGap.deviceReadyChannelsArray.push(channel); - } -}; - -/** - * Indicate that initialization code has completed and the feature is ready to be used. - * - * @param feature {String} The unique feature name - */ -PhoneGap.initializationComplete = function(feature) { - var channel = PhoneGap.deviceReadyChannelsMap[feature]; - if (channel) { - channel.fire(); - } -}; - -/** - * Create all PhoneGap objects once page has fully loaded and native side is ready. - */ -PhoneGap.Channel.join(function() { - - // Start listening for XHR callbacks - setTimeout(function() { - if (PhoneGap.UsePolling) { - PhoneGap.JSCallbackPolling(); - } - else { - var polling = prompt("usePolling", "gap_callbackServer:"); - PhoneGap.UsePolling = polling; - if (polling == "true") { - PhoneGap.UsePolling = true; - PhoneGap.JSCallbackPolling(); - } - else { - PhoneGap.UsePolling = false; - PhoneGap.JSCallback(); - } - } - }, 1); - - // Run PhoneGap constructors - PhoneGap.onPhoneGapInit.fire(); - - // Fire event to notify that all objects are created - PhoneGap.onPhoneGapReady.fire(); - - // Fire onDeviceReady event once all constructors have run and PhoneGap info has been - // received from native side, and any user defined initialization channels. - PhoneGap.Channel.join(function() { - PhoneGap.onDeviceReady.fire(); - - // Fire the onresume event, since first one happens before JavaScript is loaded - PhoneGap.onResume.fire(); - }, PhoneGap.deviceReadyChannelsArray); - -}, [ PhoneGap.onDOMContentLoaded, PhoneGap.onNativeReady ]); - -// Listen for DOMContentLoaded and notify our channel subscribers -document.addEventListener('DOMContentLoaded', function() { - PhoneGap.onDOMContentLoaded.fire(); -}, false); - -// Intercept calls to document.addEventListener and watch for deviceready -PhoneGap.m_document_addEventListener = document.addEventListener; - -document.addEventListener = function(evt, handler, capture) { - var e = evt.toLowerCase(); - if (e === 'deviceready') { - PhoneGap.onDeviceReady.subscribeOnce(handler); - } else if (e === 'resume') { - PhoneGap.onResume.subscribe(handler); - if (PhoneGap.onDeviceReady.fired) { - PhoneGap.onResume.fire(); - } - } else if (e === 'pause') { - PhoneGap.onPause.subscribe(handler); - } - else { - // If subscribing to Android backbutton - if (e === 'backbutton') { - PhoneGap.exec(null, null, "App", "overrideBackbutton", [true]); - } - - PhoneGap.m_document_addEventListener.call(document, evt, handler, capture); - } -}; - -// Intercept calls to document.removeEventListener and watch for events that -// are generated by PhoneGap native code -PhoneGap.m_document_removeEventListener = document.removeEventListener; - -document.removeEventListener = function(evt, handler, capture) { - var e = evt.toLowerCase(); - - // If unsubscribing to Android backbutton - if (e === 'backbutton') { - PhoneGap.exec(null, null, "App", "overrideBackbutton", [false]); - } - - PhoneGap.m_document_removeEventListener.call(document, evt, handler, capture); -}; - -/** - * Method to fire event from native code - */ -PhoneGap.fireEvent = function(type) { - var e = document.createEvent('Events'); - e.initEvent(type); - document.dispatchEvent(e); -}; - -/** - * If JSON not included, use our own stringify. (Android 1.6) - * The restriction on ours is that it must be an array of simple types. - * - * @param args - * @return {String} - */ -PhoneGap.stringify = function(args) { - if (typeof JSON === "undefined") { - var s = "["; - var i, type, start, name, nameType, a; - for (i = 0; i < args.length; i++) { - if (args[i] !== null) { - if (i > 0) { - s = s + ","; - } - type = typeof args[i]; - if ((type === "number") || (type === "boolean")) { - s = s + args[i]; - } else if (args[i] instanceof Array) { - s = s + "[" + args[i] + "]"; - } else if (args[i] instanceof Object) { - start = true; - s = s + '{'; - for (name in args[i]) { - if (args[i][name] !== null) { - if (!start) { - s = s + ','; - } - s = s + '"' + name + '":'; - nameType = typeof args[i][name]; - if ((nameType === "number") || (nameType === "boolean")) { - s = s + args[i][name]; - } else if ((typeof args[i][name]) === 'function') { - // don't copy the functions - s = s + '""'; - } else if (args[i][name] instanceof Object) { - s = s + PhoneGap.stringify(args[i][name]); - } else { - s = s + '"' + args[i][name] + '"'; - } - start = false; - } - } - s = s + '}'; - } else { - a = args[i].replace(/\\/g, '\\\\'); - a = a.replace(/"/g, '\\"'); - s = s + '"' + a + '"'; - } - } - } - s = s + "]"; - return s; - } else { - return JSON.stringify(args); - } -}; - -/** - * Does a deep clone of the object. - * - * @param obj - * @return {Object} - */ -PhoneGap.clone = function(obj) { - var i, retVal; - if(!obj) { - return obj; - } - - if(obj instanceof Array){ - retVal = []; - for(i = 0; i < obj.length; ++i){ - retVal.push(PhoneGap.clone(obj[i])); - } - return retVal; - } - - if (typeof obj === "function") { - return obj; - } - - if(!(obj instanceof Object)){ - return obj; - } - - if (obj instanceof Date) { - return obj; - } - - retVal = {}; - for(i in obj){ - if(!(i in retVal) || retVal[i] !== obj[i]) { - retVal[i] = PhoneGap.clone(obj[i]); - } - } - return retVal; -}; - -PhoneGap.callbackId = 0; -PhoneGap.callbacks = {}; -PhoneGap.callbackStatus = { - NO_RESULT: 0, - OK: 1, - CLASS_NOT_FOUND_EXCEPTION: 2, - ILLEGAL_ACCESS_EXCEPTION: 3, - INSTANTIATION_EXCEPTION: 4, - MALFORMED_URL_EXCEPTION: 5, - IO_EXCEPTION: 6, - INVALID_ACTION: 7, - JSON_EXCEPTION: 8, - ERROR: 9 - }; - - -/** - * Execute a PhoneGap command. It is up to the native side whether this action is synch or async. - * The native side can return: - * Synchronous: PluginResult object as a JSON string - * Asynchrounous: Empty string "" - * If async, the native side will PhoneGap.callbackSuccess or PhoneGap.callbackError, - * depending upon the result of the action. - * - * @param {Function} success The success callback - * @param {Function} fail The fail callback - * @param {String} service The name of the service to use - * @param {String} action Action to be run in PhoneGap - * @param {Array.} [args] Zero or more arguments to pass to the method - */ -PhoneGap.exec = function(success, fail, service, action, args) { - try { - var callbackId = service + PhoneGap.callbackId++; - if (success || fail) { - PhoneGap.callbacks[callbackId] = {success:success, fail:fail}; - } - - var r = prompt(PhoneGap.stringify(args), "gap:"+PhoneGap.stringify([service, action, callbackId, true])); - - // If a result was returned - if (r.length > 0) { - eval("var v="+r+";"); - - // If status is OK, then return value back to caller - if (v.status === PhoneGap.callbackStatus.OK) { - - // If there is a success callback, then call it now with - // returned value - if (success) { - try { - success(v.message); - } catch (e) { - console.log("Error in success callback: " + callbackId + " = " + e); - } - - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete PhoneGap.callbacks[callbackId]; - } - } - return v.message; - } - - // If no result - else if (v.status === PhoneGap.callbackStatus.NO_RESULT) { - - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete PhoneGap.callbacks[callbackId]; - } - } - - // If error, then display error - else { - console.log("Error: Status="+v.status+" Message="+v.message); - - // If there is a fail callback, then call it now with returned value - if (fail) { - try { - fail(v.message); - } - catch (e1) { - console.log("Error in error callback: "+callbackId+" = "+e1); - } - - // Clear callback if not expecting any more results - if (!v.keepCallback) { - delete PhoneGap.callbacks[callbackId]; - } - } - return null; - } - } - } catch (e2) { - console.log("Error: "+e2); - } -}; - -/** - * Called by native code when returning successful result from an action. - * - * @param callbackId - * @param args - */ -PhoneGap.callbackSuccess = function(callbackId, args) { - if (PhoneGap.callbacks[callbackId]) { - - // If result is to be sent to callback - if (args.status === PhoneGap.callbackStatus.OK) { - try { - if (PhoneGap.callbacks[callbackId].success) { - PhoneGap.callbacks[callbackId].success(args.message); - } - } - catch (e) { - console.log("Error in success callback: "+callbackId+" = "+e); - } - } - - // Clear callback if not expecting any more results - if (!args.keepCallback) { - delete PhoneGap.callbacks[callbackId]; - } - } -}; - -/** - * Called by native code when returning error result from an action. - * - * @param callbackId - * @param args - */ -PhoneGap.callbackError = function(callbackId, args) { - if (PhoneGap.callbacks[callbackId]) { - try { - if (PhoneGap.callbacks[callbackId].fail) { - PhoneGap.callbacks[callbackId].fail(args.message); - } - } - catch (e) { - console.log("Error in error callback: "+callbackId+" = "+e); - } - - // Clear callback if not expecting any more results - if (!args.keepCallback) { - delete PhoneGap.callbacks[callbackId]; - } - } -}; - - -/** - * Internal function used to dispatch the request to PhoneGap. It processes the - * command queue and executes the next command on the list. If one of the - * arguments is a JavaScript object, it will be passed on the QueryString of the - * url, which will be turned into a dictionary on the other end. - * @private - */ -// TODO: Is this used? -PhoneGap.run_command = function() { - if (!PhoneGap.available || !PhoneGap.queue.ready) { - return; - } - PhoneGap.queue.ready = false; - - var args = PhoneGap.queue.commands.shift(); - if (PhoneGap.queue.commands.length === 0) { - clearInterval(PhoneGap.queue.timer); - PhoneGap.queue.timer = null; - } - - var uri = []; - var dict = null; - var i; - for (i = 1; i < args.length; i++) { - var arg = args[i]; - if (arg === undefined || arg === null) { - arg = ''; - } - if (typeof(arg) === 'object') { - dict = arg; - } else { - uri.push(encodeURIComponent(arg)); - } - } - var url = "gap://" + args[0] + "/" + uri.join("/"); - if (dict !== null) { - var name; - var query_args = []; - for (name in dict) { - if (dict.hasOwnProperty(name) && (typeof (name) === 'string')) { - query_args.push(encodeURIComponent(name) + "=" + encodeURIComponent(dict[name])); - } - } - if (query_args.length > 0) { - url += "?" + query_args.join("&"); - } - } - document.location = url; - -}; - -PhoneGap.JSCallbackPort = null; -PhoneGap.JSCallbackToken = null; - -/** - * This is only for Android. - * - * Internal function that uses XHR to call into PhoneGap Java code and retrieve - * any JavaScript code that needs to be run. This is used for callbacks from - * Java to JavaScript. - */ -PhoneGap.JSCallback = function() { - - // Exit if shutting down app - if (PhoneGap.shuttingDown) { - return; - } - - // If polling flag was changed, start using polling from now on - if (PhoneGap.UsePolling) { - PhoneGap.JSCallbackPolling(); - return; - } - - var xmlhttp = new XMLHttpRequest(); - - // Callback function when XMLHttpRequest is ready - xmlhttp.onreadystatechange=function(){ - if(xmlhttp.readyState === 4){ - - // Exit if shutting down app - if (PhoneGap.shuttingDown) { - return; - } - - // If callback has JavaScript statement to execute - if (xmlhttp.status === 200) { - - // Need to url decode the response - var msg = decodeURIComponent(xmlhttp.responseText); - setTimeout(function() { - try { - var t = eval(msg); - } - catch (e) { - // If we're getting an error here, seeing the message will help in debugging - console.log("JSCallback: Message from Server: " + msg); - console.log("JSCallback Error: "+e); - } - }, 1); - setTimeout(PhoneGap.JSCallback, 1); - } - - // If callback ping (used to keep XHR request from timing out) - else if (xmlhttp.status === 404) { - setTimeout(PhoneGap.JSCallback, 10); - } - - // If security error - else if (xmlhttp.status === 403) { - console.log("JSCallback Error: Invalid token. Stopping callbacks."); - } - - // If server is stopping - else if (xmlhttp.status === 503) { - console.log("JSCallback Error: Service unavailable. Stopping callbacks."); - } - - // If request wasn't GET - else if (xmlhttp.status === 400) { - console.log("JSCallback Error: Bad request. Stopping callbacks."); - } - - // If error, revert to polling - else { - console.log("JSCallback Error: Request failed."); - PhoneGap.UsePolling = true; - PhoneGap.JSCallbackPolling(); - } - } - }; - - if (PhoneGap.JSCallbackPort === null) { - PhoneGap.JSCallbackPort = prompt("getPort", "gap_callbackServer:"); - } - if (PhoneGap.JSCallbackToken === null) { - PhoneGap.JSCallbackToken = prompt("getToken", "gap_callbackServer:"); - } - xmlhttp.open("GET", "http://127.0.0.1:"+PhoneGap.JSCallbackPort+"/"+PhoneGap.JSCallbackToken , true); - xmlhttp.send(); -}; - -/** - * The polling period to use with JSCallbackPolling. - * This can be changed by the application. The default is 50ms. - */ -PhoneGap.JSCallbackPollingPeriod = 50; - -/** - * Flag that can be set by the user to force polling to be used or force XHR to be used. - */ -PhoneGap.UsePolling = false; // T=use polling, F=use XHR - -/** - * This is only for Android. - * - * Internal function that uses polling to call into PhoneGap Java code and retrieve - * any JavaScript code that needs to be run. This is used for callbacks from - * Java to JavaScript. - */ -PhoneGap.JSCallbackPolling = function() { - - // Exit if shutting down app - if (PhoneGap.shuttingDown) { - return; - } - - // If polling flag was changed, stop using polling from now on - if (!PhoneGap.UsePolling) { - PhoneGap.JSCallback(); - return; - } - - var msg = prompt("", "gap_poll:"); - if (msg) { - setTimeout(function() { - try { - var t = eval(""+msg); - } - catch (e) { - console.log("JSCallbackPolling: Message from Server: " + msg); - console.log("JSCallbackPolling Error: "+e); - } - }, 1); - setTimeout(PhoneGap.JSCallbackPolling, 1); - } - else { - setTimeout(PhoneGap.JSCallbackPolling, PhoneGap.JSCallbackPollingPeriod); - } -}; - -/** - * Create a UUID - * - * @return {String} - */ -PhoneGap.createUUID = function() { - return PhoneGap.UUIDcreatePart(4) + '-' + - PhoneGap.UUIDcreatePart(2) + '-' + - PhoneGap.UUIDcreatePart(2) + '-' + - PhoneGap.UUIDcreatePart(2) + '-' + - PhoneGap.UUIDcreatePart(6); -}; - -PhoneGap.UUIDcreatePart = function(length) { - var uuidpart = ""; - var i, uuidchar; - for (i=0; i frequency + 10 sec - PhoneGap.exec( - function(timeout) { - if (timeout < (frequency + 10000)) { - PhoneGap.exec(null, null, "Accelerometer", "setTimeout", [frequency + 10000]); - } - }, - function(e) { }, "Accelerometer", "getTimeout", []); - - // Start watch timer - var id = PhoneGap.createUUID(); - navigator.accelerometer.timers[id] = setInterval(function() { - PhoneGap.exec(successCallback, errorCallback, "Accelerometer", "getAcceleration", []); - }, (frequency ? frequency : 1)); - - return id; -}; - -/** - * Clears the specified accelerometer watch. - * - * @param {String} id The id of the watch returned from #watchAcceleration. - */ -Accelerometer.prototype.clearWatch = function(id) { - - // Stop javascript timer & remove from timer list - if (id && navigator.accelerometer.timers[id] !== undefined) { - clearInterval(navigator.accelerometer.timers[id]); - delete navigator.accelerometer.timers[id]; - } -}; - -PhoneGap.addConstructor(function() { - if (typeof navigator.accelerometer === "undefined") { - navigator.accelerometer = new Accelerometer(); - } -}); -} - - -/* - * PhoneGap is available under *either* the terms of the modified BSD license *or* the - * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. - * - * Copyright (c) 2005-2010, Nitobi Software Inc. - * Copyright (c) 2010-2011, IBM Corporation - */ - -if (!PhoneGap.hasResource("app")) { -PhoneGap.addResource("app"); -(function() { - -/** - * Constructor - * @constructor - */ -var App = function() {}; - -/** - * Clear the resource cache. - */ -App.prototype.clearCache = function() { - PhoneGap.exec(null, null, "App", "clearCache", []); -}; - -/** - * Load the url into the webview. - * - * @param url The URL to load - * @param props Properties that can be passed in to the activity: - * wait: int => wait msec before loading URL - * loadingDialog: "Title,Message" => display a native loading dialog - * hideLoadingDialogOnPage: boolean => hide loadingDialog when page loaded instead of when deviceready event occurs. - * loadInWebView: boolean => cause all links on web page to be loaded into existing web view, instead of being loaded into new browser. - * loadUrlTimeoutValue: int => time in msec to wait before triggering a timeout error - * errorUrl: URL => URL to load if there's an error loading specified URL with loadUrl(). Should be a local URL such as file:///android_asset/www/error.html"); - * keepRunning: boolean => enable app to keep running in background - * - * Example: - * App app = new App(); - * app.loadUrl("http://server/myapp/index.html", {wait:2000, loadingDialog:"Wait,Loading App", loadUrlTimeoutValue: 60000}); - */ -App.prototype.loadUrl = function(url, props) { - PhoneGap.exec(null, null, "App", "loadUrl", [url, props]); -}; - -/** - * Cancel loadUrl that is waiting to be loaded. - */ -App.prototype.cancelLoadUrl = function() { - PhoneGap.exec(null, null, "App", "cancelLoadUrl", []); -}; - -/** - * Clear web history in this web view. - * Instead of BACK button loading the previous web page, it will exit the app. - */ -App.prototype.clearHistory = function() { - PhoneGap.exec(null, null, "App", "clearHistory", []); -}; - -/** - * Override the default behavior of the Android back button. - * If overridden, when the back button is pressed, the "backKeyDown" JavaScript event will be fired. - * - * Note: The user should not have to call this method. Instead, when the user - * registers for the "backbutton" event, this is automatically done. - * - * @param override T=override, F=cancel override - */ -App.prototype.overrideBackbutton = function(override) { - PhoneGap.exec(null, null, "App", "overrideBackbutton", [override]); -}; - -/** - * Exit and terminate the application. - */ -App.prototype.exitApp = function() { - return PhoneGap.exec(null, null, "App", "exitApp", []); -}; - -PhoneGap.addConstructor(function() { - navigator.app = new App(); -}); -}()); -} - - -/* - * PhoneGap is available under *either* the terms of the modified BSD license *or* the - * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. - * - * Copyright (c) 2005-2010, Nitobi Software Inc. - * Copyright (c) 2010-2011, IBM Corporation - */ - -if (!PhoneGap.hasResource("camera")) { -PhoneGap.addResource("camera"); - -/** - * This class provides access to the device camera. - * - * @constructor - */ -var Camera = function() { - this.successCallback = null; - this.errorCallback = null; - this.options = null; -}; - -/** - * Format of image that returned from getPicture. - * - * Example: navigator.camera.getPicture(success, fail, - * { quality: 80, - * destinationType: Camera.DestinationType.DATA_URL, - * sourceType: Camera.PictureSourceType.PHOTOLIBRARY}) - */ -Camera.DestinationType = { - DATA_URL: 0, // Return base64 encoded string - FILE_URI: 1 // Return file uri (content://media/external/images/media/2 for Android) -}; -Camera.prototype.DestinationType = Camera.DestinationType; - -/** - * Encoding of image returned from getPicture. - * - * Example: navigator.camera.getPicture(success, fail, - * { quality: 80, - * destinationType: Camera.DestinationType.DATA_URL, - * sourceType: Camera.PictureSourceType.CAMERA, - * encodingType: Camera.EncodingType.PNG}) -*/ -Camera.EncodingType = { - JPEG: 0, // Return JPEG encoded image - PNG: 1 // Return PNG encoded image -}; -Camera.prototype.EncodingType = Camera.EncodingType; - -/** - * Source to getPicture from. - * - * Example: navigator.camera.getPicture(success, fail, - * { quality: 80, - * destinationType: Camera.DestinationType.DATA_URL, - * sourceType: Camera.PictureSourceType.PHOTOLIBRARY}) - */ -Camera.PictureSourceType = { - PHOTOLIBRARY : 0, // Choose image from picture library (same as SAVEDPHOTOALBUM for Android) - CAMERA : 1, // Take picture from camera - SAVEDPHOTOALBUM : 2 // Choose image from picture library (same as PHOTOLIBRARY for Android) -}; -Camera.prototype.PictureSourceType = Camera.PictureSourceType; - -/** - * Gets a picture from source defined by "options.sourceType", and returns the - * image as defined by the "options.destinationType" option. - - * The defaults are sourceType=CAMERA and destinationType=DATA_URL. - * - * @param {Function} successCallback - * @param {Function} errorCallback - * @param {Object} options - */ -Camera.prototype.getPicture = function(successCallback, errorCallback, options) { - - // successCallback required - if (typeof successCallback !== "function") { - console.log("Camera Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Camera Error: errorCallback is not a function"); - return; - } - - this.options = options; - var quality = 80; - if (options.quality) { - quality = this.options.quality; - } - - var maxResolution = 0; - if (options.maxResolution) { - maxResolution = this.options.maxResolution; - } - - var destinationType = Camera.DestinationType.DATA_URL; - if (this.options.destinationType) { - destinationType = this.options.destinationType; - } - var sourceType = Camera.PictureSourceType.CAMERA; - if (typeof this.options.sourceType === "number") { - sourceType = this.options.sourceType; - } - var encodingType = Camera.EncodingType.JPEG; - if (typeof options.encodingType == "number") { - encodingType = this.options.encodingType; - } - - var targetWidth = -1; - if (typeof options.targetWidth == "number") { - targetWidth = options.targetWidth; - } else if (typeof options.targetWidth == "string") { - var width = new Number(options.targetWidth); - if (isNaN(width) === false) { - targetWidth = width.valueOf(); - } - } - - var targetHeight = -1; - if (typeof options.targetHeight == "number") { - targetHeight = options.targetHeight; - } else if (typeof options.targetHeight == "string") { - var height = new Number(options.targetHeight); - if (isNaN(height) === false) { - targetHeight = height.valueOf(); - } - } - - PhoneGap.exec(successCallback, errorCallback, "Camera", "takePicture", [quality, destinationType, sourceType, targetWidth, targetHeight, encodingType]); -}; - -PhoneGap.addConstructor(function() { - if (typeof navigator.camera === "undefined") { - navigator.camera = new Camera(); - } -}); -} - - -/* - * PhoneGap is available under *either* the terms of the modified BSD license *or* the - * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. - * - * Copyright (c) 2005-2010, Nitobi Software Inc. - * Copyright (c) 2010-2011, IBM Corporation - */ - -if (!PhoneGap.hasResource("capture")) { -PhoneGap.addResource("capture"); - -/** - * Represents a single file. - * - * name {DOMString} name of the file, without path information - * fullPath {DOMString} the full path of the file, including the name - * type {DOMString} mime type - * lastModifiedDate {Date} last modified date - * size {Number} size of the file in bytes - */ -var MediaFile = function(name, fullPath, type, lastModifiedDate, size){ - this.name = name || null; - this.fullPath = fullPath || null; - this.type = type || null; - this.lastModifiedDate = lastModifiedDate || null; - this.size = size || 0; -}; - -/** - * Launch device camera application for recording video(s). - * - * @param {Function} successCB - * @param {Function} errorCB - */ -MediaFile.prototype.getFormatData = function(successCallback, errorCallback){ - PhoneGap.exec(successCallback, errorCallback, "Capture", "getFormatData", [this.fullPath, this.type]); -}; - -/** - * MediaFileData encapsulates format information of a media file. - * - * @param {DOMString} codecs - * @param {long} bitrate - * @param {long} height - * @param {long} width - * @param {float} duration - */ -var MediaFileData = function(codecs, bitrate, height, width, duration){ - this.codecs = codecs || null; - this.bitrate = bitrate || 0; - this.height = height || 0; - this.width = width || 0; - this.duration = duration || 0; -}; - -/** - * The CaptureError interface encapsulates all errors in the Capture API. - */ -var CaptureError = function(){ - this.code = null; -}; - -// Capture error codes -CaptureError.CAPTURE_INTERNAL_ERR = 0; -CaptureError.CAPTURE_APPLICATION_BUSY = 1; -CaptureError.CAPTURE_INVALID_ARGUMENT = 2; -CaptureError.CAPTURE_NO_MEDIA_FILES = 3; -CaptureError.CAPTURE_NOT_SUPPORTED = 20; - -/** - * The Capture interface exposes an interface to the camera and microphone of the hosting device. - */ -var Capture = function(){ - this.supportedAudioModes = []; - this.supportedImageModes = []; - this.supportedVideoModes = []; -}; - -/** - * Launch audio recorder application for recording audio clip(s). - * - * @param {Function} successCB - * @param {Function} errorCB - * @param {CaptureAudioOptions} options - */ -Capture.prototype.captureAudio = function(successCallback, errorCallback, options){ - PhoneGap.exec(successCallback, errorCallback, "Capture", "captureAudio", [options]); -}; - -/** - * Launch camera application for taking image(s). - * - * @param {Function} successCB - * @param {Function} errorCB - * @param {CaptureImageOptions} options - */ -Capture.prototype.captureImage = function(successCallback, errorCallback, options){ - PhoneGap.exec(successCallback, errorCallback, "Capture", "captureImage", [options]); -}; - -/** - * Launch camera application for taking image(s). - * - * @param {Function} successCB - * @param {Function} errorCB - * @param {CaptureImageOptions} options - */ -Capture.prototype._castMediaFile = function(pluginResult){ - var mediaFiles = []; - var i; - for (i = 0; i < pluginResult.message.length; i++) { - var mediaFile = new MediaFile(); - mediaFile.name = pluginResult.message[i].name; - mediaFile.fullPath = pluginResult.message[i].fullPath; - mediaFile.type = pluginResult.message[i].type; - mediaFile.lastModifiedDate = pluginResult.message[i].lastModifiedDate; - mediaFile.size = pluginResult.message[i].size; - mediaFiles.push(mediaFile); - } - pluginResult.message = mediaFiles; - return pluginResult; -}; - -/** - * Launch device camera application for recording video(s). - * - * @param {Function} successCB - * @param {Function} errorCB - * @param {CaptureVideoOptions} options - */ -Capture.prototype.captureVideo = function(successCallback, errorCallback, options){ - PhoneGap.exec(successCallback, errorCallback, "Capture", "captureVideo", [options]); -}; - -/** - * Encapsulates a set of parameters that the capture device supports. - */ -var ConfigurationData = function(){ - // The ASCII-encoded string in lower case representing the media type. - this.type = null; - // The height attribute represents height of the image or video in pixels. - // In the case of a sound clip this attribute has value 0. - this.height = 0; - // The width attribute represents width of the image or video in pixels. - // In the case of a sound clip this attribute has value 0 - this.width = 0; -}; - -/** - * Encapsulates all image capture operation configuration options. - */ -var CaptureImageOptions = function(){ - // Upper limit of images user can take. Value must be equal or greater than 1. - this.limit = 1; - // The selected image mode. Must match with one of the elements in supportedImageModes array. - this.mode = null; -}; - -/** - * Encapsulates all video capture operation configuration options. - */ -var CaptureVideoOptions = function(){ - // Upper limit of videos user can record. Value must be equal or greater than 1. - this.limit = 1; - // Maximum duration of a single video clip in seconds. - this.duration = 0; - // The selected video mode. Must match with one of the elements in supportedVideoModes array. - this.mode = null; -}; - -/** - * Encapsulates all audio capture operation configuration options. - */ -var CaptureAudioOptions = function(){ - // Upper limit of sound clips user can record. Value must be equal or greater than 1. - this.limit = 1; - // Maximum duration of a single sound clip in seconds. - this.duration = 0; - // The selected audio mode. Must match with one of the elements in supportedAudioModes array. - this.mode = null; -}; - -PhoneGap.addConstructor(function(){ - if (typeof navigator.device === "undefined") { - navigator.device = window.device = new Device(); - } - if (typeof navigator.device.capture === "undefined") { - navigator.device.capture = window.device.capture = new Capture(); - } -}); -} - -/* - * PhoneGap is available under *either* the terms of the modified BSD license *or* the - * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. - * - * Copyright (c) 2005-2010, Nitobi Software Inc. - * Copyright (c) 2010-2011, IBM Corporation - */ - -if (!PhoneGap.hasResource("compass")) { -PhoneGap.addResource("compass"); - -/** - * This class provides access to device Compass data. - * @constructor - */ -var Compass = function() { - /** - * The last known Compass position. - */ - this.lastHeading = null; - - /** - * List of compass watch timers - */ - this.timers = {}; -}; - -Compass.ERROR_MSG = ["Not running", "Starting", "", "Failed to start"]; - -/** - * Asynchronously aquires the current heading. - * - * @param {Function} successCallback The function to call when the heading data is available - * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) - * @param {PositionOptions} options The options for getting the heading data such as timeout. (OPTIONAL) - */ -Compass.prototype.getCurrentHeading = function(successCallback, errorCallback, options) { - - // successCallback required - if (typeof successCallback !== "function") { - console.log("Compass Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Compass Error: errorCallback is not a function"); - return; - } - - // Get heading - PhoneGap.exec(successCallback, errorCallback, "Compass", "getHeading", []); -}; - -/** - * Asynchronously aquires the heading repeatedly at a given interval. - * - * @param {Function} successCallback The function to call each time the heading data is available - * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) - * @param {HeadingOptions} options The options for getting the heading data such as timeout and the frequency of the watch. (OPTIONAL) - * @return String The watch id that must be passed to #clearWatch to stop watching. - */ -Compass.prototype.watchHeading= function(successCallback, errorCallback, options) { - - // Default interval (100 msec) - var frequency = (options !== undefined) ? options.frequency : 100; - - // successCallback required - if (typeof successCallback !== "function") { - console.log("Compass Error: successCallback is not a function"); - return; - } - - // errorCallback optional - if (errorCallback && (typeof errorCallback !== "function")) { - console.log("Compass Error: errorCallback is not a function"); - return; - } - - // Make sure compass timeout > frequency + 10 sec - PhoneGap.exec( - function(timeout) { - if (timeout < (frequency + 10000)) { - PhoneGap.exec(null, null, "Compass", "setTimeout", [frequency + 10000]); - } - }, - function(e) { }, "Compass", "getTimeout", []); - - // Start watch timer to get headings - var id = PhoneGap.createUUID(); - navigator.compass.timers[id] = setInterval( - function() { - PhoneGap.exec(successCallback, errorCallback, "Compass", "getHeading", []); - }, (frequency ? frequency : 1)); - - return id; -}; - - -/** - * Clears the specified heading watch. - * - * @param {String} id The ID of the watch returned from #watchHeading. - */ -Compass.prototype.clearWatch = function(id) { - - // Stop javascript timer & remove from timer list - if (id && navigator.compass.timers[id]) { - clearInterval(navigator.compass.timers[id]); - delete navigator.compass.timers[id]; - } -}; - -PhoneGap.addConstructor(function() { - if (typeof navigator.compass === "undefined") { - navigator.compass = new Compass(); - } -}); -} - - -/* - * PhoneGap is available under *either* the terms of the modified BSD license *or* the - * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. - * - * Copyright (c) 2005-2010, Nitobi Software Inc. - * Copyright (c) 2010-2011, IBM Corporation - */ - -if (!PhoneGap.hasResource("contact")) { -PhoneGap.addResource("contact"); - -/** -* Contains information about a single contact. -* @constructor -* @param {DOMString} id unique identifier -* @param {DOMString} displayName -* @param {ContactName} name -* @param {DOMString} nickname -* @param {Array.} phoneNumbers array of phone numbers -* @param {Array.} emails array of email addresses -* @param {Array.} addresses array of addresses -* @param {Array.} ims instant messaging user ids -* @param {Array.} organizations -* @param {DOMString} birthday contact's birthday -* @param {DOMString} note user notes about contact -* @param {Array.} photos -* @param {Array.} categories -* @param {Array.} urls contact's web sites -*/ -var Contact = function (id, displayName, name, nickname, phoneNumbers, emails, addresses, - ims, organizations, birthday, note, photos, categories, urls) { - this.id = id || null; - this.rawId = null; - this.displayName = displayName || null; - this.name = name || null; // ContactName - this.nickname = nickname || null; - this.phoneNumbers = phoneNumbers || null; // ContactField[] - this.emails = emails || null; // ContactField[] - this.addresses = addresses || null; // ContactAddress[] - this.ims = ims || null; // ContactField[] - this.organizations = organizations || null; // ContactOrganization[] - this.birthday = birthday || null; - this.note = note || null; - this.photos = photos || null; // ContactField[] - this.categories = categories || null; // ContactField[] - this.urls = urls || null; // ContactField[] -}; - -/** - * ContactError. - * An error code assigned by an implementation when an error has occurreds - * @constructor - */ -var ContactError = function() { - this.code=null; -}; - -/** - * Error codes - */ -ContactError.UNKNOWN_ERROR = 0; -ContactError.INVALID_ARGUMENT_ERROR = 1; -ContactError.TIMEOUT_ERROR = 2; -ContactError.PENDING_OPERATION_ERROR = 3; -ContactError.IO_ERROR = 4; -ContactError.NOT_SUPPORTED_ERROR = 5; -ContactError.PERMISSION_DENIED_ERROR = 20; - -/** -* Removes contact from device storage. -* @param successCB success callback -* @param errorCB error callback -*/ -Contact.prototype.remove = function(successCB, errorCB) { - if (this.id === null) { - var errorObj = new ContactError(); - errorObj.code = ContactError.UNKNOWN_ERROR; - errorCB(errorObj); - } - else { - PhoneGap.exec(successCB, errorCB, "Contacts", "remove", [this.id]); - } -}; - -/** -* Creates a deep copy of this Contact. -* With the contact ID set to null. -* @return copy of this Contact -*/ -Contact.prototype.clone = function() { - var clonedContact = PhoneGap.clone(this); - var i; - clonedContact.id = null; - clonedContact.rawId = null; - // Loop through and clear out any id's in phones, emails, etc. - if (clonedContact.phoneNumbers) { - for (i = 0; i < clonedContact.phoneNumbers.length; i++) { - clonedContact.phoneNumbers[i].id = null; - } - } - if (clonedContact.emails) { - for (i = 0; i < clonedContact.emails.length; i++) { - clonedContact.emails[i].id = null; - } - } - if (clonedContact.addresses) { - for (i = 0; i < clonedContact.addresses.length; i++) { - clonedContact.addresses[i].id = null; - } - } - if (clonedContact.ims) { - for (i = 0; i < clonedContact.ims.length; i++) { - clonedContact.ims[i].id = null; - } - } - if (clonedContact.organizations) { - for (i = 0; i < clonedContact.organizations.length; i++) { - clonedContact.organizations[i].id = null; - } - } - if (clonedContact.tags) { - for (i = 0; i < clonedContact.tags.length; i++) { - clonedContact.tags[i].id = null; - } - } - if (clonedContact.photos) { - for (i = 0; i < clonedContact.photos.length; i++) { - clonedContact.photos[i].id = null; - } - } - if (clonedContact.urls) { - for (i = 0; i < clonedContact.urls.length; i++) { - clonedContact.urls[i].id = null; - } - } - return clonedContact; -}; - -/** -* Persists contact to device storage. -* @param successCB success callback -* @param errorCB error callback -*/ -Contact.prototype.save = function(successCB, errorCB) { - PhoneGap.exec(successCB, errorCB, "Contacts", "save", [this]); -}; - -/** -* Contact name. -* @constructor -* @param formatted -* @param familyName -* @param givenName -* @param middle -* @param prefix -* @param suffix -*/ -var ContactName = function(formatted, familyName, givenName, middle, prefix, suffix) { - this.formatted = formatted || null; - this.familyName = familyName || null; - this.givenName = givenName || null; - this.middleName = middle || null; - this.honorificPrefix = prefix || null; - this.honorificSuffix = suffix || null; -}; - -/** -* Generic contact field. -* @constructor -* @param {DOMString} id unique identifier, should only be set by native code -* @param type -* @param value -* @param pref -*/ -var ContactField = function(type, value, pref) { - this.id = null; - this.type = type || null; - this.value = value || null; - this.pref = pref || null; -}; - -/** -* Contact address. -* @constructor -* @param {DOMString} id unique identifier, should only be set by native code -* @param formatted -* @param streetAddress -* @param locality -* @param region -* @param postalCode -* @param country -*/ -var ContactAddress = function(pref, type, formatted, streetAddress, locality, region, postalCode, country) { - this.id = null; - this.pref = pref || null; - this.type = type || null; - this.formatted = formatted || null; - this.streetAddress = streetAddress || null; - this.locality = locality || null; - this.region = region || null; - this.postalCode = postalCode || null; - this.country = country || null; -}; - -/** -* Contact organization. -* @constructor -* @param {DOMString} id unique identifier, should only be set by native code -* @param name -* @param dept -* @param title -* @param startDate -* @param endDate -* @param location -* @param desc -*/ -var ContactOrganization = function(pref, type, name, dept, title) { - this.id = null; - this.pref = pref || null; - this.type = type || null; - this.name = name || null; - this.department = dept || null; - this.title = title || null; -}; - -/** -* Represents a group of Contacts. -* @constructor -*/ -var Contacts = function() { - this.inProgress = false; - this.records = []; -}; -/** -* Returns an array of Contacts matching the search criteria. -* @param fields that should be searched -* @param successCB success callback -* @param errorCB error callback -* @param {ContactFindOptions} options that can be applied to contact searching -* @return array of Contacts matching search criteria -*/ -Contacts.prototype.find = function(fields, successCB, errorCB, options) { - if (successCB === null) { - throw new TypeError("You must specify a success callback for the find command."); - } - if (fields === null || fields === "undefined" || fields.length === "undefined" || fields.length <= 0) { - if (typeof errorCB === "function") { - errorCB({"code": ContactError.INVALID_ARGUMENT_ERROR}); - } - } else { - PhoneGap.exec(successCB, errorCB, "Contacts", "search", [fields, options]); - } -}; - -/** -* This function creates a new contact, but it does not persist the contact -* to device storage. To persist the contact to device storage, invoke -* contact.save(). -* @param properties an object who's properties will be examined to create a new Contact -* @returns new Contact object -*/ -Contacts.prototype.create = function(properties) { - var i; - var contact = new Contact(); - for (i in properties) { - if (contact[i] !== 'undefined') { - contact[i] = properties[i]; - } - } - return contact; -}; - -/** -* This function returns and array of contacts. It is required as we need to convert raw -* JSON objects into concrete Contact objects. Currently this method is called after -* navigator.contacts.find but before the find methods success call back. -* -* @param jsonArray an array of JSON Objects that need to be converted to Contact objects. -* @returns an array of Contact objects -*/ -Contacts.prototype.cast = function(pluginResult) { - var contacts = []; - var i; - for (i=0; i][;base64], - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsDataURL = function(file) { - this.fileName = ""; - if (typeof file.fullPath === "undefined") { - this.fileName = file; - } else { - this.fileName = file.fullPath; - } - - // LOADING state - this.readyState = FileReader.LOADING; - - // If loadstart callback - if (typeof this.onloadstart === "function") { - this.onloadstart({"type":"loadstart", "target":this}); - } - - var me = this; - - // Read file - navigator.fileMgr.readAsDataURL(this.fileName, - - // Success callback - function(r) { - var evt; - - // If DONE (cancelled), then don't do anything - if (me.readyState === FileReader.DONE) { - return; - } - - // Save result - me.result = r; - - // If onload callback - if (typeof me.onload === "function") { - me.onload({"type":"load", "target":me}); - } - - // DONE state - me.readyState = FileReader.DONE; - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend({"type":"loadend", "target":me}); - } - }, - - // Error callback - function(e) { - var evt; - // If DONE (cancelled), then don't do anything - if (me.readyState === FileReader.DONE) { - return; - } - - // Save error - me.error = e; - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror({"type":"error", "target":me}); - } - - // DONE state - me.readyState = FileReader.DONE; - - // If onloadend callback - if (typeof me.onloadend === "function") { - me.onloadend({"type":"loadend", "target":me}); - } - } - ); -}; - -/** - * Read file and return data as a binary data. - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsBinaryString = function(file) { - // TODO - Can't return binary data to browser. - this.fileName = file; -}; - -/** - * Read file and return data as a binary data. - * - * @param file {File} File object containing file properties - */ -FileReader.prototype.readAsArrayBuffer = function(file) { - // TODO - Can't return binary data to browser. - this.fileName = file; -}; - -//----------------------------------------------------------------------------- -// File Writer -//----------------------------------------------------------------------------- - -/** - * This class writes to the mobile device file system. - * - * For Android: - * The root directory is the root of the file system. - * To write to the SD card, the file name is "sdcard/my_file.txt" - * - * @constructor - * @param file {File} File object containing file properties - * @param append if true write to the end of the file, otherwise overwrite the file - */ -var FileWriter = function(file) { - this.fileName = ""; - this.length = 0; - if (file) { - this.fileName = file.fullPath || file; - this.length = file.size || 0; - } - // default is to write at the beginning of the file - this.position = 0; - - this.readyState = 0; // EMPTY - - this.result = null; - - // Error - this.error = null; - - // Event handlers - this.onwritestart = null; // When writing starts - this.onprogress = null; // While writing the file, and reporting partial file data - this.onwrite = null; // When the write has successfully completed. - this.onwriteend = null; // When the request has completed (either in success or failure). - this.onabort = null; // When the write has been aborted. For instance, by invoking the abort() method. - this.onerror = null; // When the write has failed (see errors). -}; - -// States -FileWriter.INIT = 0; -FileWriter.WRITING = 1; -FileWriter.DONE = 2; - -/** - * Abort writing file. - */ -FileWriter.prototype.abort = function() { - // check for invalid state - if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) { - throw FileError.INVALID_STATE_ERR; - } - - // set error - var error = new FileError(), evt; - error.code = error.ABORT_ERR; - this.error = error; - - // If error callback - if (typeof this.onerror === "function") { - this.onerror({"type":"error", "target":this}); - } - // If abort callback - if (typeof this.onabort === "function") { - this.onabort({"type":"abort", "target":this}); - } - - this.readyState = FileWriter.DONE; - - // If write end callback - if (typeof this.onwriteend == "function") { - this.onwriteend({"type":"writeend", "target":this}); - } -}; - -/** - * Writes data to the file - * - * @param text to be written - */ -FileWriter.prototype.write = function(text) { - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw FileError.INVALID_STATE_ERR; - } - - // WRITING state - this.readyState = FileWriter.WRITING; - - var me = this; - - // If onwritestart callback - if (typeof me.onwritestart === "function") { - me.onwritestart({"type":"writestart", "target":me}); - } - - // Write file - navigator.fileMgr.write(this.fileName, text, this.position, - - // Success callback - function(r) { - var evt; - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // position always increases by bytes written because file would be extended - me.position += r; - // The length of the file is now where we are done writing. - me.length = me.position; - - // If onwrite callback - if (typeof me.onwrite === "function") { - me.onwrite({"type":"write", "target":me}); - } - - // DONE state - me.readyState = FileWriter.DONE; - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend({"type":"writeend", "target":me}); - } - }, - - // Error callback - function(e) { - var evt; - - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // Save error - me.error = e; - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror({"type":"error", "target":me}); - } - - // DONE state - me.readyState = FileWriter.DONE; - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend({"type":"writeend", "target":me}); - } - } - ); - -}; - -/** - * Moves the file pointer to the location specified. - * - * If the offset is a negative number the position of the file - * pointer is rewound. If the offset is greater than the file - * size the position is set to the end of the file. - * - * @param offset is the location to move the file pointer to. - */ -FileWriter.prototype.seek = function(offset) { - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw FileError.INVALID_STATE_ERR; - } - - if (!offset) { - return; - } - - // See back from end of file. - if (offset < 0) { - this.position = Math.max(offset + this.length, 0); - } - // Offset is bigger then file size so set position - // to the end of the file. - else if (offset > this.length) { - this.position = this.length; - } - // Offset is between 0 and file size so set the position - // to start writing. - else { - this.position = offset; - } -}; - -/** - * Truncates the file to the size specified. - * - * @param size to chop the file at. - */ -FileWriter.prototype.truncate = function(size) { - // Throw an exception if we are already writing a file - if (this.readyState === FileWriter.WRITING) { - throw FileError.INVALID_STATE_ERR; - } - - // WRITING state - this.readyState = FileWriter.WRITING; - - var me = this; - - // If onwritestart callback - if (typeof me.onwritestart === "function") { - me.onwritestart({"type":"writestart", "target":this}); - } - - // Write file - navigator.fileMgr.truncate(this.fileName, size, - - // Success callback - function(r) { - var evt; - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // Update the length of the file - me.length = r; - me.position = Math.min(me.position, r); - - // If onwrite callback - if (typeof me.onwrite === "function") { - me.onwrite({"type":"write", "target":me}); - } - - // DONE state - me.readyState = FileWriter.DONE; - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend({"type":"writeend", "target":me}); - } - }, - - // Error callback - function(e) { - var evt; - // If DONE (cancelled), then don't do anything - if (me.readyState === FileWriter.DONE) { - return; - } - - // Save error - me.error = e; - - // If onerror callback - if (typeof me.onerror === "function") { - me.onerror({"type":"error", "target":me}); - } - - // DONE state - me.readyState = FileWriter.DONE; - - // If onwriteend callback - if (typeof me.onwriteend === "function") { - me.onwriteend({"type":"writeend", "target":me}); - } - } - ); -}; - -/** - * Information about the state of the file or directory - * - * @constructor - * {Date} modificationTime (readonly) - */ -var Metadata = function() { - this.modificationTime=null; -}; - -/** - * Supplies arguments to methods that lookup or create files and directories - * - * @constructor - * @param {boolean} create file or directory if it doesn't exist - * @param {boolean} exclusive if true the command will fail if the file or directory exists - */ -var Flags = function(create, exclusive) { - this.create = create || false; - this.exclusive = exclusive || false; -}; - -/** - * An interface representing a file system - * - * @constructor - * {DOMString} name the unique name of the file system (readonly) - * {DirectoryEntry} root directory of the file system (readonly) - */ -var FileSystem = function() { - this.name = null; - this.root = null; -}; - -/** - * An interface that lists the files and directories in a directory. - * @constructor - */ -var DirectoryReader = function(fullPath){ - this.fullPath = fullPath || null; -}; - -/** - * Returns a list of entries from a directory. - * - * @param {Function} successCallback is called with a list of entries - * @param {Function} errorCallback is called with a FileError - */ -DirectoryReader.prototype.readEntries = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "readEntries", [this.fullPath]); -}; - -/** - * An interface representing a directory on the file system. - * - * @constructor - * {boolean} isFile always false (readonly) - * {boolean} isDirectory always true (readonly) - * {DOMString} name of the directory, excluding the path leading to it (readonly) - * {DOMString} fullPath the absolute full path to the directory (readonly) - * {FileSystem} filesystem on which the directory resides (readonly) - */ -var DirectoryEntry = function() { - this.isFile = false; - this.isDirectory = true; - this.name = null; - this.fullPath = null; - this.filesystem = null; -}; - -/** - * Copies a directory to a new location - * - * @param {DirectoryEntry} parent the directory to which to copy the entry - * @param {DOMString} newName the new name of the entry, defaults to the current name - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "copyTo", [this.fullPath, parent, newName]); -}; - -/** - * Looks up the metadata of the entry - * - * @param {Function} successCallback is called with a Metadata object - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.getMetadata = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "getMetadata", [this.fullPath]); -}; - -/** - * Gets the parent of the entry - * - * @param {Function} successCallback is called with a parent entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.getParent = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "getParent", [this.fullPath]); -}; - -/** - * Moves a directory to a new location - * - * @param {DirectoryEntry} parent the directory to which to move the entry - * @param {DOMString} newName the new name of the entry, defaults to the current name - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "moveTo", [this.fullPath, parent, newName]); -}; - -/** - * Removes the entry - * - * @param {Function} successCallback is called with no parameters - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.remove = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "remove", [this.fullPath]); -}; - -/** - * Returns a URI that can be used to identify this entry. - * - * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI. - * @return uri - */ -DirectoryEntry.prototype.toURI = function(mimeType) { - return "file://" + this.fullPath; -}; - -/** - * Creates a new DirectoryReader to read entries from this directory - */ -DirectoryEntry.prototype.createReader = function(successCallback, errorCallback) { - return new DirectoryReader(this.fullPath); -}; - -/** - * Creates or looks up a directory - * - * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a directory - * @param {Flags} options to create or excluively create the directory - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.getDirectory = function(path, options, successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "getDirectory", [this.fullPath, path, options]); -}; - -/** - * Creates or looks up a file - * - * @param {DOMString} path either a relative or absolute path from this directory in which to look up or create a file - * @param {Flags} options to create or excluively create the file - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.getFile = function(path, options, successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "getFile", [this.fullPath, path, options]); -}; - -/** - * Deletes a directory and all of it's contents - * - * @param {Function} successCallback is called with no parameters - * @param {Function} errorCallback is called with a FileError - */ -DirectoryEntry.prototype.removeRecursively = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "removeRecursively", [this.fullPath]); -}; - -/** - * An interface representing a directory on the file system. - * - * @constructor - * {boolean} isFile always true (readonly) - * {boolean} isDirectory always false (readonly) - * {DOMString} name of the file, excluding the path leading to it (readonly) - * {DOMString} fullPath the absolute full path to the file (readonly) - * {FileSystem} filesystem on which the directory resides (readonly) - */ -var FileEntry = function() { - this.isFile = true; - this.isDirectory = false; - this.name = null; - this.fullPath = null; - this.filesystem = null; -}; - -/** - * Copies a file to a new location - * - * @param {DirectoryEntry} parent the directory to which to copy the entry - * @param {DOMString} newName the new name of the entry, defaults to the current name - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.copyTo = function(parent, newName, successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "copyTo", [this.fullPath, parent, newName]); -}; - -/** - * Looks up the metadata of the entry - * - * @param {Function} successCallback is called with a Metadata object - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.getMetadata = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "getMetadata", [this.fullPath]); -}; - -/** - * Gets the parent of the entry - * - * @param {Function} successCallback is called with a parent entry - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.getParent = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "getParent", [this.fullPath]); -}; - -/** - * Moves a directory to a new location - * - * @param {DirectoryEntry} parent the directory to which to move the entry - * @param {DOMString} newName the new name of the entry, defaults to the current name - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.moveTo = function(parent, newName, successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "moveTo", [this.fullPath, parent, newName]); -}; - -/** - * Removes the entry - * - * @param {Function} successCallback is called with no parameters - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.remove = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "remove", [this.fullPath]); -}; - -/** - * Returns a URI that can be used to identify this entry. - * - * @param {DOMString} mimeType for a FileEntry, the mime type to be used to interpret the file, when loaded through this URI. - * @return uri - */ -FileEntry.prototype.toURI = function(mimeType) { - return "file://" + this.fullPath; -}; - -/** - * Creates a new FileWriter associated with the file that this FileEntry represents. - * - * @param {Function} successCallback is called with the new FileWriter - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.createWriter = function(successCallback, errorCallback) { - this.file(function(filePointer) { - var writer = new FileWriter(filePointer); - - if (writer.fileName === null || writer.fileName === "") { - if (typeof errorCallback == "function") { - errorCallback({ - "code": FileError.INVALID_STATE_ERR - }); - } - } - - if (typeof successCallback == "function") { - successCallback(writer); - } - }, errorCallback); -}; - -/** - * Returns a File that represents the current state of the file that this FileEntry represents. - * - * @param {Function} successCallback is called with the new File object - * @param {Function} errorCallback is called with a FileError - */ -FileEntry.prototype.file = function(successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "getFileMetadata", [this.fullPath]); -}; - -/** @constructor */ -var LocalFileSystem = function() { -}; - -// File error codes -LocalFileSystem.TEMPORARY = 0; -LocalFileSystem.PERSISTENT = 1; -LocalFileSystem.RESOURCE = 2; -LocalFileSystem.APPLICATION = 3; - -/** - * Requests a filesystem in which to store application data. - * - * @param {int} type of file system being requested - * @param {Function} successCallback is called with the new FileSystem - * @param {Function} errorCallback is called with a FileError - */ -LocalFileSystem.prototype.requestFileSystem = function(type, size, successCallback, errorCallback) { - if (type < 0 || type > 3) { - if (typeof errorCallback == "function") { - errorCallback({ - "code": FileError.SYNTAX_ERR - }); - } - } - else { - PhoneGap.exec(successCallback, errorCallback, "File", "requestFileSystem", [type, size]); - } -}; - -/** - * - * @param {DOMString} uri referring to a local file in a filesystem - * @param {Function} successCallback is called with the new entry - * @param {Function} errorCallback is called with a FileError - */ -LocalFileSystem.prototype.resolveLocalFileSystemURI = function(uri, successCallback, errorCallback) { - PhoneGap.exec(successCallback, errorCallback, "File", "resolveLocalFileSystemURI", [uri]); -}; - -/** -* This function returns and array of contacts. It is required as we need to convert raw -* JSON objects into concrete Contact objects. Currently this method is called after -* navigator.service.contacts.find but before the find methods success call back. -* -* @param a JSON Objects that need to be converted to DirectoryEntry or FileEntry objects. -* @returns an entry -*/ -LocalFileSystem.prototype._castFS = function(pluginResult) { - var entry = null; - entry = new DirectoryEntry(); - entry.isDirectory = pluginResult.message.root.isDirectory; - entry.isFile = pluginResult.message.root.isFile; - entry.name = pluginResult.message.root.name; - entry.fullPath = pluginResult.message.root.fullPath; - pluginResult.message.root = entry; - return pluginResult; -}; - -LocalFileSystem.prototype._castEntry = function(pluginResult) { - var entry = null; - if (pluginResult.message.isDirectory) { - console.log("This is a dir"); - entry = new DirectoryEntry(); - } - else if (pluginResult.message.isFile) { - console.log("This is a file"); - entry = new FileEntry(); - } - entry.isDirectory = pluginResult.message.isDirectory; - entry.isFile = pluginResult.message.isFile; - entry.name = pluginResult.message.name; - entry.fullPath = pluginResult.message.fullPath; - pluginResult.message = entry; - return pluginResult; -}; - -LocalFileSystem.prototype._castEntries = function(pluginResult) { - var entries = pluginResult.message; - var retVal = []; - for (var i=0; i"; - self.at_spinner = true; - } - setOffset(0); - }; - - this.content = function(text, offset) { - console.log('content'); - self.at_spinner = false; - - self._content.innerHTML = ''; - self._content.innerHTML = text; - setOffset(offset); - } - - this.enter = function(url, offset) { - console.log('View.enter: ' + url); - - var view = 'Index'; - var arg = null; - - if (url.length) { - var slash_index = url.indexOf('/'); - if (slash_index != -1) { - view = url.substr(0, slash_index); - arg = url.substr(slash_index + 1); - } - else { - view = url; - } - } - console.log('View.enter: ' + view + ' ' + arg); - self.current = url; - self.currentView = view; - self.currentPar = arg; - self['enter' + view](arg, offset); - } - - this.enterIndex = function(arg, offset) { - console.log('enterIndex'); - Menu.setInfoButton("ProjectInfo", "Informacje o projekcie", true); - self.showSearch(); - self.currentTitle = "Początek"; - var html = ""; - - html += "
"; - html += Links.button('Last', '', 'Ostatnio czytane'); - html += Links.button('Bookmarks', '', 'Zakładki'); - - for (category in self.categories) - html += Links.button('Category', category, self.categories[category], 0); - html += "
"; - - html += "" +""; - /*"";*/ - self.content(html, offset); - }; - - this.enterBook = function(id, offset) { - id = parseInt(id); - console.log('enterBook: ' + id); - Menu.setInfoButton("BookInfo", "Informacje o utworze", true); - self.showSearch(); - - Catalogue.withBook(id, function(book) { - self.currentTitle = book.authors + ', ' + book.title; - - Catalogue.withChildren(id, function(children) { - var html = "

"; - html += book.authors; - html += "" + book.title + "

\n"; - if (book.html_file) { - html += "
" + Links.button('BookText', id, "Czytaj tekst") + "
"; - } - if (children.length) { - html += "
"; - for (c in children) { - child = children[c]; - html += Links.bookLink(child); - } - html += "
"; - } - self.content(html, offset); - }); - }, function() { - History.goBack(); - }); - }; - - this.enterBookText = function(id, offset) { - self.hideSearch(); - self.spinner("Otwieranie utworu"); - console.log('enterBookText: ' + id); - Menu.setInfoButton("BookInfo", "Informacje o utworze", true); - id = parseInt(id); - - setTimeout("History.addRead("+id+");", 0); - - FileRepo.withHtml(id, function(data) { - self.content(data, offset); - }, function(err) { - alert("Błąd pobierania: nie udało się pobrać treści utworu."); - History.goBack(); - }); - Catalogue.withBook(id, function(book) { - self.currentTitle = book.authors + ', ' + book.title; - }); - }; - - - this.enterLast = function(ignored, offset) { - console.log("enterLast"); - self.showSearch(); - Menu.setInfoButton("ProjectInfo", "Informacje o projekcie", true); - self.currentTitle = 'Ostatnio czytane'; - var html = "

Ostatnio czytane

\n"; - - var last_read = History.lastRead(); - var some_books = false; - - html += "
"; - var add_books = function() { - if (last_read.length) { - var id = last_read.shift(); - Catalogue.withBook(id, function(book) { - html += Links.bookLink(book); - some_books = true; - add_books(); - }, function() { - add_books(); - }); - } - else { - if (!some_books) { - html += "

Nie przeczytano żadnych utworów.

"; - } - html += "
"; - self.content(html, offset); - } - }; - add_books(); - }; - - - this.enterBookmarks = function(ignored, offset) { - console.log("enterBookmarks"); - self.showSearch(); - Menu.setInfoButton("ProjectInfo", "Informacje o projekcie", true); - self.currentTitle = 'Zakładki'; - var html = "

Zakładki

\n"; - - var bookmarks = History.bookmarks(); - if (!bookmarks.length) { - html += "

Nie utworzono żadnych zakładek.

"; - self.content(html, offset); - return; - } - - html += "
"; - for (i in bookmarks) { - var bm = bookmarks[i]; - - var text = bm.name; - text += "
" + bm.title + "
"; - html += Links.deleteButton(bm.id); - html += Links.button(bm.view, bm.par, text, bm.offset); - } - html += "
"; - self.content(html, offset); - }; - - this.onBookmarkChange = function() { - // TODO: preserve offset - if (self.currentView == 'Bookmarks') { - self.enterBookmarks(); - } - }; - - this.enterTag = function(id, offset) { - id = parseInt(id); - console.log('enterTag: ' + id); - Menu.setInfoButton("TagInfo", "Informacje o...", true); - self.showSearch(); - - self.spinner("Otwieranie listy utworów"); - - Catalogue.withTag(id, function(tag) { - Menu.setInfoButton("TagInfo", "Informacje o " + self.category_msc[tag.category], true); - self.currentTitle = tag.category + ': ' + tag.name; - var html = "

" + tag.category + ': ' + tag.name + "

\n"; - html += "
"; - if (tag.books) { - Catalogue.withBooks(tag.books, function(books) { - for (var i in books) { - var book = books[i]; - html += Links.bookLink(book); - } - html += "
"; - self.content(html, offset); - }); - } - }, function() { - History.goBack(); - }); - }; - - - this.enterCategory = function(category, offset) { - console.log('enterCategory: ' + category); - Menu.setInfoButton("ProjectInfo", "Informacje o projekcie", true); - self.spinner("Otwieranie katalogu"); - self.showSearch(); - self.currentTitle = self.categories[category]; - - Catalogue.withCategory(category, function(tags) { - var html = "

" + self.categories[category] + "

\n"; - html += "
"; - for (i in tags) { - tag = tags[i]; - html += Links.button('Tag', tag.id, tag.name); - } - html += "
"; - self.content(html, offset); - }); - }; - - - this.enterSearch = function(query, offset) { - console.log('enterSearch: ' + query); - Menu.setInfoButton("ProjectInfo", "Informacje o projekcie", true); - self.currentTitle = 'Szukaj: ' + query; - self.showSearch(); - - var html = "

Szukana fraza:" + View.sanitize(query) + "

\n"; - - if (query.length < 2) { - html += "

Szukana fraza musi mieć co najmniej dwa znaki

"; - self.content(html, offset); - return; - } - - Catalogue.withSearch(query, function(results) { - if (results.length == 1) { - var result = results[0]; - if (result.view == 'Book' && result.item.html_file) { - self.enter(Links.href('BookText', result.item.id)); - } - else { - self.enter(Links.href(result.view, result.item.id)); - } - return; - } - if (results.length == 0) { - html += "

Brak wyników wyszukiwania

"; - } - else { - html += "
"; - for (var i in results) { - var result = results[i]; - if (result.view == 'Book') - html += Links.bookLink(result.item) - else - html += Links.button(result.view, result.item.id, result.item.name+"
"+result.item.category+"
"); - } - html += "
"; - } - self.content(html, offset); - }); - }; - - - /* info */ - - this.enterProjectInfo = function(arg, offset) { - console.log('enterProjectInfo'); - Menu.setInfoButton("ProjectInfo", "Informacje o projekcie", false); - self.hideSearch(); - self.currentTitle = "Informacje o projekcie"; - - var html = ""; - - html += '
'; - - - html += "

"; - html += "

Biblioteka internetowa Wolne Lektury "+ -" udostępnia w swoich zbiorach lektury szkolne zalecane do użytku przez" + -" Ministerstwo Edukacji Narodowej i inne dzieła literatury.

"; - - html += "

"; - - html += "" + - "

" + - "Przekaż 1% podatku na rozwój Wolnych Lektur.
" + - "Fundacja Nowoczesna Polska
" + - "KRS 0000070056

"; - - html += "

Większość pozycji w bibliotece należy do domeny publicznej "+ - "co oznacza, że nie są już chronione majatkowym prawem autorskim, "+ - "a więc można je swobodnie wykorzystywać, publikować i rozpowszechniać. "+ - "Publikujemy również kilka utworów, które autorzy udostępnili na wolnej licencji "+ - ""+ - "Creative Commons Uznanie Autorstwa - Na Tych Samych Warunkach 3.0.PL.

"; - - html += "

"; - - html += "

Copyright © 2011 Fundacja Nowoczesna Polska. Aplikacja jest wolnym oprogramowaniem "+ - "dostępnym na licencji GNU Affero GPL w wersji 3 lub późniejszej.

"; - - html += "

Więcej informacji o projekcie znajduje sie na stronie http://www.wolnelektury.pl.

"; - - html += '
'; - - - self.content(html, offset); - }; - - - this.enterBookInfo = function(id, offset) { - id = parseInt(id); - console.log('enterBookInfo: ' + id); - Menu.setInfoButton("ProjectInfo", "Informacje o projekcie", true); - self.hideSearch(); - - Catalogue.withBook(id, function(book) { - self.currentTitle = "Informacje o: " + book.title; - - var html = '

' + book.authors + ', ' + book.title + '

'; - - var url = WL + '/api/book/' + id + '/info.html'; - - var xhr = new XMLHttpRequest(); - xhr.open("GET", url); - xhr.onload = function() { - console.log('BookInfo: fetched by ajax: ' + url); - - html += '
'; - html += xhr.responseText; - html += '
'; - - self.content(html, offset); - } - xhr.onerror = function(e) { - self.content("Brak informacji.", offset); - } - xhr.send(); - }, function() { - History.goBack(); - }); - }; - - - this.enterTagInfo = function(id, offset) { - id = parseInt(id); - console.log('enterTagInfo: ' + id); - Menu.setInfoButton("ProjectInfo", "Informacje o projekcie", true); - self.hideSearch(); - - Catalogue.withTag(id, function(tag) { - self.currentTitle = "Informacje o " + tag.name; - var html = '

' + tag.name + '

'; - - var url = WL + '/api/tag/' + id + '/info.html'; - - var xhr = new XMLHttpRequest(); - xhr.open("GET", url); - xhr.onload = function() { - console.log('TagInfo: fetched by ajax: ' + url); - - html += '
'; - html += xhr.responseText; - html += '
'; - - self.content(html, offset); - } - xhr.onerror = function(e) { - self.content("Brak informacji.", offset); - } - xhr.send(); - }, function() { - History.goBack(); - }); - }; - - - /* search form submit callback */ - this.search = function() { - History.visit('Search/' + self._searchinput.value); - return false; - } - - - self.getNightMode = function() { - night_mode = window.localStorage.getItem('View.night_mode'); - if (night_mode === undefined) - return false; - else - return !!night_mode; - }; - - self.checkNightMode = function() { - night_mode = self.getNightMode(); - if (night_mode) { - document.body.setAttribute("class", "night-mode"); - } - else { - document.body.setAttribute("class", ""); - } - }; - - self.setNightMode = function(night_mode) { - night_mode = night_mode ? "1" : ""; - window.localStorage.setItem('View.night_mode', night_mode); - self.checkNightMode(); - }; - - self.toggleNightMode = function(night_mode) { - self.setNightMode(!self.getNightMode()); - }; -} diff --git a/default.properties b/default.properties deleted file mode 100644 index 46769a7..0000000 --- a/default.properties +++ /dev/null @@ -1,11 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system use, -# "build.properties", and override values to adapt the script to your -# project structure. - -# Project target. -target=android-7 diff --git a/gen/pl/org/nowoczesnapolska/wlmobi/R.java b/gen/pl/org/nowoczesnapolska/wlmobi/R.java deleted file mode 100644 index aab3d7c..0000000 --- a/gen/pl/org/nowoczesnapolska/wlmobi/R.java +++ /dev/null @@ -1,26 +0,0 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package pl.org.nowoczesnapolska.wlmobi; - -public final class R { - public static final class attr { - } - public static final class drawable { - public static final int icon=0x7f020000; - } - public static final class layout { - public static final int main=0x7f030000; - } - public static final class string { - public static final int app_name=0x7f050001; - public static final int hello=0x7f050000; - } - public static final class xml { - public static final int plugins=0x7f040000; - } -} diff --git a/libs/phonegap-1.0.0.jar b/libs/phonegap-1.0.0.jar deleted file mode 100644 index b0b0486..0000000 Binary files a/libs/phonegap-1.0.0.jar and /dev/null differ diff --git a/main.m b/main.m new file mode 100644 index 0000000..f4289ab --- /dev/null +++ b/main.m @@ -0,0 +1,17 @@ +// +// main.m +// wl-mobi +// +// Created by FNP on 10/19/11. +// Copyright __MyCompanyName__ 2011. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate"); + [pool release]; + return retVal; +} diff --git a/proguard.cfg b/proguard.cfg deleted file mode 100644 index 12dd039..0000000 --- a/proguard.cfg +++ /dev/null @@ -1,36 +0,0 @@ --optimizationpasses 5 --dontusemixedcaseclassnames --dontskipnonpubliclibraryclasses --dontpreverify --verbose --optimizations !code/simplification/arithmetic,!field/*,!class/merging/* - --keep public class * extends android.app.Activity --keep public class * extends android.app.Application --keep public class * extends android.app.Service --keep public class * extends android.content.BroadcastReceiver --keep public class * extends android.content.ContentProvider --keep public class * extends android.app.backup.BackupAgentHelper --keep public class * extends android.preference.Preference --keep public class com.android.vending.licensing.ILicensingService - --keepclasseswithmembernames class * { - native ; -} - --keepclasseswithmembernames class * { - public (android.content.Context, android.util.AttributeSet); -} - --keepclasseswithmembernames class * { - public (android.content.Context, android.util.AttributeSet, int); -} - --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} diff --git a/res/drawable-hdpi/icon.png b/res/drawable-hdpi/icon.png deleted file mode 100644 index d76c57a..0000000 Binary files a/res/drawable-hdpi/icon.png and /dev/null differ diff --git a/res/drawable-ldpi/icon.png b/res/drawable-ldpi/icon.png deleted file mode 100644 index 0f2180d..0000000 Binary files a/res/drawable-ldpi/icon.png and /dev/null differ diff --git a/res/drawable-mdpi/icon.png b/res/drawable-mdpi/icon.png deleted file mode 100644 index 128dcce..0000000 Binary files a/res/drawable-mdpi/icon.png and /dev/null differ diff --git a/res/layout/main.xml b/res/layout/main.xml deleted file mode 100644 index 3a5f117..0000000 --- a/res/layout/main.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/res/values/strings.xml b/res/values/strings.xml deleted file mode 100644 index f2d4fb8..0000000 --- a/res/values/strings.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - Hello World, Catalogue! - Wolne Lektury - diff --git a/res/xml/plugins.xml b/res/xml/plugins.xml deleted file mode 100644 index 2d8ba88..0000000 --- a/res/xml/plugins.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/pl/org/nowoczesnapolska/wlmobi/Catalogue.java b/src/pl/org/nowoczesnapolska/wlmobi/Catalogue.java deleted file mode 100644 index be22a34..0000000 --- a/src/pl/org/nowoczesnapolska/wlmobi/Catalogue.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -package pl.org.nowoczesnapolska.wlmobi; - -import android.os.Bundle; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.webkit.WebSettings; - -import com.phonegap.*; - -public class Catalogue extends DroidGap { - - String infoLabel = "Proszę czekać"; - Boolean infoEnabled = false; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - - super.loadUrl("file:///android_asset/www/index.html"); - - MenuInterface.view = appView; - - WebSettings settings = this.appView.getSettings(); - settings.setSupportZoom(true); - settings.setBuiltInZoomControls(true); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(Menu.NONE, 1, 1, "Początek"); - menu.add(Menu.NONE, 3, 2, "Dodaj zakładkę"); - menu.add(Menu.NONE, 2, 3, MenuInterface.infoLabel); - menu.add(Menu.NONE, 4, 4, "Tryb nocny"); - //MenuInflater inflater = getMenuInflater(); - //inflater.inflate(R.menu.game_menu, menu); - return super.onCreateOptionsMenu(menu); - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - MenuItem mi = menu.getItem(1); - mi.setTitle(MenuInterface.infoLabel); - mi.setEnabled(MenuInterface.infoEnabled); - return super.onPrepareOptionsMenu(menu); - } - - - @Override - public boolean onKeyDown(int i,KeyEvent e){ - if (e.getKeyCode() == KeyEvent.KEYCODE_MENU) { - return false; - } - return super.onKeyDown(i, e); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case 1: - this.appView.loadUrl("javascript:Menu.start();"); - break; - case 2: - this.appView.loadUrl("javascript:Menu.info();"); - break; - case 3: - this.appView.loadUrl("javascript:Menu.bookmark();"); - break; - case 4: - this.appView.loadUrl("javascript:Menu.toggleNightMode();"); - break; - default: - return super.onOptionsItemSelected(item); - } - return true; - } -} \ No newline at end of file diff --git a/src/pl/org/nowoczesnapolska/wlmobi/DBPut.java b/src/pl/org/nowoczesnapolska/wlmobi/DBPut.java deleted file mode 100644 index d339614..0000000 --- a/src/pl/org/nowoczesnapolska/wlmobi/DBPut.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -package pl.org.nowoczesnapolska.wlmobi; - -import org.json.JSONArray; -import org.json.JSONException; - -import android.util.Log; -import android.content.res.AssetManager; - -import com.phonegap.api.Plugin; -import com.phonegap.api.PluginResult; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.IOException; -import pl.org.nowoczesnapolska.wlmobi.Downloader; - -public class DBPut extends Plugin{ - - @Override - public PluginResult execute(String action, JSONArray args, String callbackId) { - if (action.equals("put")) { - try { - return this.put(args.getString(0), args.getString(1), args.getString(2)); - } catch (JSONException e) { - return new PluginResult(PluginResult.Status.ERROR, "Param errrors"); - } - } - else if (action.equals("fetch")) { - try { - return this.fetch(args.getString(0)); - } catch (JSONException e) { - return new PluginResult(PluginResult.Status.ERROR, "Param errrors"); - } - } - else { - return new PluginResult(PluginResult.Status.INVALID_ACTION); - } - } - - private PluginResult fetch(String url) { - String fileName = "0000000000000001.db"; - String targetPath = "/data/data/" + this.ctx.getPackageName() + "/app_database/file__0/"; - - Log.d("DBPut", "database path: " + targetPath + " / " + fileName); - - Downloader d = new Downloader(); - return d.downloadUrl(url, targetPath, fileName, "true"); - } - - - private PluginResult put(String assetPath, String targetPath, String overwrite) { - // this hard-coding is kinda creepy, should probably create the db and use getDatabasePath instead - String absoluteTargetPath = "/data/data/" + this.ctx.getPackageName() + "/app_database/" + targetPath; - int index = absoluteTargetPath.lastIndexOf('/'); - String targetDir = absoluteTargetPath.substring(0, index); - - try { - File dir = new File(targetDir); - if(!dir.exists()) { - Log.d("DBPut", "directory " + targetDir + " created"); - dir.mkdirs(); - } - - File fout = new File(absoluteTargetPath); - - if(overwrite.equals("false") && fout.exists()) { - Log.d("DBPut", "File already exists"); - return new PluginResult(PluginResult.Status.OK, "exist"); - } - - FileOutputStream fos = new FileOutputStream(fout); - - AssetManager assetManager = this.ctx.getResources().getAssets(); - InputStream is = assetManager.open(assetPath); - - byte[] buffer = new byte[1024]; - int len1 = 0; - - while ( (len1 = is.read(buffer)) > 0 ) { - fos.write(buffer,0, len1); - } - - fos.close(); - - Log.d("DBPut", "Copied to " + absoluteTargetPath); - } catch (IOException e) { - Log.d("DBPut", "Error: " + e); - return new PluginResult(PluginResult.Status.ERROR, "Error: " + e); - } - return new PluginResult(PluginResult.Status.OK, absoluteTargetPath); - } -} \ No newline at end of file diff --git a/src/pl/org/nowoczesnapolska/wlmobi/Downloader.java b/src/pl/org/nowoczesnapolska/wlmobi/Downloader.java deleted file mode 100644 index 459891b..0000000 --- a/src/pl/org/nowoczesnapolska/wlmobi/Downloader.java +++ /dev/null @@ -1,96 +0,0 @@ -package pl.org.nowoczesnapolska.wlmobi; - -/* - @author Mauro Rocco http://www.toforge.com - - Radek Czajka: don't prepend /sdcard/ -*/ - -import org.json.JSONArray; -import org.json.JSONException; - -import android.util.Log; - -import com.phonegap.api.Plugin; -import com.phonegap.api.PluginResult; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; - -public class Downloader extends Plugin{ - - @Override - public PluginResult execute(String action, JSONArray args, String callbackId) { - if (action.equals("downloadFile")) { - try { - return this.downloadUrl(args.getString(0),args.getString(1),args.getString(2),args.getString(3)); - } catch (JSONException e) { - return new PluginResult(PluginResult.Status.ERROR, "Param errrors"); - } - } - else { - return new PluginResult(PluginResult.Status.INVALID_ACTION); - } - - } - - PluginResult downloadUrl(String fileUrl, String dirName, String fileName, String overwrite){ - try{ - Log.d("DownloaderPlugin", "DIRECTORY CALLED "+dirName+" created"); - File dir = new File(dirName); - if(!dir.exists()){ - Log.d("DownloaderPlugin", "directory "+dirName+" created"); - dir.mkdirs(); - } - - File file = new File(dirName+fileName); - - if(overwrite.equals("false") && file.exists()){ - Log.d("DownloaderPlugin", "File already exist"); - return new PluginResult(PluginResult.Status.OK, "exist"); - } - - URL url = new URL(fileUrl); - Log.d("DownloaderPlugin", "connecting to server for downloading " + url); - HttpURLConnection ucon = (HttpURLConnection) url.openConnection(); - ucon.setRequestMethod("GET"); - ucon.setDoOutput(true); - ucon.connect(); - - Log.d("DownloaderPlugin", "download begining"); - - Log.d("DownloaderPlugin", "download url:" + url); - - InputStream is = ucon.getInputStream(); - - byte[] buffer = new byte[1024]; - - int len1 = 0; - - FileOutputStream fos = new FileOutputStream(file); - - while ( (len1 = is.read(buffer)) > 0 ) { - fos.write(buffer, 0, len1); - //new String(buffer, "ISO8859_1").getBytes("UTF-8"), 0, len1); - } - - fos.close(); - - Log.d("DownloaderPlugin", "Download complete in" + fileName); - - } catch (IOException e) { - - Log.d("DownloaderPlugin", "Error: " + e); - return new PluginResult(PluginResult.Status.ERROR, "Error: " + e); - - } - - return new PluginResult(PluginResult.Status.OK, fileName); - - } - -} \ No newline at end of file diff --git a/src/pl/org/nowoczesnapolska/wlmobi/MenuInterface.java b/src/pl/org/nowoczesnapolska/wlmobi/MenuInterface.java deleted file mode 100644 index 064d4de..0000000 --- a/src/pl/org/nowoczesnapolska/wlmobi/MenuInterface.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. - * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. - */ - -package pl.org.nowoczesnapolska.wlmobi; - -import org.json.JSONArray; -import org.json.JSONException; - -import android.graphics.Color; -import android.webkit.WebView; - -import com.phonegap.api.Plugin; -import com.phonegap.api.PluginResult; - -public class MenuInterface extends Plugin{ - - public static String infoLabel = "Proszę czekać..."; - public static Boolean infoEnabled = false; - public static Boolean nightEnabled = false; - public static WebView view; - - @Override - public PluginResult execute(String action, JSONArray args, String callbackId) { - if (action.equals("setInfoButton")) { - try { - return this.setInfoButton(args.getString(0), args.getString(1)); - } catch (JSONException e) { - return new PluginResult(PluginResult.Status.ERROR, "Param errrors"); - } - } - else if (action.equals("setNightMode")) { - try { - return this.setNightMode(args.getString(0)); - } catch (JSONException e) { - return new PluginResult(PluginResult.Status.ERROR, "Param errrors"); - } - } - else { - return new PluginResult(PluginResult.Status.INVALID_ACTION); - } - } - - private PluginResult setInfoButton(String label, String enabled) { - infoLabel = label; - infoEnabled = enabled.equals("true"); - - return new PluginResult(PluginResult.Status.OK); - } - - private PluginResult setNightMode(String enabled) { - nightEnabled = enabled.equals("true"); - if (nightEnabled) { - view.setBackgroundColor(0x222222ff); - } - else { - view.setBackgroundColor(Color.WHITE); - } - - return new PluginResult(PluginResult.Status.OK); - } -} diff --git a/wl_mobi-Info.plist b/wl_mobi-Info.plist new file mode 100644 index 0000000..52981a7 --- /dev/null +++ b/wl_mobi-Info.plist @@ -0,0 +1,52 @@ + + + + + CFBundleIconFiles + + icon.png + icon@2x.png + icon-72.png + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeRight + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + icon.png + CFBundleIdentifier + pl.org.nowoczesnapolska.wl_mobi + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + + NSMainNibFile~ipad + + + diff --git a/wl_mobi-Prefix.pch b/wl_mobi-Prefix.pch new file mode 100644 index 0000000..75ecfab --- /dev/null +++ b/wl_mobi-Prefix.pch @@ -0,0 +1,8 @@ +// +// Prefix header for all source files of the 'wl-mobi' target in the 'wl-mobi' project +// + +#ifdef __OBJC__ + #import + #import +#endif diff --git a/www/WolneLektury.html b/www/WolneLektury.html new file mode 100644 index 0000000..858157a --- /dev/null +++ b/www/WolneLektury.html @@ -0,0 +1,50 @@ + + + + + + Wolne Lektury + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+ +
+ + + +
+ + \ No newline at end of file diff --git a/www/css/book_text.css b/www/css/book_text.css new file mode 100644 index 0000000..f9c7eff --- /dev/null +++ b/www/css/book_text.css @@ -0,0 +1,230 @@ +/* + * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. + * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. + */ + +#book-text { + font-size: .75em; + line-height: 1.5em; + margin: 0; + max-width: 40em; +} + +#book-text a { + color: blue; + text-decoration: none; +} + +.night-mode #book-text a { + color: #88f; +} + + +/* ================================== */ +/* = Header with logo and menu = */ +/* ================================== */ +#book-text #toc, #themes, #nota_red, #info { + display: none; +} + +/* =================================================== */ +/* = Common elements: headings, paragraphs and lines = */ +/* =================================================== */ +#book-text h1 { + font-size: 2.5em; + margin: 1.5em 0; + text-align: center; + line-height: 1.5em; + font-weight: bold; +} + +#book-text h2 { + font-size: 1.7em; + margin: 1.5em 0 0; + font-weight: bold; + line-height: 1.5em; +} + +#book-text h3 { + font-size: 1.4em; + margin: 1.5em 0 0; + font-weight: normal; + line-height: 1.5em; +} + +#book-text h4 { + font-size: 1em; + margin: 1.5em 0 0; + line-height: 1.5em; +} + +#book-text p { + margin: 0; +} + +/* ======================== */ +/* = Footnotes and themes = */ +/* ======================== */ +#book-text .theme-begin { + display:none; +} + +#book-text .annotation { + font-style: normal; + font-weight: normal; + font-size: 12px; + padding-left: 2px; + position: relative; + top: -4px; +} + +#book-text #footnotes { + margin-top: 3em; +} + +#book-text #footnotes .annotation { + display: block; + float: left; + width: 2.5em; + clear: both; +} + +#book-text #footnotes div { + margin: 1.5em 0 0 0; +} + +#book-text #footnotes p, #footnotes ul { + margin-left: 2.5em; + font-size: 0.875em; +} + +#book-text #footnotes .permalink { + font-size: .75em; +} + +#book-text blockquote { + font-size: 0.875em; + margin: 0 0 0 1em; +} + +/* ============= */ +/* = Numbering = */ +/* ============= */ +#book-text .anchor{display:none;} + +/* =================== */ +/* = Custom elements = */ +/* =================== */ +#book-text span.author { + font-size: 0.5em; + display: block; + line-height: 1.5em; + margin-bottom: 0.25em; +} + +#book-text span.collection { + font-size: 0.375em; + display: block; + line-height: 1.5em; + margin-bottom: -0.25em; +} + +#book-text span.subtitle { + font-size: 0.5em; + display: block; + line-height: 1.5em; + margin-top: -0.25em; +} + +#book-text span.translator { + font-size: 0.375em; + display: block; + line-height: 1.5em; + margin-top: 0.25em; +} + +#book-text div.didaskalia { + font-style: italic; + margin: 0.5em 0 0 1.5em; +} + +#book-text div.kwestia { + margin: 0.5em 0 0; +} + +#book-text div.stanza { + margin: 1.5em 0 0; +} + +#book-text div.kwestia div.stanza { + margin: 0; +} + +#book-text p.paragraph { + text-align: justify; + margin: 1.5em 0 0; +} + +#book-text p.motto { + text-align: justify; + font-style: italic; + margin: 1.5em 0 0; +} + +#book-text p.motto_podpis { + font-size: 0.875em; + text-align: right; +} + +#book-text div.fragment { + border-bottom: 0.1em solid #999; + padding-bottom: 1.5em; +} + +#book-text div.note p, div.dedication p, div.note p.paragraph, div.dedication p.paragraph { + text-align: right; + font-style: italic; +} + +#book-text hr.spacer { + height: 3em; + visibility: hidden; +} + +#book-text hr.spacer-line { + margin: 1.5em 0; + border: none; + border-bottom: 0.1em solid #000; +} + +#book-text p.spacer-asterisk { + padding: 0; + margin: 1.5em 0; + text-align: center; +} + +#book-text div.person-list ol { + list-style: none; + padding: 0 0 0 1.5em; +} + +#book-text p.place-and-time { + font-style: italic; +} + +#book-text em.math, em.foreign-word, em.book-title, em.didaskalia { + font-style: italic; +} + +#book-text em.author-emphasis { + letter-spacing: 0.1em; +} + +#book-text em.person { + font-style: normal; + font-variant: small-caps; +} + +#book-text .verse:after { + content: "\feff"; +} diff --git a/www/css/style.css b/www/css/style.css new file mode 100644 index 0000000..03d2a3f --- /dev/null +++ b/www/css/style.css @@ -0,0 +1,210 @@ +/* + * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. + * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. + */ + +body { + padding: 0; + margin: 0; + background: white; + font-family: verdana, arial, helvetica, sans-serif; +} + +.night-mode, .night-mode #search { + color: #ddd; + background: #222; +} +.night-mode a { + color: #fff; +} + +.spinner { + margin-top: 4em; + text-align: center; +} +@-webkit-keyframes rotate { + from { + -webkit-transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + } +} +.spinner img { + -webkit-animation-name: rotate; + -webkit-animation-duration: 4s; + -webkit-animation-iteration-count: 10; + -webkit-animation-direction: right; + -webkit-animation-timing-function:linear; +} +#spinnertext { + margin-top: 2em; + font-size: .7em; +} + +#cover { + width: 100%; +} + +#searchbox { + font-size: 1.25em; + /*background: #84bf2a;*/ + padding: 3px 3px 6px 0; + display: none; +} +#search { + border: none; + width: 100%; + padding: 5px 0 5px 0; + font-size: 1em; +} +#swrap { + margin-right:85px; + margin-left:80px; +} +#searchbutton { + width:80px; + float:right; + margin-top:.5em; +} +#content { + padding: 10px; +} +.button { + display: block; + background: #ddd; + font-size: 1.25em; + padding: .5em; + margin-bottom: .5em; + border-radius: 8px; + -webkit-border-radius: 8px; + color: #295158; +} +.button img { + margin-right: .5em; + vertical-align: middle; +} +.button .sub { + font-size: .7em; +} +.button .note { + font-size: .5em; + text-align: right; +} +.button img { + float:left; +} +.button .label { + margin-left: 32px; +} + +.button-Book { + background: #ccc; +} +.button-BookText { + background: #ccc; +} +.delete { + float: right; + width: 24px; + + background: #464646; + font-size: 1.25em; + padding: .5em; + margin-bottom: .5em; + border-radius: 8px; + -webkit-border-radius: 8px; + color: white; + text-align: center; +} + +h1 .subheader { + display:block; + font-size: 70%; +} +.upper { + text-transform: capitalize; +} + + +.footer { + font-size: 0.75em; + text-align: center; +} + +.clr { + clear: both; +} + + +.info dt { + display: inline; + font-weight: bold; +} + +.info dd { + display: inline; + margin: 0; +} +.info img { + max-width: 100%; +} + +#top-bar { + background-image: -webkit-gradient(linear, left top, left bottom, + from(#7d828c), + to(#121a2e)); +} + +#back-button { + display:none; + float:left; + color: #fff; + text-decoration: none; + padding: 7px 10px; + -webkit-border-radius: 5px; + + background-image: -webkit-gradient(linear, left top, left bottom, + from(#7d828c), + color-stop(0.5, #303749), + color-stop(0.5, #121a2e), + to(#121a2e)); + border: solid 1px rgba(79, 79, 79, 0.75); + + position: relative; + padding-left: 5px; + margin-left: 1.5em; + margin-top: .5em; +} + + +#back-button:before { + content: " "; + display: block; + z-index: 0; + background-image: + -webkit-gradient(linear, left top, right bottom, + from(#7d828c), + color-stop(0.5, #303749), + color-stop(0.5, #121a2e), + to(#121a2e)); + border-left: solid 1px #484e59; + border-bottom: solid 1px #9aa5bb; + -webkit-border-top-left-radius: 5px; + -webkit-border-bottom-right-radius: 5px; + -webkit-border-bottom-left-radius: 4px; + height: 23.5px; + width: 23.5px; + display: inline-block; + -webkit-transform: rotate(45deg); + -webkit-mask-image: + -webkit-gradient(linear, left bottom, right top, + from(#000000), + color-stop(0.5,#000000), + color-stop(0.5, transparent), + to(transparent)); + position: absolute; + left: -9px; + top: 2.5px; + -webkit-background-clip: content; +} diff --git a/www/img/cc-by-sa.png b/www/img/cc-by-sa.png new file mode 100644 index 0000000..12c70b6 Binary files /dev/null and b/www/img/cc-by-sa.png differ diff --git a/www/img/icon-Book.png b/www/img/icon-Book.png new file mode 100644 index 0000000..3c18284 Binary files /dev/null and b/www/img/icon-Book.png differ diff --git a/www/img/icon-BookText.png b/www/img/icon-BookText.png new file mode 100644 index 0000000..60d38ee Binary files /dev/null and b/www/img/icon-BookText.png differ diff --git a/www/img/icon-Bookmarks.png b/www/img/icon-Bookmarks.png new file mode 100644 index 0000000..4cb6b9c Binary files /dev/null and b/www/img/icon-Bookmarks.png differ diff --git a/www/img/icon-Last.png b/www/img/icon-Last.png new file mode 100644 index 0000000..81d1b46 Binary files /dev/null and b/www/img/icon-Last.png differ diff --git a/www/img/icon-Tag.png b/www/img/icon-Tag.png new file mode 100644 index 0000000..db88d3a Binary files /dev/null and b/www/img/icon-Tag.png differ diff --git a/www/img/logo-fnp.png b/www/img/logo-fnp.png new file mode 100644 index 0000000..8720140 Binary files /dev/null and b/www/img/logo-fnp.png differ diff --git a/www/img/logo-wl.png b/www/img/logo-wl.png new file mode 100644 index 0000000..a18e950 Binary files /dev/null and b/www/img/logo-wl.png differ diff --git a/www/img/procent.png b/www/img/procent.png new file mode 100644 index 0000000..2e0d73e Binary files /dev/null and b/www/img/procent.png differ diff --git a/www/img/spinner.png b/www/img/spinner.png new file mode 100644 index 0000000..bad5a12 Binary files /dev/null and b/www/img/spinner.png differ diff --git a/www/js/NativeControls.js b/www/js/NativeControls.js new file mode 100644 index 0000000..6e6d3c3 --- /dev/null +++ b/www/js/NativeControls.js @@ -0,0 +1,309 @@ +// JS :::::::: + +/* + // This code is adapted from the work of: + // Created by Michael Nachbaur on 13/04/09. + // Copyright 2009 Decaf Ninja Software. All rights reserved. + // MIT licensed + */ + +/** + * This class exposes mobile phone interface controls to JavaScript, such as + * native tab and tool bars, etc. + * @constructor + */ +function NativeControls() { + this.tabBarTag = 0; + this.toolBarIndexes = 0; + + this.tabBarCallbacks = {}; + this.toolBarCallbacks = {}; + + this.tappedToolBarItem = null; + this.selectedTabBarItem = null; +} + +/** + * Create a native tab bar that can have tab buttons added to it which can respond to events. + */ +NativeControls.prototype.createTabBar = function() { + PhoneGap.exec("NativeControls.createTabBar"); +}; + +/** + * Show a tab bar. The tab bar has to be created first. + * @param {Object} [options] Options indicating how the tab bar should be shown: + * - \c height integer indicating the height of the tab bar (default: \c 49) + * - \c position specifies whether the tab bar will be placed at the \c top or \c bottom of the screen (default: \c bottom) + */ +NativeControls.prototype.showTabBar = function(options) { + if (!options) options = {'position' : 'bottom'}; + PhoneGap.exec("NativeControls.showTabBar", options); +}; + +/** + * Hide a tab bar. The tab bar has to be created first. + */ +NativeControls.prototype.hideTabBar = function(animate) { + if (animate == undefined || animate == null) + animate = true; + PhoneGap.exec("NativeControls.hideTabBar", { animate: animate }); +}; + +/** + * Create a new tab bar item for use on a previously created tab bar. Use ::showTabBarItems to show the new item on the tab bar. + * + * If the supplied image name is one of the labels listed below, then this method will construct a tab button + * using the standard system buttons. Note that if you use one of the system images, that the \c title you supply will be ignored. + * + * Tab Buttons + * - tabButton:More + * - tabButton:Favorites + * - tabButton:Featured + * - tabButton:TopRated + * - tabButton:Recents + * - tabButton:Contacts + * - tabButton:History + * - tabButton:Bookmarks + * - tabButton:Search + * - tabButton:Downloads + * - tabButton:MostRecent + * - tabButton:MostViewed + * @param {String} name internal name to refer to this tab by + * @param {String} [title] title text to show on the tab, or null if no text should be shown + * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown + * @param {Object} [options] Options for customizing the individual tab item + * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden + */ +NativeControls.prototype.createTabBarItem = function(name, label, image, options) { + + var tag = this.tabBarTag++; + if (options && 'onSelect' in options && typeof(options['onSelect']) == 'function') { + this.tabBarCallbacks[tag] = {'onSelect':options.onSelect,'name':name}; + //delete options.onSelect; + } + + PhoneGap.exec("NativeControls.createTabBarItem", name, label, image, tag, options); +}; + +/** + * Update an existing tab bar item to change its badge value. + * @param {String} name internal name used to represent this item when it was created + * @param {Object} options Options for customizing the individual tab item + * - \c badge value to display in the optional circular badge on the item; if null or unspecified, the badge will be hidden + */ +NativeControls.prototype.updateTabBarItem = function(name, options) { + if (!options) options = {}; + PhoneGap.exec("NativeControls.updateTabBarItem", name, options); +}; + +/** + * Show previously created items on the tab bar + * @param {String} arguments... the item names to be shown + * @param {Object} [options] dictionary of options, notable options including: + * - \c animate indicates that the items should animate onto the tab bar + * @see createTabBarItem + * @see createTabBar + */ +NativeControls.prototype.showTabBarItems = function() { + var parameters = [ "NativeControls.showTabBarItems" ]; + for (var i = 0; i < arguments.length; i++) { + parameters.push(arguments[i]); + } + PhoneGap.exec.apply(this, parameters); +}; + + +/** + * Function to detect currently selected tab bar item + * @see createTabBarItem + * @see showTabBarItems + */ +NativeControls.prototype.getSelectedTabBarItem = function() { + return this.selectedTabBarItem; +}; + + +/** + * Manually select an individual tab bar item, or nil for deselecting a currently selected tab bar item. + * @param {String} tabName the name of the tab to select, or null if all tabs should be deselected + * @see createTabBarItem + * @see showTabBarItems + */ +NativeControls.prototype.selectTabBarItem = function(tab) { + PhoneGap.exec("NativeControls.selectTabBarItem", tab); +}; + +/** + * Function called when a tab bar item has been selected. + * @param {Number} tag the tag number for the item that has been selected + */ +NativeControls.prototype.tabBarItemSelected = function(tag) +{ + this.selectedTabBarItem = tag; + if (typeof(this.tabBarCallbacks[tag].onSelect) == 'function') + this.tabBarCallbacks[tag].onSelect(this.tabBarCallbacks[tag].name); +}; + + + + +/** + * Create a toolbar. + */ +NativeControls.prototype.createToolBar = function() +{ + PhoneGap.exec("NativeControls.createToolBar"); +}; +/** + * Function called when a tab bar item has been selected. + * @param {String} title the title to set within the toolbar + */ +NativeControls.prototype.setToolBarTitle = function(title) +{ + PhoneGap.exec("NativeControls.setToolBarTitle", title); +}; +/* + * Added by Emile khattar: emile818@gmail.com emile@sign.al + * @ 2011-07-08 , 5.00 AM + */ +/** + * Set toolBarItems = nil; + */ +NativeControls.prototype.resetToolBar = function() { + PhoneGap.exec("NativeControls.resetToolBar"); +}; +/** + * Hide the tool bar + * @brief hide the tool bar + */ +NativeControls.prototype.hideToolBar = function() { + PhoneGap.exec("NativeControls.hideToolBar"); +}; + +/** + * Show the tool bar ( re-render elements ) + * @brief Show the tool bar + */ +NativeControls.prototype.showToolBar = function() { + PhoneGap.exec("NativeControls.showToolBar"); +}; + +/** + * Set the toolbar title + * @param: title + */ +NativeControls.prototype.setToolBarTitle = function(title) { + PhoneGap.exec("NativeControls.setToolBarTitle" , title ); +}; + + +/** + * Create a new tool bar button item for use on a previously created tool bar. Use ::showToolBar to show the new item on the tool bar. + * + * If the supplied image name is one of the labels listed below, then this method will construct a button + * using the standard system buttons. Note that if you use one of the system images, that the title you supply will be ignored. + * + * Tool Bar Buttons + * UIBarButtonSystemItemDone + * UIBarButtonSystemItemCancel + * UIBarButtonSystemItemEdit + * UIBarButtonSystemItemSave + * UIBarButtonSystemItemAdd + * UIBarButtonSystemItemFlexibleSpace + * UIBarButtonSystemItemFixedSpace + * UIBarButtonSystemItemCompose + * UIBarButtonSystemItemReply + * UIBarButtonSystemItemAction + * UIBarButtonSystemItemOrganize + * UIBarButtonSystemItemBookmarks + * UIBarButtonSystemItemSearch + * UIBarButtonSystemItemRefresh + * UIBarButtonSystemItemStop + * UIBarButtonSystemItemCamera + * UIBarButtonSystemItemTrash + * UIBarButtonSystemItemPlay + * UIBarButtonSystemItemPause + * UIBarButtonSystemItemRewind + * UIBarButtonSystemItemFastForward + * UIBarButtonSystemItemUndo, // iOS 3.0 and later + * UIBarButtonSystemItemRedo, // iOS 3.0 and later + * UIBarButtonSystemItemPageCurl, // iOS 4.0 and later + * @param {String} name internal name to refer to this tab by + * @param {String} [title] title text to show on the button, or null if no text should be shown + * @param {String} [image] image filename or internal identifier to show, or null if now image should be shown + * @param {Object} [options] Options for customizing the individual tab item [no option available at this time - this is for future proofing] + * + */ +NativeControls.prototype.createToolBarItem = function(name , title , image , options) { + var toolBarIndex = this.toolBarIndexes++; + if (options && 'onTap' in options && typeof(options['onTap']) == 'function') { + this.toolBarCallbacks[toolBarIndex] = {'onTap':options.onTap,'name':name}; + //delete options.onSelect; + } + //modify the NativeControls.m to change the options quickly + // the instance name on the plugin can be passed with option for now it is hardcode in objc // Emile + PhoneGap.exec("NativeControls.createToolBarItem" , name , title , image , options ); +}; + +/** + * Function called when a tool bar item has been tapped. + * @param {Number} tag the tag number for the item that has been selected + */ +NativeControls.prototype.toolBarButtonTapped = function(tag) +{ + this.tappedToolBarItem = tag; + if (typeof(this.toolBarCallbacks[tag].onTap) == 'function') + this.toolBarCallbacks[tag].onTap(this.toolBarCallbacks[tag].name); +}; + + + + + +NativeControls.prototype.createActionSheet = function(buttonTitles,actionSheetTitle,cancelButtonIndex,destructiveButtonIndex) +{ + var options = {}; + + if(actionSheetTitle != null) + { + options.title = actionSheetTitle; + } + if(cancelButtonIndex != null) + { + options.cancelButtonIndex = cancelButtonIndex; + } + if(destructiveButtonIndex != null) + { + options.destructiveButtonIndex = destructiveButtonIndex; + } + + var params = [ "NativeControls.createActionSheet",options ]; + for (var i = 0; i < buttonTitles.length; i++) + { + params.push(buttonTitles[i]); + } + PhoneGap.exec.apply(this, params); + + this.actionSheetDelegate = {}; + return this.actionSheetDelegate; +} + + +NativeControls.prototype._onActionSheetDismissed = function(index) +{ + this.actionSheetDelegate.onActionSheetDismissed(index); +} + + + +NativeControls.prototype.setStatusBarVisibilty = function(bHide) +{ + PhoneGap.exec("StatusBar.setHidden",bHide); +} + + +if(!window.plugins) + window.plugins = {}; + + window.plugins.nativeControls = new NativeControls(); diff --git a/www/js/catalogue.js b/www/js/catalogue.js new file mode 100644 index 0000000..40cd0bd --- /dev/null +++ b/www/js/catalogue.js @@ -0,0 +1,408 @@ +/* + * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. + * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. + */ + +var DB_VER = '0.9.17'; + +var WL_INITIAL = WL + '/media/api/mobile/initial/initial.db'; +var WL_UPDATE = WL + '/api/changes/SINCE.json?book_fields=author,html,parent,parent_number,sort_key,title' + + '&tag_fields=books,category,name,sort_key' + + '&tag_categories=author,epoch,genre,kind'; + + + +var categories = {'author': 'autor', + 'epoch': 'epoka', + 'genre': 'gatunek', + 'kind': 'rodzaj', + 'theme': 'motyw' + } + +// FIXME: htmlescape strings! + + +// for preparing sql statements +// use like: +// var s = new Sql("INSERT ... '{0}', '{1}' ..."; +// s.prepare("abc", ...) +var Sql = function(scheme) { + var self = this; + self.text = scheme; + + self.sql_escape = function(term) { + return term.toString().replace("'", "''"); + }; + + self.prepare = function() { + var args = arguments; + return self.text.replace(/{(\d+)}/g, function(match, number) { + return self.sql_escape(args[parseInt(number)]); + }); + } +}; + + +var Catalogue = new function() { + /* API for database */ + + var self = this; + self.db = null; + + this.init = function(success, error) { + debug('Catalogue.init'); + + self.updateDB(function() { + if (!self.db) + self.db = window.openDatabase("wolnelektury", "1.0", "WL Catalogue", 1000000); + if (self.db) { + /*var regexp = { + onFunctionCall: function(val) { + var re = new RegExp(val.getString(0)); + if (val.getString(1).match(re)) + return 1; + else + return 0; + } + }; + self.db.createFunction("REGEXP", 2, regexp);*/ + + success && success(); + } else { + error && error('Nie mogę otworzyć bazy danych: ' + err); + } + + }, function(err) { + error && error('Błąd migracji: ' + err); + }); + }; + + self.sqlSanitize = function(term) { + return term.toString().replace("'", "''"); + }; + + + /* check if DB needs updating and upload a fresh copy, if so */ + this.updateDB = function(success, error) { + var has_ver = window.localStorage.getItem('db_ver'); + if (has_ver == DB_VER) { + debug('db ok, skipping') + success && success(); + return; + } + + var done = function() { + FileRepo.clear(); + window.localStorage.setItem('db_ver', DB_VER); + debug('db updated'); + success && success(); + }; + + // db initialize + // this is Android-specific for now + self.createdb(done, error); + }; + + + this.createdb = function(success, error) { + debug('create db'); + + var dbname = "wolnelektury"; + var db = window.openDatabase(dbname, "1.0", "WL Catalogue", 1000000); + if (db) { + debug('db created successfully'); + self.db = db; + var sqls = []; + sqls.push('CREATE TABLE IF NOT EXISTS book (\ + id INTEGER PRIMARY KEY,\ + title VARCHAR,\ + html_file VARCHAR,\ + html_file_size INTEGER,\ + parent INTEGER,\ + parent_number INTEGER,\ + sort_key VARCHAR,\ + pretty_size VARCHAR,\ + authors VARCHAR,\ + _local BOOLEAN\ + );'); + sqls.push('CREATE INDEX IF NOT EXISTS book_title_index ON book (title);'); + sqls.push('CREATE INDEX IF NOT EXISTS book_sort_key_index ON book (sort_key);'); + sqls.push('CREATE INDEX IF NOT EXISTS book_parent_index ON book (parent);'); + sqls.push('CREATE TABLE IF NOT EXISTS tag (\ + id INTEGER PRIMARY KEY,\ + name VARCHAR,\ + category VARCHAR,\ + sort_key VARCHAR,\ + books VARCHAR\ + );'); + sqls.push('CREATE INDEX IF NOT EXISTS tag_name_index ON tag (name);'); + sqls.push('CREATE INDEX IF NOT EXISTS tag_category_index ON tag (category);'); + sqls.push('CREATE INDEX IF NOT EXISTS tag_sort_key_index ON tag (name);'); + sqls.push('CREATE TABLE IF NOT EXISTS state (last_checked INTEGER);'); + sqls.push('DELETE FROM state;'); + sqls.push('INSERT INTO state (last_checked) VALUES(0);'); + self.chainSqls(sqls, success, error); + /*DBPut.fetch(WL_INITIAL, function(data) { + debug('db fetch successful'); + success && success(); + }, function(data) { + error && error('Błąd podczas pobierania bazy danych: ' + data); + });*/ + } else { + error && error('Błąd podczas inicjowania bazy danych: ' + data); + } + }; + + + this.withState = function(callback) { + self.db.transaction(function(tx) { + tx.executeSql("SELECT * FROM state", [], + function(tx, results) { + if (results.rows.length) { + callback(results.rows.item(0)); + } + else { + callback({last_checked: 0}); + } + }); + }); + }; + + + this.withBook = function(id, callback, error) { + debug('withBook '+id) + self.db.transaction(function(tx) { + tx.executeSql("SELECT * FROM book WHERE id="+id, [], + function(tx, results) { + if (results.rows.length) { + callback(results.rows.item(0)); + } + else { + error && error(); + } + }); + }); + }; + + this.withBooks = function(ids, callback) { + debug('withBooks ' + ids) + self.db.transaction(function(tx) { + tx.executeSql("SELECT * FROM book WHERE id IN ("+ids+") ORDER BY sort_key", [], + function(tx, results) { + var items = []; + var count = results.rows.length; + for (var i=0; i 0) { + var url = self.viewStack.pop(); + debug('History.goBack: ' + url); + if (self.viewStack.length == 0) + View.showBack(false); + View.enter(url); + } + else { + debug('History: exiting'); + navigator.app.exitApp(); + } + }; + + + self.lastRead = function() { + var last_read = window.localStorage.getItem('History.last_ids'); + try { + return last_read.split(';'); + } catch (err) { + return []; + } + }; + + self.addRead = function(id, offset) { + id = "" + id; // this should check if int + debug("History.addRead: " + id); + var last_read = self.lastRead(); + var lastly = last_read.indexOf(id); + if (lastly != -1) { + last_read.splice(lastly, 1); + } + while (last_read.length >= 10) { + last_read.pop(); + } + last_read.unshift(id); + window.localStorage.setItem('History.last_ids', last_read.join(';')); + } + + + self.bookmarks = function() { + var bookmarks = window.localStorage.getItem('History.bookmarks'); + try { + return JSON.parse(bookmarks) || []; + } catch (err) { + return []; + } + }; + + self.addBookmark = function(name) { + var id=(new Date).getTime(); + debug("History.addBookmark: " + id); + + var bms = self.bookmarks(); + bms.unshift({ + id: id, + name: name, + title: View.currentTitle, + view: View.currentView, + par: View.currentPar, + offset: currentOffset() + }); + window.localStorage.setItem('History.bookmarks', JSON.stringify(bms)); + } + + self.deleteBookmark = function(id) { + debug("History.deleteBookmark: " + id); + var bms = self.bookmarks(); + for (b in bms) { + if (bms[b].id == id) { + bms.splice(b, 1); + } + } + window.localStorage.setItem('History.bookmarks', JSON.stringify(bms)); + View.onBookmarkChange(); + } +} diff --git a/www/js/links.js b/www/js/links.js new file mode 100644 index 0000000..3a7465a --- /dev/null +++ b/www/js/links.js @@ -0,0 +1,53 @@ +/* + * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. + * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. + */ + +var Links = new function() { + var self = this; + + self.href = function(view, par) { + return view+"/"+par; + }; + + self.button = function(view, par, text, offset) { + offset = offset || 0; + var html = "
"; + icon = view; + if (icon != 'Book' && icon != 'Bookmarks' && icon != 'BookText' && + icon != 'Last' && icon != 'Tag') { + icon = 'Tag'; + } + html += ""; + html += "
" + text + "
"; + html += "
"; + html += "
\n"; + return html; + }; + + self.bookLink = function(book) { + var target = 'Book'; + var note = ''; + + if (book.html_file) { + // this assumes that either book has a html XOR it has children + target = 'BookText'; + note = "
"; + if (book._local) + note += 'Pobrane'; + else { + note += book.pretty_size; + } + note += "
"; + } + + return self.button(target, book.id, + "
" + book.authors + "
" + + book.title + note); + }; + + self.deleteButton = function(id) { + return "
x
"; + }; +} diff --git a/www/js/main.js b/www/js/main.js new file mode 100644 index 0000000..cf92353 --- /dev/null +++ b/www/js/main.js @@ -0,0 +1,70 @@ +/* + * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. + * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. + */ + +var WL = 'http://www.wolnelektury.pl'; + + +// disable debugging +//debug = function(text) {}; +debug = function(text) {console.log(text);}; + + +function onLoad() { + debug('onLoad'); + document.addEventListener("deviceready", onDeviceReady, false); +} + +function onDeviceReady() { + debug('onDeviceReady'); + + var error = function(err) { alert(err); }; + + FileRepo.init(function() { + debug('after FileRepo.init'); + Catalogue.init(function() { + debug('after catalogue.init'); + History.init(function() { + debug('after history.init'); + View.init(function() { + Menu.init(function() { + View.go(); + Catalogue.sync(function() { + Catalogue.updateLocal(); + }, error); + }, error); + }, error); + }, error); + }, error); + }); +} + + +var currentOffset = function() { + var scr = document.body.scrollTop; + var h = document.getElementById('nothing').offsetTop; + return scr/h; +}; + +var setOffset = function(offset) { + var h = document.getElementById('nothing').offsetTop; + setTimeout(function() {scroll(0, h*offset); }, 10); +}; + + +var prettySize = function(size) { + if (!size) return ""; + var units = ['B', 'KiB', 'MiB', 'GiB']; + size = size; + var unit = units.shift(); + while (size > 1000 && units.length) { + size /= 1024; + unit = units.shift(); + } + if (size < 10) { + return Math.round(size*10)/10 + ' ' + unit; + } + return Math.round(size) + ' ' + unit; +}; + diff --git a/www/js/menu.js b/www/js/menu.js new file mode 100644 index 0000000..11f1be6 --- /dev/null +++ b/www/js/menu.js @@ -0,0 +1,70 @@ +/* + * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. + * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. + */ + +var Menu = new function() { + var self = this; + var infoView = 'ProjectInfo'; + var showInfo = true; + + self.init = function(success) { + window.plugins.nativeControls.createTabBar(); + window.plugins.nativeControls.createTabBarItem("start", "Początek","/www/img/icon-Last.png", {onSelect: Menu.start}); + window.plugins.nativeControls.createTabBarItem("addmark","Dodaj zakładkę","/www/img/icon-Bookmarks.png", {onSelect: Menu.bookmark}); + + //window.plugins.nativeControls.createTabBarItem("info",self.infoLabel,"/www/img/icon-Tag.png", {onSelect: Menu.info}); + //window.plugins.nativeControls.createTabBarItem("night","Tryb nocny","", {onSelect: Menu.toggleNightMode}); + //window.plugins.nativeControls.showTabBarItems("start", "addmark", "info", "night"); + //window.plugins.nativeControls.showTabBar(); + self.setInfoButton(self.infoView, 'O projekcie', self.showInfo); + self.setNightModeLabel(); + success && success(); + }; + + self.start = function() { + History.visit(''); + window.plugins.nativeControls.selectTabBarItem(''); + }; + + self.info = function() { + History.visit(self.infoView + '/' + View.currentPar); + window.plugins.nativeControls.selectTabBarItem(''); + }; + + self.bookmark = function() { + var name = prompt('Nazwa zakładki'); + if (name != null) + History.addBookmark(name); + window.plugins.nativeControls.selectTabBarItem(''); + }; + + self.setNightModeLabel = function() { + var label = 'Tryb nocny'; + if (View.getNightMode()) label = 'Tryb dzienny'; + window.plugins.nativeControls.createTabBarItem("night",label,"/www/img/icon-Tag.png", {onSelect: Menu.toggleNightMode}); + }; + + self.refresh = function() { + var items = new Array(); + if (View.currentView != 'Index') + items.push('start'); + items.push("addmark"); + if (self.showInfo) + items.push("info"); + items.push("night"); + window.plugins.nativeControls.showTabBarItems.apply(this, items); + window.plugins.nativeControls.showTabBar(); + }; + + self.toggleNightMode = function() { + View.toggleNightMode(); + self.setNightModeLabel(); + }; + + self.setInfoButton = function(view, label, enabled) { + self.infoView = view; + self.showInfo = enabled; + window.plugins.nativeControls.createTabBarItem("info",label,"/www/img/icon-Tag.png", {onSelect: Menu.info}); + }; +} diff --git a/www/js/menuinterface.js b/www/js/menuinterface.js new file mode 100644 index 0000000..596f859 --- /dev/null +++ b/www/js/menuinterface.js @@ -0,0 +1,41 @@ +/* + * This file is part of WolneLektury-Mobile, licensed under GNU Affero GPLv3 or later. + * Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. + */ + +/** + * + * @return Object literal singleton instance of MenuInterface + */ +var MenuInterface = { + /** + * @param asset Path to the asset (relative to assets dir) + * @param target Path to DB file (relative to app db files dir) + * @param overwrite + * @param win Success callback + * @param fail Error callback + */ + setInfoButton: function(label, enabled, win, fail) { + if (enabled == false) enabled = "false"; + else enabled = "true"; + return PhoneGap.exec( + win, + fail, + "MenuInterface", + "setInfoButton", + [label, enabled] + ); + }, + setNightMode: function(enabled, win, fail) { + if (enabled == false) enabled = "false"; + else enabled = "true"; + return PhoneGap.exec( + win, + fail, + "MenuInterface", + "setNightMode", + [enabled] + ); + }, +}; + diff --git a/www/js/phonegap-1.1.0.js b/www/js/phonegap-1.1.0.js new file mode 100644 index 0000000..a18f29d --- /dev/null +++ b/www/js/phonegap-1.1.0.js @@ -0,0 +1,4097 @@ +/* + * PhoneGap v1.1.0 is available under *either* the terms of the modified BSD license *or* the + * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text. + * + * Copyright (c) 2005-2010, Nitobi Software Inc. + * Copyright (c) 2010-2011, IBM Corporation + * Copyright (c) 2011, Codevise Solutions Ltd. + * Copyright (c) 2011, Proyectos Equis Ka, S.L. + * + */ + +if (typeof PhoneGap === "undefined") { + +if (typeof(DeviceInfo) !== 'object'){ + DeviceInfo = {}; +} +/** + * This represents the PhoneGap API itself, and provides a global namespace for accessing + * information about the state of PhoneGap. + * @class + */ +PhoneGap = { + // This queue holds the currently executing command and all pending + // commands executed with PhoneGap.exec(). + commandQueue: [], + // Indicates if we're currently in the middle of flushing the command + // queue on the native side. + commandQueueFlushing: false, + _constructors: [], + documentEventHandler: {}, // Collection of custom document event handlers + windowEventHandler: {} +}; + +/** + * List of resource files loaded by PhoneGap. + * This is used to ensure JS and other files are loaded only once. + */ +PhoneGap.resources = {base: true}; + +/** + * Determine if resource has been loaded by PhoneGap + * + * @param name + * @return + */ +PhoneGap.hasResource = function(name) { + return PhoneGap.resources[name]; +}; + +/** + * Add a resource to list of loaded resources by PhoneGap + * + * @param name + */ +PhoneGap.addResource = function(name) { + PhoneGap.resources[name] = true; +}; + +/** + * Boolean flag indicating if the PhoneGap API is available and initialized. + */ // TODO: Remove this, it is unused here ... -jm +PhoneGap.available = DeviceInfo.uuid != undefined; + +/** + * Add an initialization function to a queue that ensures it will run and initialize + * application constructors only once PhoneGap has been initialized. + * @param {Function} func The function callback you want run once PhoneGap is initialized + */ +PhoneGap.addConstructor = function(func) { + var state = document.readyState; + if ( ( state == 'loaded' || state == 'complete' ) && DeviceInfo.uuid != null ) + { + func(); + } + else + { + PhoneGap._constructors.push(func); + } +}; + +(function() + { + var timer = setInterval(function() + { + + var state = document.readyState; + + if ( ( state == 'loaded' || state == 'complete' ) && DeviceInfo.uuid != null ) + { + clearInterval(timer); // stop looking + // run our constructors list + while (PhoneGap._constructors.length > 0) + { + var constructor = PhoneGap._constructors.shift(); + try + { + constructor(); + } + catch(e) + { + if (typeof(console['log']) == 'function') + { + console.log("Failed to run constructor: " + console.processMessage(e)); + } + else + { + alert("Failed to run constructor: " + e.message); + } + } + } + // all constructors run, now fire the deviceready event + var e = document.createEvent('Events'); + e.initEvent('deviceready'); + document.dispatchEvent(e); + } + }, 1); +})(); + +// session id for calls +PhoneGap.sessionKey = 0; + +// centralized callbacks +PhoneGap.callbackId = 0; +PhoneGap.callbacks = {}; +PhoneGap.callbackStatus = { + NO_RESULT: 0, + OK: 1, + CLASS_NOT_FOUND_EXCEPTION: 2, + ILLEGAL_ACCESS_EXCEPTION: 3, + INSTANTIATION_EXCEPTION: 4, + MALFORMED_URL_EXCEPTION: 5, + IO_EXCEPTION: 6, + INVALID_ACTION: 7, + JSON_EXCEPTION: 8, + ERROR: 9 + }; + +/** + * Creates a gap bridge iframe used to notify the native code about queued + * commands. + * + * @private + */ +PhoneGap.createGapBridge = function() { + gapBridge = document.createElement("iframe"); + gapBridge.setAttribute("style", "display:none;"); + gapBridge.setAttribute("height","0px"); + gapBridge.setAttribute("width","0px"); + gapBridge.setAttribute("frameborder","0"); + document.documentElement.appendChild(gapBridge); + return gapBridge; +} + +/** + * Execute a PhoneGap command by queuing it and letting the native side know + * there are queued commands. The native side will then request all of the + * queued commands and execute them. + * + * Arguments may be in one of two formats: + * + * FORMAT ONE (preferable) + * The native side will call PhoneGap.callbackSuccess or + * PhoneGap.callbackError, depending upon the result of the action. + * + * @param {Function} success The success callback + * @param {Function} fail The fail callback + * @param {String} service The name of the service to use + * @param {String} action The name of the action to use + * @param {String[]} [args] Zero or more arguments to pass to the method + * + * FORMAT TWO + * @param {String} command Command to be run in PhoneGap, e.g. + * "ClassName.method" + * @param {String[]} [args] Zero or more arguments to pass to the method + * object parameters are passed as an array object + * [object1, object2] each object will be passed as + * JSON strings + */ +PhoneGap.exec = function() { + if (!PhoneGap.available) { + alert("ERROR: Attempting to call PhoneGap.exec()" + +" before 'deviceready'. Ignoring."); + return; + } + + var successCallback, failCallback, service, action, actionArgs; + var callbackId = null; + if (typeof arguments[0] !== "string") { + // FORMAT ONE + successCallback = arguments[0]; + failCallback = arguments[1]; + service = arguments[2]; + action = arguments[3]; + actionArgs = arguments[4]; + + // Since we need to maintain backwards compatibility, we have to pass + // an invalid callbackId even if no callback was provided since plugins + // will be expecting it. The PhoneGap.exec() implementation allocates + // an invalid callbackId and passes it even if no callbacks were given. + callbackId = 'INVALID'; + } else { + // FORMAT TWO + splitCommand = arguments[0].split("."); + action = splitCommand.pop(); + service = splitCommand.join("."); + actionArgs = Array.prototype.splice.call(arguments, 1); + } + + // Start building the command object. + var command = { + className: service, + methodName: action, + arguments: [] + }; + + // Register the callbacks and add the callbackId to the positional + // arguments if given. + if (successCallback || failCallback) { + callbackId = service + PhoneGap.callbackId++; + PhoneGap.callbacks[callbackId] = + {success:successCallback, fail:failCallback}; + } + if (callbackId != null) { + command.arguments.push(callbackId); + } + + for (var i = 0; i < actionArgs.length; ++i) { + var arg = actionArgs[i]; + if (arg == undefined || arg == null) { + continue; + } else if (typeof(arg) == 'object') { + command.options = arg; + } else { + command.arguments.push(arg); + } + } + + // Stringify and queue the command. We stringify to command now to + // effectively clone the command arguments in case they are mutated before + // the command is executed. + PhoneGap.commandQueue.push(JSON.stringify(command)); + + // If the queue length is 1, then that means it was empty before we queued + // the given command, so let the native side know that we have some + // commands to execute, unless the queue is currently being flushed, in + // which case the command will be picked up without notification. + if (PhoneGap.commandQueue.length == 1 && !PhoneGap.commandQueueFlushing) { + if (!PhoneGap.gapBridge) { + PhoneGap.gapBridge = PhoneGap.createGapBridge(); + } + + PhoneGap.gapBridge.src = "gap://ready"; + } +} + +/** + * Called by native code to retrieve all queued commands and clear the queue. + */ +PhoneGap.getAndClearQueuedCommands = function() { + json = JSON.stringify(PhoneGap.commandQueue); + PhoneGap.commandQueue = []; + return json; +} + +/** + * Called by native code when returning successful result from an action. + * + * @param callbackId + * @param args + * args.status - PhoneGap.callbackStatus + * args.message - return value + * args.keepCallback - 0 to remove callback, 1 to keep callback in PhoneGap.callbacks[] + */ +PhoneGap.callbackSuccess = function(callbackId, args) { + if (PhoneGap.callbacks[callbackId]) { + + // If result is to be sent to callback + if (args.status == PhoneGap.callbackStatus.OK) { + try { + if (PhoneGap.callbacks[callbackId].success) { + PhoneGap.callbacks[callbackId].success(args.message); + } + } + catch (e) { + console.log("Error in success callback: "+callbackId+" = "+e); + } + } + + // Clear callback if not expecting any more results + if (!args.keepCallback) { + delete PhoneGap.callbacks[callbackId]; + } + } +}; + +/** + * Called by native code when returning error result from an action. + * + * @param callbackId + * @param args + */ +PhoneGap.callbackError = function(callbackId, args) { + if (PhoneGap.callbacks[callbackId]) { + try { + if (PhoneGap.callbacks[callbackId].fail) { + PhoneGap.callbacks[callbackId].fail(args.message); + } + } + catch (e) { + console.log("Error in error callback: "+callbackId+" = "+e); + } + + // Clear callback if not expecting any more results + if (!args.keepCallback) { + delete PhoneGap.callbacks[callbackId]; + } + } +}; + + +/** + * Does a deep clone of the object. + * + * @param obj + * @return + */ +PhoneGap.clone = function(obj) { + if(!obj) { + return obj; + } + + if(obj instanceof Array){ + var retVal = new Array(); + for(var i = 0; i < obj.length; ++i){ + retVal.push(PhoneGap.clone(obj[i])); + } + return retVal; + } + + if (obj instanceof Function) { + return obj; + } + + if(!(obj instanceof Object)){ + return obj; + } + + if (obj instanceof Date) { + return obj; + } + + retVal = new Object(); + for(i in obj){ + if(!(i in retVal) || retVal[i] != obj[i]) { + retVal[i] = PhoneGap.clone(obj[i]); + } + } + return retVal; +}; + +// Intercept calls to document.addEventListener +PhoneGap.m_document_addEventListener = document.addEventListener; + +// Intercept calls to window.addEventListener +PhoneGap.m_window_addEventListener = window.addEventListener; + +/** + * Add a custom window event handler. + * + * @param {String} event The event name that callback handles + * @param {Function} callback The event handler + */ +PhoneGap.addWindowEventHandler = function(event, callback) { + PhoneGap.windowEventHandler[event] = callback; +} + +/** + * Add a custom document event handler. + * + * @param {String} event The event name that callback handles + * @param {Function} callback The event handler + */ +PhoneGap.addDocumentEventHandler = function(event, callback) { + PhoneGap.documentEventHandler[event] = callback; +} + +/** + * Intercept adding document event listeners and handle our own + * + * @param {Object} evt + * @param {Function} handler + * @param capture + */ +document.addEventListener = function(evt, handler, capture) { + var e = evt.toLowerCase(); + + // If subscribing to an event that is handled by a plugin + if (typeof PhoneGap.documentEventHandler[e] !== "undefined") { + if (PhoneGap.documentEventHandler[e](e, handler, true)) { + return; // Stop default behavior + } + } + + PhoneGap.m_document_addEventListener.call(document, evt, handler, capture); +}; + +/** + * Intercept adding window event listeners and handle our own + * + * @param {Object} evt + * @param {Function} handler + * @param capture + */ +window.addEventListener = function(evt, handler, capture) { + var e = evt.toLowerCase(); + + // If subscribing to an event that is handled by a plugin + if (typeof PhoneGap.windowEventHandler[e] !== "undefined") { + if (PhoneGap.windowEventHandler[e](e, handler, true)) { + return; // Stop default behavior + } + } + + PhoneGap.m_window_addEventListener.call(window, evt, handler, capture); +}; + +// Intercept calls to document.removeEventListener and watch for events that +// are generated by PhoneGap native code +PhoneGap.m_document_removeEventListener = document.removeEventListener; + +// Intercept calls to window.removeEventListener +PhoneGap.m_window_removeEventListener = window.removeEventListener; + +/** + * Intercept removing document event listeners and handle our own + * + * @param {Object} evt + * @param {Function} handler + * @param capture + */ +document.removeEventListener = function(evt, handler, capture) { + var e = evt.toLowerCase(); + + // If unsubcribing from an event that is handled by a plugin + if (typeof PhoneGap.documentEventHandler[e] !== "undefined") { + if (PhoneGap.documentEventHandler[e](e, handler, false)) { + return; // Stop default behavior + } + } + + PhoneGap.m_document_removeEventListener.call(document, evt, handler, capture); +}; + +/** + * Intercept removing window event listeners and handle our own + * + * @param {Object} evt + * @param {Function} handler + * @param capture + */ +window.removeEventListener = function(evt, handler, capture) { + var e = evt.toLowerCase(); + + // If unsubcribing from an event that is handled by a plugin + if (typeof PhoneGap.windowEventHandler[e] !== "undefined") { + if (PhoneGap.windowEventHandler[e](e, handler, false)) { + return; // Stop default behavior + } + } + + PhoneGap.m_window_removeEventListener.call(window, evt, handler, capture); +}; + +/** + * Method to fire document event + * + * @param {String} type The event type to fire + * @param {Object} data Data to send with event + */ +PhoneGap.fireDocumentEvent = function(type, data) { + var e = document.createEvent('Events'); + e.initEvent(type); + if (data) { + for (var i in data) { + e[i] = data[i]; + } + } + document.dispatchEvent(e); +}; + +/** + * Method to fire window event + * + * @param {String} type The event type to fire + * @param {Object} data Data to send with event + */ +PhoneGap.fireWindowEvent = function(type, data) { + var e = document.createEvent('Events'); + e.initEvent(type); + if (data) { + for (var i in data) { + e[i] = data[i]; + } + } + window.dispatchEvent(e); +}; + +/** + * Method to fire event from native code + * Leaving this generic version to handle problems with iOS 3.x. Is currently used by orientation and battery events + * Remove when iOS 3.x no longer supported and call fireWindowEvent or fireDocumentEvent directly + */ +PhoneGap.fireEvent = function(type, target, data) { + var e = document.createEvent('Events'); + e.initEvent(type); + if (data) { + for (var i in data) { + e[i] = data[i]; + } + } + target = target || document; + if (target.dispatchEvent === undefined) { // ie window.dispatchEvent is undefined in iOS 3.x + target = document; + } + + target.dispatchEvent(e); +}; +/** + * Create a UUID + * + * @return + */ +PhoneGap.createUUID = function() { + return PhoneGap.UUIDcreatePart(4) + '-' + + PhoneGap.UUIDcreatePart(2) + '-' + + PhoneGap.UUIDcreatePart(2) + '-' + + PhoneGap.UUIDcreatePart(2) + '-' + + PhoneGap.UUIDcreatePart(6); +}; + +PhoneGap.UUIDcreatePart = function(length) { + var uuidpart = ""; + for (var i=0; i -1) { + me._batteryListener.splice(pos, 1); + } + } else if (eventType === "batterylow") { + var pos = me._lowListener.indexOf(handler); + if (pos > -1) { + me._lowListener.splice(pos, 1); + } + } else if (eventType === "batterycritical") { + var pos = me._criticalListener.indexOf(handler); + if (pos > -1) { + me._criticalListener.splice(pos, 1); + } + } + + // If there are no more registered event listeners stop the battery listener on native side. + if (me._batteryListener.length === 0 && me._lowListener.length === 0 && me._criticalListener.length === 0) { + PhoneGap.exec(null, null, "com.phonegap.battery", "stop", []); + } + } +}; + +/** + * Callback for battery status + * + * @param {Object} info keys: level, isPlugged + */ +Battery.prototype._status = function(info) { + if (info) { + var me = this; + if (me._level != info.level || me._isPlugged != info.isPlugged) { + // Fire batterystatus event + //PhoneGap.fireWindowEvent("batterystatus", info); + // use this workaround since iOS 3.x does have window.dispatchEvent + PhoneGap.fireEvent("batterystatus", window, info); + + // Fire low battery event + if (info.level == 20 || info.level == 5) { + if (info.level == 20) { + //PhoneGap.fireWindowEvent("batterylow", info); + // use this workaround since iOS 3.x does not have window.dispatchEvent + PhoneGap.fireEvent("batterylow", window, info); + } + else { + //PhoneGap.fireWindowEvent("batterycritical", info); + // use this workaround since iOS 3.x does not have window.dispatchEvent + PhoneGap.fireEvent("batterycritical", window, info); + } + } + } + me._level = info.level; + me._isPlugged = info.isPlugged; + } +}; + +/** + * Error callback for battery start + */ +Battery.prototype._error = function(e) { + console.log("Error initializing Battery: " + e); +}; + +PhoneGap.addConstructor(function() { + if (typeof navigator.battery === "undefined") { + navigator.battery = new Battery(); + PhoneGap.addWindowEventHandler("batterystatus", navigator.battery.eventHandler); + PhoneGap.addWindowEventHandler("batterylow", navigator.battery.eventHandler); + PhoneGap.addWindowEventHandler("batterycritical", navigator.battery.eventHandler); + } +}); +}if (!PhoneGap.hasResource("camera")) { + PhoneGap.addResource("camera"); + + +/** + * This class provides access to the device camera. + * @constructor + */ +Camera = function() { + +} +/** + * Available Camera Options + * {boolean} allowEdit - true to allow editing image, default = false + * {number} quality 0-100 (low to high) default = 100 + * {Camera.DestinationType} destinationType default = DATA_URL + * {Camera.PictureSourceType} sourceType default = CAMERA + * {number} targetWidth - width in pixels to scale image default = 0 (no scaling) + * {number} targetHeight - height in pixels to scale image default = 0 (no scaling) + * {Camera.EncodingType} - encodingType default = JPEG + */ +/** + * Format of image that is returned from getPicture. + * + * Example: navigator.camera.getPicture(success, fail, + * { quality: 80, + * destinationType: Camera.DestinationType.DATA_URL, + * sourceType: Camera.PictureSourceType.PHOTOLIBRARY}) + */ +Camera.DestinationType = { + DATA_URL: 0, // Return base64 encoded string + FILE_URI: 1 // Return file uri +}; +Camera.prototype.DestinationType = Camera.DestinationType; + +/** + * Source to getPicture from. + * + * Example: navigator.camera.getPicture(success, fail, + * { quality: 80, + * destinationType: Camera.DestinationType.DATA_URL, + * sourceType: Camera.PictureSourceType.PHOTOLIBRARY}) + */ +Camera.PictureSourceType = { + PHOTOLIBRARY : 0, // Choose image from picture library + CAMERA : 1, // Take picture from camera + SAVEDPHOTOALBUM : 2 // Choose image from picture library +}; +Camera.prototype.PictureSourceType = Camera.PictureSourceType; + +/** + * Encoding of image returned from getPicture. + * + * Example: navigator.camera.getPicture(success, fail, + * { quality: 80, + * destinationType: Camera.DestinationType.DATA_URL, + * sourceType: Camera.PictureSourceType.CAMERA, + * encodingType: Camera.EncodingType.PNG}) + */ +Camera.EncodingType = { + JPEG: 0, // Return JPEG encoded image + PNG: 1 // Return PNG encoded image +}; +Camera.prototype.EncodingType = Camera.EncodingType; + +/** + * Type of pictures to select from. Only applicable when + * PictureSourceType is PHOTOLIBRARY or SAVEDPHOTOALBUM + * + * Example: navigator.camera.getPicture(success, fail, + * { quality: 80, + * destinationType: Camera.DestinationType.DATA_URL, + * sourceType: Camera.PictureSourceType.PHOTOLIBRARY, + * mediaType: Camera.MediaType.PICTURE}) + */ +Camera.MediaType = { + PICTURE: 0, // allow selection of still pictures only. DEFAULT. Will return format specified via DestinationType + VIDEO: 1, // allow selection of video only, ONLY RETURNS URL + ALLMEDIA : 2 // allow selection from all media types +}; +Camera.prototype.MediaType = Camera.MediaType; + +/** + * Gets a picture from source defined by "options.sourceType", and returns the + * image as defined by the "options.destinationType" option. + + * The defaults are sourceType=CAMERA and destinationType=DATA_URL. + * + * @param {Function} successCallback + * @param {Function} errorCallback + * @param {Object} options + */ +Camera.prototype.getPicture = function(successCallback, errorCallback, options) { + // successCallback required + if (typeof successCallback != "function") { + console.log("Camera Error: successCallback is not a function"); + return; + } + + // errorCallback optional + if (errorCallback && (typeof errorCallback != "function")) { + console.log("Camera Error: errorCallback is not a function"); + return; + } + + PhoneGap.exec(successCallback, errorCallback, "com.phonegap.camera","getPicture",[options]); +}; + + + +PhoneGap.addConstructor(function() { + if (typeof navigator.camera == "undefined") navigator.camera = new Camera(); +}); +}; + +if (!PhoneGap.hasResource("device")) { + PhoneGap.addResource("device"); + +/** + * this represents the mobile device, and provides properties for inspecting the model, version, UUID of the + * phone, etc. + * @constructor + */ +Device = function() +{ + this.platform = null; + this.version = null; + this.name = null; + this.phonegap = null; + this.uuid = null; + try + { + this.platform = DeviceInfo.platform; + this.version = DeviceInfo.version; + this.name = DeviceInfo.name; + this.phonegap = DeviceInfo.gap; + this.uuid = DeviceInfo.uuid; + + } + catch(e) + { + // TODO: + } + this.available = PhoneGap.available = this.uuid != null; +} + +PhoneGap.addConstructor(function() { + if (typeof navigator.device === "undefined") { + navigator.device = window.device = new Device(); + } +}); +}; + +if (!PhoneGap.hasResource("capture")) { + PhoneGap.addResource("capture"); +/** + * The CaptureError interface encapsulates all errors in the Capture API. + */ +function CaptureError() { + this.code = null; +}; + +// Capture error codes +CaptureError.CAPTURE_INTERNAL_ERR = 0; +CaptureError.CAPTURE_APPLICATION_BUSY = 1; +CaptureError.CAPTURE_INVALID_ARGUMENT = 2; +CaptureError.CAPTURE_NO_MEDIA_FILES = 3; +CaptureError.CAPTURE_NOT_SUPPORTED = 20; + +/** + * The Capture interface exposes an interface to the camera and microphone of the hosting device. + */ +function Capture() { + this.supportedAudioModes = []; + this.supportedImageModes = []; + this.supportedVideoModes = []; +}; + +/** + * Launch audio recorder application for recording audio clip(s). + * + * @param {Function} successCB + * @param {Function} errorCB + * @param {CaptureAudioOptions} options + * + * No audio recorder to launch for iOS - return CAPTURE_NOT_SUPPORTED + */ +Capture.prototype.captureAudio = function(successCallback, errorCallback, options) { + /*if (errorCallback && typeof errorCallback === "function") { + errorCallback({ + "code": CaptureError.CAPTURE_NOT_SUPPORTED + }); + }*/ + PhoneGap.exec(successCallback, errorCallback, "com.phonegap.mediacapture", "captureAudio", [options]); +}; + +/** + * Launch camera application for taking image(s). + * + * @param {Function} successCB + * @param {Function} errorCB + * @param {CaptureImageOptions} options + */ +Capture.prototype.captureImage = function(successCallback, errorCallback, options) { + PhoneGap.exec(successCallback, errorCallback, "com.phonegap.mediacapture", "captureImage", [options]); +}; + +/** + * Launch camera application for taking image(s). + * + * @param {Function} successCB + * @param {Function} errorCB + * @param {CaptureImageOptions} options + */ +Capture.prototype._castMediaFile = function(pluginResult) { + var mediaFiles = []; + var i; + for (i=0; i} categories +* @param {ContactField[]} urls contact's web sites +*/ +var Contact = function(id, displayName, name, nickname, phoneNumbers, emails, addresses, + ims, organizations, birthday, note, photos, categories, urls) { + this.id = id || null; + this.displayName = displayName || null; + this.name = name || null; // ContactName + this.nickname = nickname || null; + this.phoneNumbers = phoneNumbers || null; // ContactField[] + this.emails = emails || null; // ContactField[] + this.addresses = addresses || null; // ContactAddress[] + this.ims = ims || null; // ContactField[] + this.organizations = organizations || null; // ContactOrganization[] + this.birthday = birthday || null; // JS Date + this.note = note || null; + this.photos = photos || null; // ContactField[] + this.categories = categories || null; + this.urls = urls || null; // ContactField[] +}; + +/** +* Converts Dates to milliseconds before sending to iOS +*/ +Contact.prototype.convertDatesOut = function() +{ + var dates = new Array("birthday"); + for (var i=0; i][;base64], + * + * @param file {File} File object containing file properties + */ +FileReader.prototype.readAsDataURL = function(file) { + this.fileName = ""; + + if (typeof file.fullPath === "undefined") { + this.fileName = file; + } else { + this.fileName = file.fullPath; + } + + // LOADING state + this.readyState = FileReader.LOADING; + + // If loadstart callback + if (typeof this.onloadstart === "function") { + var evt = File._createEvent("loadstart", this); + this.onloadstart(evt); + } + + var me = this; + + // Read file + navigator.fileMgr.readAsDataURL(this.fileName, + + // Success callback + function(r) { + var evt; + + // If DONE (cancelled), then don't do anything + if (me.readyState === FileReader.DONE) { + return; + } + + // Save result + me.result = r; + + // If onload callback + if (typeof me.onload === "function") { + evt = File._createEvent("load", me); + me.onload(evt); + } + + // DONE state + me.readyState = FileReader.DONE; + + // If onloadend callback + if (typeof me.onloadend === "function") { + evt = File._createEvent("loadend", me); + me.onloadend(evt); + } + }, + + // Error callback + function(e) { + var evt; + // If DONE (cancelled), then don't do anything + if (me.readyState === FileReader.DONE) { + return; + } + + // Save error + me.error = e; + + // If onerror callback + if (typeof me.onerror === "function") { + evt = File._createEvent("error", me); + me.onerror(evt); + } + + // DONE state + me.readyState = FileReader.DONE; + + // If onloadend callback + if (typeof me.onloadend === "function") { + evt = File._createEvent("loadend", me); + me.onloadend(evt); + } + } + ); +}; + +/** + * Read file and return data as a binary data. + * + * @param file The name of the file + */ +FileReader.prototype.readAsBinaryString = function(file) { + // TODO - Can't return binary data to browser. + this.fileName = file; +}; + +/** + * Read file and return data as a binary data. + * + * @param file The name of the file + */ +FileReader.prototype.readAsArrayBuffer = function(file) { + // TODO - Can't return binary data to browser. + this.fileName = file; +}; + +//----------------------------------------------------------------------------- +// File Writer +//----------------------------------------------------------------------------- + +/** + * This class writes to the mobile device file system. + * + @param file {File} a File object representing a file on the file system +*/ +FileWriter = function(file) { + this.fileName = ""; + this.length = 0; + if (file) { + this.fileName = file.fullPath || file; + this.length = file.size || 0; + } + + // default is to write at the beginning of the file + this.position = 0; + + this.readyState = 0; // EMPTY + + this.result = null; + + // Error + this.error = null; + + // Event handlers + this.onwritestart = null; // When writing starts + this.onprogress = null; // While writing the file, and reporting partial file data + this.onwrite = null; // When the write has successfully completed. + this.onwriteend = null; // When the request has completed (either in success or failure). + this.onabort = null; // When the write has been aborted. For instance, by invoking the abort() method. + this.onerror = null; // When the write has failed (see errors). +} + +// States +FileWriter.INIT = 0; +FileWriter.WRITING = 1; +FileWriter.DONE = 2; + +/** + * Abort writing file. + */ +FileWriter.prototype.abort = function() { + // check for invalid state + if (this.readyState === FileWriter.DONE || this.readyState === FileWriter.INIT) { + throw FileError.INVALID_STATE_ERR; + } + + // set error + var error = new FileError(), evt; + error.code = error.ABORT_ERR; + this.error = error; + + // If error callback + if (typeof this.onerror === "function") { + evt = File._createEvent("error", this); + this.onerror(evt); + } + // If abort callback + if (typeof this.onabort === "function") { + evt = File._createEvent("abort", this); + this.onabort(evt); + } + + this.readyState = FileWriter.DONE; + + // If write end callback + if (typeof this.onwriteend == "function") { + evt = File._createEvent("writeend", this); + this.onwriteend(evt); + } +}; + +/** + * @Deprecated: use write instead + * + * @param file to write the data to + * @param text to be written + * @param bAppend if true write to end of file, otherwise overwrite the file + */ +FileWriter.prototype.writeAsText = function(file, text, bAppend) { + // Throw an exception if we are already writing a file + if (this.readyState === FileWriter.WRITING) { + throw FileError.INVALID_STATE_ERR; + } + + if (bAppend !== true) { + bAppend = false; // for null values + } + + this.fileName = file; + + // WRITING state + this.readyState = FileWriter.WRITING; + + var me = this; + + // If onwritestart callback + if (typeof me.onwritestart === "function") { + var evt = File._createEvent("writestart", me); + me.onwritestart(evt); + } + + + // Write file + navigator.fileMgr.writeAsText(file, text, bAppend, + // Success callback + function(r) { + var evt; + + // If DONE (cancelled), then don't do anything + if (me.readyState === FileWriter.DONE) { + return; + } + + // Save result + me.result = r; + + // If onwrite callback + if (typeof me.onwrite === "function") { + evt = File._createEvent("write", me); + me.onwrite(evt); + } + + // DONE state + me.readyState = FileWriter.DONE; + + // If onwriteend callback + if (typeof me.onwriteend === "function") { + evt = File._createEvent("writeend", me); + me.onwriteend(evt); + } + }, + + // Error callback + function(e) { + var evt; + + // If DONE (cancelled), then don't do anything + if (me.readyState === FileWriter.DONE) { + return; + } + + // Save error + me.error = e; + + // If onerror callback + if (typeof me.onerror === "function") { + evt = File._createEvent("error", me); + me.onerror(evt); + } + + // DONE state + me.readyState = FileWriter.DONE; + + // If onwriteend callback + if (typeof me.onwriteend === "function") { + evt = File._createEvent("writeend", me); + me.onwriteend(evt); + } + } + ); +}; + +/** + * Writes data to the file + * + * @param text to be written + */ +FileWriter.prototype.write = function(text) { + // Throw an exception if we are already writing a file + if (this.readyState === FileWriter.WRITING) { + throw FileError.INVALID_STATE_ERR; + } + + // WRITING state + this.readyState = FileWriter.WRITING; + + var me = this; + + // If onwritestart callback + if (typeof me.onwritestart === "function") { + var evt = File._createEvent("writestart", me); + me.onwritestart(evt); + } + + // Write file + navigator.fileMgr.write(this.fileName, text, this.position, + + // Success callback + function(r) { + var evt; + // If DONE (cancelled), then don't do anything + if (me.readyState === FileWriter.DONE) { + return; + } + + + // position always increases by bytes written because file would be extended + me.position += r; + // The length of the file is now where we are done writing. + me.length = me.position; + + // If onwrite callback + if (typeof me.onwrite === "function") { + evt = File._createEvent("write", me); + me.onwrite(evt); + } + + // DONE state + me.readyState = FileWriter.DONE; + + // If onwriteend callback + if (typeof me.onwriteend === "function") { + evt = File._createEvent("writeend", me); + me.onwriteend(evt); + } + }, + + // Error callback + function(e) { + var evt; + + // If DONE (cancelled), then don't do anything + if (me.readyState === FileWriter.DONE) { + return; + } + + // Save error + me.error = e; + + // If onerror callback + if (typeof me.onerror === "function") { + evt = File._createEvent("error", me); + me.onerror(evt); + } + + // DONE state + me.readyState = FileWriter.DONE; + + // If onwriteend callback + if (typeof me.onwriteend === "function") { + evt = File._createEvent("writeend", me); + me.onwriteend(evt); + } + } + ); + +}; + +/** + * Moves the file pointer to the location specified. + * + * If the offset is a negative number the position of the file + * pointer is rewound. If the offset is greater than the file + * size the position is set to the end of the file. + * + * @param offset is the location to move the file pointer to. + */ +FileWriter.prototype.seek = function(offset) { + // Throw an exception if we are already writing a file + if (this.readyState === FileWriter.WRITING) { + throw FileError.INVALID_STATE_ERR; + } + + if (!offset) { + return; + } + + // See back from end of file. + if (offset < 0) { + this.position = Math.max(offset + this.length, 0); + } + // Offset is bigger then file size so set position + // to the end of the file. + else if (offset > this.length) { + this.position = this.length; + } + // Offset is between 0 and file size so set the position + // to start writing. + else { + this.position = offset; + } +}; + +/** + * Truncates the file to the size specified. + * + * @param size to chop the file at. + */ +FileWriter.prototype.truncate = function(size) { + // Throw an exception if we are already writing a file + if (this.readyState === FileWriter.WRITING) { + throw FileError.INVALID_STATE_ERR; + } + // what if no size specified? + + // WRITING state + this.readyState = FileWriter.WRITING; + + var me = this; + + // If onwritestart callback + if (typeof me.onwritestart === "function") { + var evt = File._createEvent("writestart", me); + me.onwritestart(evt); + } + + // Write file + navigator.fileMgr.truncate(this.fileName, size, + + // Success callback + function(r) { + var evt; + // If DONE (cancelled), then don't do anything + if (me.readyState === FileWriter.DONE) { + return; + } + + // Update the length of the file + me.length = r; + me.position = Math.min(me.position, r); + + // If onwrite callback + if (typeof me.onwrite === "function") { + evt = File._createEvent("write", me); + me.onwrite(evt); + } + + // DONE state + me.readyState = FileWriter.DONE; + + // If onwriteend callback + if (typeof me.onwriteend === "function") { + evt = File._createEvent("writeend", me); + me.onwriteend(evt); + } + }, + + // Error callback + function(e) { + var evt; + // If DONE (cancelled), then don't do anything + if (me.readyState === FileWriter.DONE) { + return; + } + + // Save error + me.error = e; + + // If onerror callback + if (typeof me.onerror === "function") { + evt = File._createEvent("error", me); + me.onerror(evt); + } + + // DONE state + me.readyState = FileWriter.DONE; + + // If onwriteend callback + if (typeof me.onwriteend === "function") { + evt = File._createEvent("writeend", me); + me.onwriteend(evt); + } + } + ); +}; + +LocalFileSystem = function() { +}; + +// File error codes +LocalFileSystem.TEMPORARY = 0; +LocalFileSystem.PERSISTENT = 1; +LocalFileSystem.RESOURCE = 2; +LocalFileSystem.APPLICATION = 3; + +/** + * Requests a filesystem in which to store application data. + * + * @param {int} type of file system being requested + * @param {Function} successCallback is called with the new FileSystem + * @param {Function} errorCallback is called with a FileError + */ +LocalFileSystem.prototype.requestFileSystem = function(type, size, successCallback, errorCallback) { + if (type < 0 || type > 3) { + if (typeof errorCallback == "function") { + errorCallback({ + "code": FileError.SYNTAX_ERR + }); + } + } + else { + PhoneGap.exec(successCallback, errorCallback, "com.phonegap.file", "requestFileSystem", [type, size]); + } +}; + +/** + * + * @param {DOMString} uri referring to a local file in a filesystem + * @param {Function} successCallback is called with the new entry + * @param {Function} errorCallback is called with a FileError + */ +LocalFileSystem.prototype.resolveLocalFileSystemURI = function(uri, successCallback, errorCallback) { + PhoneGap.exec(successCallback, errorCallback, "com.phonegap.file", "resolveLocalFileSystemURI", [uri]); +}; + +/** +* This function is required as we need to convert raw +* JSON objects into concrete File and Directory objects. +* +* @param a JSON Objects that need to be converted to DirectoryEntry or FileEntry objects. +* @returns an entry +*/ +LocalFileSystem.prototype._castFS = function(pluginResult) { + var entry = null; + entry = new DirectoryEntry(); + entry.isDirectory = pluginResult.message.root.isDirectory; + entry.isFile = pluginResult.message.root.isFile; + entry.name = pluginResult.message.root.name; + entry.fullPath = pluginResult.message.root.fullPath; + pluginResult.message.root = entry; + return pluginResult; +} + +LocalFileSystem.prototype._castEntry = function(pluginResult) { + var entry = null; + if (pluginResult.message.isDirectory) { + entry = new DirectoryEntry(); + } + else if (pluginResult.message.isFile) { + entry = new FileEntry(); + } + entry.isDirectory = pluginResult.message.isDirectory; + entry.isFile = pluginResult.message.isFile; + entry.name = pluginResult.message.name; + entry.fullPath = pluginResult.message.fullPath; + pluginResult.message = entry; + return pluginResult; +} + +LocalFileSystem.prototype._castEntries = function(pluginResult) { + var entries = pluginResult.message; + var retVal = []; + for (i=0; i"; + self.at_spinner = true; + } + setOffset(0); + }; + + this.content = function(text, offset) { + debug('content'); + self.at_spinner = false; + + self._content.innerHTML = ''; + self._content.innerHTML = text; + setOffset(offset); + } + + this.enter = function(url, offset) { + debug('View.enter: ' + url); + + var view = 'Index'; + var arg = null; + + if (url.length) { + var slash_index = url.indexOf('/'); + if (slash_index != -1) { + view = url.substr(0, slash_index); + arg = url.substr(slash_index + 1); + } + else { + view = url; + } + } + debug('View.enter: ' + view + ' ' + arg); + self.current = url; + self.currentView = view; + self.currentPar = arg; + self['enter' + view](arg, offset); + Menu.refresh(); + } + + this.enterIndex = function(arg, offset) { + debug('enterIndex'); + Menu.setInfoButton("ProjectInfo", "O projekcie", true); + self.showSearch(); + self.currentTitle = "Początek"; + var html = ""; + + html += "
"; + html += Links.button('Last', '', 'Ostatnio czytane'); + html += Links.button('Bookmarks', '', 'Zakładki'); + + for (category in self.categories) + html += Links.button('Category', category, self.categories[category], 0); + html += "
"; + + html += "" +""; + /*"";*/ + self.content(html, offset); + }; + + this.enterBook = function(id, offset) { + id = parseInt(id); + debug('enterBook: ' + id); + Menu.setInfoButton("BookInfo", "O utworze", true); + self.showSearch(); + + Catalogue.withBook(id, function(book) { + self.currentTitle = book.authors + ', ' + book.title; + + Catalogue.withChildren(id, function(children) { + var html = "

"; + html += book.authors; + html += "" + book.title + "

\n"; + if (book.html_file) { + html += "
" + Links.button('BookText', id, "Czytaj tekst") + "
"; + } + if (children.length) { + html += "
"; + for (c in children) { + child = children[c]; + html += Links.bookLink(child); + } + html += "
"; + } + self.content(html, offset); + }); + }, function() { + History.goBack(); + }); + }; + + this.enterBookText = function(id, offset) { + self.hideSearch(); + self.spinner("Otwieranie utworu"); + debug('enterBookText: ' + id); + Menu.setInfoButton("BookInfo", "O utworze", true); + id = parseInt(id); + + setTimeout("History.addRead("+id+");", 0); + + FileRepo.withHtml(id, function(data) { + self.content(data, offset); + }, function(err) { + alert("Błąd pobierania: nie udało się pobrać treści utworu."); + History.goBack(); + }); + Catalogue.withBook(id, function(book) { + self.currentTitle = book.authors + ', ' + book.title; + }); + }; + + + this.enterLast = function(ignored, offset) { + debug("enterLast"); + self.showSearch(); + Menu.setInfoButton("ProjectInfo", "O projekcie", true); + self.currentTitle = 'Ostatnio czytane'; + var html = "

Ostatnio czytane

\n"; + + var last_read = History.lastRead(); + var some_books = false; + + html += "
"; + var add_books = function() { + if (last_read.length) { + var id = last_read.shift(); + Catalogue.withBook(id, function(book) { + html += Links.bookLink(book); + some_books = true; + add_books(); + }, function() { + add_books(); + }); + } + else { + if (!some_books) { + html += "

Nie przeczytano żadnych utworów.

"; + } + html += "
"; + self.content(html, offset); + } + }; + add_books(); + }; + + + this.enterBookmarks = function(ignored, offset) { + debug("enterBookmarks"); + self.showSearch(); + Menu.setInfoButton("ProjectInfo", "O projekcie", true); + self.currentTitle = 'Zakładki'; + var html = "

Zakładki

\n"; + + var bookmarks = History.bookmarks(); + if (!bookmarks.length) { + html += "

Nie utworzono żadnych zakładek.

"; + self.content(html, offset); + return; + } + + html += "
"; + for (i in bookmarks) { + var bm = bookmarks[i]; + + var text = bm.name; + text += "
" + bm.title + "
"; + html += Links.deleteButton(bm.id); + html += Links.button(bm.view, bm.par, text, bm.offset); + } + html += "
"; + self.content(html, offset); + }; + + this.onBookmarkChange = function() { + // TODO: preserve offset + if (self.currentView == 'Bookmarks') { + self.enterBookmarks(); + } + }; + + this.enterTag = function(id, offset) { + id = parseInt(id); + debug('enterTag: ' + id); + Menu.setInfoButton("TagInfo", "O...", true); + self.showSearch(); + + self.spinner("Otwieranie listy utworów"); + + Catalogue.withTag(id, function(tag) { + Menu.setInfoButton("TagInfo", "O " + self.category_msc[tag.category], true); + self.currentTitle = tag.category + ': ' + tag.name; + var html = "

" + tag.category + ': ' + tag.name + "

\n"; + html += "
"; + if (tag.books) { + Catalogue.withBooks(tag.books, function(books) { + for (var i in books) { + var book = books[i]; + html += Links.bookLink(book); + } + html += "
"; + self.content(html, offset); + }); + } + }, function() { + History.goBack(); + }); + }; + + + this.enterCategory = function(category, offset) { + debug('enterCategory: ' + category); + Menu.setInfoButton("ProjectInfo", "O projekcie", true); + self.spinner("Otwieranie katalogu"); + self.showSearch(); + self.currentTitle = self.categories[category]; + + Catalogue.withCategory(category, function(tags) { + var html = "

" + self.categories[category] + "

\n"; + html += "
"; + for (i in tags) { + tag = tags[i]; + html += Links.button('Tag', tag.id, tag.name); + } + html += "
"; + self.content(html, offset); + }); + }; + + + this.enterSearch = function(query, offset) { + debug('enterSearch: ' + query); + Menu.setInfoButton("ProjectInfo", "O projekcie", true); + self.currentTitle = 'Szukaj: ' + query; + self.showSearch(); + + var html = "

Szukana fraza:" + View.sanitize(query) + "

\n"; + + if (query.length < 2) { + html += "

Szukana fraza musi mieć co najmniej dwa znaki

"; + self.content(html, offset); + return; + } + + Catalogue.withSearch(query, function(results) { + if (results.length == 1) { + var result = results[0]; + if (result.view == 'Book' && result.item.html_file) { + self.enter(Links.href('BookText', result.item.id)); + } + else { + self.enter(Links.href(result.view, result.item.id)); + } + return; + } + if (results.length == 0) { + html += "

Brak wyników wyszukiwania

"; + } + else { + html += "
"; + for (var i in results) { + var result = results[i]; + if (result.view == 'Book') + html += Links.bookLink(result.item) + else + html += Links.button(result.view, result.item.id, result.item.name+"
"+result.item.category+"
"); + } + html += "
"; + } + self.content(html, offset); + }); + }; + + + /* info */ + + this.enterProjectInfo = function(arg, offset) { + debug('enterProjectInfo'); + Menu.setInfoButton("ProjectInfo", "O projekcie", false); + self.hideSearch(); + self.currentTitle = "O projekcie"; + + var html = ""; + + html += '
'; + + + html += "

"; + html += "

Biblioteka internetowa Wolne Lektury "+ +" udostępnia w swoich zbiorach lektury szkolne zalecane do użytku przez" + +" Ministerstwo Edukacji Narodowej i inne dzieła literatury.

"; + + html += "

"; + + html += "" + + "

" + + "Przekaż 1% podatku na rozwój Wolnych Lektur.
" + + "Fundacja Nowoczesna Polska
" + + "KRS 0000070056

"; + + html += "

Większość pozycji w bibliotece należy do domeny publicznej "+ + "co oznacza, że nie są już chronione majatkowym prawem autorskim, "+ + "a więc można je swobodnie wykorzystywać, publikować i rozpowszechniać. "+ + "Publikujemy również kilka utworów, które autorzy udostępnili na wolnej licencji "+ + ""+ + "Creative Commons Uznanie Autorstwa - Na Tych Samych Warunkach 3.0.PL.

"; + + html += "

"; + + html += "

Copyright © 2011 Fundacja Nowoczesna Polska. Aplikacja jest wolnym oprogramowaniem "+ + "dostępnym na licencji GNU Affero GPL w wersji 3 lub późniejszej.

"; + + html += "

Więcej informacji o projekcie znajduje sie na stronie http://www.wolnelektury.pl.

"; + + html += '
'; + + + self.content(html, offset); + }; + + + this.enterBookInfo = function(id, offset) { + id = parseInt(id); + debug('enterBookInfo: ' + id); + Menu.setInfoButton("ProjectInfo", "O projekcie", true); + self.hideSearch(); + + Catalogue.withBook(id, function(book) { + self.currentTitle = "Informacje o: " + book.title; + + var html = '

' + book.authors + ', ' + book.title + '

'; + + var url = WL + '/api/book/' + id + '/info.html'; + + var xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.onload = function() { + debug('BookInfo: fetched by ajax: ' + url); + + html += '
'; + html += xhr.responseText; + html += '
'; + + self.content(html, offset); + } + xhr.onerror = function(e) { + self.content("Brak informacji.", offset); + } + xhr.send(); + }, function() { + History.goBack(); + }); + }; + + + this.enterTagInfo = function(id, offset) { + id = parseInt(id); + debug('enterTagInfo: ' + id); + Menu.setInfoButton("ProjectInfo", "O projekcie", true); + self.hideSearch(); + + Catalogue.withTag(id, function(tag) { + self.currentTitle = "Informacje o " + tag.name; + var html = '

' + tag.name + '

'; + + var url = WL + '/api/tag/' + id + '/info.html'; + + var xhr = new XMLHttpRequest(); + xhr.open("GET", url); + xhr.onload = function() { + debug('TagInfo: fetched by ajax: ' + url); + + html += '
'; + html += xhr.responseText; + html += '
'; + + self.content(html, offset); + } + xhr.onerror = function(e) { + self.content("Brak informacji.", offset); + } + xhr.send(); + }, function() { + History.goBack(); + }); + }; + + + /* search form submit callback */ + this.search = function() { + History.visit('Search/' + self._searchinput.value); + self._content.focus() + return false; + } + + + self.getNightMode = function() { + night_mode = window.localStorage.getItem('View.night_mode'); + if (night_mode === undefined) + return false; + else + return !!night_mode; + }; + + self.checkNightMode = function() { + night_mode = self.getNightMode(); + if (night_mode) { + document.body.setAttribute("class", "night-mode"); + } + else { + document.body.setAttribute("class", ""); + } + }; + + self.setNightMode = function(night_mode) { + night_mode = night_mode ? "1" : ""; + window.localStorage.setItem('View.night_mode', night_mode); + self.checkNightMode(); + }; + + self.toggleNightMode = function(night_mode) { + self.setNightMode(!self.getNightMode()); + }; + + self.showBack = function(show) { + if (show) + self._back.style.display = 'inline-block'; + else + self._back.style.display = 'none'; + } +}