First commit to the repo

This commit is contained in:
José Carlos Cuevas 2015-02-22 05:17:26 +01:00
commit 827c689e9d
23 changed files with 22394 additions and 0 deletions

202
LICENSE Normal file
View file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2014 Mozilla Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

68
README.md Normal file
View file

@ -0,0 +1,68 @@
# Privileged empty app
This is a privileged empty app template that provides you with a barebones structure for you to build your app.
This is part of the [mortar](https://github.com/mozilla/mortar/) template collection for building [Open Web Apps](https://developer.mozilla.org/Apps).
## Obtaining
There are a few ways to get this template:
If you use [Git](http://www.git-scm.com/):
````bash
git clone https://github.com/mozilla/mortar-privileged-empty-app.git
````
Or download the latest version in this [ZIP file](https://github.com/mozilla/mortar-privileged-empty-app/archive/master.zip).
## Usage
Import the app into the [App Manager](https://developer.mozilla.org/Firefox_OS/Using_the_App_Manager). Then you can run it in the simulator, or in a Firefox OS device.
## Code walkthrough
The `manifest.webapp` file contains metadata about the app, such as its name, description, icon and required permissions for running under Firefox OS.
Moving over to `index.html`, this is the starting point for the app when it's launched, and also where the layout is defined and the JavaScript files with the functionality and logic are loaded.
The appearance is defined in `css/app.css`. There are just some very basic rules.
We define the app's behaviour in `js/app.js`. Right now we're just basically displaying a "Hello world" message.
Finally we are also including `js/libs/l10n.js`, which contains [L10n](https://developer.mozilla.org/en-US/docs/Web/API/L10n_API), a library for translating the strings in the app. Using this library, users can run the app in their own language, as long as you provide the translations for those languages. We're currently including a translation to Spanish as an example, but feel free to contribute with more translations in `data/locales.ini`, looking at `data/es.properties` and `data/en-US.properties` to see the syntax in action. The way it works, it will automatically translate the HTML elements that contain a `data-l10n-id` attribute with the translation identifier.
For any dynamically shown content, you need to use the `navigator.webL10n.get` function, but since that is slightly tedious to write each time, we're aliasing it to just `translate`:
```javascript
var translate = navigator.mozL10n.get;
```
## Getting help
If you find something that doesn't quite work as you'd expect, we'd appreciate if you [filed a bug](https://github.com/mozilla/mortar-privileged-empty-app/issues)!
We need your help in order to help you. Therefore:
1. Tell us which version of the template are you using. Where did you get the code from?
* Specify the environment where the bug occurs i.e. which version of the Simulator or Firefox OS device. An example would be `1.2 simulator` or `Boot2Gecko 1.4.0.0`.
* Describe the problem in detail. What were you doing? What happened? What did you expect to happen?
* Probably also provide a test case so we can see what is happening and try to reproduce the error.
Ultimately it all boils down to the fact that if we can't reproduce it, we can't help you or fix it either.
## Contributing
Contributions are always welcome! If you want to collaborate, whether that is with a new feature or fixing a bug, we recommend you...
1. Have a look at the [issue tracker](https://github.com/mozilla/mortar-privileged-empty-app/issues) first--to make sure there isn't anyone working on that already.
* If it's a new issue/feature, or no one is working on it already, fork the project in GitHub (you'll need an account if you don't have it yet).
* Create the bug to let us know you want to work on this. That way we are aware of and can keep an eye on it, or maybe tell you that it is not a bug but an intended feature, and save you the hassle of working on something that is not needed.
* Clone your fork to your computer (i.e. get the code onto your computer)
* Make a new branch, and switch to that new branch
* Do the changes you deem necessary
* Push the branch to GitHub
* Send a pull request
To make your changes as easy to merge back onto the project as possible, you should only work on one feature per branch. That makes code review simpler and faster!

2536
css/af.ui.base.css Normal file

File diff suppressed because it is too large Load diff

4476
css/af.ui.css Normal file

File diff suppressed because one or more lines are too long

18
css/app.css Normal file
View file

@ -0,0 +1,18 @@
html, body {
margin: 0;
padding: 0.5rem;
}
body {
font-size: 1rem;
background: #fff;
}
h1 {
margin: 0 0 1rem 0;
}
p {
font-size: inherit;
}

1677
css/app.css.bak Normal file

File diff suppressed because it is too large Load diff

1
css/icons.min.css vendored Normal file

File diff suppressed because one or more lines are too long

11
data/en-US.properties Normal file
View file

@ -0,0 +1,11 @@
app_title = ToDo List
app_description.innerHTML = ToDo List. Never forget anything!
message = Let's start
main_list = ToDo Lists
back_button = Back
add_list = Add list
settings = Settings
about = About
create_list = Create list
new_list_name = Name:
add_new_list = Add new list

11
data/es.properties Normal file
View file

@ -0,0 +1,11 @@
app_title = Lista de tareas
app_description.innerHTML = Lista de tareas. ¡Que no se te olvide nada!
message = Comenzar
main_list = Listas de tareas
back_button = Atrás
add_list = Añadir lista
settings = Ajustes
about = Acerca de
create_list = Crear lista
new_list_name = Nombre:
add_new_list = Añadir nueva lista

5
data/locales.ini Normal file
View file

@ -0,0 +1,5 @@
@import url(en-US.properties)
[es]
@import url(es.properties)

290
img/icons/icon.svg Normal file
View file

@ -0,0 +1,290 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128px"
height="128px"
viewBox="0 0 128 128"
version="1.1"
id="svg2"
inkscape:version="0.48.5 r10040"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/reset/Projects/FirefoxOS/todolist/img/icons/icon16x16.png"
inkscape:export-xdpi="11.394754"
inkscape:export-ydpi="11.394754">
<metadata
id="metadata14">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>empty</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1142"
inkscape:window-height="661"
id="namedview12"
showgrid="false"
inkscape:zoom="3.6875"
inkscape:cx="22.508475"
inkscape:cy="64"
inkscape:window-x="136"
inkscape:window-y="45"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" />
<!-- Generator: Sketch 3.0.2 (7799) - http://www.bohemiancoding.com/sketch -->
<title
id="title4">empty</title>
<description
id="description6">Created with Sketch.</description>
<defs
id="defs8">
<linearGradient
id="linearGradient3869">
<stop
id="stop3871"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop3873"
offset="1"
style="stop-color:#39513f;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3824">
<stop
style="stop-color:#9fcea0;stop-opacity:1;"
offset="0"
id="stop3826" />
<stop
style="stop-color:#00af00;stop-opacity:1;"
offset="1"
id="stop3828" />
</linearGradient>
<linearGradient
id="linearGradient3762">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3764" />
<stop
id="stop3774"
offset="0.47690737"
style="stop-color:#eeeee8;stop-opacity:1;" />
<stop
id="stop3770"
offset="0.74999255"
style="stop-color:#96928d;stop-opacity:1;" />
<stop
style="stop-color:#6c6c66;stop-opacity:1;"
offset="1"
id="stop3766" />
</linearGradient>
<linearGradient
id="linearGradient3761">
<stop
style="stop-color:#4e9131;stop-opacity:1;"
offset="0"
id="stop3763" />
<stop
style="stop-color:#39513f;stop-opacity:1;"
offset="1"
id="stop3765" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3761"
id="linearGradient3767"
x1="129.66949"
y1="65.8983"
x2="129.66949"
y2="188.59828"
gradientUnits="userSpaceOnUse" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3762"
id="radialGradient3772"
cx="65.708519"
cy="70.428398"
fx="65.708519"
fy="70.428398"
r="36.483051"
gradientTransform="matrix(2.7546709,-2.1393411,1.5436748,1.9876754,-233.93701,104.09238)"
gradientUnits="userSpaceOnUse" />
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter3804">
<feFlood
flood-opacity="0.5"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3806" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3808" />
<feGaussianBlur
in="composite"
stdDeviation="2"
result="blur"
id="feGaussianBlur3810" />
<feOffset
dx="4"
dy="4"
result="offset"
id="feOffset3812" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3814" />
</filter>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3824"
id="linearGradient3830"
x1="69.152542"
y1="67.254234"
x2="89.220337"
y2="92.474579"
gradientUnits="userSpaceOnUse" />
<filter
style="color-interpolation-filters:sRGB;"
inkscape:label="Drop Shadow"
id="filter3855">
<feFlood
flood-opacity="0.5"
flood-color="rgb(0,0,0)"
result="flood"
id="feFlood3857" />
<feComposite
in="flood"
in2="SourceGraphic"
operator="in"
result="composite1"
id="feComposite3859" />
<feGaussianBlur
in="composite"
stdDeviation="2"
result="blur"
id="feGaussianBlur3861" />
<feOffset
dx="4"
dy="4"
result="offset"
id="feOffset3863" />
<feComposite
in="SourceGraphic"
in2="offset"
operator="over"
result="composite2"
id="feComposite3865" />
</filter>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3869"
id="radialGradient3877"
cx="128.29376"
cy="106.21819"
fx="128.29376"
fy="106.21819"
r="63.18644"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.18873,-0.67565133,0.75155916,1.322281,-192.20031,-13.361663)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3869"
id="radialGradient3881"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.18873,-0.67565133,0.75155916,1.322281,-126.84438,50.909516)"
cx="128.29376"
cy="106.21819"
fx="128.29376"
fy="106.21819"
r="63.18644" />
</defs>
<path
sodipodi:type="arc"
style="fill:url(#linearGradient3767);fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path2991"
sodipodi:cx="129.35593"
sodipodi:cy="128.27118"
sodipodi:rx="63.18644"
sodipodi:ry="63.18644"
d="m 192.54237,128.27118 a 63.18644,63.18644 0 1 1 -126.372883,0 63.18644,63.18644 0 1 1 126.372883,0 z"
transform="translate(-65.355927,-64.271179)" />
<rect
transform="matrix(0.96250734,-0.27125562,0.27125562,0.96250734,0,0)"
ry="7"
rx="7"
y="47.915066"
x="4.5326066"
height="65.627121"
width="69.966103"
id="rect3802"
style="fill:url(#radialGradient3772);fill-opacity:1;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;filter:url(#filter3804)" />
<path
style="fill:url(#radialGradient3877);fill-opacity:1;fill-rule:evenodd;stroke:none;opacity:0.30384615"
d="M 64 0.8125 C 29.103093 0.8125 0.8125 29.103093 0.8125 64 C 0.8125 92.051574 19.109021 115.81172 44.40625 124.0625 C 39.953168 115.40869 37.4375 105.5898 37.4375 95.1875 C 37.4375 60.290593 65.728093 32 100.625 32 C 107.47033 32 114.04555 33.11159 120.21875 35.125 C 109.73295 14.747626 88.494603 0.8125 64 0.8125 z "
id="path3867" />
<rect
style="fill:url(#radialGradient3772);fill-opacity:1;stroke:#000000;stroke-width:3;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="rect3760"
width="69.966103"
height="65.627121"
x="4.5326066"
y="47.915066"
rx="7"
ry="7"
transform="matrix(0.96250734,-0.27125562,0.27125562,0.96250734,0,0)" />
<path
sodipodi:nodetypes="cscscscscscscc"
inkscape:connector-curvature="0"
id="path3818"
d="m 42.033898,71.322034 c 0,0 7.157969,-0.322336 15.457627,5.694915 10.847458,7.864407 12.20339,13.016949 12.20339,13.016949 0,0 0.271187,-1.084745 2.711865,-1.627118 2.440678,-0.542373 2.983051,-0.81356 2.983051,-0.81356 0,0 -1.084746,-8.135593 12.745762,-26.847458 13.830507,-18.711864 19.254237,-19.254237 19.254237,-19.254237 0,0 -0.81356,0.271187 -2.71186,-1.355932 -1.89831,-1.627118 -3.52543,-3.79661 -3.52543,-3.79661 0,0 -7.864404,2.711864 -18.983048,17.627119 -11.118645,14.915254 -13.830509,20.610169 -13.830509,20.610169 0,0 -1.418567,-3.094324 -11.661017,-6.508474 C 46.101695,64.542373 42.305085,65.355932 42.305085,65.355932 z"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
<path
sodipodi:nodetypes="cscscscscscscc"
inkscape:connector-curvature="0"
id="path3820"
d="m 42.033898,71.322034 c 0,0 7.157969,-0.322336 15.457627,5.694915 10.847458,7.864407 12.20339,13.016949 12.20339,13.016949 0,0 0.271187,-1.084745 2.711865,-1.627118 2.440678,-0.542373 2.983051,-0.81356 2.983051,-0.81356 0,0 -1.084746,-8.135593 12.745762,-26.847458 13.830507,-18.711864 19.254237,-19.254237 19.254237,-19.254237 0,0 -0.81356,0.271187 -2.71186,-1.355932 -1.89831,-1.627118 -3.52543,-3.79661 -3.52543,-3.79661 0,0 -7.864404,2.711864 -18.983048,17.627119 -11.118645,14.915254 -13.830509,20.610169 -13.830509,20.610169 0,0 -1.418567,-3.094324 -11.661017,-6.508474 C 46.101695,64.542373 42.305085,65.355932 42.305085,65.355932 z"
style="fill:#00af00;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
<g
id="g3832"
style="filter:url(#filter3855)">
<path
sodipodi:nodetypes="cscscscscscscc"
inkscape:connector-curvature="0"
id="path3822"
d="m 42.033898,69.423729 c 0,0 7.971528,-0.322336 16.271186,5.694915 10.847458,7.864407 11.118645,12.20339 11.118645,12.20339 0,0 0,-0.813559 2.440678,-1.355932 2.440678,-0.542373 2.983051,-0.81356 2.983051,-0.81356 0,0 -2.440678,-8.406779 11.38983,-27.118644 13.830502,-18.711864 17.627122,-16.542373 17.627122,-16.542373 0,0 1.62711,-1.084745 -0.27119,-2.711864 -1.89831,-1.627118 -2.44068,-2.440678 -2.44068,-2.440678 0,0 -7.864404,2.711864 -18.983048,17.627119 -11.118645,14.915254 -13.830509,20.610169 -13.830509,20.610169 0,0 -1.418567,-3.094324 -11.661017,-6.508474 C 46.101695,64.542373 42.305085,65.355932 42.305085,65.355932 z"
style="fill:url(#linearGradient3830);fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="cscscscscscscc"
inkscape:connector-curvature="0"
id="path3816"
d="m 42.033898,71.322034 c 0,0 7.157969,-0.322336 15.457627,5.694915 10.847458,7.864407 12.20339,13.016949 12.20339,13.016949 0,0 0.271187,-1.084745 2.711865,-1.627118 2.440678,-0.542373 2.983051,-0.81356 2.983051,-0.81356 0,0 -1.084746,-8.135593 12.745762,-26.847458 13.830507,-18.711864 19.254237,-19.254237 19.254237,-19.254237 0,0 -0.81356,0.271187 -2.71186,-1.355932 -1.89831,-1.627118 -3.52543,-3.79661 -3.52543,-3.79661 0,0 -7.864404,2.711864 -18.983048,17.627119 -11.118645,14.915254 -13.830509,20.610169 -13.830509,20.610169 0,0 -1.418567,-3.094324 -11.661017,-6.508474 C 46.101695,64.542373 42.305085,65.355932 42.305085,65.355932 z"
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

BIN
img/icons/icon128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
img/icons/icon16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 936 B

BIN
img/icons/icon48x48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
img/icons/icon60x60.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

69
index.html Normal file
View file

@ -0,0 +1,69 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>ToDo List</title>
<meta name="description" content="ToDo List">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<meta http-equiv="Pragma" content="no-cache">
<link rel="stylesheet" type="text/css" href="css/icons.min.css" />
<link rel="stylesheet" type="text/css" href="css/af.ui.css" />
<link rel="stylesheet" href="css/app.css">
<script type="text/javascript" src="js/libs/jquery.js"></script>
<script type="text/javascript" src="js/libs/fastclick.js"></script>
<script type="text/javascript" src="js/libs/appframework.ui.min.js"></script>
<script type="text/javascript" src="js/init.js"></script>
<script type="text/javascript" src="js/app.js" defer></script>
<!--
The following two lines are for loading the localisations library
and the localisation data-so people can use the app in their
own language (as long as you provide translations).
-->
<link rel="prefetch" type="application/l10n" href="data/locales.ini" />
<script type="text/javascript" src="js/libs/l10n.js" defer></script>
</head>
<body>
<div id="afui">
<div class="view" id="mainview">
<header>
<h1 data-l10n-id="app_title">ToDo List</h1>
</header>
<div class="pages">
<div data-title="ToDo Lists" id="main" class="panel" selected="true">
<ul id="list_of_lists" class="list">
<li id="add_list_last_elem"><a id="add_list" data-l10n-id="add_list">Add List</a></li>
</ul>
</div>
<div data-title="New list" id="new_list" class="panel" selected="false">
<div class="formGroupHead" data-l10n-id="create_list">Create list</div>
<form>
<label for="new_list_name_input" data-l10n-id="new_list_name">Name:</label>
<input id="new_list_name_input" type="text" />
<a id="add_new_list_button" class="button icon add" data-l10n-id="add_new_list">Add new list</a>
</form>
</div>
<div data-title="Untitled" id="list_panel" class="panel" selected="false">
<ul id="list_display" class="list">
<input id="new_elem_text" type="text" />
<a id="add_new_item" class="button icon add" data-l10n-id="add_new_item">Add new item</a>
<hr />
<a id="delete_list" class="button icon remove red" data-l10n-id="delete_list">Delete list</a>
</ul>
</div>
<!-- <div data-title="Settings" id="settings" class="panel" selected="false">
<p>Coming soon...</p>
</div>
<div data-title="About" id="about" class="panel" selected="false">
<p>Coming soon...</p>
</div> -->
</div>
<!-- <footer>
<a href="#main" id="navbar_home" class="icon home" data-l10n-id="main_list">Lists</a>
<a href="#new_list" id="navbar_settings" class="icon settings" data-l10n-id="settings">Settings</a>
<a href="#about" id="navbar_about" class="icon info" data-l10n-id="about">About</a>
</footer> -->
</div>
</div>
</body>
</html>

162
js/app.js Normal file
View file

@ -0,0 +1,162 @@
// DOMContentLoaded is fired once the document has been loaded and parsed,
// but without waiting for other external resources to load (css/images/etc)
// That makes the app more responsive and perceived as faster.
// https://developer.mozilla.org/Web/Reference/Events/DOMContentLoaded
function openList(elementClicked) {
var listID = elementClicked.data('listID');
var listTitle = localStorage.getItem('ToDoList_list' + listID);
$('ul#list_display').find('li').remove();
var numElements = localStorage.getItem('ToDoList_' + listID + '_element_count');
if((numElements) && (numElements > 0)) {
var text;
for(var count = 0; count < numElements; count++) {
text = localStorage.getItem('ToDoList_' + listID + '_element_' + count);
if(text) {
var checked = localStorage.getItem('ToDoList_' + listID + '_element_' + count + '_checked');
var list_display = $('#new_elem_text');
if (checked == 'true') {
list_display.before('<li id="element_' + listID + '_' + count +'"><span class="icon check"></span>' + text + '</li>');
} else {
list_display.before('<li id="element_' + listID + '_' + count +'"><span class="icon minimize"></span>' + text + '</li>');
}
}
}
}
$('#add_new_item').data('currentlist', listID);
$.afui.loadContent('#list_panel', false, false, "slide");
$.afui.setTitle(listTitle);
}
function addItemToList(listID, text) {
var numElements = localStorage.getItem('ToDoList_' + listID + '_element_count');
var elementPosition = 0;
if((numElements) && (numElements > 0)) {
var count = 0;
while ((localStorage.getItem('ToDoList_' + listID + '_element_' + count)) && (count < numElements)) {
count++;
}
if(count < numElements) {
elementPosition = count;
} else {
elementPosition = numElements;
numElements++;
}
} else {
elementPosition = 0;
numElements = 1;
}
localStorage.setItem('ToDoList_' + listID + '_element_' + elementPosition, text);
localStorage.setItem('ToDoList_' + listID + '_element_' + count + '_checked', 'false');
localStorage.setItem('ToDoList_' + listID + '_element_count', numElements);
var list_display = $('#new_elem_text');
list_display.before('<li id="element_' + listID + '_' + count +'"><span class="icon minimize"></span>' + text + '</li>');
}
function addNewList(newListName) {
var lastID = 0;
if(localStorage.getItem('ToDoList_LastID')) {
lastID = localStorage.getItem('ToDoList_LastID');
}
var emptyID = 0;
if(lastID !== 0) {
var count = 0;
while((localStorage.getItem('ToDoList_list' + count)) && (count < lastID)) {
count++;
}
if(count < lastID) {
emptyID = lastID;
}
}
if(emptyID !== 0) {
localStorage.setItem('ToDoList_list' + lastID, newListName);
$('li#add_list_last_elem').before('<li><a id="list_' + lastID + '">' + newListName + '</li>');
$('a#list_' + lastID).click(function () { openList(lastID); });
lastID++;
localStorage.setItem('ToDoList_LastID', lastID);
} else {
localStorage.setItem('ToDoList_list' + emptyID, newListName);
$('li#add_list_last_elem').before('<li><a id="list_' + emptyID + '">' + newListName + '</li>');
$('a#list_' + emptyID).click(function () { openList(emptyID); });
}
}
// Loads the lists in the Store element
function loadLists() {
console.log('Recovering data');
var maxLists = localStorage.getItem('ToDoList_LastID');
if(maxLists) {
console.log('Lists found: ' + maxLists);
var listData;
for(var count = 0; count < maxLists; count++) {
listData = localStorage.getItem('ToDoList_list' + count);
if(listData) {
console.log('Adding list item ' + count);
$('li#add_list_last_elem').before('<li><a id="list_' + count + '">' + listData + '</li>');
$('a#list_' + count).click(function () { openList($(this)); });
$('a#list_' + count).data('listID', count);
}
}
}
}
window.addEventListener('DOMContentLoaded', function() {
// We'll ask the browser to use strict code to help us catch errors earlier.
// https://developer.mozilla.org/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode
'use strict';
var translate = navigator.mozL10n.get;
// We want to wait until the localisations library has loaded all the strings.
// So we'll tell it to let us know once it's ready.
navigator.mozL10n.once(start);
// ---
function start() {
// var message = document.getElementById('message');
// We're using textContent because inserting content from external sources into your page using innerHTML can be dangerous.
// https://developer.mozilla.org/Web/API/Element.innerHTML#Security_considerations
// message.textContent = translate('message');
loadLists();
$('#add_list').click(function(){
$.afui.loadContent('#new_list', false, false, "slide");
});
$('#add_new_list_button').click(function(){
var newListName = $('#new_list_name_input').val();
if((newListName.length > 0) && (newListName != '')) {
addNewList(newListName);
$('#new_list_name_input').val('');
$.afui.goBack();
}
});
$('#add_new_item').click(function() {
var text = $('#new_elem_text').val();
if((text) && (text.length > 0)) {
var listID = $('#add_new_item').data('currentlist');
addItemToList(listID, text);
}
});
}
});

11
js/init.js Normal file
View file

@ -0,0 +1,11 @@
$.afui.autoLaunch = false; //By default, it is set to true and you're app will run right away. We set it to false to show a splashscreen
/* This function runs when the content is loaded.*/
$(document).ready(function(){
setTimeout(function(){
$.afui.launch();
},1500);
});
/* window.addEventListener('load', function() {
new FastClick(document.body);
}, false); */

102
js/libs/appframework.ui.min.js vendored Normal file
View file

@ -0,0 +1,102 @@
/*! intel-appframework - v3.0.0 - 2014-10-16 */
/*
Intel 2014
@author Ian Maffett
@description jQuery helper functions for App Framework
2011-2014 Intel
@author Intel
@version 3.0
2014 Intel
Intel 2014
Intel 2014
Intel 2014
Intel 2014
Intel 2014
*/
(function(a,f){function h(a,c){if(a)if(a.nodeType)c[c.length++]=a;else for(var d=0,b=a.length;d<b;d++)c[c.length++]=a[d]}function b(a,c){a.os={};a.os.webkit=c.match(/WebKit\/([\d.]+)/)?!0:!1;a.os.android=c.match(/(Android)\s+([\d.]+)/)||c.match(/Silk-Accelerated/)?!0:!1;a.os.androidICS=a.os.android&&c.match(/(Android)\s4/)?!0:!1;a.os.ipad=c.match(/(iPad).*OS\s([\d_]+)/)?!0:!1;a.os.iphone=!a.os.ipad&&c.match(/(iPhone\sOS)\s([\d_]+)/)?!0:!1;a.os.ios7=(a.os.ipad||a.os.iphone)&&(c.match(/7_/)||c.match(/8_/))?
!0:!1;a.os.webos=c.match(/(webOS|hpwOS)[\s\/]([\d.]+)/)?!0:!1;a.os.touchpad=a.os.webos&&c.match(/TouchPad/)?!0:!1;a.os.ios=a.os.ipad||a.os.iphone;a.os.playbook=c.match(/PlayBook/)?!0:!1;a.os.blackberry10=c.match(/BB10/)?!0:!1;a.os.blackberry=a.os.playbook||a.os.blackberry10||c.match(/BlackBerry/)?!0:!1;a.os.chrome=c.match(/Chrome/)?!0:!1;a.os.opera=c.match(/Opera/)?!0:!1;a.os.fennec=c.match(/fennec/i)?!0:c.match(/Firefox/)?!0:!1;a.os.ie=c.match(/MSIE 10.0/i)||c.match(/Trident\/7/i)?!0:!1;a.os.ieTouch=
a.os.ie&&c.toLowerCase().match(/touch/i)?!0:!1;a.os.tizen=c.match(/Tizen/i)?!0:!1;a.os.supportsTouch=f.DocumentTouch&&g instanceof f.DocumentTouch||"ontouchstart"in f;a.os.kindle=c.match(/Silk-Accelerated/)?!0:!1;a.feat={};a.feat.cssPrefix=a.os.webkit?"Webkit":a.os.fennec?"Moz":a.os.ie?"ms":a.os.opera?"O":"";a.feat.cssTransformStart=!a.os.opera?"3d(":"(";a.feat.cssTransformEnd=!a.os.opera?",0)":")";a.os.android&&!a.os.webkit&&(a.os.android=!1)}jQuery.event.props.push("touches");jQuery.event.props.push("originalTouches");
jQuery.event.props.push("changedTouches");var g=f.document,e={},c="object"===typeof MSApp;a.extend(a.fn,{vendorCss:function(c,d,b){this.css(c.toLowerCase(),d,b);return this.css(a.feat.cssPrefix+c,d,b)},cssTranslate:function(c){this.vendorCss("Transform","translate"+a.feat.cssTransformStart+c+a.feat.cssTransformEnd)},computedStyle:function(a){if(!(0===this.length||void 0==a))return f.getComputedStyle(this[0],"")[a]},replaceClass:function(a,c){if(void 0==a||void 0==c)return this;var d=function(a){g=
g.replace(a in e?e[a]:e[a]=RegExp("(^|\\s)"+a+"(\\s|$)")," ")},b=0;for(;b<this.length;b++){var g=this[b].className;a.split(/\s+/g).concat(c.split(/\s+/g)).forEach(d);g=g.trim();this[b].className=0<g.length?(g+" "+c).trim():c}return this}});b(a,navigator.userAgent);a.__detectUA=b;a.uuid=function(){var a=function(){return(65536*(1+Math.random())|0).toString(16).substring(1)};return a()+a()+"-"+a()+"-"+a()+"-"+a()+"-"+a()+a()+a()};a.getCssMatrix=function(c){a.is$(c)&&(c=c.get(0));var d=f.WebKitCSSMatrix||
f.MSCSSMatrix;if(void 0===c)return d?new d:{a:0,b:0,c:0,d:0,e:0,f:0};c=f.getComputedStyle(c);c=c.webkitTransform||c.transform||c[a.feat.cssPrefix+"Transform"];return d?new d(c):c?(d=c.replace(/[^0-9\-.,]/g,"").split(","),{a:+d[0],b:+d[1],c:+d[2],d:+d[3],e:+d[4],f:+d[5]}):{a:0,b:0,c:0,d:0,e:0,f:0}};a.create=function(d,b){var e,k=new a;if(b||"<"!==d[0]){b.html&&(b.innerHTML=b.html,delete b.html);e=g.createElement(d);for(var f in b)e[f]=b[f];k[k.length++]=e}else e=g.createElement("div"),c?MSApp.execUnsafeLocalFunction(function(){e.innerHTML=
d.trim()}):e.innerHTML=d,h(e.childNodes,k);return k};a.query=function(c,d){try{return a(c,d)}catch(b){return a()}};a.isObject=function(a){return"object"===typeof a};a.is$=function(c){return c instanceof a};f.$afm=a;a.feat.TouchList=function(){this.length=0};a.feat.TouchList.prototype={item:function(a){return this[a]},_add:function(a){this[this.length]=a;this.length++}};var d=1E3;a.feat.Touch=function(){this.identifier=d++};a.feat.Touch.prototype={clientX:0,clientY:0,screenX:0,screenY:0,pageX:0,pageY:0,
identifier:0}})(jQuery,window);window.af=window.jq=jQuery;
(function(a){var f=window.location.pathname+window.location.search,h=function(){function c(){if(d.useOSThemes){var c=a(document.body);c.removeClass("ios ios7 win8 tizen bb android light dark firefox");a.os.android?c.addClass("android"):a.os.ie?c.addClass("win8"):a.os.blackberry||a.os.blackberry10||a.os.playbook?(c.addClass("bb"),d.backButtonText="Back"):a.os.ios7?c.addClass("ios7"):a.os.ios?c.addClass("ios7"):a.os.tizen?c.addClass("tizen"):a.os.fennec&&c.addClass("firefox")}a.os.ios7&&d.overlayStatusbar&&
d.ready(function(){a(document.body).addClass("overlayStatusbar")})}var d=this;"function"===typeof define&&define.amd?(d.autoLaunch=!1,define("appframeworkui",[],function(){return a.afui})):"undefined"!==typeof module&&module.exports&&(d.autoLaunch=!1,a.afui=d);var b=function(){c();window.FastClick&&FastClick.attach(document.documentElement)};if("complete"===document.readyState||"loaded"===document.readyState)if(b(),d.init)d.autoBoot();else a(window).one("afui:init",function(){d.autoBoot()});else a(document).ready(function(){b();
if(d.init)d.autoBoot();else a(window).one("afui:init",function(){d.autoBoot()})},!1);window.addEventListener("popstate",function(){if(d.useInternalRouting){var a=d.getPanelId(document.location.hash);"#"!==document.location.href.replace(document.location.origin+"/","")&&(""===a&&1===d.history.length&&(a="#"+d.firstPanel.id),""!==a&&0!==af(a).filter(".panel").length&&a!=="#"+d.activeDiv.id&&d.goBack())}},!1);window.addEventListener("orientationchange",function(){window.scrollTo(0,0)})},b=[];h.prototype=
{init:!1,showLoading:!0,loadingText:"Loading Content",remotePages:{},history:[],views:{},_readyFunc:null,doingTransition:!1,ajaxUrl:"",transitionType:"slide",firstPanel:"",hasLaunched:!1,isLaunching:!1,launchCompleted:!1,activeDiv:"",customClickHandler:"",useOSThemes:!0,overlayStatusbar:!1,useAutoPressed:!0,useInternalRouting:!0,autoBoot:function(){this.hasLaunched=!0;this.autoLaunch&&this.launch()},blockPageBounce:function(a){!1===a?(window.removeEventListener("touchmove",this.handlePageBounce,!1),
window.removeEventListener("touchstart",this.handlePageBounce,!1)):(window.addEventListener("touchmove",this.handlePageBounce,!1),window.addEventListener("touchstart",this.handlePageBounce,!1))},handlePageBounce:function(c){if("touchstart"===c.type)this._startTouchY=c.touches[0].screenY;else{var d=a(c.target).closest(".panel");if(0===d.length)return c.preventDefault();var d=d.get(0),b=d.scrollHeight>d.clientHeight,e="touch"===a(d).computedStyle("-webkit-overflow-scrolling"),g="hidden"!==a(d).computedStyle("overflowY"),
k=parseInt(a(d).computedStyle("height"),10);b&&(e&&g)&&(b=c.touches[0].screenY,k=this._startTouchY>=b&&d.scrollHeight-d.scrollTop===k,(this._startTouchY<=b&&0===d.scrollTop||k)&&c.preventDefault())}},registerDataDirective:function(a,d){b.push({sel:a,cb:d})},enableTabBar:function(){a(document).on("click",".button-grouped.tabbed",function(c){var d=a(c.target);d.closest(".tabbed").find(".button").data("ignore-pressed","true").removeClass("pressed");d.closest(".button").addClass("pressed");setTimeout(function(){d.closest(".button").addClass("pressed")})})},
disableTabBar:function(){a(document).off("click",".button-grouped.tabbed");a(".button-grouped.tabbed .button").removeAttr("data-ignore-pressed")},manageHistory:!0,loadDefaultHash:!0,actionsheet:function(c){return a.query(document.body).actionsheet(c)},popup:function(c){return a.query(document.body).popup(c)},blockUI:function(c){a.blockUI(c)},unblockUI:function(){a.unblockUI()},autoLaunch:!0,ready:function(c){if(this.launchCompleted)c();else a(document).one("afui:ready",function(){c()})},goBack:function(c){var d=
a(this.activeDiv).closest(".view");c&&c.target&&(d=a(c.target).closest(".view"));if(0!==d.length&&this.views[d.prop("id")]){var b=this.views[d.prop("id")];if(0!==b.length&&(c=b.pop(),0!==c.length))if(0<b.length){if((b=b[b.length-1].target)&&c.target!==b)this.runTransition(c.transition,c.target,b,!0),this.loadContentData(b,d,!0),this.updateHash(b.id)}else try{this.dismissView(c.target,c.transition)}catch(e){}}},clearHistory:function(){var a=this.findViewTarget(this.activeDiv);this.views[a.prop("id")]=
[];this.setBackButtonVisibility(!1)},pushHistory:function(c,d,b,e){try{this.manageHistory&&(window.history.pushState(d,d,f+"#"+d+e),a(window).trigger("hashchange",null,{newUrl:f+"#"+d+e,oldUrl:f+c}))}catch(g){}},updateHash:function(c){if(this.manageHistory){c=-1===c.indexOf("#")?"#"+c:c;var d=window.location.hash,b=this.getPanelId(c).substring(1);try{window.history.replaceState(b,b,f+c),a(window).trigger("hashchange",null,{newUrl:f+c,oldUrl:f+d})}catch(e){}}},getPanelId:function(a){var d=a.indexOf("/");
return-1===d?a:a.substring(0,d)},setBackButtonText:function(c){a(this.activeDiv).parent().find("header .backButton").html(c)},setTitle:function(c){var d="";"string"===typeof c?(d=c,c=a(this.activeDiv).closest(".view")):a(c).attr("data-title")?d=a(c).attr("data-title"):a(c).attr("title")&&(d=a(c).attr("title"));d&&a(c).closest(".view").children("header").find("h1").html(d)},getTitle:function(){return a(this.activeDiv).closest(".view").children("header").find("h1").html()},setBackButtonVisibility:function(c){a(this.activeDiv).closest(".view").children("header").find(".backButton").css("visibility",
c?"visibile":"hidden")},updateBadge:function(c,d,b,e){void 0===b&&(b="");c=a(c);var g=c.find("span.af-badge");0===g.length?("absolute"!==c.css("position")&&c.css("position","relative"),g=a.create("span",{className:"af-badge "+b,html:d}),c.append(g)):g.html(d);g.removeClass("tl bl br tr");g.addClass(b);void 0===e&&(e="red");a.isObject(e)?g.css(e):e&&g.css("background",e);g.data("ignore-pressed","true")},removeBadge:function(c){a(c).find("span.af-badge").remove()},showMask:function(c){c||(c=this.loadingText||
"");a.query("#afui_mask>h1").html(c);a.query("#afui_mask").show()},hideMask:function(){a.query("#afui_mask").hide()},dismissView:function(c,d){d=d.replace(":dismiss","");var b=a(c).closest(".view");this.runTransition(d,b,null,!0,a(c.hash).addClass("active").closest(".view"));this.activeDiv=a(".view").not(b).find(".panel.active").get(0);this.updateHash(this.activeDiv.id)},loadContent:function(a,d,b,e,g){this.doingTransition||0!==a.length&&(-1!==a.indexOf("#")?this.loadDiv(a,d,b,e,g):this.loadAjax(a,
d,b,e,g))},loadDiv:function(c,d,b,e,g){var k=c.replace("#",""),f=k.indexOf("/");-1!==f&&(k.substr(f),k=k.substr(0,f));if(k=a.query("#"+k).get(0))if(k===this.activeDiv&&!b)this.doingTransition=!1;else{this.transitionType=e;var f=this.findViewTarget(k),h=this.findPreviousPanel(k,f),n=(g=g?this.findViewTarget(g):this.findViewTarget(this.activeDiv))&&g.get(0)!==f.get(0)&&g.closest(".splitview").get(0)===f.closest(".splitview").get(0)&&0!==g.closest(".splitview").length;n&&(d=!1);a(k).trigger("panelbeforeload");
a(h).trigger("panelbeforeunload");var s=!1;n||(n=1===g.parent().closest(".view").length);n&&(g&&g.get(0)!==f.get(0))&&a(g).trigger("nestedviewunload");!n&&(d||g&&g.get(0)!==f.get(0))?(this.runViewTransition(e,f,g||d,k,b),this.updateViewHistory(f,k,e,c),s=!0):(this.runTransition(e,h,k,b),this.updateViewHistory(f,k,e,c));this.loadContentData(k,f,!1,s)}else a(document).trigger("missingpanel",null,{missingTarget:c}),this.doingTransition=!1},findViewTarget:function(c){c=a(c).closest(".view");if(!c)return!1;
this.views[c.prop("id")]||(this.views[c.prop("id")]=[]);return c},findPreviousPanel:function(c,d){var b=a(d).find(">.pages .panel.active").not(c);0===b.length&&(b=a(d).find(">.pages .panel:first-of-type"));return b.get(0)},loadContentData:function(a,d,b,e){this.activeDiv=a;this.setTitle(a,d,b,e);this.showBackButton(d,e);this.setActiveTab(a,d)},setActiveTab:function(c,d){var b;"string"!==typeof c&&(b=a(c).prop("id"));b="#"+b;d.find("footer").find("a").removeClass("pressed").attr("data-ignore-pressed",
"true").filter("[href='"+b+"']").addClass("pressed")},showBackButton:function(a,d){var b=this.views[a.prop("id")].length,e=a.children("header");0!==e.length&&(2<=b&&!0!==d?1!==e.find(".backButton").length&&e.prepend("<a class='backButton back'>Back</a>"):e.find(".backButton").remove())},loadAjax:function(c,d,b,g,f){var k=this,h=e(c),q=a(".panel[data-crc='"+h+"']"),n=f.getAttribute("data-refresh");if(0<q.length)if(n)k.showLoading&&k.showMask("Loading Content"),a.ajax(c).then(function(a){q.html(a);
k.showLoading&&k.hideMask();return k.loadContent("#"+q.prop("id"),d,b,g,f)});else return k.loadContent("#"+q.prop("id"),d,b,g,f);k.showLoading&&k.showMask("Loading Content");a.ajax(c).then(function(e){e=a.create("div",{html:e});e.hasClass(".panel")?e=e.find(".panel"):(e=e.attr("data-title",c),e.prop("id",h),e.addClass("panel"));a(k.activeDiv).closest(".pages").append(e);e.attr("data-crc",h);k.showLoading&&k.hideMask();k.loadContent("#"+e.prop("id"),d,b,g,f)}).fail(function(a){k.showLoading&&k.hideMask();
console.log("Error with ajax request",a)})},runTransition:function(c,d,b,e,g){c||(c="slide");-1!==c.indexOf(":back")&&(c=c.replace(":back",""),e=!0);var k=this,f=e?d:b;d=e?b:d;b=!1;-1!==c.indexOf("-reveal")&&(c=c.replace("-reveal",""),b=!0);a(f).css("zIndex","10");a(d).css("zIndex","1");a(g).css("zIndex","1").addClass("active");var h=a(d).animation().remove(c+"-in");!b&&h?(e&&h.reverse(),h.end(function(){e?(this.classList.add("active"),a(this).trigger("panelload")):(this.classList.remove("active"),
a(this).trigger("panelunload"));k.doingTransition=!1}).run(c+"-out")):e?(a(d).trigger("panelload"),a(d).addClass("activeDiv")):a(d).trigger("panelunload");f=a(f).animation().remove(c+"-out");e&&f.reverse();f.end(function(){k.doingTransition=!1;e?(g&&a(g).css("zIndex","10"),this.classList.remove("active"),a(this).trigger("panelunload")):(this.classList.add("active"),a(this).trigger("panelload"),a(g).trigger("panelload"))}).run(c+"-in")},runViewTransition:function(c,d,b,e,g){d.addClass("active");a(e).addClass("active");
"none"===c?(this.doingTransition=!1,setTimeout(function(){b.removeClass("active")},50)):this.runTransition(c,b,d,g,e)},updateViewHistory:function(a,d,b,e){var g=this.views[a.prop("id")];g||(g=this.views[a.prop("id")]=[]);1<=g.length&&g[g.length-1].target===d||(this.pushHistory(d.id,d.id,b,e.replace(d.id,"").replace("#","")),this.views[a.prop("id")].push({target:d,transition:b}))},launch:function(){if(!1===this.hasLaunched||this.launchCompleted)this.hasLaunched=!0;else{if(this.isLaunching)return!0;
this.isLaunching=!0;this.blockPageBounce();var c=this,d=a.create("div",{id:"afui_mask",className:"ui-loader",html:"<span class='ui-icon ui-icon-loading spin'></span><h1>Loading Content</h1>"}).css({"z-index":2E4,display:"none"});document.body.appendChild(d.get(0));d=a(".view[data-default='true']");if(0===d.length)d=a(".view").eq(0);else throw"You need to create a view";d.addClass("active");this.views[d.prop("id")]=[];var e=window.location.hash,f=0===d.find(".panel[data-selected='true']").length?d.find(".panel").eq(0):
d.find(".panel[data-selected='true']");f.addClass("active");this.activeDiv=f.get(0);this.views[d.prop("id")].push({target:f.get(0),transition:this.transitionType});this.defaultPanel=f.get(0);this.loadContentData(f.get(0),d,!1,!0);this.updateHash(f.get(0).id);this.loadDefaultHash&&setTimeout(function(){this.loadContent(e,!1,0,"none")}.bind(this));this.enableTabBar();a(document).on("click","a",function(a){c.useInternalRouting&&g(a,a.currentTarget)});a(document).on("click",function(d){for(var e=b.length,
g=a(d.target),f=0;f<e;f++){var h=b[f],m=g.closest(h.sel);0<m.length&&h.cb.call(c,m.get(0),d)}});a(document).on("click",".backButton, [data-back]",c.goBack.bind(c));d=a("[data-include]");if(0===d.length)this.launchCompleted=!0,a(document).trigger("afui:ready");else{var h=[];d.each(function(){var c=this.getAttribute("data-include"),d=a(this);h.push(a.get(c,function(a){d.append(a)}))});a.when.apply(a,h).then(function(){this.launchCompleted=!0;a(document).trigger("afui:ready")}).fail(function(){this.launchCompleted=
!0;a(document).trigger("afui:ready")})}a(document).on("click","footer a:not(.button)",function(c){c=a(c.target);var d=c.closest("footer");c.parent().find("a:not(.button)").attr("data-ignore-pressed","true").removeClass("pressed");"true"!==d.attr("data-ignore-pressed")&&c.addClass("pressed")})}}};var g=function(c,d){d=d||c.currentTarget;if(d!==document){if("a"!==d.tagName.toLowerCase()&&d.parentNode)return g(c,d.parentNode);if("undefined"!==d.tagName&&"a"===d.tagName.toLowerCase()&&!(-1!==d.href.toLowerCase().indexOf("javascript:")||
d.getAttribute("data-ignore"))){var b=d.href,e=location.protocol+"//"+location.hostname+":"+location.port+location.pathname;0===b.indexOf(e)&&(b=b.substring(e.length));if("#"===b||b.indexOf("#")===b.length-1||0===b.length&&0===d.hash.length)return c.preventDefault();e=/^((http|https|file):\/\/)/;-1!==d.href.indexOf(":")&&e.test(d.href)&&c.preventDefault();e=d.getAttribute("data-transition");!e&&0<a(d).closest("footer").length&&(e="none");if(e&&-1!==e.indexOf(":dismiss"))return a.afui.dismissView(d,
e);b=0<d.hash.length?d.hash:b;a.afui.loadContent(b,!1,0,e,d)}}},e=function(a,b){void 0===b&&(b=0);var e=0,e=0;b^=-1;for(var g=0,f=a.length;g<f;g++)e=(b^a.charCodeAt(g))&255,e="0x"+"00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F 63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC 51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E 7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D 806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA 11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F 30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D".substr(9*
e,8),b=b>>>8^e;return(b^-1)>>>0};a.afui=new h;a.afui.init=!0;a(window).trigger("afui:preinit");a(window).trigger("afui:init")})(jQuery);
(function(a){a.fn.actionsheet=function(a){for(var b,g=0;g<this.length;g++)b=new f(this[g],a);return 1===this.length?b:this};var f=function(h,b){if(this.el="string"===typeof h||h instanceof String?document.getElementById(h):h){if(this instanceof f){if("object"===typeof b)for(var g in b)this[g]=b[g]}else return new f(h,b);var e;g=function(){};if("string"===typeof b)e=a("<div id='af_actionsheet'><div style='width:100%'>"+b+"<a href='javascript:;' class='cancel'>Cancel</a></div></div>");else if("object"===
typeof b){e=a("<div id='af_actionsheet'><div style='width:100%'></div></div>");var c=a(e.children().get(0));b.push({text:"Cancel",cssClasses:"cancel"});for(var d=0;d<b.length;d++){var m=a("<a href='javascript:;'>"+(b[d].text||"TEXT NOT ENTERED")+"</a>");m[0].onclick=b[d].handler||g;b[d].cssClasses&&0<b[d].cssClasses.length&&m.addClass(b[d].cssClasses);c.append(m)}}a(h).find("#af_actionsheet").remove();a(h).find("#af_action_mask").remove();a(h).append(e);e.vendorCss("Transition","all 0ms");this.el.style.overflow=
"hidden";e.on("click","a",this.sheetClickHandler.bind(this));this.activeSheet=e;e.cssTranslate("0,"+e.height()+"px");a(h).append("<div id='af_action_mask' style='position:absolute;top:0px;left:0px;right:0px;bottom:0px;z-index:9998;background:rgba(0,0,0,.4)'/>");setTimeout(function(){e.vendorCss("Transition","all 300ms");e.cssTranslate("0,0")},10);a("#af_action_mask").bind("touchstart touchmove touchend click",function(a){a.preventDefault();a.stopPropagation()})}else window.alert("Could not find element for actionsheet "+
h)};f.prototype={activeSheet:null,sheetClickHandler:function(){this.hideSheet();return!1},hideSheet:function(){this.activeSheet.off("click","a",this.sheetClickHandler);a(this.el).find("#af_action_mask").unbind("click").remove();this.activeSheet.vendorCss("Transition","all 0ms");var f=this.activeSheet,b=this.el;setTimeout(function(){f.vendorCss("Transition","all 300ms");f.cssTranslate("0,"+(f.height()+60)+"px");setTimeout(function(){f.remove();f=null;b.style.overflow="none"},350)},10)}};a.afui.actionsheet=
function(f){return a(document.body).actionsheet(f)}})(jQuery);
(function(a){a.afui.registerDataDirective("[data-grower]",function(f,h){var b=a(f).closest("[data-grower]"),g=b.offset(),e=b.closest(".view"),c=h.target.hash||b.attr("data-grower");e.css("zIndex","1");var d=a(c).closest(".view"),m=b.width()/window.innerWidth,l=b.height()/window.innerHeight,p={left:g.left,top:g.top,x:m,y:l};a(c).trigger("panelgrowstart",[b.get(0)]);d.addClass("active").css("zIndex","10");d.vendorCss("TransformOrigin","0 0");d.data("growTransProps",p);d.vendorCss("TransitionDuration",
"0");d.vendorCss("Transform","translate3d("+g.left+"px,"+g.top+"px,0) scale("+m+","+l+")");d.data("growTarget",b.closest(".panel"));d.data("growFrom",a(c).attr("id"));a.afui.loadContent(c,e,!1,"stretch");a(c).one("panelload",function(){d.vendorCss("Transform","");a(c).trigger("panelgrowcomplete",[b.get(0)])})});a.afui.registerDataDirective("[data-grower-back]",function(f){var h=a(f).closest(".view"),b=a("#"+h.data("growFrom"));b.trigger("panelgrowendstart");f=h.data("growTransProps");var g="#"+h.data("growTarget").prop("id");
a(g).closest(".view").addClass("active");h.addClass("animation-active");h.transition().end(function(){h.removeClass("active");b.trigger("panelgrowendstart");a.afui.loadContent(g,!1,!1,"none")}).run("translate3d("+f.left+"px,"+f.top+"px,0) scale("+f.x+","+f.y+")","300ms")})})(jQuery);
(function(a){function f(a,c,b,d){var e=Math.abs(a-c),g=Math.abs(b-d);return e>=g?0<a-c?"Left":"Right":0<b-d?"Up":"Down"}function h(){b.last&&Date.now()-b.last>=e&&(b.el.trigger("longTap"),b={})}var b={},g,e=750,c,d=!1,m=!1;a(document).ready(function(){var l;a(document.body).bind("touchstart",function(f){f.originalEvent&&(f=f.originalEvent);if(f.touches&&0!==f.touches.length){var k=Date.now(),r=k-(b.last||k);f.touches&&0!==f.touches.length&&(b.el=a("tagName"in f.touches[0].target?f.touches[0].target:
f.touches[0].target.parentNode),g&&clearTimeout(g),b.x1=f.touches[0].pageX,b.y1=f.touches[0].pageY,b.x2=b.y2=0,0<r&&250>=r&&(b.isDoubleTap=!0),b.last=k,c=setTimeout(h,e),a.afui.useAutoPressed&&!b.el.attr("data-ignore-pressed")&&b.el.addClass("pressed"),l&&(a.afui.useAutoPressed&&!l.attr("data-ignore-pressed")&&l[0]!==b.el[0])&&l.removeClass("pressed"),l=b.el,m=d=!1)}}).bind("touchmove",function(e){e.originalEvent&&(e=e.originalEvent);b.x2=e.touches[0].pageX;b.y2=e.touches[0].pageY;if(!m&&(5<Math.abs(b.x2-
b.x1)||5<Math.abs(b.y2-b.y1))){var g=5<Math.abs(b.x2-b.x1),h=5<Math.abs(b.y2-b.y1);m=!0;b.el.trigger("swipeStart",[e]);b.el.trigger("swipeStart"+f(b.x1,b.x2,b.y1,b.y2),[b,e]);var l=b.el.closest(".swipe, .swipe-reveal, .swipe-x, .swipe-y"),n=b.el.closest(".x-scroll, .y-scroll, .scroll");d=0!==b.el.closest(".swipe, .swipe-reveal").length;0!==n.parent(l).length?d=!1:g&&0!==b.el.closest(".swipe-x").length?d=!0:h&&0!==b.el.closest(".swipe-y").length&&(d=!0)}a.os.android&&m&&d&&e.preventDefault();clearTimeout(c)}).bind("touchend",
function(c){c.originalEvent&&(c=c.originalEvent);if(b.el)if(a.afui.useAutoPressed&&!b.el.attr("data-ignore-pressed")&&b.el.removeClass("pressed"),b.isDoubleTap)b.el.trigger("doubleTap"),b={};else if(0<b.x2||0<b.y2){(30<Math.abs(b.x1-b.x2)||30<Math.abs(b.y1-b.y2))&&b.el.trigger("swipe");c=f(b.x1,b.x2,b.y1,b.y2);var d=".x-scroll",e=".swipe-x";if("up"===c.toLowerCase()||"down"===c.toLowerCase())d=".y-scroll",e=".swipe-y";e=b.el.closest(e);d=b.el.closest(d);(0===e.length||0===d.length||0==e.find(d).length)&&
b.el.trigger("swipe"+c);b.x1=b.x2=b.y1=b.y2=b.last=0}else"last"in b&&(b.el.trigger("tap"),g=setTimeout(function(){g=null;b.el&&b.el.trigger("singleTap");b={}},250))}).bind("touchcancel",function(){b.el&&(a.afui.useAutoPressed&&!b.el.attr("data-ignore-pressed"))&&b.el.removeClass("pressed");b={};clearTimeout(c)})});"swipe swipeLeft swipeRight swipeUp swipeDown doubleTap tap singleTap longTap".split(" ").forEach(function(c){a.fn[c]=function(a){return this.bind(c,a)}})})(jQuery);
(function(a){var f=a.afui.setTitle;a.afui.animateHeader=function(h){a.afui.setTitle=!1!==h?function(b,g,e,c){var d;"string"===typeof b?d=b:a(b).attr("data-title")?d=a(b).attr("data-title"):a(b).attr("title")&&(d=a(b).attr("title"));d&&0!==d.length&&(b=a(this.activeDiv).closest(".view").children("header").eq(0),e=e?"header-unload":"header-load",g=b.find("h1").eq(0).html(),b.find("h1").eq(0).html(d).removeClass("header-unload header-load"),c||(b.find("h1").animation().run(e+"-to"),c=a("<h1>"+g+"</h1>"),
b.append(c),c.animation().end(function(){a(this).remove()}).run(e)))}:f}})(jQuery);
(function(a){a.fn.popup=function(a){return new h(this[0],a)};var f=[],h=function(b,e){if(this.container="string"===typeof b||b instanceof String?document.getElementById(b):b)try{if("string"===typeof e||"number"===typeof e)e={message:e,cancelOnly:"true",cancelText:"OK"};this.id=e.id=e.id||a.uuid();this.addCssClass=e.addCssClass?e.addCssClass:"";this.suppressTitle=e.suppressTitle||this.suppressTitle;this.title=e.suppressTitle?"":e.title||"Alert";this.message=e.message||"";this.cancelText=e.cancelText||
"Cancel";this.cancelCallback=e.cancelCallback||function(){};this.cancelClass=e.cancelClass||"button";this.doneText=e.doneText||"Done";this.doneCallback=e.doneCallback||function(){};this.doneClass=e.doneClass||"button";this.cancelOnly=e.cancelOnly||!1;this.onShow=e.onShow||function(){};this.autoCloseDone=void 0!==e.autoCloseDone?e.autoCloseDone:!0;f.push(this);1===f.length&&this.show()}catch(c){console.log("error adding popup "+c)}else window.alert("Error finding container for popup "+b)};h.prototype=
{id:null,addCssClass:null,title:null,message:null,cancelText:null,cancelCallback:null,cancelClass:null,doneText:null,doneCallback:null,doneClass:null,cancelOnly:!1,onShow:null,autoCloseDone:!0,suppressTitle:!1,show:function(){var b=this,e=a("<div id='"+this.id+"' class='afPopup hidden "+this.addCssClass+"'><header>"+this.title+"</header><div>"+this.message+"</div><footer><a href='javascript:;' class='"+this.cancelClass+"' id='cancel'>"+this.cancelText+"</a><a href='javascript:;' class='"+this.doneClass+
"' id='action'>"+this.doneText+"</a><div style='clear:both'></div></footer></div>");a(this.container).append(e);e.bind("close",function(){b.hide()});this.cancelOnly&&(e.find("A#action").hide(),e.find("A#cancel").addClass("center"));e.find("A").each(function(){var c=a(this);c.bind("click",function(a){"cancel"===c.attr("id")?(b.cancelCallback.call(b.cancelCallback,b),b.hide()):(b.doneCallback.call(b.doneCallback,b),b.autoCloseDone&&b.hide());a.preventDefault()})});b.positionPopup();a.blockUI(0.5);e.bind("orientationchange",
function(){b.positionPopup()});e.find("header").show();e.find("footer").show();setTimeout(function(){e.removeClass("hidden").addClass("show");b.onShow(b)},50)},hide:function(){var b=this;a.query("#"+b.id).addClass("hidden");a.unblockUI();!a.os.ie&&!a.os.android?setTimeout(function(){b.remove()},250):b.remove()},remove:function(){var b=a.query("#"+this.id);b.unbind("close");b.find("BUTTON#action").unbind("click");b.find("BUTTON#cancel").unbind("click");b.unbind("orientationchange").remove();f.splice(0,
1);0<f.length&&f[0].show()},positionPopup:function(){var b=a.query("#"+this.id);b.css("top",window.innerHeight/2.5+window.pageYOffset-b[0].clientHeight/2+"px");b.css("left",window.innerWidth/2-b[0].clientWidth/2+"px")}};var b=!1;a.blockUI=function(g){b||(g=g?" style='opacity:"+g+";'":"",a.query("BODY").prepend(a("<div id='mask'"+g+"></div>")),a.query("BODY DIV#mask").bind("touchstart",function(a){a.preventDefault()}),a.query("BODY DIV#mask").bind("touchmove",function(a){a.preventDefault()}),b=!0)};
a.unblockUI=function(){b=!1;a.query("BODY DIV#mask").unbind("touchstart");a.query("BODY DIV#mask").unbind("touchmove");a("BODY DIV#mask").remove()};a.afui.registerDataDirective("[data-alert]",function(b){b=a(b).attr("data-message");0!==b.length&&a(document.body).popup(b)});a.afui.popup=function(b){return a(document.body).popup(b)}})(jQuery);
(function(a){function f(a){this.element=a;this.element.classList.remove("animation-reverse");this.keepClass=!1}function h(a){this.element=a;this.element}a.fn.animation=function(){var a=this;this.each(function(){a=new f(this)});return a};var b=function(a){this.element.removeEventListener("webkitAnimationEnd",this.endCBCache,!1);this.element.removeEventListener("animationend",this.endCBCache,!1);this.element.removeEventListener("MSAnimationEnd",this.endCBCache,!1);this.endcb&&this.endcb.call(this.element,
a);this.element.classList.remove("animation-reverse");this.element.classList.remove("animation-active");this.keepClass||this.element.classList.remove(this.animClass)};f.prototype={element:null,animClass:null,runEnd:!1,keepClass:!1,keep:function(){this.keepClass=!0;return this},remove:function(a){this.element.classList.remove(a);this.element.offsetWidth=this.element.offsetWidth;return this},endCBCache:null,run:function(a,c){this.runEnd=!1;this.element.classList.add("animation-active");this.element.offsetWidth=
this.element.offsetWidth;this.element.classList.add(a);this.animClass=a;var d=window.getComputedStyle(this.element,null),g=d.animation-c;g||(g=d.animationDuration);g||(g=d.MozAnimationDuration);g||(g=d.webkitAnimationDuration);g=parseFloat(g);if(0.01>=g||isNaN(g))this.runEnd=!0;this.endCBCache=b.bind(this);if(this.runEnd)return this.endCBCache(),this;this.element.addEventListener("webkitAnimationEnd",this.endCBCache,!1);this.element.addEventListener("animationend",this.endCBCache,!1);this.element.addEventListener("MSAnimationEnd",
this.endCBCache,!1);return this},reverse:function(){this.element.classList.add("animation-reverse");return this},reRun:function(a){this.remove(a);return this.run(a)},endcb:function(){},end:function(a){this.endcb=a;return this}};a.fn.transition=function(){var a=this;this.each(function(){a=new h(this)});return a};var g=function(b){clearTimeout(this.timer);this.element.removeEventListener("webkitTransitionEnd",this.endCBCache,!1);this.element.removeEventListener("transitionend",this.endCBCache,!1);this.element.removeEventListener("MSTransitionEnd",
this.endCBCache,!1);this.endcb&&this.endcb.call(this.element,b);this.keepEnd||(a(this.element).vendorCss("TransitionDuration",""),a(this.element).vendorCss("Transform",""))};h.prototype={element:null,runEnd:!1,keepEnd:!1,keep:function(){this.keepEnd=!0;return this},endCBCache:null,timer:null,run:function(b,c){this.endCBCache=g.bind(this);this.element.addEventListener("webkitTransitionEnd",this.endCBCache,!1);this.element.addEventListener("transitionend",this.endCBCache,!1);this.element.addEventListener("MSTransitionEnd",
this.endCBCache,!1);a(this.element).vendorCss("TransitionDuration",c);a(this.element).vendorCss("Transform",b);this.timer=setTimeout(function(){this.endCBCache()}.bind(this),parseInt(c,10)+50);return this},endcb:function(){},end:function(a){this.endcb=a;return this}}})(jQuery);(function(a){a.afui.ready(function(){setTimeout(function(){a("#splashscreen").remove()},250)})})(jQuery);
(function(a){function f(){return this}var h=null,b,g={push:function(b,c,d){b=a(b).closest(".view").children().filter(":not(nav):not(aside)");d=d||h;for(var g=0;g<b.length;g++){var f=a(b[g]).show().animation();c?f.remove("slide-"+d+"-out").reverse():f.keep();f.run("slide-"+d+"-out")}},cover:function(){},reveal:function(a,b){return this.push(a,b)}};f.prototype={defaultTransition:"slide",defaultAnimation:"cover",autoHide:function(a){a.preventDefault();this.hide()},checkViewToClose:function(a){this.autoHide(a)},
autoHideCheck:null,selfCheckViewToClose:null,show:function(e,c,d){if(!this.isTransitioning){var f=this;h="right"===c?"right":"left";d=g[d]?d:this.defaultAnimation;var l=document.getElementById(e.replace("#",""));l&&(b=l,l.classList.contains("active")||(this.isTransitioning=!0,this.autoHideCheck=this.autoHide.bind(this),a(l).closest(".view").children().filter(":not(nav):not(aside)").off("touchstart",this.autoHideCheck),l.classList.add(h),e=a(l).show(),c="right"===h?"left":"right",0<a(l).closest(".view").find(".slide-"+
c+"-out").length&&(a(l).closest(".view").find(".slide-"+c+"-out").removeClass("slide-"+c+"-out"),a(l).closest(".view").find("aside.active, nav.active").removeClass("left right active").hide()),"reveal"!==d?e.css("zIndex","999").animation().run("slide-"+h+"-in").end(function(){this.classList.add("active");f.isTransitioning=!1}):e.animation().run("blank").end(function(){a(this).css("zIndex","999");this.classList.add("active");f.isTransitioning=!1}),l.activeAnimation=d,l.activePosition=h,l.toggled=!0,
g[d](l,!1),setTimeout(function(){a(l).closest(".view").children().filter(":not(nav):not(aside)").on("touchstart",f.autoHideCheck)}),this.selfCheckViewToClose=f.checkViewToClose.bind(this),a(l).bind("nestedviewunload",this.selfCheckViewToClose)))}},hide:function(e,c){if(!this.isTransitioning){var d=this,f=e&&document.getElementById(e.replace("#",""))||b;a(f).unbind("nestedviewunload",this.selfCheckViewToClose);if(f&&f.toggled){a(f).closest(".view").children().filter(":not(nav):not(aside)").off("touchstart",
this.autoHideCheck);var h=c||f.activePosition,p=a(f).animation();"reveal"===f.activeAnimation&&a(f).css("zIndex","1");var k="reveal"===f.activeAnimation?"blank":"slide-"+h+"-in";p.reverse().reRun(k).end(function(){this.classList.remove("active");this.classList.remove(h);this.style.display="none";this.style.zIndex="";d.isTransitioning=!1});if(g[f.activeAnimation])g[f.activeAnimation](f,!0);f.toggled=!1;b=null}}}};a.afui.drawer=new f;a.afui.registerDataDirective("[data-left-menu]:not([data-menu-close]),[data-right-menu]:not([data-menu-close])",
function(b){var c=a(b);b=c.attr("data-left-menu")?"left":"right";var d="left"===b?c.attr("data-left-menu"):c.attr("data-right-menu"),c=c.attr("data-transition");this.drawer.show(d,b,c)});a.afui.registerDataDirective("[data-menu-close]",function(b){var c=a(b),d=null;c.attr("data-left-menu")&&(d="left");c.attr("data-right-menu")&&(d="right");c="left"===d?c.attr("data-left-menu"):c.attr("data-right-menu");if(!c&&(c=a(b).closest("nav").prop("id"),!c||0===c.length))c=a(b).closest(".view").find("nav.active,aside.active").prop("id");
this.drawer.hide(c,d)})})(jQuery);
(function(a){var f,h=0,b,g;a.afui.swipeThreshold=0.3;a(document).on("swipeStartLeft",".swipe-reveal",function(c,d,m){m.preventDefault();f=a(c.target).closest(".swipe-content");h=d.x2;g=f.closest(".swipe-reveal").find(".swipe-hidden").width();0===a.getCssMatrix(c.target).e&&(f.bind("touchmove",e),f.one("touchend",function(){f.unbind("touchmove",e);Math.abs(b)/g<a.afui.swipeThreshold&&(g=0);f.transition().keep().end(function(){f=g=null}).run("translate3d("+-g+"px,0px,0)","100ms")}))});a(document).on("swipeStartRight",
".swipe-reveal",function(c,d,m){m.preventDefault();f=a(c.target).closest(".swipe-content");g=f.closest(".swipe-reveal").find(".swipe-hidden").width();0!==a.getCssMatrix(c.target).e&&(h=d.x2+g,f.bind("touchmove",e),f.one("touchend",function(){f.unbind("touchmove",e);1-Math.abs(b)/g>a.afui.swipeThreshold&&(g=0);f.transition().keep().end(function(){f=g=null}).run("translate3d("+-g+"px,0px,0)","100ms")}))});var e=function(a){a=-(h-a.touches[0].pageX);a<-g?a="-"+g:0<a&&(a=0);b=a;f.cssTranslate(a+"px,0")}})(jQuery);
(function(a){var f=!1;if(!a.os.supportsTouch){try{document.createEvent("TouchEvent");return}catch(h){}a.os.supportsTouch=!0;var b=function(a){a.preventDefault();a.stopPropagation()},g=navigator.userAgent.match(/Phone/i)?2:7,e=function(a,c){var d=c.tagName.toUpperCase();-1<d.indexOf("SELECT")||(-1<d.indexOf("TEXTAREA")||-1<d.indexOf("INPUT"))||b(a)},c=function(b,c,d,g){d=d?d:c.target;g||e(c,d);g=document.createEvent("MouseEvent");g.initEvent(b,!0,!0);g.initMouseEvent(b,!0,!0,window,c.detail,c.screenX,
c.screenY,c.clientX,c.clientY,c.ctrlKey,c.shiftKey,c.altKey,c.metaKey,c.button,c.relatedTarget);g.touches=new a.feat.TouchList;g.changedTouches=new a.feat.TouchList;g.targetTouches=new a.feat.TouchList;var f=new a.feat.Touch;f.pageX=c.pageX;f.pageY=c.pageY;f.target=c.target;g.changedTouches._add(f);"touchend"!==b&&(g.touches=g.changedTouches,g.targetTouches=g.changedTouches);g.mouseToTouch=!0;if(a.os.ie)for(c=c.target;null!==c;)c.hasAttribute("on"+b)&&eval(c.getAttribute("on"+b)),c=c.parentElement;
d.dispatchEvent(g)},d=!1,m=null,l=0,p=0;window.navigator.msPointerEnabled?(document.addEventListener("MSPointerDown",function(a){d=!0;m=a.target;"a"===a.target.nodeName.toLowerCase()&&"javascript:;"===a.target.href.toLowerCase()&&(a.target.href="");c("touchstart",a,null,!0);f=!1;l=a.clientX;p=a.clientY;return!0},!0),document.addEventListener("MSPointerUp",function(a){if(d)return c("touchend",a,m,!0),m=null,d=!1,!0},!0),document.addEventListener("MSPointerMove",function(a){if(!(Math.abs(a.clientX-
l)<=g||Math.abs(a.clientY-p)<=g)&&d)return c("touchmove",a,m,!0),f=!0},!0)):(document.addEventListener("mousedown",function(a){d=!0;m=a.target;"a"===a.target.nodeName.toLowerCase()&&"javascript:;"===a.target.href.toLowerCase()&&(a.target.href="#");c("touchstart",a);f=!1;l=a.clientX;p=a.clientY},!0),document.addEventListener("mouseup",function(a){d&&(c("touchend",a,m),m=null,d=!1)},!0),document.addEventListener("mousemove",function(a){!(a.clientX===l&&a.clientY===p)&&d&&(c("touchmove",a,m),f=!0)},
!0));document.addEventListener("drag",b,!0);document.addEventListener("dragstart",b,!0);document.addEventListener("dragenter",b,!0);document.addEventListener("dragover",b,!0);document.addEventListener("dragleave",b,!0);document.addEventListener("dragend",b,!0);document.addEventListener("drop",b,!0);document.addEventListener("selectstart",function(a){e(a,a.target)},!0);document.addEventListener("click",function(a){!a.mouseToTouch&&a.target===m&&b(a);f&&(b(a),f=!1)},!0)}})(jQuery,window);
(function(a){a.fn.toast=function(a){return new f(this[0],a)};var f=function(){var f=function(b,g){if(this.container="string"===typeof b||b instanceof String?document.getElementById(b):b){if("string"===typeof g||"number"===typeof g)g={message:g};this.addCssClass=g.addCssClass?g.addCssClass:"";this.message=g.message||"";this.delay=g.delay||this.delay;this.position=g.position||"";this.addCssClass+=" "+this.position;this.type=g.type||"";this.container=a(this.container);0===this.container.find(".afToastContainer").length&&
this.container.append("<div class='afToastContainer'></div>");this.container=this.container.find(".afToastContainer");this.container.removeClass("tr br tl bl tc bc").addClass(this.addCssClass);!1===g.autoClose&&(this.autoClose=!1);this.show()}else window.alert("Error finding container for toast "+b)};f.prototype={addCssClass:null,message:null,delay:5E3,el:null,container:null,timer:null,autoClose:!0,show:function(){var b=this;this.el=a("<div class='afToast "+this.type+"'><div>"+this.message+"</div></div>").get(0);
this.container.append(this.el);var g=a(this.el),e=this.el.clientHeight;g.addClass("hidden");setTimeout(function(){g.css("height",e);g.removeClass("hidden")},20);this.autoClose&&(this.timer=setTimeout(function(){b.hide()},this.delay));g.bind("click",function(){b.hide()})},hide:function(){var b=this;clearTimeout(this.timer);a(this.el).unbind("click").addClass("hidden");a(this.el).css("height","0px");!a.os.ie&&!a.os.android?setTimeout(function(){b.remove()},300):b.remove()},remove:function(){a(this.el).remove()}};
return f}();a.afui.toast=function(f){a(document.body).toast(f)};a.afui.registerDataDirective("[data-toast]",function(f){var b=a(f);f=b.attr("data-message")||"";if(0!==f.length){var g=b.attr("data-position")||"tr",e=b.attr("data-type"),c="false"===b.attr("data-auto-close")?!1:!0,b=b.attr("data-delay")||0;f={message:f,position:g,delay:b,autoClose:c,type:e};a(document.body).toast(f)}})})(jQuery);

841
js/libs/fastclick.js Normal file
View file

@ -0,0 +1,841 @@
;(function () {
'use strict';
/**
* @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.
*
* @codingstandard ftlabs-jsv2
* @copyright The Financial Times Limited [All Rights Reserved]
* @license MIT License (see LICENSE.txt)
*/
/*jslint browser:true, node:true*/
/*global define, Event, Node*/
/**
* Instantiate fast-clicking listeners on the specified layer.
*
* @constructor
* @param {Element} layer The layer to listen on
* @param {Object} [options={}] The options to override the defaults
*/
function FastClick(layer, options) {
var oldOnClick;
options = options || {};
/**
* Whether a click is currently being tracked.
*
* @type boolean
*/
this.trackingClick = false;
/**
* Timestamp for when click tracking started.
*
* @type number
*/
this.trackingClickStart = 0;
/**
* The element being tracked for a click.
*
* @type EventTarget
*/
this.targetElement = null;
/**
* X-coordinate of touch start event.
*
* @type number
*/
this.touchStartX = 0;
/**
* Y-coordinate of touch start event.
*
* @type number
*/
this.touchStartY = 0;
/**
* ID of the last touch, retrieved from Touch.identifier.
*
* @type number
*/
this.lastTouchIdentifier = 0;
/**
* Touchmove boundary, beyond which a click will be cancelled.
*
* @type number
*/
this.touchBoundary = options.touchBoundary || 10;
/**
* The FastClick layer.
*
* @type Element
*/
this.layer = layer;
/**
* The minimum time between tap(touchstart and touchend) events
*
* @type number
*/
this.tapDelay = options.tapDelay || 200;
/**
* The maximum time for a tap
*
* @type number
*/
this.tapTimeout = options.tapTimeout || 700;
if (FastClick.notNeeded(layer)) {
return;
}
// Some old versions of Android don't have Function.prototype.bind
function bind(method, context) {
return function() { return method.apply(context, arguments); };
}
var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];
var context = this;
for (var i = 0, l = methods.length; i < l; i++) {
context[methods[i]] = bind(context[methods[i]], context);
}
// Set up event handlers as required
if (deviceIsAndroid) {
layer.addEventListener('mouseover', this.onMouse, true);
layer.addEventListener('mousedown', this.onMouse, true);
layer.addEventListener('mouseup', this.onMouse, true);
}
layer.addEventListener('click', this.onClick, true);
layer.addEventListener('touchstart', this.onTouchStart, false);
layer.addEventListener('touchmove', this.onTouchMove, false);
layer.addEventListener('touchend', this.onTouchEnd, false);
layer.addEventListener('touchcancel', this.onTouchCancel, false);
// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick
// layer when they are cancelled.
if (!Event.prototype.stopImmediatePropagation) {
layer.removeEventListener = function(type, callback, capture) {
var rmv = Node.prototype.removeEventListener;
if (type === 'click') {
rmv.call(layer, type, callback.hijacked || callback, capture);
} else {
rmv.call(layer, type, callback, capture);
}
};
layer.addEventListener = function(type, callback, capture) {
var adv = Node.prototype.addEventListener;
if (type === 'click') {
adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {
if (!event.propagationStopped) {
callback(event);
}
}), capture);
} else {
adv.call(layer, type, callback, capture);
}
};
}
// If a handler is already declared in the element's onclick attribute, it will be fired before
// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and
// adding it as listener.
if (typeof layer.onclick === 'function') {
// Android browser on at least 3.2 requires a new reference to the function in layer.onclick
// - the old one won't work if passed to addEventListener directly.
oldOnClick = layer.onclick;
layer.addEventListener('click', function(event) {
oldOnClick(event);
}, false);
layer.onclick = null;
}
}
/**
* Windows Phone 8.1 fakes user agent string to look like Android and iPhone.
*
* @type boolean
*/
var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0;
/**
* Android requires exceptions.
*
* @type boolean
*/
var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone;
/**
* iOS requires exceptions.
*
* @type boolean
*/
var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;
/**
* iOS 4 requires an exception for select elements.
*
* @type boolean
*/
var deviceIsIOS4 = deviceIsIOS && (/OS 4_\d(_\d)?/).test(navigator.userAgent);
/**
* iOS 6.0-7.* requires the target element to be manually derived
*
* @type boolean
*/
var deviceIsIOSWithBadTarget = deviceIsIOS && (/OS [6-7]_\d/).test(navigator.userAgent);
/**
* BlackBerry requires exceptions.
*
* @type boolean
*/
var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;
/**
* Determine whether a given element requires a native click.
*
* @param {EventTarget|Element} target Target DOM element
* @returns {boolean} Returns true if the element needs a native click
*/
FastClick.prototype.needsClick = function(target) {
switch (target.nodeName.toLowerCase()) {
// Don't send a synthetic click to disabled inputs (issue #62)
case 'button':
case 'select':
case 'textarea':
if (target.disabled) {
return true;
}
break;
case 'input':
// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)
if ((deviceIsIOS && target.type === 'file') || target.disabled) {
return true;
}
break;
case 'label':
case 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames
case 'video':
return true;
}
return (/\bneedsclick\b/).test(target.className);
};
/**
* Determine whether a given element requires a call to focus to simulate click into element.
*
* @param {EventTarget|Element} target Target DOM element
* @returns {boolean} Returns true if the element requires a call to focus to simulate native click.
*/
FastClick.prototype.needsFocus = function(target) {
switch (target.nodeName.toLowerCase()) {
case 'textarea':
return true;
case 'select':
return !deviceIsAndroid;
case 'input':
switch (target.type) {
case 'button':
case 'checkbox':
case 'file':
case 'image':
case 'radio':
case 'submit':
return false;
}
// No point in attempting to focus disabled inputs
return !target.disabled && !target.readOnly;
default:
return (/\bneedsfocus\b/).test(target.className);
}
};
/**
* Send a click event to the specified element.
*
* @param {EventTarget|Element} targetElement
* @param {Event} event
*/
FastClick.prototype.sendClick = function(targetElement, event) {
var clickEvent, touch;
// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
if (document.activeElement && document.activeElement !== targetElement) {
document.activeElement.blur();
}
touch = event.changedTouches[0];
// Synthesise a click event, with an extra attribute so it can be tracked
clickEvent = document.createEvent('MouseEvents');
clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
clickEvent.forwardedTouchEvent = true;
targetElement.dispatchEvent(clickEvent);
};
FastClick.prototype.determineEventType = function(targetElement) {
//Issue #159: Android Chrome Select Box does not open with a synthetic click event
if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {
return 'mousedown';
}
return 'click';
};
/**
* @param {EventTarget|Element} targetElement
*/
FastClick.prototype.focus = function(targetElement) {
var length;
// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') {
length = targetElement.value.length;
targetElement.setSelectionRange(length, length);
} else {
targetElement.focus();
}
};
/**
* Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.
*
* @param {EventTarget|Element} targetElement
*/
FastClick.prototype.updateScrollParent = function(targetElement) {
var scrollParent, parentElement;
scrollParent = targetElement.fastClickScrollParent;
// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the
// target element was moved to another parent.
if (!scrollParent || !scrollParent.contains(targetElement)) {
parentElement = targetElement;
do {
if (parentElement.scrollHeight > parentElement.offsetHeight) {
scrollParent = parentElement;
targetElement.fastClickScrollParent = parentElement;
break;
}
parentElement = parentElement.parentElement;
} while (parentElement);
}
// Always update the scroll top tracker if possible.
if (scrollParent) {
scrollParent.fastClickLastScrollTop = scrollParent.scrollTop;
}
};
/**
* @param {EventTarget} targetElement
* @returns {Element|EventTarget}
*/
FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {
// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.
if (eventTarget.nodeType === Node.TEXT_NODE) {
return eventTarget.parentNode;
}
return eventTarget;
};
/**
* On touch start, record the position and scroll offset.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onTouchStart = function(event) {
var targetElement, touch, selection;
// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).
if (event.targetTouches.length > 1) {
return true;
}
targetElement = this.getTargetElementFromEventTarget(event.target);
touch = event.targetTouches[0];
if (deviceIsIOS) {
// Only trusted events will deselect text on iOS (issue #49)
selection = window.getSelection();
if (selection.rangeCount && !selection.isCollapsed) {
return true;
}
if (!deviceIsIOS4) {
// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):
// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched
// with the same identifier as the touch event that previously triggered the click that triggered the alert.
// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an
// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.
// Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,
// which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,
// random integers, it's safe to to continue if the identifier is 0 here.
if (touch.identifier && touch.identifier === this.lastTouchIdentifier) {
event.preventDefault();
return false;
}
this.lastTouchIdentifier = touch.identifier;
// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:
// 1) the user does a fling scroll on the scrollable layer
// 2) the user stops the fling scroll with another tap
// then the event.target of the last 'touchend' event will be the element that was under the user's finger
// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check
// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).
this.updateScrollParent(targetElement);
}
}
this.trackingClick = true;
this.trackingClickStart = event.timeStamp;
this.targetElement = targetElement;
this.touchStartX = touch.pageX;
this.touchStartY = touch.pageY;
// Prevent phantom clicks on fast double-tap (issue #36)
if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
event.preventDefault();
}
return true;
};
/**
* Based on a touchmove event object, check whether the touch has moved past a boundary since it started.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.touchHasMoved = function(event) {
var touch = event.changedTouches[0], boundary = this.touchBoundary;
if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {
return true;
}
return false;
};
/**
* Update the last position.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onTouchMove = function(event) {
if (!this.trackingClick) {
return true;
}
// If the touch has moved, cancel the click tracking
if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {
this.trackingClick = false;
this.targetElement = null;
}
return true;
};
/**
* Attempt to find the labelled control for the given label element.
*
* @param {EventTarget|HTMLLabelElement} labelElement
* @returns {Element|null}
*/
FastClick.prototype.findControl = function(labelElement) {
// Fast path for newer browsers supporting the HTML5 control attribute
if (labelElement.control !== undefined) {
return labelElement.control;
}
// All browsers under test that support touch events also support the HTML5 htmlFor attribute
if (labelElement.htmlFor) {
return document.getElementById(labelElement.htmlFor);
}
// If no for attribute exists, attempt to retrieve the first labellable descendant element
// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label
return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');
};
/**
* On touch end, determine whether to send a click event at once.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onTouchEnd = function(event) {
var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;
if (!this.trackingClick) {
return true;
}
// Prevent phantom clicks on fast double-tap (issue #36)
if ((event.timeStamp - this.lastClickTime) < this.tapDelay) {
this.cancelNextClick = true;
return true;
}
if ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) {
return true;
}
// Reset to prevent wrong click cancel on input (issue #156).
this.cancelNextClick = false;
this.lastClickTime = event.timeStamp;
trackingClickStart = this.trackingClickStart;
this.trackingClick = false;
this.trackingClickStart = 0;
// On some iOS devices, the targetElement supplied with the event is invalid if the layer
// is performing a transition or scroll, and has to be re-detected manually. Note that
// for this to function correctly, it must be called *after* the event target is checked!
// See issue #57; also filed as rdar://13048589 .
if (deviceIsIOSWithBadTarget) {
touch = event.changedTouches[0];
// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null
targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;
targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;
}
targetTagName = targetElement.tagName.toLowerCase();
if (targetTagName === 'label') {
forElement = this.findControl(targetElement);
if (forElement) {
this.focus(targetElement);
if (deviceIsAndroid) {
return false;
}
targetElement = forElement;
}
} else if (this.needsFocus(targetElement)) {
// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.
// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).
if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {
this.targetElement = null;
return false;
}
this.focus(targetElement);
this.sendClick(targetElement, event);
// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.
// Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)
if (!deviceIsIOS || targetTagName !== 'select') {
this.targetElement = null;
event.preventDefault();
}
return false;
}
if (deviceIsIOS && !deviceIsIOS4) {
// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled
// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).
scrollParent = targetElement.fastClickScrollParent;
if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {
return true;
}
}
// Prevent the actual click from going though - unless the target node is marked as requiring
// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.
if (!this.needsClick(targetElement)) {
event.preventDefault();
this.sendClick(targetElement, event);
}
return false;
};
/**
* On touch cancel, stop tracking the click.
*
* @returns {void}
*/
FastClick.prototype.onTouchCancel = function() {
this.trackingClick = false;
this.targetElement = null;
};
/**
* Determine mouse events which should be permitted.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onMouse = function(event) {
// If a target element was never set (because a touch event was never fired) allow the event
if (!this.targetElement) {
return true;
}
if (event.forwardedTouchEvent) {
return true;
}
// Programmatically generated events targeting a specific element should be permitted
if (!event.cancelable) {
return true;
}
// Derive and check the target element to see whether the mouse event needs to be permitted;
// unless explicitly enabled, prevent non-touch click events from triggering actions,
// to prevent ghost/doubleclicks.
if (!this.needsClick(this.targetElement) || this.cancelNextClick) {
// Prevent any user-added listeners declared on FastClick element from being fired.
if (event.stopImmediatePropagation) {
event.stopImmediatePropagation();
} else {
// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)
event.propagationStopped = true;
}
// Cancel the event
event.stopPropagation();
event.preventDefault();
return false;
}
// If the mouse event is permitted, return true for the action to go through.
return true;
};
/**
* On actual clicks, determine whether this is a touch-generated click, a click action occurring
* naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or
* an actual click which should be permitted.
*
* @param {Event} event
* @returns {boolean}
*/
FastClick.prototype.onClick = function(event) {
var permitted;
// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.
if (this.trackingClick) {
this.targetElement = null;
this.trackingClick = false;
return true;
}
// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.
if (event.target.type === 'submit' && event.detail === 0) {
return true;
}
permitted = this.onMouse(event);
// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.
if (!permitted) {
this.targetElement = null;
}
// If clicks are permitted, return true for the action to go through.
return permitted;
};
/**
* Remove all FastClick's event listeners.
*
* @returns {void}
*/
FastClick.prototype.destroy = function() {
var layer = this.layer;
if (deviceIsAndroid) {
layer.removeEventListener('mouseover', this.onMouse, true);
layer.removeEventListener('mousedown', this.onMouse, true);
layer.removeEventListener('mouseup', this.onMouse, true);
}
layer.removeEventListener('click', this.onClick, true);
layer.removeEventListener('touchstart', this.onTouchStart, false);
layer.removeEventListener('touchmove', this.onTouchMove, false);
layer.removeEventListener('touchend', this.onTouchEnd, false);
layer.removeEventListener('touchcancel', this.onTouchCancel, false);
};
/**
* Check whether FastClick is needed.
*
* @param {Element} layer The layer to listen on
*/
FastClick.notNeeded = function(layer) {
var metaViewport;
var chromeVersion;
var blackberryVersion;
var firefoxVersion;
// Devices that don't support touch don't need FastClick
if (typeof window.ontouchstart === 'undefined') {
return true;
}
// Chrome version - zero for other browsers
chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
if (chromeVersion) {
if (deviceIsAndroid) {
metaViewport = document.querySelector('meta[name=viewport]');
if (metaViewport) {
// Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89)
if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
return true;
}
// Chrome 32 and above with width=device-width or less don't need FastClick
if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {
return true;
}
}
// Chrome desktop doesn't need FastClick (issue #15)
} else {
return true;
}
}
if (deviceIsBlackBerry10) {
blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/);
// BlackBerry 10.3+ does not require Fastclick library.
// https://github.com/ftlabs/fastclick/issues/251
if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {
metaViewport = document.querySelector('meta[name=viewport]');
if (metaViewport) {
// user-scalable=no eliminates click delay.
if (metaViewport.content.indexOf('user-scalable=no') !== -1) {
return true;
}
// width=device-width (or less than device-width) eliminates click delay.
if (document.documentElement.scrollWidth <= window.outerWidth) {
return true;
}
}
}
}
// IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97)
if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {
return true;
}
// Firefox version - zero for other browsers
firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];
if (firefoxVersion >= 27) {
// Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896
metaViewport = document.querySelector('meta[name=viewport]');
if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {
return true;
}
}
// IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version
// http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx
if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {
return true;
}
return false;
};
/**
* Factory method for creating a FastClick object
*
* @param {Element} layer The layer to listen on
* @param {Object} [options={}] The options to override the defaults
*/
FastClick.attach = function(layer, options) {
return new FastClick(layer, options);
};
if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
// AMD. Register as an anonymous module.
define(function() {
return FastClick;
});
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = FastClick.attach;
module.exports.FastClick = FastClick;
} else {
window.FastClick = FastClick;
}
}());

10308
js/libs/jquery.js vendored Normal file

File diff suppressed because it is too large Load diff

1571
js/libs/l10n.js Normal file

File diff suppressed because it is too large Load diff

35
manifest.webapp Normal file
View file

@ -0,0 +1,35 @@
{
"version": "0.1.0",
"name": "ToDo List",
"description": "A template with the bare minimum structure",
"launch_path": "/index.html",
"icons": {
"16": "/img/icons/icon16x16.png",
"48": "/img/icons/icon48x48.png",
"60": "/img/icons/icon60x60.png",
"128": "/img/icons/icon128x128.png"
},
"developer": {
"name": "José Carlos Cuevas",
"url": "https://github.com/resetreboot"
},
"type": "privileged",
"permissions": {"storage": true},
"installs_allowed_from": [
"*"
],
"datastores-owned": {
"ToDoList": {
"access": "readwrite",
"description": "ToDo List Datastore"
}
},
"locales": {
"es": {
"name": "Lista de Tareas",
"description": "Una sencilla lista de tareas",
"permissions": {"storage": true}
}
},
"default_locale": "en"
}