Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
60
gaia/distros/spark/apps/studio/Basics-preview.html
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Basics Preview</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/base/base.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-theme/gaia-theme.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-fonts/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-icons/gaia-icons.css">
|
||||
|
||||
<script src="bower_components/gaia-component/gaia-component.js"></script>
|
||||
<script src="bower_components/gaia-icons/gaia-icons.js"></script>
|
||||
<script src="bower_components/gaia-button/gaia-button.js"></script>
|
||||
<script src="bower_components/gaia-text-input/gaia-text-input.js"></script>
|
||||
|
||||
<link rel="prefetch" type="application/l10n" href="data/locales.ini" />
|
||||
<script type="text/javascript" src="js/libs/l10n.js" defer></script>
|
||||
<style>
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #00539F;
|
||||
background-image: url(/css/blueprint.png);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#canvas {
|
||||
position: absolute;
|
||||
top: 10%;
|
||||
left: 10%;
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
padding: 0.5rem;
|
||||
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
a {
|
||||
color: var(--link-color);
|
||||
}
|
||||
|
||||
gaia-button.preview {
|
||||
margin: 0 !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="theme-settings">
|
||||
<div id="canvas">
|
||||
Some text and <a href="#">a link</a>.
|
||||
<gaia-button class="preview">a button</gaia-button>
|
||||
<gaia-text-input placeholder="Some input"></gaia-text-input>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
44
gaia/distros/spark/apps/studio/Header-preview.html
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Header Preview</title>
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/base/base.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-theme/gaia-theme.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-fonts/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-icons/gaia-icons.css">
|
||||
|
||||
<script src="bower_components/gaia-component/gaia-component.js"></script>
|
||||
<script src="bower_components/gaia-icons/gaia-icons.js"></script>
|
||||
<script src="bower_components/gaia-header/dist/gaia-header.js"></script>
|
||||
|
||||
<link rel="prefetch" type="application/l10n" href="data/locales.ini" />
|
||||
<script type="text/javascript" src="js/libs/l10n.js" defer></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #00539F;
|
||||
background-image: url(/css/blueprint.png);
|
||||
}
|
||||
gaia-header {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<gaia-header action="back">
|
||||
<h1>Header with action</h1>
|
||||
</gaia-header>
|
||||
|
||||
<gaia-header>
|
||||
<h1>Header with button</h1>
|
||||
<button>Save</button>
|
||||
</gaia-header>
|
||||
|
||||
<gaia-header>
|
||||
<h1>Header with disabled button</h1>
|
||||
<button disabled>Save</button>
|
||||
</gaia-header>
|
||||
</body>
|
||||
</html>
|
||||
202
gaia/distros/spark/apps/studio/LICENSE
Executable 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.
|
||||
|
||||
26
gaia/distros/spark/apps/studio/bower_components/base/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "base",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "base.css",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"homepage": "https://github.com/gaia-components/base",
|
||||
"_release": "737e000325",
|
||||
"_resolution": {
|
||||
"type": "branch",
|
||||
"branch": "master",
|
||||
"commit": "737e0003253ee4f3ceff5c1223543a1b3f7d39dd"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/base.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "gaia-components/base",
|
||||
"_direct": true
|
||||
}
|
||||
227
gaia/distros/spark/apps/studio/bower_components/base/base.css
vendored
Executable file
|
|
@ -0,0 +1,227 @@
|
|||
|
||||
/** Variables
|
||||
---------------------------------------------------------*/
|
||||
|
||||
:root {
|
||||
--dim-micro: 6px;
|
||||
--dim-small: 12px;
|
||||
--dim-medium: 24px;
|
||||
--dim-mega: 48px;
|
||||
|
||||
--base-xs: 6px;
|
||||
--base-s: 18px;
|
||||
--base-m: 24px;
|
||||
--base-l: 30px;
|
||||
--base-xl: 42px;
|
||||
--base-xxl: 60px;
|
||||
|
||||
--base-font-xs: 10px;
|
||||
--base-font-s: 14px;
|
||||
--base-font-m: 17px;
|
||||
--base-font-l: 23px;
|
||||
--base-font-xl: 60px;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Apply a natural box layout
|
||||
* model to all elements
|
||||
*/
|
||||
|
||||
*,
|
||||
*:after,
|
||||
*:before {
|
||||
box-sizing: border-box; /* 1 */
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/** Document
|
||||
---------------------------------------------------------*/
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/** Body
|
||||
---------------------------------------------------------*/
|
||||
|
||||
body {
|
||||
height: 100%;
|
||||
font: 300 17px/21px 'FiraSans';
|
||||
background-color: var(--background);
|
||||
color: var(--text-color);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/** Tags
|
||||
---------------------------------------------------------*/
|
||||
|
||||
a {
|
||||
color: var(--highlight-color, inherit);
|
||||
text-decoration: none;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 1px;
|
||||
margin: var(--dim-small) 0 var(--dim-small) 0;
|
||||
border: 0;
|
||||
background:
|
||||
var(--border-color,
|
||||
var(--background-plus,
|
||||
rgba(0,0,0,0.2)));
|
||||
}
|
||||
|
||||
em {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.alpha {
|
||||
font-size: 23px;
|
||||
font-weight: 200;
|
||||
font-style: italic;
|
||||
line-height: 26px;
|
||||
margin: 6px 0 24px 0;
|
||||
}
|
||||
|
||||
.beta {
|
||||
font-size: 17px;
|
||||
font-weight: 400;
|
||||
margin: 32px 0 16px 0;
|
||||
}
|
||||
|
||||
.gamma {
|
||||
font-size: 14px;
|
||||
text-transform: uppercase;
|
||||
font-weight: normal;
|
||||
margin: 32px 0 16px 0;
|
||||
}
|
||||
|
||||
.milli {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.large {
|
||||
font-size: 23px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.mega {
|
||||
font-size: 60px;
|
||||
line-height: 60px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.giga {}
|
||||
.kilo {}
|
||||
|
||||
/* alignment */
|
||||
.l-align-right { float: right; }
|
||||
.l-align-left { float: left; }
|
||||
.l-align-center { text-align: center; }
|
||||
.l-text-align-left { text-align: left; }
|
||||
.l-text-align-right { text-align: right; }
|
||||
.l-text-valign-top {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.l-width-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/** Flexbox
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.l-flex { display: flex; }
|
||||
.l-flex-col { display: flex; flex-direction: column; }
|
||||
|
||||
.l-flex-col-v-align {
|
||||
display: flex !important;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.l-flex-v-align { align-items: center; }
|
||||
.l-flex-h-align { justify-content: center; }
|
||||
.l-flex-grow { flex: 1; }
|
||||
|
||||
/** Margin
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/* Top */
|
||||
|
||||
.l-mt-small { margin-top: var(--dim-small); }
|
||||
.l-mt-med { margin-top: var(--dim-medium); }
|
||||
|
||||
/* Bottom */
|
||||
|
||||
.l-mb-small { margin-bottom: var(--dim-small); }
|
||||
.l-mb-med { margin-bottom: var(--dim-medium); }
|
||||
.l-mb-large {}
|
||||
.l-mb-mega { margin-bottom: var(--dim-mega); }
|
||||
|
||||
/* Left */
|
||||
|
||||
.l-ml-small { margin-left: var(--dim-small); }
|
||||
|
||||
/* Right */
|
||||
|
||||
.l-mr-small { margin-right: var(--dim-small); }
|
||||
|
||||
/* Auto */
|
||||
|
||||
.l-mlr-auto { margin-left: auto; margin-right: auto; }
|
||||
.l-m-auto { margin: auto }
|
||||
|
||||
/* Margin */
|
||||
|
||||
.l-m-small { margin: var(--dim-small) }
|
||||
.l-m-med { margin: var(--dim-medium) }
|
||||
.l-m-0 { margin: 0 }
|
||||
|
||||
/** Padding
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.l-p-small { padding: var(--dim-small); }
|
||||
.l-pl-small { padding-left: var(--dim-small); }
|
||||
.l-pr-small { padding-right: var(--dim-small); }
|
||||
.l-plr-small {
|
||||
padding-right: var(--dim-small);
|
||||
padding-left: var(--dim-small);
|
||||
}
|
||||
.l-pb-small { padding-bottom: var(--dim-small); }
|
||||
.l-pt-small { padding-top: var(--dim-small); }
|
||||
.l-pt-mega { padding-top: var(--dim-mega); }
|
||||
.l-pt-micro { padding-top: var(--dim-micro); }
|
||||
.l-pb-micro { padding-bottom: var(--dim-micro); }
|
||||
.l-p-0 { padding: 0 ;}
|
||||
|
||||
/** Helpers
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.l-clearfix:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.l-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.is-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.is-invisible {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
16
gaia/distros/spark/apps/studio/bower_components/base/bower.json
vendored
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "base",
|
||||
"version": "0.0.0",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "base.css",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
26
gaia/distros/spark/apps/studio/bower_components/font-fit/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "font-fit",
|
||||
"main": "font-fit.js",
|
||||
"version": "0.3.0",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"homepage": "https://github.com/gaia-components/font-fit",
|
||||
"_release": "0.3.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.3.0",
|
||||
"commit": "229824447d7ac46a2af6eca7d91382bdcf6f0c04"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/font-fit.git",
|
||||
"_target": "~0.3.0",
|
||||
"_originalSource": "gaia-components/font-fit"
|
||||
}
|
||||
16
gaia/distros/spark/apps/studio/bower_components/font-fit/bower.json
vendored
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "font-fit",
|
||||
"main": "font-fit.js",
|
||||
"version": "0.3.0",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
132
gaia/distros/spark/apps/studio/bower_components/font-fit/font-fit.js
vendored
Executable file
|
|
@ -0,0 +1,132 @@
|
|||
;(function(define){define(function(require,exports,module){
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Simple logger.
|
||||
*
|
||||
* @return {Function}
|
||||
*/
|
||||
var debug = 0 ? console.log.bind(console) : function(){};
|
||||
|
||||
/**
|
||||
* Global canvas cache.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var cache = {};
|
||||
|
||||
/**
|
||||
* Default min/max font-size.
|
||||
*
|
||||
* @type {Number}
|
||||
*/
|
||||
var MIN = 16;
|
||||
var MAX = 24;
|
||||
|
||||
/**
|
||||
* The number of pixels to subtract from
|
||||
* the given `config.space` to ensure
|
||||
* HTML text doesn't overflow container.
|
||||
*
|
||||
* Ideally we would use 1px, but in some
|
||||
* cases italicised text in canvas is ~2px
|
||||
* longer than the same text in HTML.
|
||||
*
|
||||
* http://bugzil.la/1126391
|
||||
*
|
||||
* @type {Number}
|
||||
*/
|
||||
var BUFFER = 3;
|
||||
|
||||
/**
|
||||
* Get the font-size that closest fits
|
||||
* the given space with the given font.
|
||||
*
|
||||
* Config:
|
||||
*
|
||||
* - {String} `text` The text string
|
||||
* - {String} `font` Font shorthand string
|
||||
* - {Number} `space` Width (px) to fit the text into
|
||||
* - {Number} `min` Min font-size (px) (optional)
|
||||
* - {Number} `max` Max font-size (px) (optional)
|
||||
*
|
||||
* @param {Object} config
|
||||
* @return {Object} {fontSize,overflowing,textWidth}
|
||||
*/
|
||||
module.exports = function(config) {
|
||||
debug('font fit', config);
|
||||
var space = config.space - BUFFER;
|
||||
var min = config.min || MIN;
|
||||
var max = config.max || MAX;
|
||||
var text = trim(config.text);
|
||||
var fontSize = max;
|
||||
var textWidth;
|
||||
var font;
|
||||
|
||||
do {
|
||||
font = config.font.replace(/\d+px/, fontSize + 'px');
|
||||
textWidth = getTextWidth(text, font);
|
||||
} while (textWidth > space && fontSize !== min && fontSize--);
|
||||
|
||||
return {
|
||||
textWidth: textWidth,
|
||||
fontSize: fontSize,
|
||||
overflowing: textWidth > space
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the width of the given text
|
||||
* with the given font style.
|
||||
*
|
||||
* @param {String} text
|
||||
* @param {String} font (CSS shorthand)
|
||||
* @return {Number} (px)
|
||||
*/
|
||||
function getTextWidth(text, font) {
|
||||
var ctx = getCanvasContext(font);
|
||||
var width = ctx.measureText(text).width;
|
||||
debug('got text width', width);
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a canvas context configured
|
||||
* to the given font style.
|
||||
*
|
||||
* @param {String} font
|
||||
* @return {CanvasRenderingContext2D}
|
||||
*/
|
||||
function getCanvasContext(font) {
|
||||
debug('get canvas context', font);
|
||||
|
||||
var cached = cache[font];
|
||||
if (cached) { return cached; }
|
||||
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.setAttribute('moz-opaque', 'true');
|
||||
canvas.setAttribute('width', '1px');
|
||||
canvas.setAttribute('height', '1px');
|
||||
debug('created canvas', canvas);
|
||||
|
||||
var ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
ctx.font = font;
|
||||
|
||||
return cache[font] = ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim leading, trailing
|
||||
* and excess whitespace.
|
||||
*
|
||||
* @param {String} text
|
||||
* @return {String}
|
||||
*/
|
||||
function trim(text) {
|
||||
return text.replace(/\s+/g, ' ').trim();
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('font-fit',this));
|
||||
107
gaia/distros/spark/apps/studio/bower_components/font-fit/index.html
vendored
Executable file
|
|
@ -0,0 +1,107 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>font-fit demo</title>
|
||||
<script src="font-fit.js"></script>
|
||||
<style>
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
body {
|
||||
font: 24px Arial;
|
||||
background: #222;
|
||||
color: #eee;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
header {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
input {
|
||||
display: block;
|
||||
background: #151515;
|
||||
border: 0;
|
||||
color: #666;
|
||||
font-size: 16px;
|
||||
|
||||
width: 100%;
|
||||
padding: 8px 14px;
|
||||
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
button {
|
||||
display: block;
|
||||
vertical-align: top;
|
||||
background: #444;
|
||||
border: 0;
|
||||
color: #fff;
|
||||
font-size: 17px;
|
||||
letter-spacing: 1px;
|
||||
line-height: 1;
|
||||
padding: 8px 11px;
|
||||
border-radius: 0 4px 4px 0;
|
||||
|
||||
}
|
||||
|
||||
section {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: -3%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<input id="input" value="font-fit.js">
|
||||
<button id="button">Fit</button>
|
||||
</header>
|
||||
<section>
|
||||
<h1 id="el"></h1>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
var fontFit = window['font-fit'];
|
||||
|
||||
function run() {
|
||||
el.textContent = input.value;
|
||||
var result = fontFit({
|
||||
text: el.textContent,
|
||||
font: 'bold 24px sans-serif',
|
||||
space: el.clientWidth,
|
||||
max: 350
|
||||
});
|
||||
|
||||
el.style.fontSize = result.fontSize + 'px';
|
||||
}
|
||||
|
||||
run();
|
||||
button.onclick = run;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
30
gaia/distros/spark/apps/studio/bower_components/font-fit/package.json
vendored
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "font-fit",
|
||||
"homepage": "https://github.com/gaia-components/font-fit",
|
||||
"version": "0.2.1",
|
||||
"main": "font-fit.js",
|
||||
"directories": {
|
||||
"example": "examples",
|
||||
"test": "test"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bower": "^1.3.5",
|
||||
"browserify": "^5.11.2",
|
||||
"karma": "^0.12.16",
|
||||
"karma-firefox-launcher": "^0.1.3",
|
||||
"karma-mocha": "^0.1.3",
|
||||
"karma-sinon-chai": "^0.1.6",
|
||||
"mozilla-download": "^0.4.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./node_modules/karma/bin/karma start test/karma.conf.js --single-run",
|
||||
"test-dev": "./node_modules/karma/bin/karma start test/karma.conf.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/gaia-components/font-fit.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/gaia-components/font-fit/issues"
|
||||
}
|
||||
}
|
||||
26
gaia/distros/spark/apps/studio/bower_components/fxos-achievements-service/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "fxos-achievements-service",
|
||||
"version": "0.0.14",
|
||||
"description": "Achievements service for embedding achievements support into Gaia apps",
|
||||
"homepage": "https://github.com/fxos/fxos-achievements-service",
|
||||
"license": "MPL",
|
||||
"main": "achievements-service.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"example",
|
||||
"componenets",
|
||||
"node_modules",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"test"
|
||||
],
|
||||
"_release": "0.0.14",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.0.14",
|
||||
"commit": "fb68564ecd9a653a52e80a05d0de1f1cf39f9bbc"
|
||||
},
|
||||
"_source": "git://github.com/fxos/achievements-service.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "fxos/achievements-service"
|
||||
}
|
||||
363
gaia/distros/spark/apps/studio/bower_components/fxos-achievements-service/LICENSE
vendored
Executable file
|
|
@ -0,0 +1,363 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
||||
144
gaia/distros/spark/apps/studio/bower_components/fxos-achievements-service/achievements-service.js
vendored
Executable file
|
|
@ -0,0 +1,144 @@
|
|||
'use strict';
|
||||
|
||||
/* global Notification, console */
|
||||
|
||||
const DEFAULT_IMAGE_SIZE = 64;
|
||||
const MOZ_SETTINGS_NOT_AVAILABLE_MSG = 'navigator.mozSettings is not available';
|
||||
|
||||
class ImageHelper {
|
||||
static getImage(aSrc) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let image = new Image();
|
||||
image.src = aSrc;
|
||||
image.onload = () => resolve(image);
|
||||
image.onerror = reason => reject(reason);
|
||||
}).catch(reason => console.warn('Could not load an achievement image:',
|
||||
reason));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Data URL for an image from source.
|
||||
* @param {String} aSrc source path to the image
|
||||
* @return {Promise} a promise of Data URL.
|
||||
*/
|
||||
static generateImageDataURL(aSrc) {
|
||||
return ImageHelper.getImage(aSrc).then(image => {
|
||||
try {
|
||||
let canvas = document.createElement('canvas');
|
||||
canvas.height = canvas.width = DEFAULT_IMAGE_SIZE;
|
||||
let context = canvas.getContext('2d');
|
||||
let dataUrl;
|
||||
|
||||
context.drawImage(image, 0, 0, DEFAULT_IMAGE_SIZE, DEFAULT_IMAGE_SIZE);
|
||||
dataUrl = canvas.toDataURL();
|
||||
|
||||
// Clean up.
|
||||
canvas.width = canvas.height = 0;
|
||||
canvas = null;
|
||||
|
||||
return dataUrl;
|
||||
} catch(e) {
|
||||
return Promise.reject('Could not convert image to Data URL.');
|
||||
}
|
||||
}).catch(reason => console.warn(reason));
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsHelper {
|
||||
static get(name, defaultValue) {
|
||||
if (!name) {
|
||||
return Promise.reject('Setting name is missing');
|
||||
}
|
||||
|
||||
if (!navigator.mozSettings) {
|
||||
console.warn(MOZ_SETTINGS_NOT_AVAILABLE_MSG);
|
||||
return Promise.reject(MOZ_SETTINGS_NOT_AVAILABLE_MSG);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let setting = navigator.mozSettings.createLock().get(name, defaultValue);
|
||||
setting.onsuccess = () => {
|
||||
let settingValue = setting.result[name] || defaultValue;
|
||||
resolve(settingValue);
|
||||
};
|
||||
setting.onerror = () => { reject(setting.error); };
|
||||
});
|
||||
}
|
||||
|
||||
static set(settings) {
|
||||
if (!settings) {
|
||||
return Promise.reject('Settings are missing');
|
||||
}
|
||||
|
||||
if (!navigator.mozSettings) {
|
||||
console.warn(MOZ_SETTINGS_NOT_AVAILABLE_MSG);
|
||||
return Promise.reject(MOZ_SETTINGS_NOT_AVAILABLE_MSG);
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let result = navigator.mozSettings.createLock().set(settings);
|
||||
result.onsuccess = () => { resolve(result.result); };
|
||||
result.onerror = () => { reject(result.error); };
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default class AchievementsService {
|
||||
/**
|
||||
* Reward an achievement and store a record in 'achievements' setting.
|
||||
* @param {JSON} options attributes for the achievement that is awarded:
|
||||
* {String} criteria URL of the criteria for earning
|
||||
* the achievement
|
||||
* {String} evidence A URN of the evidence of
|
||||
* achievement unlocked
|
||||
* {String} name Achievement name
|
||||
* {String} description Achievement description
|
||||
* {String} image Achievement image
|
||||
*/
|
||||
reward({criteria, evidence, name, description, image}) {
|
||||
if (!evidence) {
|
||||
return Promise.reject('Evidence is not provided.');
|
||||
}
|
||||
|
||||
let issuedOn;
|
||||
return SettingsHelper.get('achievements', []).then(achievements => {
|
||||
let achievement = achievements.find(
|
||||
achievement => achievement.criteria === criteria);
|
||||
|
||||
if (!achievement) {
|
||||
return Promise.reject('Achievement is not registered.');
|
||||
}
|
||||
if (achievement.evidence) {
|
||||
return Promise.reject('Achievement is already awarded.');
|
||||
}
|
||||
|
||||
achievement.evidence = evidence;
|
||||
achievement.uid = 'achievement' + Math.round(Math.random() * 100000000);
|
||||
achievement.issuedOn = issuedOn = Date.now();
|
||||
achievement.recipient = {}; // TODO
|
||||
|
||||
return achievements;
|
||||
}).then(achievements => Promise.all([
|
||||
ImageHelper.generateImageDataURL(image),
|
||||
SettingsHelper.set({ 'achievements': achievements })
|
||||
])).then(([image]) => {
|
||||
// Send a Notification via WebAPI to be handled by the Gaia::System
|
||||
let notification = new Notification(name, {
|
||||
body: description,
|
||||
icon: image,
|
||||
tag: issuedOn
|
||||
});
|
||||
|
||||
notification.onclick = () => {
|
||||
let activity = new window.MozActivity({
|
||||
name: 'configure',
|
||||
data: {
|
||||
target: 'device',
|
||||
section: 'achievements'
|
||||
}
|
||||
});
|
||||
activity.onsuccess = activity.onerror = () => { notification.close(); };
|
||||
};
|
||||
}).catch(reason => console.warn(reason));
|
||||
}
|
||||
}
|
||||
17
gaia/distros/spark/apps/studio/bower_components/fxos-achievements-service/bower.json
vendored
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "fxos-achievements-service",
|
||||
"version": "0.0.14",
|
||||
"description": "Achievements service for embedding achievements support into Gaia apps",
|
||||
"homepage": "https://github.com/fxos/fxos-achievements-service",
|
||||
"license": "MPL",
|
||||
"main": "achievements-service.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"example",
|
||||
"componenets",
|
||||
"node_modules",
|
||||
"package.json",
|
||||
"README.md",
|
||||
"test"
|
||||
]
|
||||
}
|
||||
175
gaia/distros/spark/apps/studio/bower_components/fxos-achievements-service/dist/achievements-service.js
vendored
Executable file
|
|
@ -0,0 +1,175 @@
|
|||
(function(exports) {
|
||||
"use strict";
|
||||
|
||||
var _toArray = function (arr) {
|
||||
return Array.isArray(arr) ? arr : Array.from(arr);
|
||||
};
|
||||
|
||||
"use strict";
|
||||
|
||||
/* global Notification, console */
|
||||
|
||||
var DEFAULT_IMAGE_SIZE = 64;
|
||||
var MOZ_SETTINGS_NOT_AVAILABLE_MSG = "navigator.mozSettings is not available";
|
||||
|
||||
var ImageHelper = (function () {
|
||||
var ImageHelper = function ImageHelper() {};
|
||||
|
||||
ImageHelper.getImage = function (aSrc) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var image = new Image();
|
||||
image.src = aSrc;
|
||||
image.onload = function () {
|
||||
return resolve(image);
|
||||
};
|
||||
image.onerror = function (reason) {
|
||||
return reject(reason);
|
||||
};
|
||||
})["catch"](function (reason) {
|
||||
return console.warn("Could not load an achievement image:", reason);
|
||||
});
|
||||
};
|
||||
|
||||
ImageHelper.generateImageDataURL = function (aSrc) {
|
||||
return ImageHelper.getImage(aSrc).then(function (image) {
|
||||
try {
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.height = canvas.width = DEFAULT_IMAGE_SIZE;
|
||||
var context = canvas.getContext("2d");
|
||||
var dataUrl;
|
||||
|
||||
context.drawImage(image, 0, 0, DEFAULT_IMAGE_SIZE, DEFAULT_IMAGE_SIZE);
|
||||
dataUrl = canvas.toDataURL();
|
||||
|
||||
// Clean up.
|
||||
canvas.width = canvas.height = 0;
|
||||
canvas = null;
|
||||
|
||||
return dataUrl;
|
||||
} catch (e) {
|
||||
return Promise.reject("Could not convert image to Data URL.");
|
||||
}
|
||||
})["catch"](function (reason) {
|
||||
return console.warn(reason);
|
||||
});
|
||||
};
|
||||
|
||||
return ImageHelper;
|
||||
})();
|
||||
|
||||
var SettingsHelper = (function () {
|
||||
var SettingsHelper = function SettingsHelper() {};
|
||||
|
||||
SettingsHelper.get = function (name, defaultValue) {
|
||||
if (!name) {
|
||||
return Promise.reject("Setting name is missing");
|
||||
}
|
||||
|
||||
if (!navigator.mozSettings) {
|
||||
console.warn(MOZ_SETTINGS_NOT_AVAILABLE_MSG);
|
||||
return Promise.reject(MOZ_SETTINGS_NOT_AVAILABLE_MSG);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
var setting = navigator.mozSettings.createLock().get(name, defaultValue);
|
||||
setting.onsuccess = function () {
|
||||
var settingValue = setting.result[name] || defaultValue;
|
||||
resolve(settingValue);
|
||||
};
|
||||
setting.onerror = function () {
|
||||
reject(setting.error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
SettingsHelper.set = function (settings) {
|
||||
if (!settings) {
|
||||
return Promise.reject("Settings are missing");
|
||||
}
|
||||
|
||||
if (!navigator.mozSettings) {
|
||||
console.warn(MOZ_SETTINGS_NOT_AVAILABLE_MSG);
|
||||
return Promise.reject(MOZ_SETTINGS_NOT_AVAILABLE_MSG);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
var result = navigator.mozSettings.createLock().set(settings);
|
||||
result.onsuccess = function () {
|
||||
resolve(result.result);
|
||||
};
|
||||
result.onerror = function () {
|
||||
reject(result.error);
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
return SettingsHelper;
|
||||
})();
|
||||
|
||||
var AchievementsService = (function () {
|
||||
var AchievementsService = function AchievementsService() {};
|
||||
|
||||
AchievementsService.prototype.reward = function (_ref) {
|
||||
var criteria = _ref.criteria;
|
||||
var evidence = _ref.evidence;
|
||||
var name = _ref.name;
|
||||
var description = _ref.description;
|
||||
var image = _ref.image;
|
||||
if (!evidence) {
|
||||
return Promise.reject("Evidence is not provided.");
|
||||
}
|
||||
|
||||
var issuedOn;
|
||||
return SettingsHelper.get("achievements", []).then(function (achievements) {
|
||||
var achievement = achievements.find(function (achievement) {
|
||||
return achievement.criteria === criteria;
|
||||
});
|
||||
|
||||
if (!achievement) {
|
||||
return Promise.reject("Achievement is not registered.");
|
||||
}
|
||||
if (achievement.evidence) {
|
||||
return Promise.reject("Achievement is already awarded.");
|
||||
}
|
||||
|
||||
achievement.evidence = evidence;
|
||||
achievement.uid = "achievement" + Math.round(Math.random() * 100000000);
|
||||
achievement.issuedOn = issuedOn = Date.now();
|
||||
achievement.recipient = {}; // TODO
|
||||
|
||||
return achievements;
|
||||
}).then(function (achievements) {
|
||||
return Promise.all([ImageHelper.generateImageDataURL(image), SettingsHelper.set({ achievements: achievements })]);
|
||||
}).then(function (_ref2) {
|
||||
var _ref3 = _toArray(_ref2);
|
||||
|
||||
var image = _ref3[0];
|
||||
// Send a Notification via WebAPI to be handled by the Gaia::System
|
||||
var notification = new Notification(name, {
|
||||
body: description,
|
||||
icon: image,
|
||||
tag: issuedOn
|
||||
});
|
||||
|
||||
notification.onclick = function () {
|
||||
var activity = new window.MozActivity({
|
||||
name: "configure",
|
||||
data: {
|
||||
target: "device",
|
||||
section: "achievements"
|
||||
}
|
||||
});
|
||||
activity.onsuccess = activity.onerror = function () {
|
||||
notification.close();
|
||||
};
|
||||
};
|
||||
})["catch"](function (reason) {
|
||||
return console.warn(reason);
|
||||
});
|
||||
};
|
||||
|
||||
return AchievementsService;
|
||||
})();
|
||||
|
||||
exports.AchievementsService = AchievementsService;
|
||||
})(window);
|
||||
28
gaia/distros/spark/apps/studio/bower_components/fxos-achievements-service/gulpfile.js
vendored
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
'use strict';
|
||||
|
||||
/* global require, console */
|
||||
|
||||
var gulp = require('gulp');
|
||||
var to5 = require('gulp-6to5');
|
||||
|
||||
/**
|
||||
* converts javascript to es5.
|
||||
*/
|
||||
gulp.task('to5', function () {
|
||||
try {
|
||||
return gulp.src('./achievements-service.js')
|
||||
.pipe(to5({ modules: 'amd' }).on('error', function(e) {
|
||||
console.log('error running 6to5', e);
|
||||
}))
|
||||
.pipe(gulp.dest('./dist/'));
|
||||
} catch(e) {
|
||||
console.log('Got error in 6to5', e);
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task('default', ['to5']);
|
||||
|
||||
/**
|
||||
* Runs travis tests
|
||||
*/
|
||||
gulp.task('travis', ['to5']);
|
||||
22
gaia/distros/spark/apps/studio/bower_components/fxos-dev-mode-dialog/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "fxos-dev-mode-dialog",
|
||||
"version": "0.0.3",
|
||||
"description": "Developer Mode prompt for Gaia apps.",
|
||||
"homepage": "https://github.com/fxos/fxos-dev-mode-dialog",
|
||||
"license": "MPL",
|
||||
"main": "fxos-dev-mode-dialog.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"_release": "0.0.3",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.0.3",
|
||||
"commit": "42c516cadecc0e12fb579056aac231431c88dac8"
|
||||
},
|
||||
"_source": "git://github.com/fxos/fxos-dev-mode-dialog.git",
|
||||
"_target": "0.0.3",
|
||||
"_originalSource": "fxos/fxos-dev-mode-dialog"
|
||||
}
|
||||
363
gaia/distros/spark/apps/studio/bower_components/fxos-dev-mode-dialog/LICENSE
vendored
Executable file
|
|
@ -0,0 +1,363 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
||||
13
gaia/distros/spark/apps/studio/bower_components/fxos-dev-mode-dialog/bower.json
vendored
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "fxos-dev-mode-dialog",
|
||||
"version": "0.0.3",
|
||||
"description": "Developer Mode prompt for Gaia apps.",
|
||||
"homepage": "https://github.com/fxos/fxos-dev-mode-dialog",
|
||||
"license": "MPL",
|
||||
"main": "fxos-dev-mode-dialog.js",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"package.json",
|
||||
"README.md"
|
||||
]
|
||||
}
|
||||
157
gaia/distros/spark/apps/studio/bower_components/fxos-dev-mode-dialog/fxos-dev-mode-dialog.js
vendored
Executable file
|
|
@ -0,0 +1,157 @@
|
|||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
var template = `<style>
|
||||
.modal-dialog {
|
||||
background: #2d2d2d;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
z-index: 100;
|
||||
}
|
||||
.modal-dialog > section {
|
||||
color: #FAFAFA;
|
||||
padding: 80px 25px 0;
|
||||
-moz-box-sizing: padding-box;
|
||||
font-size: 22px;
|
||||
line-height: 30px;
|
||||
font-weight: 300;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
overflow-y: scroll;
|
||||
max-height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.modal-dialog h1 {
|
||||
font-size: 19px;
|
||||
font-weight: 400;
|
||||
line-height: 28px;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
padding-top: 10px;
|
||||
}
|
||||
/* Menu & buttons setup */
|
||||
.modal-dialog menu {
|
||||
padding: 15px;
|
||||
background: #4d4d4d;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.modal-dialog p {
|
||||
word-wrap: break-word;
|
||||
margin: 10px 0 0;
|
||||
padding: 10px 0;
|
||||
border-top: 0.1rem solid #686868;
|
||||
line-height: 30px;
|
||||
}
|
||||
.modal-dialog p > span {
|
||||
padding-top: 25px;
|
||||
display: block;
|
||||
}
|
||||
.modal-dialog menu button {
|
||||
font-family: sans-serif;
|
||||
font-style: italic;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
margin: 0 0 10px;
|
||||
padding: 0 2px;
|
||||
font-size: 16px;
|
||||
line-height: 40px;
|
||||
-moz-box-sizing: border-box;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
background: #d8d8d8;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
color: #333;
|
||||
text-align: center;
|
||||
-moz-margin-end: 10px;
|
||||
}
|
||||
/* Pressed */
|
||||
.modal-dialog menu button:active {
|
||||
background: #00aacc;
|
||||
color: #fff;
|
||||
}
|
||||
.modal-dialog menu button:last-child {
|
||||
-moz-margin-end: 0;
|
||||
}
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<div class="modal-dialog hidden">
|
||||
<section>
|
||||
<h1>Developer Mode not enabled</h1>
|
||||
<p>To gain access to this and other customization features,
|
||||
you must enable Developer Mode.
|
||||
<span>Click Continue to go to Settings app and enable Developer Mode.</span>
|
||||
</p>
|
||||
</section>
|
||||
<menu>
|
||||
<button class="cancel">Cancel</button>
|
||||
<button class="continue">Continue</button>
|
||||
</menu>
|
||||
</div>`;
|
||||
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
|
||||
proto.createdCallback = function() {
|
||||
this.shadow = this.createShadowRoot();
|
||||
this.shadow.innerHTML = template;
|
||||
this.modalDialog = this.shadow.querySelector('.modal-dialog');
|
||||
this.cancelButton = this.shadow.querySelector('.cancel');
|
||||
this.continueButton = this.shadow.querySelector('.continue');
|
||||
|
||||
this.cancelButton.addEventListener(
|
||||
'click', this.handleCancel.bind(this));
|
||||
this.continueButton.addEventListener(
|
||||
'click', this.handleContinue.bind(this));
|
||||
|
||||
// If dev mode perf is enabled emit 'enabled' event else
|
||||
// show the confirm modal dialog
|
||||
navigator.getFeature('dom.apps.developer_mode').then(enabled => {
|
||||
if (enabled) {
|
||||
// Emit Enabled Event
|
||||
this.dispatchEvent(new CustomEvent('enabled'));
|
||||
} else {
|
||||
this.modalDialog.classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
proto.handleCancel = function(e) {
|
||||
window.close();
|
||||
};
|
||||
|
||||
proto.handleContinue = function(e) {
|
||||
// Invoke Settings activity to enable developer mode
|
||||
// XXX: Bug 1163889
|
||||
var activity = new window.MozActivity({
|
||||
name: 'configure',
|
||||
data: {
|
||||
target: 'device',
|
||||
section: 'full-developer-mode'
|
||||
}
|
||||
});
|
||||
activity.onerror = function() {
|
||||
console.log('Settings configure activity error:', activity.error.name);
|
||||
};
|
||||
};
|
||||
|
||||
try {
|
||||
document.registerElement('fxos-dev-mode-dialog', { prototype: proto });
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
})(window);
|
||||
36
gaia/distros/spark/apps/studio/bower_components/gaia-button/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "gaia-button",
|
||||
"version": "0.0.5",
|
||||
"main": "gaia-button.js",
|
||||
"homepage": "https://github.com/gaia-components/gaia-button",
|
||||
"authors": [
|
||||
"cyee@mozilla.com"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"devDependencies": {
|
||||
"gaia-fonts": "gaia-components/gaia-fonts#~0.2.1",
|
||||
"gaia-icons": "gaia-components/gaia-icons#~0.7.1",
|
||||
"base": "gaia-components/base",
|
||||
"gaia-theme": "gaia-components/gaia-theme#~0.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"gaia-component": "gaia-components/gaia-component#~0.3.0"
|
||||
},
|
||||
"_release": "0.0.5",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.0.5",
|
||||
"commit": "12bf8729513253f5d43429fe064ed62bb1fa85b6"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-button.git",
|
||||
"_target": "0.0.5",
|
||||
"_originalSource": "gaia-components/gaia-button",
|
||||
"_direct": true
|
||||
}
|
||||
26
gaia/distros/spark/apps/studio/bower_components/gaia-button/bower.json
vendored
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "gaia-button",
|
||||
"version": "0.0.3",
|
||||
"main": "gaia-button.js",
|
||||
"homepage": "https://github.com/gaia-components/gaia-button",
|
||||
"authors": [
|
||||
"cyee@mozilla.com"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"devDependencies": {
|
||||
"gaia-fonts": "gaia-components/gaia-fonts#~0.2.1",
|
||||
"gaia-icons": "gaia-components/gaia-icons#~0.7.1",
|
||||
"base": "gaia-components/base",
|
||||
"gaia-theme": "gaia-components/gaia-theme#~0.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"gaia-component": "gaia-components/gaia-component#~0.3.0"
|
||||
}
|
||||
}
|
||||
198
gaia/distros/spark/apps/studio/bower_components/gaia-button/gaia-button.js
vendored
Executable file
|
|
@ -0,0 +1,198 @@
|
|||
(function(define){define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var component = require('gaia-component');
|
||||
|
||||
/**
|
||||
* Exports
|
||||
*/
|
||||
|
||||
module.exports = component.register('gaia-button', {
|
||||
created: function() {
|
||||
this.setupShadowRoot();
|
||||
this.setAttribute('role', 'button');
|
||||
this.tabIndex = 0;
|
||||
},
|
||||
|
||||
attrs: {
|
||||
circular: {
|
||||
get: function() { return this.getAttribute('circular'); },
|
||||
set: function(value) {
|
||||
value = !!(value === '' || value);
|
||||
if (value) {
|
||||
this.setAttribute('circular', '');
|
||||
} else {
|
||||
this.removeAttribute('circular');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
disabled: {
|
||||
get: function() { return this.getAttribute('disabled'); },
|
||||
set: function(value) {
|
||||
value = !!(value === '' || value);
|
||||
if (value) {
|
||||
this.setAttribute('disabled', '');
|
||||
} else {
|
||||
this.removeAttribute('disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
template: `
|
||||
<div class="inner">
|
||||
<div class="background"></div>
|
||||
<div class="content"><content></content></div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
height: 50px;
|
||||
min-width: 50%;
|
||||
border-radius: 50px;
|
||||
margin: var(--base-m, 18px) 0;
|
||||
outline: 0;
|
||||
font-style: italic;
|
||||
font-size: 17px;
|
||||
cursor: pointer;
|
||||
-moz-user-select: none;
|
||||
line-height: 1;
|
||||
|
||||
background:
|
||||
var(--button-background,
|
||||
var(--input-background,
|
||||
var(--background-plus,
|
||||
#fff)));
|
||||
|
||||
color:
|
||||
var(--button-color,
|
||||
var(--text-color,
|
||||
inherit));
|
||||
|
||||
box-shadow:
|
||||
var(--button-box-shadow,
|
||||
var(--box-shadow,
|
||||
none));
|
||||
|
||||
transition: color 0ms 300ms;
|
||||
}
|
||||
|
||||
@media(min-width:500px) {
|
||||
:host { min-width: 140px; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Pressed
|
||||
*/
|
||||
|
||||
:host(:active) {
|
||||
color: var(--button-color-active, #fff);
|
||||
box-shadow: var(--button-box-shadow-active, none);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* [circular]
|
||||
*/
|
||||
|
||||
:host([circular]) {
|
||||
width: 50px;
|
||||
min-width: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
:host([disabled]) {
|
||||
pointer-events: none;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/** Inner
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/** Background
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.background {
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
|
||||
transition: opacity 500ms 200ms;
|
||||
|
||||
background:
|
||||
var(--button-background-active,
|
||||
var(--highlight-color,
|
||||
#333));
|
||||
}
|
||||
|
||||
:active .background {
|
||||
transition: none;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Content
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* 1. In some cases events seems to be getting
|
||||
* swallowed by text-nodes. Ignoring pointer-
|
||||
* events means we can listen on parent nodes
|
||||
* instead.
|
||||
*/
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
height: 100%;
|
||||
padding: 0 18px;
|
||||
pointer-events: none; /* 1 */
|
||||
}
|
||||
|
||||
[circular] .content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
i:before {
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
::content i {
|
||||
margin-left: -2px;
|
||||
margin-right: -2px;
|
||||
}
|
||||
|
||||
::content i + span,
|
||||
::content span + i {
|
||||
-moz-margin-start: 8px;
|
||||
}
|
||||
|
||||
</style>`
|
||||
});
|
||||
|
||||
});})((function(n,w){return typeof define=='function'&&define.amd?
|
||||
define:typeof module=='object'?function(c){c(require,exports,module);}:function(c){
|
||||
var m={exports:{}},r=function(n){return w[n];};w[n]=c(r,m.exports,m)||m.exports;};})('gaia-button',this));
|
||||
66
gaia/distros/spark/apps/studio/bower_components/gaia-button/index.html
vendored
Executable file
|
|
@ -0,0 +1,66 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><gaia-button></title>
|
||||
<meta name="description" content="gaia-text-input demo" />
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/base/base.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-theme/gaia-theme.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-icons/gaia-icons.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-fonts/style.css">
|
||||
<script src="bower_components/gaia-theme/lib/gaia-theme-selector.js"></script>
|
||||
<script src="bower_components/gaia-component/gaia-component.js"></script>
|
||||
<script src="gaia-button.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
padding-top: 48px;
|
||||
background-color: var(--background);
|
||||
}
|
||||
/*
|
||||
[data-icon=back-light] {
|
||||
margin-left: -9px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
[data-icon=forward-light] {
|
||||
margin-left: 10px;
|
||||
margin-right: -9px;
|
||||
}*/
|
||||
|
||||
[flex] {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body role="application" class="l-align-center">
|
||||
<gaia-theme-selector></gaia-theme-selector>
|
||||
<h1 class="large l-align-center l-mb-mega"><gaia-button></h1>
|
||||
|
||||
<section>
|
||||
<gaia-button>Gaia button 1</gaia-button>
|
||||
<gaia-button disabled>Gaia button 1</gaia-button>
|
||||
</section>
|
||||
|
||||
<hr/>
|
||||
|
||||
<section>
|
||||
<gaia-button><i data-icon="back-light"></i><span>Back</span></gaia-button>
|
||||
<gaia-button><span>Forward</span><i data-icon="forward-light"></i></gaia-button>
|
||||
</section>
|
||||
|
||||
<hr/>
|
||||
|
||||
<section flex>
|
||||
<gaia-button circular><i data-icon="camera"></i></gaia-button>
|
||||
<gaia-button circular><i data-icon="bug"></i></gaia-button>
|
||||
<gaia-button circular><i data-icon="video"></i></gaia-button>
|
||||
<gaia-button circular><i data-icon="camera"></i></gaia-button>
|
||||
<gaia-button circular><i data-icon="reload"></i></gaia-button>
|
||||
<gaia-button circular><i data-icon="airplane"></i></gaia-button>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
22
gaia/distros/spark/apps/studio/bower_components/gaia-color-picker/LICENSE
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-color-picker/demo/icons/icon128x128.png
vendored
Executable file
|
After Width: | Height: | Size: 4.9 KiB |
32
gaia/distros/spark/apps/studio/bower_components/gaia-color-picker/demo/index.html
vendored
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1">
|
||||
|
||||
<title>Pick a Color</title>
|
||||
<script src="js/gaia-color-picker.js"></script>
|
||||
<script defer src="js/app.js"></script>
|
||||
<style>
|
||||
gaia-color-picker {
|
||||
display: block;
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
@media (orientation: landscape) {
|
||||
gaia-color-picker {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Pick a Color</h1>
|
||||
<gaia-color-picker value="#fff" id="picker"></gaia-color-picker>
|
||||
<pre id="values"></pre>
|
||||
</body>
|
||||
</html>
|
||||
15
gaia/distros/spark/apps/studio/bower_components/gaia-color-picker/demo/js/app.js
vendored
Executable file
|
|
@ -0,0 +1,15 @@
|
|||
var picker = document.getElementById('picker');
|
||||
var values = document.getElementById('values');
|
||||
picker.onchange = function() {
|
||||
values.textContent = `
|
||||
${picker.value}
|
||||
R: ${picker.r} G: ${picker.g} B: ${picker.b}
|
||||
H: ${picker.h.toPrecision(3)} \
|
||||
S: ${picker.s.toPrecision(3)} \
|
||||
V: ${picker.v.toPrecision(3)}
|
||||
`;
|
||||
};
|
||||
|
||||
window.onresize = function() {
|
||||
picker.resize();
|
||||
}
|
||||
954
gaia/distros/spark/apps/studio/bower_components/gaia-color-picker/demo/js/gaia-color-picker.js
vendored
Executable file
|
|
@ -0,0 +1,954 @@
|
|||
/**
|
||||
* This module defines a custom <gaia-color-picker> element and exports the
|
||||
* GaiaColorPicker() constructor as its only global symbol.
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* <gaia-color-picker id="picker" value="#aabbcc"></gaia-color-picker>
|
||||
* <script>
|
||||
* var picker = document.getElementById('picker');
|
||||
* picker.onchange = function() {
|
||||
* console.log(picker.r, picker.g, picker.b, picker.value);
|
||||
* };
|
||||
* </script>
|
||||
*
|
||||
* ATTRIBUTES
|
||||
*
|
||||
* A <gaia-color-picker> element defines an HTML attribute named "value" that
|
||||
* can be use to query or set the currently selected color. The value of this
|
||||
* attribute is a standard CSS hexadecimal color specification in the form
|
||||
* #rgb or #rrggbb.
|
||||
*
|
||||
* PROPERTIES
|
||||
*
|
||||
* A <gaia-color-picker> element defines the following JavaScript properties:
|
||||
*
|
||||
* value: a read/write string property that reflects the "value" attribute.
|
||||
*
|
||||
* r: the red component of the current color. A read-only integer 0-255.
|
||||
*
|
||||
* g: the green component of the current color. A read-only integer 0-255.
|
||||
*
|
||||
* b: the red component of the current color. A read-only integer 0-255.
|
||||
*
|
||||
* h: the hue the current color. A read-only number 0 - 360.
|
||||
*
|
||||
* s: the saturation of the current color. A read-only number 0.0 - 1.0.
|
||||
*
|
||||
* v: the value of the current color. A read-only number 0.0 - 1.0.
|
||||
*
|
||||
* EVENTS
|
||||
*
|
||||
* When the user interacts with a <gaia-color-picker> component to select a
|
||||
* new color, the component emits a "change" event. There are no details in
|
||||
* the event object. The changed color is available through the properties
|
||||
* listed above.
|
||||
*
|
||||
* METHODS
|
||||
*
|
||||
* A <gaia-color-picker> element defines the following methods:
|
||||
*
|
||||
* resize(): call this function when the size of the component has changed
|
||||
* to tell it to resize its internal canvases and re-draw its color wheel.
|
||||
* You should call this on window.resize events and any time the document
|
||||
* layout changes in such a way that the component size changes. Note that
|
||||
* this recomputes all the pixels of hte hue/saturation color disk and is
|
||||
* a relatively expensive operation.
|
||||
*
|
||||
* STATIC FUNCTIONS
|
||||
*
|
||||
* This module defines color space conversion utility functions as
|
||||
* properties of the GaiaColorPicker constructor:
|
||||
*
|
||||
* GaiaColorPicker.rgb2hsv(red, green, blue): returns [hue, saturation, value]
|
||||
*
|
||||
* GaiaColorPicker.hsv2rgb(hue, saturation, value): returns [red, green, blue]
|
||||
*
|
||||
* GaiaColorPicker.rgb2hex(red, green, blue): returns hex color string "#rrggbb"
|
||||
*
|
||||
* GaiaColorPicker.hex2rgb("#rrggbb"): returns [red, green, blue]
|
||||
*
|
||||
* GaiaColorPicker.hsv2hex(hue, saturation, value): returns "#rrggbb"
|
||||
*
|
||||
* GaiaColorPicker.hex2hsv("#rrggbb"): returns [hue, saturation, value]
|
||||
*/
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
/*jshint esnext:true*/
|
||||
|
||||
var GaiaColorPicker = document.registerElement('gaia-color-picker', {
|
||||
prototype: Object.create(HTMLElement.prototype, {
|
||||
|
||||
createdCallback: {
|
||||
value: function() { this._impl = new ColorPickerImpl(this); }
|
||||
},
|
||||
|
||||
attachedCallback: {
|
||||
value: function() { this._impl.attach(); }
|
||||
},
|
||||
|
||||
detachedCallback: {
|
||||
value: function() { this._impl.detach(); }
|
||||
},
|
||||
|
||||
attributeChangedCallback: {
|
||||
value: function(name, oldval, newval) {
|
||||
// If the user deletes the attribute we will do nothing, since
|
||||
// there isn't really a reasonable default value to revert to.
|
||||
if (name === 'value' && newval !== null) {
|
||||
this.value = newval;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
resize: {
|
||||
value: function() { this._impl.resize(); }
|
||||
},
|
||||
|
||||
h: {
|
||||
get: function() { return this._impl.h; }
|
||||
},
|
||||
|
||||
s: {
|
||||
get: function() { return this._impl.s; }
|
||||
},
|
||||
|
||||
v: {
|
||||
get: function() { return this._impl.v; }
|
||||
},
|
||||
|
||||
r: {
|
||||
get: function() { return this._impl.r; }
|
||||
},
|
||||
|
||||
g: {
|
||||
get: function() { return this._impl.g; }
|
||||
},
|
||||
|
||||
b: {
|
||||
get: function() { return this._impl.b; }
|
||||
},
|
||||
|
||||
value: {
|
||||
get: function() { return this._impl.hexColorString; },
|
||||
set: function(newval) { this._impl.setHexColorString(newval); }
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// Expose the utility functions through the constructor
|
||||
GaiaColorPicker.hsv2rgb = hsv2rgb;
|
||||
GaiaColorPicker.rgb2hsv = rgb2hsv;
|
||||
GaiaColorPicker.hsv2hex = hsv2hex;
|
||||
GaiaColorPicker.rgb2hex = rgb2hex;
|
||||
GaiaColorPicker.hex2rgb = hex2rgb;
|
||||
GaiaColorPicker.hex2hsv = hex2hsv;
|
||||
|
||||
// Export the constructor
|
||||
exports.GaiaColorPicker = GaiaColorPicker;
|
||||
|
||||
/*
|
||||
* Implementation details below
|
||||
*/
|
||||
|
||||
const TEMPLATE = `
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
|
||||
#container {
|
||||
display: block;
|
||||
position: relative; /* so that we can absolutely position content */
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mark {
|
||||
display: block;
|
||||
position: absolute;
|
||||
border: solid white 4px;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-left: -20px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
.mark:before {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: relative;
|
||||
border: solid black 1px;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
content: '';
|
||||
margin-left: -4px;
|
||||
margin-top: -4px;
|
||||
}
|
||||
|
||||
#popup {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
border: solid white 6px;
|
||||
border-radius: 50%;
|
||||
border-bottom-right-radius: 5px;
|
||||
transform: translateY(-150%) translateX(-50%) rotate(45deg);
|
||||
box-shadow: 6px 2px 4px black;
|
||||
}
|
||||
|
||||
#popup:before {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
border: solid black 1px;
|
||||
border-radius: 50%;
|
||||
border-bottom-right-radius: 5px;
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
margin-left: -6px;
|
||||
margin-top: -6px;
|
||||
content: '';
|
||||
}
|
||||
|
||||
</style>
|
||||
<div id="container">
|
||||
<canvas id="hues"></canvas>
|
||||
<canvas id="values"></canvas>
|
||||
<div class="mark" id="huemark"></div>
|
||||
<div class="mark" id="valuemark"></div>
|
||||
<div id="popup"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const R0 = 0.10; // The inner radius of the hue/saturation ring
|
||||
const R1 = 0.70; // The outer radius of the hue/saturation ring
|
||||
const R2 = 0.97; // The outer radius of the value ring
|
||||
const DEGREES = 180/Math.PI; // Convert radians to degrees
|
||||
const RADIANS = Math.PI/180; // Convert degrees to radians
|
||||
const PI = Math.PI;
|
||||
const TWOPI = 2 * Math.PI;
|
||||
const HALFPI = Math.PI/2;
|
||||
|
||||
function ColorPickerImpl(element) {
|
||||
// Lazily create the template the first time a color picker is created
|
||||
if (!ColorPickerImpl.template) {
|
||||
ColorPickerImpl.template = document.createElement('template');
|
||||
ColorPickerImpl.template.innerHTML = TEMPLATE;
|
||||
}
|
||||
|
||||
// This is the <gaia-color-picker> element we are the implementation for
|
||||
this.element = element;
|
||||
|
||||
// Create the elements we need in the shadow DOM
|
||||
this.shadow = element.createShadowRoot();
|
||||
this.shadow.appendChild(ColorPickerImpl.template.content.cloneNode(true));
|
||||
|
||||
// Get references to the elements we'll need to manipulate
|
||||
this.huecanvas = this.shadow.getElementById('hues');
|
||||
this.valcanvas = this.shadow.getElementById('values');
|
||||
this.huemark = this.shadow.getElementById('huemark');
|
||||
this.valuemark = this.shadow.getElementById('valuemark');
|
||||
this.popup = this.shadow.getElementById('popup');
|
||||
|
||||
// Start off pure white
|
||||
this.h = 0;
|
||||
this.s = 0.0;
|
||||
this.v = 1.0;
|
||||
this.r = 255;
|
||||
this.g = 255;
|
||||
this.b = 255;
|
||||
this.hexColorString = '#ffffff';
|
||||
|
||||
// But if there is a "value" attribute on the element, use that
|
||||
var initialValue = this.element.getAttribute('value');
|
||||
if (initialValue) {
|
||||
this.setHexColorString(initialValue);
|
||||
}
|
||||
|
||||
// Register event handlers for user interaction
|
||||
this.shadow.addEventListener('mousedown', this);
|
||||
this.shadow.addEventListener('touchstart', this);
|
||||
this.shadow.addEventListener('touchmove', this);
|
||||
this.shadow.addEventListener('touchend', this);
|
||||
|
||||
// If we're already in the document, do the rest now
|
||||
if (this.element.parentNode) {
|
||||
this.attach();
|
||||
}
|
||||
else {
|
||||
this.attached = false;
|
||||
}
|
||||
}
|
||||
|
||||
ColorPickerImpl.prototype.attach = function() {
|
||||
this.attached = true;
|
||||
this.resize();
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.detach = function() {
|
||||
this.attached = false;
|
||||
this.huecanvas.width = 0;
|
||||
this.valcanvas.width = 0;
|
||||
this.huecontext = null;
|
||||
this.valuecontext = null;
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.resize = function() {
|
||||
//
|
||||
// When the color picker is first added to the document, or when we notice
|
||||
// that its size has changed, we resize the canvas elements and pre-draw
|
||||
// as much of the color wheel as we can.
|
||||
//
|
||||
// Drawing a color wheel is a fairly expensive operation and as the user
|
||||
// moves her finger across the component we'll have to redraw it quickly.
|
||||
// To optimize this, we use two canvas layers and pre-draw as much as
|
||||
// possible. On the bottom "hue layer" we draw only bright colors with
|
||||
// value 1. On the top "value layer" we draw transparent black, with
|
||||
// opacity set to modify the apparent value of the colors below.
|
||||
//
|
||||
// In this function we will pre-draw the hue/saturation plane for value=1
|
||||
// on the hue layer. This is an expensive operation that involves setting
|
||||
// tens of thousands of individual pixels in an ImageData object. Then,
|
||||
// when the user interacts with the color picker to change the value to v,
|
||||
// we can change the apparent value of the entire hue/saturation plane by
|
||||
// drawing a single circle of transparent black with opacity (1 - v) in
|
||||
// the value plane. A single draw operation in the value plane will make
|
||||
// it look like we've changed the value of each individual pixel in the
|
||||
// hue/saturation wheel.
|
||||
//
|
||||
// Similarly, this function will also pre-draw the outer value ring of the
|
||||
// color wheel in the value layer. We will draw wedges of transparent black
|
||||
// with opacity ranging from 1 down to 0. Then, when the user interacts
|
||||
// with the color wheel and we need to display all possible values of a
|
||||
// given hue/saturation color, all we need to do is draw a solid ring of
|
||||
// that color in the hue plane, and because of the pre-drawn gradient in
|
||||
// the value plane, the user will see all possible values of that
|
||||
// hue/saturation combination.
|
||||
//
|
||||
// The upshot is that all the tricky and time-consuming drawing is done
|
||||
// here only when we resize the canvas. And updating the component visuals
|
||||
// when the user interacts with it is fast and nearly trivial.
|
||||
//
|
||||
|
||||
// Compute our dimensions. Note that we want to use device pixels
|
||||
// not CSS pixels.
|
||||
this.dpr = window.devicePixelRatio;
|
||||
this.width = this.element.clientWidth * this.dpr;
|
||||
this.height = this.element.clientHeight * this.dpr;
|
||||
this.cx = this.width / 2; // center of the circle
|
||||
this.cy = this.height / 2;
|
||||
this.radius = Math.min(this.cx, this.cy);
|
||||
this.r0 = Math.round(R0 * this.radius); // inner radius of hue ring
|
||||
this.r1 = Math.round(R1 * this.radius); // outer radius of hue ring
|
||||
this.r2 = Math.round(R2 * this.radius); // outer radius of value ring
|
||||
|
||||
// If we are not in the document yet, or have 0 size, there is nothing
|
||||
// to do here.
|
||||
if (!this.attached || this.width === 0 || this.height === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the canvas dimensions
|
||||
// XXX: note that it would be more efficient to force the canvases to
|
||||
// be square. But then the layout would be tricker
|
||||
this.huecanvas.width = this.width;
|
||||
this.huecanvas.height = this.height;
|
||||
this.valcanvas.width = this.width;
|
||||
this.valcanvas.height = this.height;
|
||||
|
||||
// Get the canvas contexts
|
||||
this.huectx = this.huecanvas.getContext('2d', {alpha: false});
|
||||
this.valctx = this.valcanvas.getContext('2d');
|
||||
|
||||
// Do the pre-drawing
|
||||
this.drawHueSaturationPlane();
|
||||
this.drawValueGradient();
|
||||
|
||||
// And do the regular drawing by calling updateState() to force a redraw
|
||||
// We do not generate a change event in this case
|
||||
this.updateState(this.h, this.s, this.v, false, true);
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.handleEvent = function(e) {
|
||||
var box = this.element.getBoundingClientRect();
|
||||
var x, y, hit;
|
||||
|
||||
// Get the mouse or touch coordinates from the event, convert to
|
||||
// be relative to this element, and convert from CSS to device pixels
|
||||
if (e instanceof MouseEvent) {
|
||||
x = (e.clientX - box.left) * this.dpr;
|
||||
y = (e.clientY - box.top) * this.dpr;
|
||||
}
|
||||
else if (e instanceof TouchEvent) {
|
||||
var touch = e.changedTouches[0];
|
||||
x = (touch.clientX - box.left) * this.dpr;
|
||||
y = (touch.clientY - box.top) * this.dpr;
|
||||
}
|
||||
|
||||
if (e.type === 'touchstart' || e.type === 'mousedown') {
|
||||
if (e.type === 'mousedown') {
|
||||
window.addEventListener('mousemove', this, true);
|
||||
window.addEventListener('mouseup', this, true);
|
||||
}
|
||||
|
||||
hit = this.hit(x, y);
|
||||
if (hit === 'hue') {
|
||||
this.changeHueSaturation(x, y);
|
||||
this.dragging = 'hue';
|
||||
this.showPopup(x, y);
|
||||
}
|
||||
else if (hit === 'value') {
|
||||
this.changeValue(x, y);
|
||||
this.dragging = 'value';
|
||||
this.showPopup(x, y);
|
||||
}
|
||||
}
|
||||
else if (this.dragging &&
|
||||
(e.type === 'touchmove' || e.type === 'mousemove'))
|
||||
{
|
||||
hit = this.hit(x, y);
|
||||
if (hit === this.dragging) {
|
||||
if (hit === 'hue') {
|
||||
this.changeHueSaturation(x, y);
|
||||
}
|
||||
else if (hit === 'value') {
|
||||
this.changeValue(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (e.type === 'touchend' || e.type === 'mouseup') {
|
||||
if (e.type === 'mouseup') {
|
||||
window.removeEventListener('mousemove', this, true);
|
||||
window.removeEventListener('mouseup', this, true);
|
||||
}
|
||||
this.dragging = null;
|
||||
this.hidePopup();
|
||||
}
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.setHexColorString = function(hexstring) {
|
||||
// If the hexstring is the same as the current value, do nothing.
|
||||
// This is important to prevent recursion since calling this function
|
||||
// sets the HTML attribute, and setting the HTML attribute calls
|
||||
// this function.
|
||||
if (hexstring === this.hexColorString) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the new value
|
||||
var rgb = hex2rgb(hexstring);
|
||||
|
||||
// Convert to hsv and update the color picker with the new color.
|
||||
// Don't emit a change event for this update, however, since this
|
||||
// is used for changes caused by JS code, not by the user.
|
||||
this.updateState(...rgb2hsv(...rgb), false);
|
||||
|
||||
// Make sure this new hexstring is visible through the attribute, too.
|
||||
this.element.setAttribute('value', this.hexColorString);
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.updateState = function(h, s, v,
|
||||
notify = true,
|
||||
force = false)
|
||||
{
|
||||
var hueChange = force || (h !== this.h) || (s !== this.s);
|
||||
var valueChange = force || (v !== this.v);
|
||||
|
||||
if (!hueChange && !valueChange) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.h = h;
|
||||
this.s = s;
|
||||
this.v = v;
|
||||
[this.r, this.g, this.b] = hsv2rgb(h, s, v);
|
||||
this.hexColorString = rgb2hex(this.r, this.g, this.b);
|
||||
|
||||
if (this.attached) {
|
||||
if (hueChange) {
|
||||
this.hueChanged = true;
|
||||
}
|
||||
if (valueChange) {
|
||||
this.valueChanged = true;
|
||||
}
|
||||
|
||||
if (!this.redrawRequested) {
|
||||
this.redrawRequested = requestAnimationFrame(function() {
|
||||
this.setMarkColor();
|
||||
|
||||
if (this.hueChanged) {
|
||||
this.updateHue();
|
||||
}
|
||||
|
||||
if (this.valueChanged) {
|
||||
this.updateValue();
|
||||
}
|
||||
|
||||
this.redrawRequested = null;
|
||||
this.hueChanged = false;
|
||||
this.valueChanged = false;
|
||||
|
||||
// Don't send change events out any faster than 60 times a second
|
||||
// even if touch events are coming in faster than that.
|
||||
if (notify) {
|
||||
this.element.dispatchEvent(new Event('change'));
|
||||
}
|
||||
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Draw the value=1 plane of the HSV color cylinder into the hue canvas
|
||||
ColorPickerImpl.prototype.drawHueSaturationPlane = function() {
|
||||
var r0 = this.r0;
|
||||
var r1 = this.r1;
|
||||
var width = 2 * r1;
|
||||
var height = 2 * r1;
|
||||
|
||||
// Precompute this value to make the inner loop as fast as possible
|
||||
var conversion = 1 / (r1 - r0);
|
||||
|
||||
var imagedata = this.huectx.getImageData(this.cx - r1,
|
||||
this.cy - r1,
|
||||
width, height);
|
||||
var pixels = imagedata.data;
|
||||
|
||||
for(var y = 0; y < height; y++) {
|
||||
var dy = y - r1;
|
||||
|
||||
for(var x = 0; x < width; x++) {
|
||||
var dx = x - r1;
|
||||
var distance = Math.sqrt(dx*dx + dy*dy);
|
||||
|
||||
// if this pixel is outside r1, do nothing
|
||||
if (distance > r1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var index = (y * width + x) * 4;
|
||||
|
||||
// If the pixel is inside r0, make it pure white
|
||||
if (distance < r0) {
|
||||
pixels[index] = 255;
|
||||
pixels[index+1] = 255;
|
||||
pixels[index+2] = 255;
|
||||
pixels[index+3] = 255;
|
||||
}
|
||||
else {
|
||||
// Convert dx, dy to polar (hue, saturation)
|
||||
var hue = Math.atan2(-dy, dx) * DEGREES;
|
||||
if (hue < 0) {
|
||||
hue += 360;
|
||||
}
|
||||
var saturation = (distance - r0) * conversion;
|
||||
|
||||
// Convert that color to rgb
|
||||
var rgb = hsv2rgb(hue, saturation, 1.0);
|
||||
pixels[index] = rgb[0];
|
||||
pixels[index + 1] = rgb[1];
|
||||
pixels[index + 2] = rgb[2];
|
||||
pixels[index + 3] = 255; // Opaque
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.huectx.putImageData(imagedata, this.cx - r1, this.cy - r1);
|
||||
};
|
||||
|
||||
// Draw a gradient of transparent black colors into the value context
|
||||
// We do this by seting pixels directly in an ImageData so that we can
|
||||
// avoid thin lines and moire patterns that appear when we try to fill
|
||||
// individual wedges of color
|
||||
ColorPickerImpl.prototype.drawValueGradient = function() {
|
||||
var r1 = this.r1;
|
||||
var r2 = this.r2;
|
||||
var width = 2 * r2;
|
||||
var height = 2 * r2;
|
||||
|
||||
var imagedata = this.valctx.getImageData(this.cx - r2,
|
||||
this.cy - r2,
|
||||
width, height);
|
||||
var pixels = imagedata.data;
|
||||
|
||||
for(var y = 0; y < height; y++) {
|
||||
var dy = y - r2;
|
||||
var dy2 = dy * dy;
|
||||
|
||||
for(var x = 0; x < width; x++) {
|
||||
var dx = x - r2;
|
||||
var distance = Math.sqrt(dx*dx + dy2);
|
||||
|
||||
// If this pixel is outside r2 continue.
|
||||
if (distance > r2) {
|
||||
if (dx > 0) { // If we're on the right, we're done with this line
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// Otherwise, skip ahead to the first pixel on the circle
|
||||
var newx = Math.ceil(r2 - Math.sqrt(r2*r2 - dy2))-1;
|
||||
// make sure we're not moving backwards and starting an
|
||||
// infinite loop
|
||||
if (newx > x) {
|
||||
x = newx;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// If we've moved inside the ring skip immediately to the next part
|
||||
if (distance < r1) { // if inside the ring
|
||||
if (dx < 0) { // and on the left side
|
||||
x = width - x; // skip to the matching right side
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// figure out the angle to (dx,dy) and convert to our value
|
||||
var angle = Math.atan2(dy, -dx) + HALFPI;
|
||||
if (angle < 0) {
|
||||
angle += TWOPI;
|
||||
}
|
||||
var value = angle/TWOPI;
|
||||
var opacity = Math.round((1 - value) * 255);
|
||||
|
||||
var index = (y * width + x) * 4;
|
||||
pixels[index] = 0;
|
||||
pixels[index + 1] = 0;
|
||||
pixels[index + 2] = 0;
|
||||
pixels[index + 3] = opacity;
|
||||
}
|
||||
}
|
||||
|
||||
this.valctx.putImageData(imagedata, this.cx - r2, this.cy - r2);
|
||||
|
||||
// Draw an opaque gradient ring between the hues and values
|
||||
var radiansPerSegment = TWOPI / 256;
|
||||
var startAngle;
|
||||
var endAngle = 3 * HALFPI;
|
||||
// The inner half of this line will be overwritten by the solid
|
||||
// transparent circle we draw, so we draw it twice as wide as we need
|
||||
this.valctx.lineWidth = 3 * this.dpr;
|
||||
this.valctx.lineCap = 'square';
|
||||
|
||||
for(var level = 255; level >= 0; level--) {
|
||||
startAngle = endAngle;
|
||||
endAngle = startAngle - radiansPerSegment;
|
||||
// And now draw another segment in a contrasting color to
|
||||
// separate the values from the hues. Note that these are
|
||||
// opaque colors and are all shades of gray.
|
||||
this.valctx.beginPath();
|
||||
this.valctx.arc(this.cx, this.cy, this.r1, startAngle, endAngle, true);
|
||||
this.valctx.strokeStyle = rgb2hex(level, level, level);
|
||||
if (level === 0) {
|
||||
this.valctx.lineCap = 'butt';
|
||||
}
|
||||
this.valctx.stroke();
|
||||
}
|
||||
|
||||
// Finally draw an opaque black border around the entire circle. This is
|
||||
// needed because the solid ring of color we draw on the hue canvas is
|
||||
// antialiased, and the individual pixels we draw on the value canvas
|
||||
// are jaggy, so we end up with a tiny fringe of partially lit pixels
|
||||
// showing at the edge.
|
||||
this.valctx.beginPath();
|
||||
this.valctx.arc(this.cx, this.cy, this.r2, 0, TWOPI);
|
||||
this.valctx.strokeStyle = '#000';
|
||||
this.valctx.lineWidth = 2 * this.dpr;
|
||||
this.valctx.stroke();
|
||||
};
|
||||
|
||||
// Return 'hue' if (x, y) is in the hue/saturation disk.
|
||||
// Return 'value' if (x, y) is in the value ring.
|
||||
// Otherwise return null.
|
||||
ColorPickerImpl.prototype.hit = function(x, y) {
|
||||
var dx = x - this.cy;
|
||||
var dy = y - this.cy;
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
if (d < this.r1) {
|
||||
return 'hue';
|
||||
}
|
||||
else if (d < this.r2) {
|
||||
return 'value';
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.changeHueSaturation = function(x, y) {
|
||||
var dx = x - this.cx;
|
||||
var dy = y - this.cy;
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
var hue, saturation;
|
||||
|
||||
// user clicked on the hue/saturation disc
|
||||
if (d >= this.r0) {
|
||||
// User clicked on the colorful part of the ring
|
||||
hue = Math.atan2(-dy, dx) * DEGREES;
|
||||
if (hue < 0) {
|
||||
hue += 360;
|
||||
}
|
||||
saturation = (d - this.r0) / (this.r1 - this.r0);
|
||||
}
|
||||
else {
|
||||
// user clicked on the white circle in the middle
|
||||
hue = 0;
|
||||
saturation = 0;
|
||||
}
|
||||
|
||||
this.updateState(hue, saturation, this.v);
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.changeValue = function(x, y) {
|
||||
var dx = x - this.cx;
|
||||
var dy = y - this.cy;
|
||||
var angle = Math.atan2(-dy, dx) - HALFPI;
|
||||
if (angle < 0) {
|
||||
angle += TWOPI;
|
||||
}
|
||||
var value = angle / TWOPI;
|
||||
this.updateState(this.h, this.s, value);
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.updateValue = function() {
|
||||
// Move the marker that indicates the currently selected value
|
||||
var angle = this.v * TWOPI + HALFPI;
|
||||
|
||||
var r = (this.r1 + this.r2)/2;
|
||||
var x = this.cx + r * Math.cos(angle);
|
||||
var y = this.cy - r * Math.sin(angle);
|
||||
this.valuemark.style.left = (x / this.dpr) + 'px';
|
||||
this.valuemark.style.top = (y / this.dpr) + 'px';
|
||||
this.popup.style.left = (x / this.dpr) + 'px';
|
||||
this.popup.style.top = (y / this.dpr) + 'px';
|
||||
|
||||
// Draw a transparent black circle in the value canvas to alter the
|
||||
// apparent values of the colors in the hue canvas. We need to do a
|
||||
// copy operation so that the colors already in the canvas do not get
|
||||
// combined with the pixels we're drawing.
|
||||
//
|
||||
// XXX This code works correctly on the desktop but not in Firefox for
|
||||
// Android or on FirefoxOS, so until bug 1126055 is resolved, we're
|
||||
// just not going to alter the value of the central color disk.
|
||||
//
|
||||
// var opacity = 1 - this.v;
|
||||
// this.valctx.save();
|
||||
// this.valctx.beginPath();
|
||||
// this.valctx.arc(this.cx, this.cy, this.r1, 0, TWOPI, false);
|
||||
// this.valctx.clip();
|
||||
// this.valctx.globalCompositeOperation = 'copy';
|
||||
// this.valctx.fillStyle = 'rgba(0,0,0,' + opacity + ')';
|
||||
// this.valctx.fill();
|
||||
// this.valctx.restore();
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.updateHue = function() {
|
||||
// Compute the position of the hue marker and move it
|
||||
var x = this.cx, y = this.cy;
|
||||
|
||||
if (this.s !== 0) {
|
||||
var d = this.r0 + this.s * (this.r1 - this.r0);
|
||||
var angle = this.h * RADIANS;
|
||||
|
||||
x += d * Math.cos(angle);
|
||||
y -= d * Math.sin(angle);
|
||||
}
|
||||
this.huemark.style.left = (x / this.dpr) + 'px';
|
||||
this.huemark.style.top = (y / this.dpr) + 'px';
|
||||
this.popup.style.left = (x / this.dpr) + 'px';
|
||||
this.popup.style.top = (y / this.dpr) + 'px';
|
||||
|
||||
// Draw a solid ring of the current hue/saturation at value=1 in the
|
||||
// hue canvas so that a gradient of the color appears through the
|
||||
// pre-drawn gradient in the value canvas.
|
||||
this.huectx.beginPath();
|
||||
this.huectx.arc(this.cx, this.cy, this.r1, 0, TWOPI, true);
|
||||
this.huectx.arc(this.cx, this.cy, this.r2, 0, TWOPI, false);
|
||||
this.huectx.fillStyle = hsv2hex(this.h, this.s, 1);
|
||||
this.huectx.fill();
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.setMarkColor = function() {
|
||||
this.huemark.style.backgroundColor = this.hexColorString;
|
||||
this.valuemark.style.backgroundColor = this.hexColorString;
|
||||
this.popup.style.backgroundColor = this.hexColorString;
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.showPopup = function(x, y) {
|
||||
// Set the initial position of the popup and show it
|
||||
this.popup.style.left = x / this.dpr + 'px';
|
||||
this.popup.style.top = y / this.dpr + 'px';
|
||||
this.popup.style.display = 'block';
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.hidePopup = function() {
|
||||
this.popup.style.display = 'none';
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Color conversion utilities
|
||||
*/
|
||||
|
||||
//
|
||||
// Convert a (r,g,b) color into (hue, saturation, value)
|
||||
//
|
||||
// See http://en.wikipedia.org/wiki/HSL_and_HSV for the details
|
||||
// of the conversion algorithm.
|
||||
//
|
||||
// Note that if r, g, and b are all multiplied by x (0 <= x <= 1)
|
||||
// the hue and saturation are unchanged in this algorithm and the value
|
||||
// is also multiplied by x. This means that if a color is overlaid with
|
||||
// a translucent black with opacity a, it is the same as reducing the
|
||||
// value of the color by a factor of (1-a), and that the hue and saturation
|
||||
// of the color are unchanged by the overlay. This fact is critical to the
|
||||
// way we render the color wheel for this color picker component.
|
||||
//
|
||||
function rgb2hsv(r, g, b) {
|
||||
r = r/255;
|
||||
g = g/255;
|
||||
b = b/255;
|
||||
|
||||
var min = Math.min(r, g, b);
|
||||
var max = Math.max(r, g, b);
|
||||
var chroma = max - min;
|
||||
|
||||
var hue, saturation, value;
|
||||
|
||||
// Compute the hue
|
||||
if (chroma === 0) {
|
||||
hue = 0; // technically hue is undefined in this case
|
||||
}
|
||||
else {
|
||||
if (max === r) {
|
||||
hue = (g - b) / chroma;
|
||||
if (hue < 0) {
|
||||
hue += 6;
|
||||
}
|
||||
}
|
||||
else if (max === g) {
|
||||
hue = (b - r) / chroma + 2;
|
||||
}
|
||||
else { // max === b
|
||||
hue = (r - g) / chroma + 4;
|
||||
}
|
||||
}
|
||||
|
||||
// convert hue to degrees from 0 to 360;
|
||||
hue *= 60;
|
||||
|
||||
// Value and saturation are easy:
|
||||
value = max;
|
||||
saturation = (value === 0) ? 0 : chroma / value;
|
||||
|
||||
return [hue, saturation, value];
|
||||
}
|
||||
|
||||
// Convert a (hue, saturation, value) color to (r, g, b)
|
||||
function hsv2rgb(h, s, v) {
|
||||
var chroma = s * v;
|
||||
var hprime = h / 60;
|
||||
var x = chroma * (1 - Math.abs(hprime % 2 - 1));
|
||||
var r, g, b;
|
||||
|
||||
switch(Math.floor(hprime)) {
|
||||
case 0:
|
||||
r = chroma;
|
||||
g = x;
|
||||
b = 0;
|
||||
break;
|
||||
case 1:
|
||||
r = x;
|
||||
g = chroma;
|
||||
b = 0;
|
||||
break;
|
||||
case 2:
|
||||
r = 0;
|
||||
g = chroma;
|
||||
b = x;
|
||||
break;
|
||||
case 3:
|
||||
r = 0;
|
||||
g = x;
|
||||
b = chroma;
|
||||
break;
|
||||
case 4:
|
||||
r = x;
|
||||
g = 0;
|
||||
b = chroma;
|
||||
break;
|
||||
case 5:
|
||||
r = chroma;
|
||||
g = 0;
|
||||
b = x;
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
var m = v - chroma;
|
||||
r = Math.round((r + m) * 255);
|
||||
g = Math.round((g + m) * 255);
|
||||
b = Math.round((b + m) * 255);
|
||||
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
// Convert a (r, g, b) color triplet to "#rrggbb" hexadecimal form
|
||||
function rgb2hex(r, g, b) {
|
||||
r = r.toString(16);
|
||||
g = g.toString(16);
|
||||
b = b.toString(16);
|
||||
|
||||
if (r.length === 1) {
|
||||
r = '0' + r;
|
||||
}
|
||||
if (g.length === 1) {
|
||||
g = '0' + g;
|
||||
}
|
||||
if (b.length === 1) {
|
||||
b = '0' + b;
|
||||
}
|
||||
|
||||
return '#' + r + g + b;
|
||||
}
|
||||
|
||||
// Convert a "#rrggbb" color string to a (r, g, b) triplet.
|
||||
function hex2rgb(hex) {
|
||||
if (!/^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$/.test(hex)) {
|
||||
throw new TypeError('Invalid color specification: "' + hex + '"');
|
||||
}
|
||||
|
||||
var r, g, b;
|
||||
if (hex.length === 4) {
|
||||
r = hex[1] + hex[1];
|
||||
g = hex[2] + hex[2];
|
||||
b = hex[3] + hex[3];
|
||||
}
|
||||
else {
|
||||
r = hex.substring(1, 3);
|
||||
g = hex.substring(3, 5);
|
||||
b = hex.substring(5, 7);
|
||||
}
|
||||
|
||||
return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16)];
|
||||
}
|
||||
|
||||
// Convert a (hue, saturation, value) color to "#rrggbb" form.
|
||||
function hsv2hex(h, s, v) {
|
||||
return rgb2hex(...hsv2rgb(h, s, v));
|
||||
}
|
||||
|
||||
// Convert a "#rrggbb" color string to a (hue, saturation, value) triplet
|
||||
function hex2hsv(hex) {
|
||||
return rgb2hsv(...hex2rgb(hex));
|
||||
}
|
||||
}(window));
|
||||
10
gaia/distros/spark/apps/studio/bower_components/gaia-color-picker/demo/manifest.webapp
vendored
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "Color Picker Demo",
|
||||
"description": "Test the gaia-color-picker component",
|
||||
"launch_path": "/index.html",
|
||||
"icons": {
|
||||
"128": "/icons/icon128x128.png"
|
||||
},
|
||||
"type": "certified",
|
||||
"permissions": {}
|
||||
}
|
||||
899
gaia/distros/spark/apps/studio/bower_components/gaia-color-picker/gaia-color-picker.js
vendored
Executable file
|
|
@ -0,0 +1,899 @@
|
|||
/**
|
||||
* This module defines a custom <gaia-color-picker> element and exports the
|
||||
* GaiaColorPicker() constructor as its only global symbol.
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* <gaia-color-picker id="picker" value="#aabbcc"></gaia-color-picker>
|
||||
* <script>
|
||||
* var picker = document.getElementById('picker');
|
||||
* picker.onchange = function() {
|
||||
* console.log(picker.r, picker.g, picker.b, picker.value);
|
||||
* };
|
||||
* </script>
|
||||
*
|
||||
* ATTRIBUTES
|
||||
*
|
||||
* A <gaia-color-picker> element defines an HTML attribute named "value" that
|
||||
* can be use to query or set the currently selected color. The value of this
|
||||
* attribute is a standard CSS hexadecimal color specification in the form
|
||||
* #rgb or #rrggbb.
|
||||
*
|
||||
* PROPERTIES
|
||||
*
|
||||
* A <gaia-color-picker> element defines the following JavaScript properties:
|
||||
*
|
||||
* value: a read/write string property that reflects the "value" attribute.
|
||||
*
|
||||
* r: the red component of the current color. A read-only integer 0-255.
|
||||
*
|
||||
* g: the green component of the current color. A read-only integer 0-255.
|
||||
*
|
||||
* b: the red component of the current color. A read-only integer 0-255.
|
||||
*
|
||||
* h: the hue the current color. A read-only number 0 - 360.
|
||||
*
|
||||
* s: the saturation of the current color. A read-only number 0.0 - 1.0.
|
||||
*
|
||||
* v: the value of the current color. A read-only number 0.0 - 1.0.
|
||||
*
|
||||
* EVENTS
|
||||
*
|
||||
* When the user interacts with a <gaia-color-picker> component to select a
|
||||
* new color, the component emits a "change" event. There are no details in
|
||||
* the event object. The changed color is available through the properties
|
||||
* listed above.
|
||||
*
|
||||
* METHODS
|
||||
*
|
||||
* A <gaia-color-picker> element defines the following methods:
|
||||
*
|
||||
* resize(): call this function when the size of the component has changed
|
||||
* to tell it to resize its internal canvases and re-draw its color wheel.
|
||||
* You should call this on window.resize events and any time the document
|
||||
* layout changes in such a way that the component size changes. Note that
|
||||
* this recomputes all the pixels of hte hue/saturation color disk and is
|
||||
* a relatively expensive operation.
|
||||
*
|
||||
* STATIC FUNCTIONS
|
||||
*
|
||||
* This module defines color space conversion utility functions as
|
||||
* properties of the GaiaColorPicker constructor:
|
||||
*
|
||||
* GaiaColorPicker.rgb2hsv(red, green, blue): returns [hue, saturation, value]
|
||||
*
|
||||
* GaiaColorPicker.hsv2rgb(hue, saturation, value): returns [red, green, blue]
|
||||
*
|
||||
* GaiaColorPicker.rgb2hex(red, green, blue): returns hex color string "#rrggbb"
|
||||
*
|
||||
* GaiaColorPicker.hex2rgb("#rrggbb"): returns [red, green, blue]
|
||||
*
|
||||
* GaiaColorPicker.hsv2hex(hue, saturation, value): returns "#rrggbb"
|
||||
*
|
||||
* GaiaColorPicker.hex2hsv("#rrggbb"): returns [hue, saturation, value]
|
||||
*/
|
||||
(function(exports) {
|
||||
'use strict';
|
||||
/*jshint esnext:true*/
|
||||
|
||||
var GaiaColorPicker = document.registerElement('gaia-color-picker', {
|
||||
prototype: Object.create(HTMLElement.prototype, {
|
||||
|
||||
createdCallback: {
|
||||
value: function() { this._impl = new ColorPickerImpl(this); }
|
||||
},
|
||||
|
||||
attachedCallback: {
|
||||
value: function() { this._impl.attach(); }
|
||||
},
|
||||
|
||||
detachedCallback: {
|
||||
value: function() { this._impl.detach(); }
|
||||
},
|
||||
|
||||
attributeChangedCallback: {
|
||||
value: function(name, oldval, newval) {
|
||||
// If the user deletes the attribute we will do nothing, since
|
||||
// there isn't really a reasonable default value to revert to.
|
||||
if (name === 'value' && newval !== null) {
|
||||
this.value = newval;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
resize: {
|
||||
value: function() { this._impl.resize(); }
|
||||
},
|
||||
|
||||
h: {
|
||||
get: function() { return this._impl.h; }
|
||||
},
|
||||
|
||||
s: {
|
||||
get: function() { return this._impl.s; }
|
||||
},
|
||||
|
||||
v: {
|
||||
get: function() { return this._impl.v; }
|
||||
},
|
||||
|
||||
r: {
|
||||
get: function() { return this._impl.r; }
|
||||
},
|
||||
|
||||
g: {
|
||||
get: function() { return this._impl.g; }
|
||||
},
|
||||
|
||||
b: {
|
||||
get: function() { return this._impl.b; }
|
||||
},
|
||||
|
||||
value: {
|
||||
get: function() { return this._impl.hexColorString; },
|
||||
set: function(newval) { this._impl.setHexColorString(newval); }
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// Expose the utility functions through the constructor
|
||||
GaiaColorPicker.hsv2rgb = hsv2rgb;
|
||||
GaiaColorPicker.rgb2hsv = rgb2hsv;
|
||||
GaiaColorPicker.hsv2hex = hsv2hex;
|
||||
GaiaColorPicker.rgb2hex = rgb2hex;
|
||||
GaiaColorPicker.hex2rgb = hex2rgb;
|
||||
GaiaColorPicker.hex2hsv = hex2hsv;
|
||||
|
||||
// Export the constructor
|
||||
exports.GaiaColorPicker = GaiaColorPicker;
|
||||
|
||||
/*
|
||||
* Implementation details below
|
||||
*/
|
||||
|
||||
const TEMPLATE = `
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
#container {
|
||||
display: block;
|
||||
position: relative; /* so that we can absolutely position content */
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mark {
|
||||
display: block;
|
||||
position: absolute;
|
||||
border: solid white 2px;
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
#popup {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 65px;
|
||||
height: 65px;
|
||||
border: solid white 3px;
|
||||
border-radius: 50%;
|
||||
border-bottom-right-radius: 3px;
|
||||
transform: translate(-50%, -150%) rotate(45deg);
|
||||
box-shadow: 2px 2px 5px rgba(0, 0, 0, .6);
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.preview {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
border: solid #bbb 1px;
|
||||
}
|
||||
|
||||
</style>
|
||||
<div id="container">
|
||||
<canvas id="canvas"></canvas>
|
||||
<div class="mark" id="huemark"><div class="preview"></div></div>
|
||||
<div class="mark" id="valuemark"><div class="preview"></div></div>
|
||||
<div id="popup"><div class="preview" id="swatch"></div></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const R0 = 0.10; // The inner radius of the hue/saturation ring
|
||||
const R1 = 0.70; // The outer radius of the hue/saturation ring
|
||||
const R2 = 0.98; // The outer radius of the value ring
|
||||
const DEGREES = 180/Math.PI; // Convert radians to degrees
|
||||
const RADIANS = Math.PI/180; // Convert degrees to radians
|
||||
const PI = Math.PI;
|
||||
const TWOPI = 2 * Math.PI;
|
||||
const HALFPI = Math.PI/2;
|
||||
|
||||
function ColorPickerImpl(element) {
|
||||
// Lazily create the template the first time a color picker is created
|
||||
if (!ColorPickerImpl.template) {
|
||||
ColorPickerImpl.template = document.createElement('template');
|
||||
ColorPickerImpl.template.innerHTML = TEMPLATE;
|
||||
}
|
||||
|
||||
// This is the <gaia-color-picker> element we are the implementation for
|
||||
this.element = element;
|
||||
|
||||
// Create the elements we need in the shadow DOM
|
||||
this.shadow = element.createShadowRoot();
|
||||
this.shadow.appendChild(ColorPickerImpl.template.content.cloneNode(true));
|
||||
|
||||
// Get references to the elements we'll need to manipulate
|
||||
this.canvas = this.shadow.getElementById('canvas');
|
||||
this.huemark = this.shadow.getElementById('huemark');
|
||||
this.valuemark = this.shadow.getElementById('valuemark');
|
||||
this.popup = this.shadow.getElementById('popup');
|
||||
this.swatch = this.shadow.getElementById('swatch');
|
||||
|
||||
// And create the offscreen canvas element that we use for drawing
|
||||
this.offscreen = document.createElement('canvas');
|
||||
|
||||
// Start off pure white
|
||||
this.h = 0;
|
||||
this.s = 0.0;
|
||||
this.v = 1.0;
|
||||
this.r = 255;
|
||||
this.g = 255;
|
||||
this.b = 255;
|
||||
this.hexColorString = '#ffffff';
|
||||
|
||||
// But if there is a "value" attribute on the element, use that
|
||||
var initialValue = this.element.getAttribute('value');
|
||||
if (initialValue) {
|
||||
this.setHexColorString(initialValue);
|
||||
}
|
||||
|
||||
// Register event handlers for user interaction
|
||||
this.shadow.addEventListener('touchstart', this);
|
||||
this.shadow.addEventListener('touchmove', this);
|
||||
this.shadow.addEventListener('touchend', this);
|
||||
this.shadow.addEventListener('mousedown', this);
|
||||
this.mouseEventHandlerRegistered = true;
|
||||
|
||||
// If we're already in the document, do the rest now
|
||||
if (this.element.parentNode) {
|
||||
this.attach();
|
||||
}
|
||||
else {
|
||||
this.attached = false;
|
||||
}
|
||||
}
|
||||
|
||||
ColorPickerImpl.prototype.attach = function() {
|
||||
this.attached = true;
|
||||
this.resize();
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.detach = function() {
|
||||
this.attached = false;
|
||||
this.canvas.width = 0;
|
||||
this.offscreen.width = 0;
|
||||
this.context = null;
|
||||
this.offctx = null;
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.resize = function() {
|
||||
//
|
||||
// When the color picker is first added to the document, or when we notice
|
||||
// that its size has changed, we resize the canvas elements and pre-draw
|
||||
// as much of the color wheel as we can.
|
||||
//
|
||||
// Drawing a color wheel is a fairly expensive operation and as the user
|
||||
// moves her finger across the component we'll have to redraw it quickly.
|
||||
// To optimize this, we use two canvas layers and pre-draw as much as
|
||||
// possible. On the bottom "hue layer" we draw only bright colors with
|
||||
// value 1. On the top "value layer" we draw transparent black, with
|
||||
// opacity set to modify the apparent value of the colors below.
|
||||
//
|
||||
// In this function we will pre-draw the hue/saturation plane for value=1
|
||||
// on the hue layer. This is an expensive operation that involves setting
|
||||
// tens of thousands of individual pixels in an ImageData object. Then,
|
||||
// when the user interacts with the color picker to change the value to v,
|
||||
// we can change the apparent value of the entire hue/saturation plane by
|
||||
// drawing a single circle of transparent black with opacity (1 - v) in
|
||||
// the value plane. A single draw operation in the value plane will make
|
||||
// it look like we've changed the value of each individual pixel in the
|
||||
// hue/saturation wheel.
|
||||
//
|
||||
// Similarly, this function will also pre-draw the outer value ring of the
|
||||
// color wheel in the value layer. We will draw wedges of transparent black
|
||||
// with opacity ranging from 1 down to 0. Then, when the user interacts
|
||||
// with the color wheel and we need to display all possible values of a
|
||||
// given hue/saturation color, all we need to do is draw a solid ring of
|
||||
// that color in the hue plane, and because of the pre-drawn gradient in
|
||||
// the value plane, the user will see all possible values of that
|
||||
// hue/saturation combination.
|
||||
//
|
||||
// The upshot is that all the tricky and time-consuming drawing is done
|
||||
// here only when we resize the canvas. And updating the component visuals
|
||||
// when the user interacts with it is fast and nearly trivial.
|
||||
//
|
||||
|
||||
// Compute our dimensions. Note that we want to use device pixels
|
||||
// not CSS pixels.
|
||||
this.dpr = window.devicePixelRatio;
|
||||
this.width = this.element.clientWidth * this.dpr;
|
||||
this.height = this.element.clientHeight * this.dpr;
|
||||
|
||||
// Canvas dimension in device pixels: width and height are the same
|
||||
this.canvasSize = Math.min(this.width, this.height);
|
||||
this.radius = this.canvasSize / 2;
|
||||
this.r0 = Math.round(R0 * this.radius); // inner radius of hue ring
|
||||
this.r1 = Math.round(R1 * this.radius); // outer radius of hue ring
|
||||
this.r2 = Math.round(R2 * this.radius); // outer radius of value ring
|
||||
|
||||
// The center of the square canvas
|
||||
this.cx = this.radius;
|
||||
this.cy = this.radius;
|
||||
|
||||
// Canvas screen size in CSS pixels
|
||||
this.canvasScreenSize = this.canvasSize / this.dpr;
|
||||
|
||||
// Canvas screen position in CSS pixels
|
||||
this.canvasLeft = (this.element.clientWidth - this.canvasScreenSize) / 2;
|
||||
this.canvasTop = (this.element.clientHeight - this.canvasScreenSize) / 2;
|
||||
|
||||
// If we are not in the document yet, or have 0 size, there is nothing
|
||||
// to do here.
|
||||
if (!this.attached || this.width === 0 || this.height === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the onscreen and offscreen canvas dimensions
|
||||
this.canvas.width = this.canvas.height = this.canvasSize;
|
||||
this.offscreen.width = this.offscreen.height = this.canvasSize;
|
||||
|
||||
// Set the onscreen canvas size and position.
|
||||
this.canvas.style.left = this.canvasLeft + 'px';
|
||||
this.canvas.style.top = this.canvasTop + 'px';
|
||||
this.canvas.style.width = this.canvasScreenSize + 'px';
|
||||
this.canvas.style.height = this.canvasScreenSize + 'px';
|
||||
|
||||
// Get the canvas contexts.
|
||||
this.context = this.canvas.getContext('2d', { alpha: false });
|
||||
this.offctx = this.offscreen.getContext('2d');
|
||||
|
||||
// Do the pre-drawing into the offscreen canvas
|
||||
this.predraw();
|
||||
|
||||
// And do the regular drawing by calling updateState() to force a redraw
|
||||
// We do not generate a change event in this case
|
||||
this.updateState(this.h, this.s, this.v, false, true);
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.handleEvent = function(e) {
|
||||
var box = this.canvas.getBoundingClientRect();
|
||||
var x, y, hit;
|
||||
|
||||
// Get the mouse or touch coordinates from the event, convert to
|
||||
// be relative to this element, and convert from CSS to device pixels
|
||||
if (e instanceof MouseEvent) {
|
||||
x = (e.clientX - box.left) * this.dpr;
|
||||
y = (e.clientY - box.top) * this.dpr;
|
||||
}
|
||||
else if (e instanceof TouchEvent) {
|
||||
// if we ever get a touch event stop listening for mouse events
|
||||
// we never want to receive both kinds.
|
||||
if (this.mouseEventHandlerRegistered) {
|
||||
this.shadow.removeEventListener('mousedown', this);
|
||||
this.mouseEventHandlerRegistered = false;
|
||||
}
|
||||
var touch = e.changedTouches[0];
|
||||
x = (touch.clientX - box.left) * this.dpr;
|
||||
y = (touch.clientY - box.top) * this.dpr;
|
||||
}
|
||||
|
||||
if (e.type === 'touchstart' || e.type === 'mousedown') {
|
||||
if (e.type === 'mousedown') {
|
||||
window.addEventListener('mousemove', this, true);
|
||||
window.addEventListener('mouseup', this, true);
|
||||
}
|
||||
|
||||
hit = this.hittest(x, y);
|
||||
if (hit === 'hue') {
|
||||
this.hitHueSaturation(x, y);
|
||||
this.dragging = 'hue';
|
||||
}
|
||||
else if (hit === 'value') {
|
||||
this.hitValue(x, y);
|
||||
this.dragging = 'value';
|
||||
}
|
||||
if (this.dragging) {
|
||||
this.movePopup();
|
||||
this.showPopup();
|
||||
}
|
||||
}
|
||||
else if (this.dragging &&
|
||||
(e.type === 'touchmove' || e.type === 'mousemove'))
|
||||
{
|
||||
hit = this.hittest(x, y);
|
||||
if (hit === this.dragging) {
|
||||
if (hit === 'hue') {
|
||||
this.hitHueSaturation(x, y);
|
||||
}
|
||||
else if (hit === 'value') {
|
||||
this.hitValue(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (e.type === 'touchend' || e.type === 'mouseup') {
|
||||
if (e.type === 'mouseup') {
|
||||
window.removeEventListener('mousemove', this, true);
|
||||
window.removeEventListener('mouseup', this, true);
|
||||
}
|
||||
this.dragging = null;
|
||||
this.hidePopup();
|
||||
}
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.setHexColorString = function(hexstring) {
|
||||
// If the hexstring is the same as the current value, do nothing.
|
||||
// This is important to prevent recursion since calling this function
|
||||
// sets the HTML attribute, and setting the HTML attribute calls
|
||||
// this function.
|
||||
if (hexstring === this.hexColorString) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the new value
|
||||
var rgb = hex2rgb(hexstring);
|
||||
|
||||
// Convert to hsv and update the color picker with the new color.
|
||||
// Don't emit a change event for this update, however, since this
|
||||
// is used for changes caused by JS code, not by the user.
|
||||
this.updateState(...rgb2hsv(...rgb), false);
|
||||
|
||||
// Make sure this new hexstring is visible through the attribute, too.
|
||||
this.element.setAttribute('value', this.hexColorString);
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.updateState = function(h, s, v,
|
||||
notify = true,
|
||||
force = false)
|
||||
{
|
||||
var changed = force || (h !== this.h) || (s !== this.s) || (v !== this.v);
|
||||
|
||||
if (!changed) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.h = h;
|
||||
this.s = s;
|
||||
this.v = v;
|
||||
[this.r, this.g, this.b] = hsv2rgb(h, s, v);
|
||||
this.hexColorString = rgb2hex(this.r, this.g, this.b);
|
||||
|
||||
if (this.attached) {
|
||||
if (!this.redrawRequested) {
|
||||
this.redrawRequested = requestAnimationFrame(function(t) {
|
||||
this.redrawRequested = null;
|
||||
this.draw();
|
||||
this.setMarkColor();
|
||||
this.moveHueMark();
|
||||
this.moveValueMark();
|
||||
this.movePopup();
|
||||
|
||||
// Don't send change events out any faster than once per frame
|
||||
// even if touch events are coming in faster than that.
|
||||
if (notify) {
|
||||
this.element.dispatchEvent(new Event('change'));
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Draw the unchanging parts of the color wheel into the offscreen canvas
|
||||
// The center of the wheel is the value=1 plane of the HSV color cylinder.
|
||||
// Outside of this center wheel is a gradient of transparent black colors.
|
||||
// Note that we only have to call predraw when the size of the canvas changes.
|
||||
ColorPickerImpl.prototype.predraw = function() {
|
||||
var r0 = this.r0;
|
||||
var r1 = this.r1;
|
||||
var r2 = this.r2;
|
||||
var width = 2 * r2;
|
||||
var height = 2 * r2;
|
||||
var conversion = 1 / (r1 - r0); // Precompute for speed
|
||||
|
||||
// Get the rectangle of the canvas inside r2
|
||||
var imagedata = this.offctx.getImageData(this.cx - r2,
|
||||
this.cy - r2,
|
||||
width, height);
|
||||
|
||||
// And loop through all of the pixels in the rectangle
|
||||
var pixels = imagedata.data;
|
||||
for(var y = 0; y < height; y++) {
|
||||
var dy = y - r2;
|
||||
var dy2 = dy * dy;
|
||||
|
||||
for(var x = 0; x < width; x++) {
|
||||
var dx = x - r2;
|
||||
var distance = Math.sqrt(dx*dx + dy2);
|
||||
|
||||
// If this pixel is outside skip to the next one
|
||||
if (distance > r2) {
|
||||
if (dx > 0) { // If we're on the right, we're done with this line
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// Otherwise, skip ahead to the first pixel on the circle
|
||||
var newx = Math.ceil(r2 - Math.sqrt(r2*r2 - dy2))-1;
|
||||
// make sure we're not moving backwards and starting an
|
||||
// infinite loop
|
||||
if (newx > x) {
|
||||
x = newx;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var index = (y * width + x) * 4;
|
||||
|
||||
if (distance > r1) {
|
||||
// If we are between r1 and r2, set the pixel to the appropriate
|
||||
// transparent color to create a gradient for the value ring.
|
||||
// figure out the angle to (dx,dy) and convert to our value
|
||||
var angle = Math.atan2(dy, -dx) + HALFPI;
|
||||
if (angle < 0) {
|
||||
angle += TWOPI;
|
||||
}
|
||||
var value = angle/TWOPI;
|
||||
var opacity = Math.round((1 - value) * 255);
|
||||
|
||||
pixels[index] = 0;
|
||||
pixels[index + 1] = 0;
|
||||
pixels[index + 2] = 0;
|
||||
pixels[index + 3] = opacity;
|
||||
}
|
||||
else {
|
||||
// If we are inside r1, set the pixel to the appropriate
|
||||
// hue/saturation.
|
||||
|
||||
// If the pixel is inside r0, make it pure white
|
||||
if (distance < r0) {
|
||||
pixels[index] = 255;
|
||||
pixels[index+1] = 255;
|
||||
pixels[index+2] = 255;
|
||||
pixels[index+3] = 255;
|
||||
}
|
||||
else {
|
||||
// Convert dx, dy to polar (hue, saturation)
|
||||
var hue = Math.atan2(-dy, dx) * DEGREES;
|
||||
if (hue < 0) {
|
||||
hue += 360;
|
||||
}
|
||||
var saturation = (distance - r0) * conversion;
|
||||
|
||||
// Convert that color to rgb
|
||||
var rgb = hsv2rgb(hue, saturation, 1.0);
|
||||
pixels[index] = rgb[0];
|
||||
pixels[index + 1] = rgb[1];
|
||||
pixels[index + 2] = rgb[2];
|
||||
pixels[index + 3] = 255; // Opaque
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the pixels back into the offscreen canvas for use by this.draw()
|
||||
this.offctx.putImageData(imagedata, this.cx - r2, this.cy - r2);
|
||||
};
|
||||
|
||||
// Return 'hue' if (x, y) is in the hue/saturation disk.
|
||||
// Return 'value' if (x, y) is in the value ring.
|
||||
// Otherwise return null.
|
||||
ColorPickerImpl.prototype.hittest = function(x, y) {
|
||||
var dx = x - this.cy;
|
||||
var dy = y - this.cy;
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
if (d < this.r1) {
|
||||
return 'hue';
|
||||
}
|
||||
else if (d < this.r2) {
|
||||
return 'value';
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.hitHueSaturation = function(x, y) {
|
||||
var dx = x - this.cx;
|
||||
var dy = y - this.cy;
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
var hue, saturation;
|
||||
|
||||
// user clicked on the hue/saturation disc
|
||||
if (d >= this.r0) {
|
||||
// User clicked on the colorful part of the ring
|
||||
hue = Math.atan2(-dy, dx) * DEGREES;
|
||||
if (hue < 0) {
|
||||
hue += 360;
|
||||
}
|
||||
saturation = (d - this.r0) / (this.r1 - this.r0);
|
||||
}
|
||||
else {
|
||||
// user clicked on the white circle in the middle
|
||||
hue = 0;
|
||||
saturation = 0;
|
||||
}
|
||||
|
||||
this.updateState(hue, saturation, this.v);
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.hitValue = function(x, y) {
|
||||
var dx = x - this.cx;
|
||||
var dy = y - this.cy;
|
||||
var angle = Math.atan2(-dy, dx) - HALFPI;
|
||||
if (angle < 0) {
|
||||
angle += TWOPI;
|
||||
}
|
||||
var value = angle / TWOPI;
|
||||
this.updateState(this.h, this.s, value);
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.draw = function() {
|
||||
var opacity = 1 - this.v;
|
||||
var gray = Math.round(opacity * 255);
|
||||
|
||||
// Fill the outer value ring with the current hue and saturation
|
||||
// at value = 1.
|
||||
this.context.beginPath();
|
||||
this.context.arc(this.cx, this.cy, this.r2, 0, TWOPI);
|
||||
this.context.fillStyle = hsv2hex(this.h, this.s, 1);
|
||||
this.context.fill();
|
||||
|
||||
// Overlap it with the offscreen canvas
|
||||
this.context.drawImage(this.offscreen, 0, 0);
|
||||
|
||||
// Now draw over the hue/saturation ring with a translucent color
|
||||
// to reduce the value to the appropriate level.
|
||||
this.context.beginPath();
|
||||
this.context.arc(this.cx, this.cy, this.r1, 0, TWOPI);
|
||||
this.context.fillStyle = 'rgba(0,0,0,' + opacity + ')';
|
||||
this.context.fill();
|
||||
|
||||
// Set the border width
|
||||
this.context.lineWidth = 1 * this.dpr;
|
||||
|
||||
// Draw an inner border with a color that contrasts with the current value
|
||||
this.context.strokeStyle = rgb2hex(gray, gray, gray);
|
||||
this.context.stroke();
|
||||
|
||||
// Draw an outer border
|
||||
this.context.beginPath();
|
||||
this.context.arc(this.cx, this.cy, this.r2, 0, TWOPI);
|
||||
this.context.strokeStyle = '#000';
|
||||
this.context.stroke();
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.moveValueMark = function() {
|
||||
// Move the marker that indicates the currently selected value
|
||||
var angle = this.v * TWOPI + HALFPI;
|
||||
|
||||
var r = (this.r1 + this.r2)/2;
|
||||
var x = this.cx + r * Math.cos(angle);
|
||||
var y = this.cy - r * Math.sin(angle);
|
||||
x = this.canvasLeft + x / this.dpr;
|
||||
y = this.canvasTop + y / this.dpr;
|
||||
this.valuemark.style.left = x + 'px';
|
||||
this.valuemark.style.top = y + 'px';
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.moveHueMark = function() {
|
||||
// Compute the position of the hue marker and move it
|
||||
var x = this.cx, y = this.cy;
|
||||
|
||||
if (this.s !== 0) {
|
||||
var d = this.r0 + this.s * (this.r1 - this.r0);
|
||||
var angle = this.h * RADIANS;
|
||||
|
||||
x += d * Math.cos(angle);
|
||||
y -= d * Math.sin(angle);
|
||||
}
|
||||
|
||||
x = this.canvasLeft + x / this.dpr;
|
||||
y = this.canvasTop + y / this.dpr;
|
||||
|
||||
this.huemark.style.left = x + 'px';
|
||||
this.huemark.style.top = y + 'px';
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.movePopup = function() {
|
||||
if (this.dragging == 'hue') {
|
||||
this.popup.style.left = this.huemark.style.left;
|
||||
this.popup.style.top = this.huemark.style.top;
|
||||
}
|
||||
if (this.dragging == 'value') {
|
||||
this.popup.style.left = this.valuemark.style.left;
|
||||
this.popup.style.top = this.valuemark.style.top;
|
||||
}
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.setMarkColor = function() {
|
||||
this.huemark.style.backgroundColor = this.hexColorString;
|
||||
this.valuemark.style.backgroundColor = this.hexColorString;
|
||||
this.swatch.style.backgroundColor = this.hexColorString;
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.showPopup = function() {
|
||||
this.popup.style.display = 'block';
|
||||
};
|
||||
|
||||
ColorPickerImpl.prototype.hidePopup = function() {
|
||||
this.popup.style.display = 'none';
|
||||
};
|
||||
|
||||
/*
|
||||
* Color conversion utilities
|
||||
*/
|
||||
|
||||
//
|
||||
// Convert a (r,g,b) color into (hue, saturation, value)
|
||||
//
|
||||
// See http://en.wikipedia.org/wiki/HSL_and_HSV for the details
|
||||
// of the conversion algorithm.
|
||||
//
|
||||
// Note that if r, g, and b are all multiplied by x (0 <= x <= 1)
|
||||
// the hue and saturation are unchanged in this algorithm and the value
|
||||
// is also multiplied by x. This means that if a color is overlaid with
|
||||
// a translucent black with opacity a, it is the same as reducing the
|
||||
// value of the color by a factor of (1-a), and that the hue and saturation
|
||||
// of the color are unchanged by the overlay. This fact is critical to the
|
||||
// way we render the color wheel for this color picker component.
|
||||
//
|
||||
function rgb2hsv(r, g, b) {
|
||||
r = r/255;
|
||||
g = g/255;
|
||||
b = b/255;
|
||||
|
||||
var min = Math.min(r, g, b);
|
||||
var max = Math.max(r, g, b);
|
||||
var chroma = max - min;
|
||||
|
||||
var hue, saturation, value;
|
||||
|
||||
// Compute the hue
|
||||
if (chroma === 0) {
|
||||
hue = 0; // technically hue is undefined in this case
|
||||
}
|
||||
else {
|
||||
if (max === r) {
|
||||
hue = (g - b) / chroma;
|
||||
if (hue < 0) {
|
||||
hue += 6;
|
||||
}
|
||||
}
|
||||
else if (max === g) {
|
||||
hue = (b - r) / chroma + 2;
|
||||
}
|
||||
else { // max === b
|
||||
hue = (r - g) / chroma + 4;
|
||||
}
|
||||
}
|
||||
|
||||
// convert hue to degrees from 0 to 360;
|
||||
hue *= 60;
|
||||
|
||||
// Value and saturation are easy:
|
||||
value = max;
|
||||
saturation = (value === 0) ? 0 : chroma / value;
|
||||
|
||||
return [hue, saturation, value];
|
||||
}
|
||||
|
||||
// Convert a (hue, saturation, value) color to (r, g, b)
|
||||
function hsv2rgb(h, s, v) {
|
||||
var chroma = s * v;
|
||||
var hprime = h / 60;
|
||||
var x = chroma * (1 - Math.abs(hprime % 2 - 1));
|
||||
var r, g, b;
|
||||
|
||||
switch(Math.floor(hprime)) {
|
||||
case 0:
|
||||
r = chroma;
|
||||
g = x;
|
||||
b = 0;
|
||||
break;
|
||||
case 1:
|
||||
r = x;
|
||||
g = chroma;
|
||||
b = 0;
|
||||
break;
|
||||
case 2:
|
||||
r = 0;
|
||||
g = chroma;
|
||||
b = x;
|
||||
break;
|
||||
case 3:
|
||||
r = 0;
|
||||
g = x;
|
||||
b = chroma;
|
||||
break;
|
||||
case 4:
|
||||
r = x;
|
||||
g = 0;
|
||||
b = chroma;
|
||||
break;
|
||||
case 5:
|
||||
r = chroma;
|
||||
g = 0;
|
||||
b = x;
|
||||
break;
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
var m = v - chroma;
|
||||
r = Math.round((r + m) * 255);
|
||||
g = Math.round((g + m) * 255);
|
||||
b = Math.round((b + m) * 255);
|
||||
|
||||
return [r, g, b];
|
||||
}
|
||||
|
||||
// Convert a (r, g, b) color triplet to "#rrggbb" hexadecimal form
|
||||
function rgb2hex(r, g, b) {
|
||||
r = r.toString(16);
|
||||
g = g.toString(16);
|
||||
b = b.toString(16);
|
||||
|
||||
if (r.length === 1) {
|
||||
r = '0' + r;
|
||||
}
|
||||
if (g.length === 1) {
|
||||
g = '0' + g;
|
||||
}
|
||||
if (b.length === 1) {
|
||||
b = '0' + b;
|
||||
}
|
||||
|
||||
return '#' + r + g + b;
|
||||
}
|
||||
|
||||
// Convert a "#rrggbb" color string to a (r, g, b) triplet.
|
||||
function hex2rgb(hex) {
|
||||
if (!/^#[0-9a-fA-F]{3}$|^#[0-9a-fA-F]{6}$/.test(hex)) {
|
||||
throw new TypeError('Invalid color specification: "' + hex + '"');
|
||||
}
|
||||
|
||||
var r, g, b;
|
||||
if (hex.length === 4) {
|
||||
r = hex[1] + hex[1];
|
||||
g = hex[2] + hex[2];
|
||||
b = hex[3] + hex[3];
|
||||
}
|
||||
else {
|
||||
r = hex.substring(1, 3);
|
||||
g = hex.substring(3, 5);
|
||||
b = hex.substring(5, 7);
|
||||
}
|
||||
|
||||
return [parseInt(r, 16), parseInt(g, 16), parseInt(b, 16)];
|
||||
}
|
||||
|
||||
// Convert a (hue, saturation, value) color to "#rrggbb" form.
|
||||
function hsv2hex(h, s, v) {
|
||||
return rgb2hex(...hsv2rgb(h, s, v));
|
||||
}
|
||||
|
||||
// Convert a "#rrggbb" color string to a (hue, saturation, value) triplet
|
||||
function hex2hsv(hex) {
|
||||
return rgb2hsv(...hex2rgb(hex));
|
||||
}
|
||||
}(window));
|
||||
28
gaia/distros/spark/apps/studio/bower_components/gaia-component/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"name": "gaia-component",
|
||||
"version": "0.3.7",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "gaia-component.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"README.md",
|
||||
"package.json",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"homepage": "https://github.com/gaia-components/gaia-component",
|
||||
"_release": "0.3.7",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.3.7",
|
||||
"commit": "097f53f2dbcac4124aa8f6be731c3fc6c8ec0507"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-component.git",
|
||||
"_target": "~0.3.0",
|
||||
"_originalSource": "gaia-components/gaia-component"
|
||||
}
|
||||
18
gaia/distros/spark/apps/studio/bower_components/gaia-component/bower.json
vendored
Executable file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "gaia-component",
|
||||
"version": "0.3.7",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "gaia-component.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"README.md",
|
||||
"package.json",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
407
gaia/distros/spark/apps/studio/bower_components/gaia-component/gaia-component.js
vendored
Executable file
|
|
@ -0,0 +1,407 @@
|
|||
/* globals define */
|
||||
;(function(define){'use strict';define(function(require,exports,module){
|
||||
/**
|
||||
* Locals
|
||||
*/
|
||||
var textContent = Object.getOwnPropertyDescriptor(Node.prototype,
|
||||
'textContent');
|
||||
var innerHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
|
||||
var removeAttribute = Element.prototype.removeAttribute;
|
||||
var setAttribute = Element.prototype.setAttribute;
|
||||
var noop = function() {};
|
||||
|
||||
/**
|
||||
* Register a new component.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} props
|
||||
* @return {constructor}
|
||||
* @public
|
||||
*/
|
||||
exports.register = function(name, props) {
|
||||
var baseProto = getBaseProto(props.extends);
|
||||
|
||||
// Clean up
|
||||
delete props.extends;
|
||||
|
||||
// Pull out CSS that needs to be in the light-dom
|
||||
if (props.template) {
|
||||
var output = processCss(props.template, name);
|
||||
|
||||
props.template = document.createElement('template');
|
||||
props.template.innerHTML = output.template;
|
||||
props.lightCss = output.lightCss;
|
||||
|
||||
props.globalCss = props.globalCss || '';
|
||||
props.globalCss += output.globalCss;
|
||||
}
|
||||
|
||||
// Inject global CSS into the document,
|
||||
// and delete as no longer needed
|
||||
injectGlobalCss(props.globalCss);
|
||||
delete props.globalCss;
|
||||
|
||||
// Merge base getter/setter attributes with the user's,
|
||||
// then define the property descriptors on the prototype.
|
||||
var descriptors = mixin(props.attrs || {}, base.descriptors);
|
||||
|
||||
// Store the orginal descriptors somewhere
|
||||
// a little more private and delete the original
|
||||
props._attrs = props.attrs;
|
||||
delete props.attrs;
|
||||
|
||||
// Create the prototype, extended from base and
|
||||
// define the descriptors directly on the prototype
|
||||
var proto = createProto(baseProto, props);
|
||||
Object.defineProperties(proto, descriptors);
|
||||
|
||||
// Register the custom-element and return the constructor
|
||||
try {
|
||||
return document.registerElement(name, { prototype: proto });
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var base = {
|
||||
properties: {
|
||||
GaiaComponent: true,
|
||||
attributeChanged: noop,
|
||||
attached: noop,
|
||||
detached: noop,
|
||||
created: noop,
|
||||
|
||||
createdCallback: function() {
|
||||
if (this.rtl) { addDirObserver(); }
|
||||
injectLightCss(this);
|
||||
this.created();
|
||||
},
|
||||
|
||||
/**
|
||||
* It is very common to want to keep object
|
||||
* properties in-sync with attributes,
|
||||
* for example:
|
||||
*
|
||||
* el.value = 'foo';
|
||||
* el.setAttribute('value', 'foo');
|
||||
*
|
||||
* So we support an object on the prototype
|
||||
* named 'attrs' to provide a consistent
|
||||
* way for component authors to define
|
||||
* these properties. When an attribute
|
||||
* changes we keep the attr[name]
|
||||
* up-to-date.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String||null} from
|
||||
* @param {String||null} to
|
||||
*/
|
||||
attributeChangedCallback: function(name, from, to) {
|
||||
var prop = toCamelCase(name);
|
||||
if (this._attrs && this._attrs[prop]) { this[prop] = to; }
|
||||
this.attributeChanged(name, from, to);
|
||||
},
|
||||
|
||||
attachedCallback: function() { this.attached(); },
|
||||
detachedCallback: function() { this.detached(); },
|
||||
|
||||
/**
|
||||
* A convenient method for setting up
|
||||
* a shadow-root using the defined template.
|
||||
*
|
||||
* @return {ShadowRoot}
|
||||
*/
|
||||
setupShadowRoot: function() {
|
||||
if (!this.template) { return; }
|
||||
var node = document.importNode(this.template.content, true);
|
||||
this.createShadowRoot().appendChild(node);
|
||||
return this.shadowRoot;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets an attribute internally
|
||||
* and externally. This is so that
|
||||
* we can style internal shadow-dom
|
||||
* content.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String} value
|
||||
*/
|
||||
setAttr: function(name, value) {
|
||||
var internal = this.shadowRoot.firstElementChild;
|
||||
setAttribute.call(internal, name, value);
|
||||
setAttribute.call(this, name, value);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes an attribute internally
|
||||
* and externally. This is so that
|
||||
* we can style internal shadow-dom
|
||||
* content.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {String} value
|
||||
*/
|
||||
removeAttr: function(name) {
|
||||
var internal = this.shadowRoot.firstElementChild;
|
||||
removeAttribute.call(internal, name);
|
||||
removeAttribute.call(this, name);
|
||||
}
|
||||
},
|
||||
|
||||
descriptors: {
|
||||
textContent: {
|
||||
set: function(value) {
|
||||
textContent.set.call(this, value);
|
||||
if (this.lightStyle) { this.appendChild(this.lightStyle); }
|
||||
},
|
||||
|
||||
get: function() {
|
||||
return textContent.get();
|
||||
}
|
||||
},
|
||||
|
||||
innerHTML: {
|
||||
set: function(value) {
|
||||
innerHTML.set.call(this, value);
|
||||
if (this.lightStyle) { this.appendChild(this.lightStyle); }
|
||||
},
|
||||
|
||||
get: innerHTML.get
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The default base prototype to use
|
||||
* when `extends` is undefined.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var defaultPrototype = createProto(HTMLElement.prototype, base.properties);
|
||||
|
||||
/**
|
||||
* Returns a suitable prototype based
|
||||
* on the object passed.
|
||||
*
|
||||
* @private
|
||||
* @param {HTMLElementPrototype|undefined} proto
|
||||
* @return {HTMLElementPrototype}
|
||||
*/
|
||||
function getBaseProto(proto) {
|
||||
if (!proto) { return defaultPrototype; }
|
||||
proto = proto.prototype || proto;
|
||||
return !proto.GaiaComponent ?
|
||||
createProto(proto, base.properties) : proto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends the given proto and mixes
|
||||
* in the given properties.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} proto
|
||||
* @param {Object} props
|
||||
* @return {Object}
|
||||
*/
|
||||
function createProto(proto, props) {
|
||||
return mixin(Object.create(proto), props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects presence of shadow-dom
|
||||
* CSS selectors.
|
||||
*
|
||||
* @private
|
||||
* @return {Boolean}
|
||||
*/
|
||||
var hasShadowCSS = (function() {
|
||||
var div = document.createElement('div');
|
||||
try { div.querySelector(':host'); div.querySelector('::content'); return true; }
|
||||
catch (e) { return false; }
|
||||
})();
|
||||
|
||||
/**
|
||||
* Regexs used to extract shadow-css
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var regex = {
|
||||
shadowCss: /(?:\:host|\:\:content)[^{]*\{[^}]*\}/g,
|
||||
':host': /(?:\:host)/g,
|
||||
':host()': /\:host\((.+)\)(?: \:\:content)?/g,
|
||||
':host-context': /\:host-context\((.+)\)([^{,]+)?/g,
|
||||
'::content': /(?:\:\:content)/g
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts the :host and ::content rules
|
||||
* from the shadow-dom CSS and rewrites
|
||||
* them to work from the <style scoped>
|
||||
* injected at the root of the component.
|
||||
*
|
||||
* @private
|
||||
* @return {String}
|
||||
*/
|
||||
function processCss(template, name) {
|
||||
var globalCss = '';
|
||||
var lightCss = '';
|
||||
|
||||
if (!hasShadowCSS) {
|
||||
template = template.replace(regex.shadowCss, function(match) {
|
||||
var hostContext = regex[':host-context'].exec(match);
|
||||
|
||||
if (hostContext) {
|
||||
globalCss += match
|
||||
.replace(regex['::content'], '')
|
||||
.replace(regex[':host-context'], '$1 ' + name + '$2')
|
||||
.replace(/ +/g, ' '); // excess whitespace
|
||||
} else {
|
||||
lightCss += match
|
||||
.replace(regex[':host()'], name + '$1')
|
||||
.replace(regex[':host'], name)
|
||||
.replace(regex['::content'], name);
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
template: template,
|
||||
lightCss: lightCss,
|
||||
globalCss: globalCss
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Some CSS rules, such as @keyframes
|
||||
* and @font-face don't work inside
|
||||
* scoped or shadow <style>. So we
|
||||
* have to put them into 'global'
|
||||
* <style> in the head of the
|
||||
* document.
|
||||
*
|
||||
* @private
|
||||
* @param {String} css
|
||||
*/
|
||||
function injectGlobalCss(css) {
|
||||
if (!css) {return;}
|
||||
var style = document.createElement('style');
|
||||
style.innerHTML = css.trim();
|
||||
headReady().then(function() {
|
||||
document.head.appendChild(style);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolves a promise once document.head is ready.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function headReady() {
|
||||
return new Promise(function(resolve) {
|
||||
if (document.head) { return resolve(); }
|
||||
window.addEventListener('load', function fn() {
|
||||
window.removeEventListener('load', fn);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The Gecko platform doesn't yet have
|
||||
* `::content` or `:host`, selectors,
|
||||
* without these we are unable to style
|
||||
* user-content in the light-dom from
|
||||
* within our shadow-dom style-sheet.
|
||||
*
|
||||
* To workaround this, we clone the <style>
|
||||
* node into the root of the component,
|
||||
* so our selectors are able to target
|
||||
* light-dom content.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function injectLightCss(el) {
|
||||
if (hasShadowCSS) { return; }
|
||||
el.lightStyle = document.createElement('style');
|
||||
el.lightStyle.setAttribute('scoped', '');
|
||||
el.lightStyle.innerHTML = el.lightCss;
|
||||
el.appendChild(el.lightStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert hyphen separated
|
||||
* string to camel-case.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* toCamelCase('foo-bar'); //=> 'fooBar'
|
||||
*
|
||||
* @private
|
||||
* @param {Sring} string
|
||||
* @return {String}
|
||||
*/
|
||||
function toCamelCase(string) {
|
||||
return string.replace(/-(.)/g, function replacer(string, p1) {
|
||||
return p1.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Observer (singleton)
|
||||
*
|
||||
* @type {MutationObserver|undefined}
|
||||
*/
|
||||
var dirObserver;
|
||||
|
||||
/**
|
||||
* Observes the document `dir` (direction)
|
||||
* attribute and dispatches a global event
|
||||
* when it changes.
|
||||
*
|
||||
* Components can listen to this event and
|
||||
* make internal changes if need be.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function addDirObserver() {
|
||||
if (dirObserver) { return; }
|
||||
|
||||
dirObserver = new MutationObserver(onChanged);
|
||||
dirObserver.observe(document.documentElement, {
|
||||
attributeFilter: ['dir'],
|
||||
attributes: true
|
||||
});
|
||||
|
||||
function onChanged(mutations) {
|
||||
document.dispatchEvent(new Event('dirchanged'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the values of all properties from
|
||||
* source object `target` to a target object `source`.
|
||||
* It will return the target object.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} target
|
||||
* @param {Object} source
|
||||
* @returns {Object}
|
||||
*/
|
||||
function mixin(target, source) {
|
||||
for (var key in source) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-component',this));
|
||||
32
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "gaia-dialog",
|
||||
"version": "0.0.6",
|
||||
"homepage": "https://github.com/gaia-components/gaia-dialog",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "gaia-dialog.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"examples",
|
||||
"test",
|
||||
"tests",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"gaia-text-input": "gaia-components/gaia-text-input",
|
||||
"gaia-icons": "gaia-components/gaia-icons#~0.7.4"
|
||||
},
|
||||
"_release": "0.0.6",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.0.6",
|
||||
"commit": "526ea56e2083807b862f696431ac174f7b33f317"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-dialog.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "gaia-components/gaia-dialog"
|
||||
}
|
||||
23
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/bower.json
vendored
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "gaia-dialog",
|
||||
"version": "0.0.6",
|
||||
"homepage": "https://github.com/gaia-components/gaia-dialog",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "gaia-dialog.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"examples",
|
||||
"test",
|
||||
"tests",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"gaia-text-input": "gaia-components/gaia-text-input",
|
||||
"gaia-icons": "gaia-components/gaia-icons#~0.7.4"
|
||||
}
|
||||
}
|
||||
117
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/gaia-dialog-action.js
vendored
Executable file
|
|
@ -0,0 +1,117 @@
|
|||
;(function(define){define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var GaiaDialog = require('gaia-dialog');
|
||||
|
||||
/**
|
||||
* Extend from the `HTMLElement` prototype
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = GaiaDialog.extend();
|
||||
|
||||
/**
|
||||
* Runs when an instance of `GaiaTabs`
|
||||
* is first created.
|
||||
*
|
||||
* The initial value of the `select` attribute
|
||||
* is used to select a tab.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.createdCallback = function() {
|
||||
this.onCreated();
|
||||
this.els.submit = this.shadowRoot.querySelector('.submit');
|
||||
this.els.cancel = this.shadowRoot.querySelector('.cancel');
|
||||
};
|
||||
|
||||
proto.template = `
|
||||
<style>
|
||||
.shadow-host {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shadow-host[opened],
|
||||
.shadow-host.animating {
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/** Button
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content section {
|
||||
padding: 33px 16px;
|
||||
}
|
||||
|
||||
.shadow-content button {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: 0rem 25px;
|
||||
font: inherit;
|
||||
background: var(--color-beta);
|
||||
color: var(--color-epsilon);
|
||||
transition: all 200ms;
|
||||
transition-delay: 300ms;
|
||||
}
|
||||
|
||||
.shadow-content button:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
left: 6px;
|
||||
right: 6px;
|
||||
top: 49px;
|
||||
background: #E7E7E7;
|
||||
}
|
||||
|
||||
.shadow-content button:last-child:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shadow-content button:active {
|
||||
background-color: var(--highlight-color);
|
||||
color: #fff;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.shadow-content button:active:after {
|
||||
background: var(--highlight-color);
|
||||
transition: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<gaia-dialog>
|
||||
<section>
|
||||
<content select="h1"></content>
|
||||
</section>
|
||||
<content select="button"></content>
|
||||
<button class="cancel">Cancel</button>
|
||||
</gaia-dialog>`;
|
||||
|
||||
// Register and expose the constructor
|
||||
try {
|
||||
module.exports = document.registerElement('gaia-dialog-action', { prototype: proto });
|
||||
module.exports.proto = proto;
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-dialog-action',this));
|
||||
66
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/gaia-dialog-alert.js
vendored
Executable file
|
|
@ -0,0 +1,66 @@
|
|||
;(function(define){define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var GaiaDialog = require('gaia-dialog');
|
||||
|
||||
|
||||
var proto = GaiaDialog.extend();
|
||||
|
||||
/**
|
||||
* Runs when an instance of `GaiaTabs`
|
||||
* is first created.
|
||||
*
|
||||
* The initial value of the `select` attribute
|
||||
* is used to select a tab.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.createdCallback = function() {
|
||||
this.onCreated();
|
||||
this.els.submit = this.shadowRoot.querySelector('.submit');
|
||||
this.els.submit.addEventListener('click', this.close.bind(this));
|
||||
};
|
||||
|
||||
proto.template = `
|
||||
<style>
|
||||
.shadow-host {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shadow-host[opened],
|
||||
.shadow-host.animating {
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<gaia-dialog>
|
||||
<section>
|
||||
<p><content></content></p>
|
||||
</section>
|
||||
<div>
|
||||
<button class="submit primary">Ok</button>
|
||||
</div>
|
||||
</gaia-dialog>`;
|
||||
|
||||
// Register and expose the constructor
|
||||
try {
|
||||
module.exports = document.registerElement('gaia-dialog-alert', { prototype: proto });
|
||||
module.exports.proto = proto;
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-dialog-alert',this));
|
||||
75
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/gaia-dialog-confirm.js
vendored
Executable file
|
|
@ -0,0 +1,75 @@
|
|||
;(function(define){define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var GaiaDialog = require('gaia-dialog');
|
||||
|
||||
/**
|
||||
* Extend from the `HTMLElement` prototype
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = GaiaDialog.extend();
|
||||
|
||||
/**
|
||||
* Runs when an instance of `GaiaTabs`
|
||||
* is first created.
|
||||
*
|
||||
* The initial value of the `select` attribute
|
||||
* is used to select a tab.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.createdCallback = function() {
|
||||
this.onCreated();
|
||||
|
||||
this.els.submit = this.shadowRoot.querySelector('.submit');
|
||||
this.els.cancel = this.shadowRoot.querySelector('.cancel');
|
||||
|
||||
this.els.cancel.addEventListener('click', this.close.bind(this));
|
||||
this.els.submit.addEventListener('click', this.close.bind(this));
|
||||
};
|
||||
|
||||
proto.template = `
|
||||
<style>
|
||||
.shadow-host {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shadow-host[opened],
|
||||
.shadow-host.animating {
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<gaia-dialog>
|
||||
<section>
|
||||
<p><content></content></p>
|
||||
</section>
|
||||
<fieldset>
|
||||
<button class="cancel">Cancel</button>
|
||||
<button class="submit danger">Confirm</button>
|
||||
</fieldset>
|
||||
</gaia-dialog>`;
|
||||
|
||||
// Register and expose the constructor
|
||||
try {
|
||||
module.exports = document.registerElement('gaia-dialog-confirm', { prototype: proto });
|
||||
module.exports.proto = proto;
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-dialog-alert',this));
|
||||
128
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/gaia-dialog-menu.js
vendored
Executable file
|
|
@ -0,0 +1,128 @@
|
|||
;(function(define){define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var GaiaDialog = require('gaia-dialog');
|
||||
|
||||
/**
|
||||
* Detects presence of shadow-dom
|
||||
* CSS selectors.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
var hasShadowCSS = (function() {
|
||||
try { document.querySelector(':host'); return true; }
|
||||
catch (e) { return false; }
|
||||
})();
|
||||
|
||||
/**
|
||||
* Extend from the `HTMLElement` prototype
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = GaiaDialog.extend();
|
||||
|
||||
/**
|
||||
* Runs when an instance of `GaiaTabs`
|
||||
* is first created.
|
||||
*
|
||||
* The initial value of the `select` attribute
|
||||
* is used to select a tab.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.createdCallback = function() {
|
||||
this.onCreated();
|
||||
this.els.submit = this.shadowRoot.querySelector('.submit');
|
||||
this.els.cancel = this.shadowRoot.querySelector('.cancel');
|
||||
};
|
||||
|
||||
proto.template = `
|
||||
<style>
|
||||
:host {
|
||||
display: none;
|
||||
}
|
||||
|
||||
:host[opened],
|
||||
:host.animating {
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
::content > button {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: 0rem 16px;
|
||||
font: inherit;
|
||||
font-style: italic;
|
||||
text-align: left;
|
||||
background: var(--color-beta);
|
||||
color: var(--highlight-color);
|
||||
}
|
||||
|
||||
::content > button[data-icon]:before {
|
||||
width: 50px;
|
||||
font-size: 22px;
|
||||
margin-left: -16px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/** Button Divider Line
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::content > button:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
left: 6px;
|
||||
right: 6px;
|
||||
top: 49px;
|
||||
background: #E7E7E7;
|
||||
}
|
||||
|
||||
::content > button:last-of-type:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<gaia-dialog>
|
||||
<div class="items"><content select="button"></content></div>
|
||||
</gaia-dialog>`;
|
||||
|
||||
// If the browser doesn't support shadow-css
|
||||
// selectors yet, we update the template
|
||||
// to use the shim classes instead.
|
||||
if (!hasShadowCSS) {
|
||||
proto.template = proto.template
|
||||
.replace('::content', 'gaia-dialog-menu.shadow-content', 'g')
|
||||
.replace(':host', 'gaia-dialog-menu.shadow-host', 'g');
|
||||
}
|
||||
|
||||
// Register and expose the constructor
|
||||
try {
|
||||
module.exports = document.registerElement('gaia-dialog-menu', { prototype: proto });
|
||||
module.exports.proto = proto;
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-dialog-menu',this));
|
||||
80
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/gaia-dialog-prompt.js
vendored
Executable file
|
|
@ -0,0 +1,80 @@
|
|||
;(function(define){define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var GetTextInput = require('gaia-text-input');
|
||||
var GaiaDialog = require('gaia-dialog');
|
||||
|
||||
/**
|
||||
* Extend from `GaiaDialog` prototype
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = GaiaDialog.extend();
|
||||
|
||||
/**
|
||||
* Runs when an instance of `GaiaTabs`
|
||||
* is first created.
|
||||
*
|
||||
* The initial value of the `select` attribute
|
||||
* is used to select a tab.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.createdCallback = function() {
|
||||
this.onCreated();
|
||||
|
||||
this.els.input = this.shadowRoot.querySelector('gaia-text-input');
|
||||
this.els.submit = this.shadowRoot.querySelector('.submit');
|
||||
this.els.cancel = this.shadowRoot.querySelector('.cancel');
|
||||
|
||||
this.els.input.placeholder = this.firstChild.textContent;
|
||||
this.els.cancel.addEventListener('click', this.close.bind(this));
|
||||
this.els.submit.addEventListener('click', this.close.bind(this));
|
||||
};
|
||||
|
||||
proto.template = `
|
||||
<style>
|
||||
gaia-dialog-prompt {
|
||||
display: none;
|
||||
}
|
||||
|
||||
gaia-dialog-prompt[opened],
|
||||
gaia-dialog-prompt.animating {
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
gaia-text-input {
|
||||
margin: 16px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<gaia-dialog>
|
||||
<div><gaia-text-input></gaia-text-input></div>
|
||||
<fieldset>
|
||||
<button class="cancel">Cancel</button>
|
||||
<button class="submit primary">Ok</button>
|
||||
</fieldset>
|
||||
</gaia-dialog>`;
|
||||
|
||||
// Register and expose the constructor
|
||||
try {
|
||||
module.exports = document.registerElement('gaia-dialog-prompt', { prototype: proto });
|
||||
module.exports.proto = proto;
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-dialog-prompt',this));
|
||||
257
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/gaia-dialog-select.js
vendored
Executable file
|
|
@ -0,0 +1,257 @@
|
|||
;(function(define){define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
|
||||
var GaiaDialog = require('gaia-dialog');
|
||||
|
||||
// Load icon-font
|
||||
require('gaia-icons');
|
||||
|
||||
/**
|
||||
* Extend from `GaiaDialog` prototype
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = GaiaDialog.extend();
|
||||
|
||||
/**
|
||||
* Runs when an instance of `GaiaTabs`
|
||||
* is first created.
|
||||
*
|
||||
* The initial value of the `select` attribute
|
||||
* is used to select a tab.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.createdCallback = function() {
|
||||
this.onCreated();
|
||||
|
||||
this.els.submit = this.shadowRoot.querySelector('.submit');
|
||||
this.els.cancel = this.shadowRoot.querySelector('.cancel');
|
||||
this.els.list = this.shadowRoot.querySelector('ul');
|
||||
|
||||
this.multiple = this.hasAttribute('multiple');
|
||||
|
||||
on(this.els.list, 'click', this.onListClick, this);
|
||||
on(this.els.submit, 'click', this.close, this);
|
||||
on(this.els.cancel, 'click', this.close, this);
|
||||
};
|
||||
|
||||
proto.onListClick = function(e) {
|
||||
var el = getLi(e.target);
|
||||
var selected = el.getAttribute('aria-selected') === 'true';
|
||||
|
||||
if (this.multiple) { this.onChangeMultiple(el, selected); }
|
||||
else { this.onChange(el, selected); }
|
||||
};
|
||||
|
||||
proto.onChange = function(el, selected) {
|
||||
this.clearSelected();
|
||||
if (!selected) { el.setAttribute('aria-selected', !selected); }
|
||||
this.fireChange();
|
||||
this.close();
|
||||
};
|
||||
|
||||
proto.onChangeMultiple = function(el, selected) {
|
||||
el.setAttribute('aria-selected', !selected);
|
||||
this.fireChange();
|
||||
};
|
||||
|
||||
proto.clearSelected = function() {
|
||||
[].forEach.call(this.selectedOptions, function(option) {
|
||||
option.removeAttribute('aria-selected');
|
||||
});
|
||||
};
|
||||
|
||||
proto.fireChange = function() {
|
||||
var e = new CustomEvent('change', { detail: { value: this.valueString }});
|
||||
this.dispatchEvent(e);
|
||||
};
|
||||
|
||||
proto.attrs = {
|
||||
multiple: {
|
||||
get: function() { return !!this._multiple; },
|
||||
set: function(value) {
|
||||
value = value === '' ? true : value;
|
||||
if (value === this._multiple) { return; }
|
||||
if (!value) {
|
||||
this._multiple = false;
|
||||
this.removeAttribute('multiple');
|
||||
} else {
|
||||
this._multiple = true;
|
||||
this.setAttribute('multiple', '');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
options: {
|
||||
get: function() { return this.querySelectorAll('li'); }
|
||||
},
|
||||
|
||||
selectedOptions: {
|
||||
get: function() { return this.querySelectorAll('li[aria-selected="true"]'); }
|
||||
},
|
||||
|
||||
selected: {
|
||||
get: function() { return this.selectedOptions[0]; }
|
||||
},
|
||||
|
||||
value: {
|
||||
get: function() {
|
||||
var selected = this.selectedOptions[0];
|
||||
return selected && selected.getAttribute('value');
|
||||
}
|
||||
},
|
||||
|
||||
valueString: {
|
||||
get: function() {
|
||||
var selected = this.selected;
|
||||
return selected && selected.textContent;
|
||||
}
|
||||
},
|
||||
|
||||
length: {
|
||||
get: function() { return this.options.length; }
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperties(proto, proto.attrs);
|
||||
|
||||
proto.template = `
|
||||
<style>
|
||||
.shadow-host {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shadow-host[opened],
|
||||
.shadow-host.animating {
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/** Title (duplicate from gaia-dialog)
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content h1 {
|
||||
padding: 16px;
|
||||
font-size: 23px;
|
||||
line-height: 26px;
|
||||
font-weight: 200;
|
||||
font-style: italic;
|
||||
color: #858585;
|
||||
}
|
||||
|
||||
/** List
|
||||
---------------------------------------------------------*/
|
||||
|
||||
ul {
|
||||
display: block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/** Options
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content li {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 16px;
|
||||
text-align: left;
|
||||
-moz-user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.shadow-content li[aria-selected='true'] {
|
||||
color: #00CAF2;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.shadow-content li:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
bottom: 1px;
|
||||
background: #E7E7E7;
|
||||
}
|
||||
|
||||
.shadow-content li:last-of-type:after {
|
||||
display: none
|
||||
}
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
gaia-dialog:not([multiple]) .submit {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
gaia-dialog:not([multiple]) .cancel {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
gaia-dialog:not([multiple]) .cancel:after {
|
||||
display: none% !important;
|
||||
}
|
||||
|
||||
/** Tick Icon
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content li[aria-selected='true']:before {
|
||||
content: 'tick';
|
||||
position: absolute;
|
||||
top: 50%; right: 20px;
|
||||
display: block;
|
||||
margin-top: -12px;
|
||||
font-family: 'gaia-icons';
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<gaia-dialog>
|
||||
<content select="h1"></content>
|
||||
<ul><content select="li"></content></ul>
|
||||
<fieldset>
|
||||
<button class="cancel">Cancel</button>
|
||||
<button class="submit primary">Select</button>
|
||||
</fieldset>
|
||||
</gaia-dialog>`;
|
||||
|
||||
|
||||
function on(el, name, fn, ctx) {
|
||||
if (ctx) { fn = fn.bind(ctx); }
|
||||
el.addEventListener(name, fn);
|
||||
}
|
||||
|
||||
function getLi(el) {
|
||||
return el && (el.tagName === 'LI' ? el : getLi(el.parentNode));
|
||||
}
|
||||
|
||||
|
||||
// Register and expose the constructor
|
||||
try {
|
||||
module.exports = document.registerElement('gaia-dialog-select', { prototype: proto });
|
||||
module.exports.proto = proto;
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-dialog-select',this));
|
||||
586
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/gaia-dialog.js
vendored
Executable file
|
|
@ -0,0 +1,586 @@
|
|||
;(function(define){define(function(require,exports,module){
|
||||
/*jshint laxbreak:true*/
|
||||
/*jshint esnext:true*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Extend from the `HTMLElement` prototype
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
|
||||
var innerHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
|
||||
var removeAttribute = proto.removeAttribute;
|
||||
var setAttribute = proto.setAttribute;
|
||||
var has = Object.prototype.hasOwnProperty;
|
||||
|
||||
/**
|
||||
* Runs when an instance of `GaiaTabs`
|
||||
* is first created.
|
||||
*
|
||||
* The initial value of the `select` attribute
|
||||
* is used to select a tab.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.createdCallback = function() {
|
||||
this.createShadowRoot().innerHTML = template;
|
||||
|
||||
this.els = {
|
||||
inner: this.shadowRoot.querySelector('.dialog-inner'),
|
||||
background: this.shadowRoot.querySelector('.background'),
|
||||
window: this.shadowRoot.querySelector('.window')
|
||||
};
|
||||
|
||||
this.shadowRoot.addEventListener('click', e => this.onClick(e));
|
||||
this.setupAnimationListeners();
|
||||
this.styleHack();
|
||||
};
|
||||
|
||||
proto.onClick = function(e) {
|
||||
var el = closest('[on-click]', e.target, this);
|
||||
if (!el) { return; }
|
||||
var method = el.getAttribute('on-click');
|
||||
if (typeof this[method] == 'function') { this[method](); }
|
||||
};
|
||||
|
||||
proto.setupAnimationListeners = function() {
|
||||
this.addEventListener('animationstart', this.onAnimationStart.bind(this));
|
||||
this.addEventListener('animationend', this.onAnimationEnd.bind(this));
|
||||
};
|
||||
|
||||
proto.styleHack = function() {
|
||||
var style = this.shadowRoot.querySelector('style').cloneNode(true);
|
||||
this.classList.add('shadow-content', 'shadow-host');
|
||||
style.setAttribute('scoped', '');
|
||||
this.appendChild(style);
|
||||
};
|
||||
|
||||
proto.open = function(options) {
|
||||
if (this.isOpen) { return; }
|
||||
this.animateIn(options);
|
||||
this.isOpen = true;
|
||||
this.setAttribute('opened', '');
|
||||
this.dispatch('opened');
|
||||
};
|
||||
|
||||
proto.close = function(options) {
|
||||
if (!this.isOpen) { return; }
|
||||
var self = this;
|
||||
self.isOpen = false;
|
||||
this.animateOut(function() {
|
||||
self.removeAttribute('opened');
|
||||
self.dispatch('closed');
|
||||
});
|
||||
};
|
||||
|
||||
proto.attributeChangedCallback = function(name, from, to) {
|
||||
if (this.attrs[name]) { this[name] = to; }
|
||||
};
|
||||
|
||||
proto.setAttribute = function(attr, value) {
|
||||
this.els.inner.setAttribute(attr, value);
|
||||
setAttribute.call(this, attr, value);
|
||||
};
|
||||
|
||||
proto.removeAttribute = function(attr) {
|
||||
this.els.inner.removeAttribute(attr);
|
||||
removeAttribute.call(this, attr);
|
||||
};
|
||||
|
||||
proto.animateIn = function(e) {
|
||||
var hasTarget = e && ('clientX' in e || e.touches);
|
||||
if (hasTarget) { return this.animateInFromTarget(e); }
|
||||
|
||||
var self = this;
|
||||
this.dispatch('animationstart');
|
||||
this.els.background.classList.add('animate-in');
|
||||
this.els.background.addEventListener('animationend', function fn() {
|
||||
self.els.background.removeEventListener('animationend', fn);
|
||||
self.els.window.classList.add('animate-in');
|
||||
self.dispatch('animationend');
|
||||
});
|
||||
};
|
||||
|
||||
proto.animateInFromTarget = function(e) {
|
||||
var pos = e.touches && e.touches[0] || e;
|
||||
var scale = Math.sqrt(innerWidth * innerHeight) / 10;
|
||||
var background = this.els.background;
|
||||
var duration = scale * 7;
|
||||
var end = 'transitionend';
|
||||
var self = this;
|
||||
|
||||
background.style.transform = 'translate(' + pos.clientX + 'px, ' + pos.clientY + 'px)';
|
||||
background.style.transitionDuration = duration + 'ms';
|
||||
background.classList.add('circular');
|
||||
this.dispatch('animationstart');
|
||||
|
||||
var reflow = background.offsetTop;
|
||||
|
||||
background.style.transform += ' scale(' + scale + ')';
|
||||
background.style.opacity = 1;
|
||||
|
||||
background.addEventListener(end, function fn() {
|
||||
background.removeEventListener(end, fn);
|
||||
self.els.window.classList.add('animate-in');
|
||||
self.dispatch('animationend');
|
||||
});
|
||||
};
|
||||
|
||||
proto.animateOut = function(callback) {
|
||||
var end = 'animationend';
|
||||
var background = this.els.background;
|
||||
var self = this;
|
||||
var classes = {
|
||||
el: this.classList,
|
||||
window: this.els.window.classList,
|
||||
background: this.els.background.classList
|
||||
};
|
||||
|
||||
this.dispatch('animationstart');
|
||||
classes.window.add('animate-out');
|
||||
|
||||
this.els.window.addEventListener(end, function fn(e) {
|
||||
self.els.window.removeEventListener(end, fn);
|
||||
e.stopPropagation();
|
||||
classes.background.add('animate-out');
|
||||
self.els.background.addEventListener(end, function fn() {
|
||||
self.els.background.removeEventListener(end, fn);
|
||||
classes.window.remove('animate-out', 'animate-in');
|
||||
classes.background.remove('animate-out', 'animate-in');
|
||||
background.classList.remove('circular');
|
||||
background.style = '';
|
||||
self.dispatch('animationend');
|
||||
if (callback) { callback(); }
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
proto.onAnimationStart = function() {
|
||||
this.classList.add('animating');
|
||||
};
|
||||
|
||||
proto.onAnimationEnd = function() {
|
||||
this.classList.remove('animating');
|
||||
};
|
||||
|
||||
proto.dispatch = function(name) {
|
||||
this.dispatchEvent(new CustomEvent(name));
|
||||
};
|
||||
|
||||
proto.attrs = {
|
||||
opened: {
|
||||
get: function() { return !!this.isOpen; },
|
||||
set: function(value) {
|
||||
value = value === '' || value;
|
||||
if (!value) { this.close(); }
|
||||
else { this.open(); }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.defineProperties(proto, proto.attrs);
|
||||
|
||||
// Override `innerHTML` to prevent the scoped
|
||||
// stylesheet being erased by mistake.
|
||||
Object.defineProperty(proto, 'innerHTML', {
|
||||
get: function() { return innerHTML.get.call(this); },
|
||||
set: function(html) {
|
||||
var style = this.querySelector('style');
|
||||
innerHTML.set.call(this, html);
|
||||
this.appendChild(style);
|
||||
}
|
||||
});
|
||||
|
||||
var template = `
|
||||
<style>
|
||||
|
||||
.shadow-content * {
|
||||
box-sizing: border-box;
|
||||
font-weight: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.shadow-content p,
|
||||
.shadow-content h1,
|
||||
.shadow-content h2,
|
||||
.shadow-content h3,
|
||||
.shadow-content h4,
|
||||
.shadow-content button,
|
||||
.shadow-content fieldset {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.shadow-host {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0px; left: 0px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 200;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.shadow-host[opened],
|
||||
.shadow-host.animating {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/** Inner
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.dialog-inner {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/** Background
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.background {
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
background: rgba(199,199,199,0.85);
|
||||
}
|
||||
|
||||
/**
|
||||
* .circular
|
||||
*/
|
||||
|
||||
.background.circular {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: -20px;
|
||||
border-radius: 50%;
|
||||
will-change: transform, opacity;
|
||||
transition-property: opacity, transform;
|
||||
transition-timing-function: linear;
|
||||
}
|
||||
|
||||
/**
|
||||
* .animate-in
|
||||
*/
|
||||
|
||||
.background.animate-in {
|
||||
animation-name: gaia-dialog-fade-in;
|
||||
animation-duration: 300ms;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
/**
|
||||
* .animate-out
|
||||
*/
|
||||
|
||||
.background.animate-out {
|
||||
animation-name: gaia-dialog-fade-out;
|
||||
animation-delay: 300ms;
|
||||
animation-duration: 300ms;
|
||||
animation-fill-mode: forwards;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/** Window
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.window {
|
||||
position: relative;
|
||||
width: 90%;
|
||||
max-width: 350px;
|
||||
margin: auto;
|
||||
box-shadow: 0 1px 0 0px rgba(0,0,0,0.15);
|
||||
background: var(--color-iota);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.window.animate-in {
|
||||
animation-name: gaia-dialog-entrance;
|
||||
animation-duration: 300ms;
|
||||
animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.275);
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.window.animate-out {
|
||||
animation-name: gaia-dialog-fade-out;
|
||||
animation-duration: 200ms;
|
||||
animation-delay: 100ms;
|
||||
animation-timing-function: linear;
|
||||
animation-fill-mode: forwards;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/** Title
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content h1 {
|
||||
padding: 16px;
|
||||
font-size: 23px;
|
||||
line-height: 26px;
|
||||
font-weight: 200;
|
||||
font-style: italic;
|
||||
color: #858585;
|
||||
}
|
||||
|
||||
.shadow-content strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.shadow-content small {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
/** Section
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content section {
|
||||
padding: 33px 18px;
|
||||
color: #858585;
|
||||
}
|
||||
|
||||
.shadow-content section > *:not(:last-child) {
|
||||
margin-bottom: 13px;
|
||||
}
|
||||
|
||||
/** Paragraphs
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content p {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content button {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: 0rem 16px;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
background: var(--color-beta);
|
||||
color: var(--color-epsilon);
|
||||
transition: all 200ms;
|
||||
transition-delay: 300ms;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* .primary
|
||||
*/
|
||||
|
||||
.shadow-content button.primary {
|
||||
color: var(--highlight-color);
|
||||
}
|
||||
|
||||
/**
|
||||
* .danger
|
||||
*/
|
||||
|
||||
.shadow-content button.danger {
|
||||
color: var(--color-destructive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disabled buttons
|
||||
*/
|
||||
|
||||
.shadow-content button[disabled] {
|
||||
color: var(--color-zeta);
|
||||
}
|
||||
|
||||
/** Button Divider Line
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content button:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 1px;
|
||||
left: 6px;
|
||||
right: 6px;
|
||||
top: 49px;
|
||||
background: #E7E7E7;
|
||||
}
|
||||
|
||||
.shadow-content button:last-of-type:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.shadow-content button:active {
|
||||
background-color: var(--highlight-color);
|
||||
color: #fff;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.shadow-content button:active:after {
|
||||
background: var(--highlight-color);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.shadow-content button[data-icon]:before {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/** Fieldset (button group)
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.shadow-content fieldset {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.shadow-content fieldset button {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.shadow-content fieldset button:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
bottom: 6px;
|
||||
right: 0px;
|
||||
left: auto;
|
||||
width: 1px;
|
||||
height: calc(100% - 12px);
|
||||
background: #e7e7e7;
|
||||
transition: all 200ms;
|
||||
transition-delay: 200ms;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="dialog-inner">
|
||||
<div class="background" on-click="close"></div>
|
||||
<div class="window"><content></content></div>
|
||||
</div>`;
|
||||
|
||||
var animations = `
|
||||
@keyframes gaia-dialog-entrance {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(100px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes gaia-dialog-fade-in {
|
||||
0% { opacity: 0 }
|
||||
100% { opacity: 1 }
|
||||
}
|
||||
|
||||
@keyframes gaia-dialog-fade-out {
|
||||
0% { opacity: 1 }
|
||||
100% { opacity: 0 }
|
||||
}`;
|
||||
|
||||
(function() {
|
||||
var style = document.createElement('style');
|
||||
style.innerHTML = animations;
|
||||
|
||||
headReady().then(() => {
|
||||
document.head.appendChild(style);
|
||||
});
|
||||
|
||||
/**
|
||||
* Resolves a promise once document.head is ready.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
function headReady() {
|
||||
return new Promise(resolve => {
|
||||
if (document.head) { return resolve(); }
|
||||
window.addEventListener('load', function fn() {
|
||||
window.removeEventListener('load', fn);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
// Register and expose the constructor
|
||||
try {
|
||||
module.exports = document.registerElement('gaia-dialog', { prototype: proto });
|
||||
module.exports.proto = proto;
|
||||
|
||||
module.exports.extend = function() {
|
||||
return mixin(Object.create(proto), extended);
|
||||
};
|
||||
} catch (e) {
|
||||
if (e.name !== 'NotSupportedError') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
var extended = {
|
||||
onCreated: function() {
|
||||
var self = this;
|
||||
|
||||
this.createShadowRoot().innerHTML = this.template;
|
||||
this.els = { dialog: this.shadowRoot.querySelector('gaia-dialog') };
|
||||
this.setupAnimationListeners();
|
||||
this.styleHack();
|
||||
|
||||
this.els.dialog.addEventListener('opened', function() {
|
||||
setAttribute.call(self, 'opened', '');
|
||||
});
|
||||
|
||||
this.els.dialog.addEventListener('closed', function() {
|
||||
removeAttribute.call(self, 'opened');
|
||||
});
|
||||
},
|
||||
|
||||
open: function(e) {
|
||||
this.els.dialog.open(e);
|
||||
},
|
||||
|
||||
close: function() {
|
||||
this.els.dialog.close();
|
||||
},
|
||||
|
||||
setAttribute: function(attr, value) {
|
||||
this.els.dialog.setAttribute(attr, value);
|
||||
setAttribute.call(this, attr, value);
|
||||
},
|
||||
|
||||
removeAttribute: function(attr) {
|
||||
this.els.dialog.removeAttribute(attr);
|
||||
removeAttribute.call(this, attr);
|
||||
}
|
||||
};
|
||||
|
||||
function closest(selector, el, top) {
|
||||
return el && el !== top
|
||||
? (el.matches(selector) ? el : closest(el.parentNode))
|
||||
: null;
|
||||
}
|
||||
|
||||
function mixin(a, b) {
|
||||
for (var key in b) { a[key] = b[key]; }
|
||||
return a;
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-dialog',this));
|
||||
122
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/index.html
vendored
Executable file
|
|
@ -0,0 +1,122 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><gaia-dialog></title>
|
||||
<meta name="description" content="gaia-dialog" />
|
||||
<link rel="import" type="text/html" href="../src/gaia-dialog.html">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/base/base.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-theme/gaia-theme.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-fonts/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-icons/gaia-icons.css">
|
||||
<script src="bower_components/gaia-theme/lib/gaia-theme-selector.js"></script>
|
||||
<script src="bower_components/pressed/pressed.js"></script>
|
||||
<script src="bower_components/gaia-icons/gaia-icons.js"></script>
|
||||
<script src="bower_components/gaia-button/gaia-button.js"></script>
|
||||
<script src="bower_components/gaia-text-input/gaia-text-input.js"></script>
|
||||
<script src="gaia-dialog.js"></script>
|
||||
<script src="gaia-dialog-alert.js"></script>
|
||||
<script src="gaia-dialog-confirm.js"></script>
|
||||
<script src="gaia-dialog-prompt.js"></script>
|
||||
<script src="gaia-dialog-action.js"></script>
|
||||
<script src="gaia-dialog-select.js"></script>
|
||||
<script src="gaia-dialog-menu.js"></script>
|
||||
<style>
|
||||
body {
|
||||
padding-top: 48px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="l-align-center">
|
||||
<gaia-theme-selector></gaia-theme-selector>
|
||||
|
||||
<div id="buttons">
|
||||
<div class="l-mb-small"><gaia-button data-for="gaia-dialog-alert">Alert</gaia-button></div>
|
||||
<div class="l-mb-small"><gaia-button data-for="gaia-dialog-confirm">Confirm</gaia-button></div>
|
||||
<div class="l-mb-small"><gaia-button data-for="gaia-dialog-prompt">Prompt</gaia-button></div>
|
||||
<div class="l-mb-small"><gaia-button data-for="gaia-dialog-action">Action</gaia-button></div>
|
||||
<div class="l-mb-small"><gaia-button data-for="gaia-dialog-select">Select</gaia-button></div>
|
||||
<div class="l-mb-small"><gaia-button data-for="gaia-dialog-select[multiple]">Select Multiple</gaia-button></div>
|
||||
<div class="l-mb-small"><gaia-button data-for="gaia-dialog-menu">Menu</gaia-button></div>
|
||||
<div class="l-mb-small"><gaia-button data-for="#custom-dialog-1">Custom</gaia-button></div>
|
||||
</div>
|
||||
|
||||
<div id="dialogs">
|
||||
<gaia-dialog-alert>No SIM card is present</gaia-dialog-alert>
|
||||
<gaia-dialog-confirm>Are you sure you want to delete this contact?</gaia-dialog-confirm>
|
||||
<gaia-dialog-prompt>Device name</gaia-dialog-prompt>
|
||||
|
||||
<gaia-dialog-action>
|
||||
<h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eu mollis tortor.</h1>
|
||||
<button>Action 1</button>
|
||||
<button>Action 2</button>
|
||||
</gaia-dialog-action>
|
||||
|
||||
<gaia-dialog-select>
|
||||
<h1>Ring tone</h1>
|
||||
<li>Classic prism</li>
|
||||
<li>Wallphone</li>
|
||||
<li>Disco drive</li>
|
||||
<li>Touchmatic</li>
|
||||
<li>Classic courier</li>
|
||||
<li>Hacker</li>
|
||||
</gaia-dialog-select>
|
||||
|
||||
<gaia-dialog-select multiple>
|
||||
<h1>Ring tone</h1>
|
||||
<li>Classic prism</li>
|
||||
<li>Wallphone</li>
|
||||
<li>Disco drive</li>
|
||||
<li>Touchmatic</li>
|
||||
<li>Classic courier</li>
|
||||
<li>Hacker</li>
|
||||
</gaia-dialog-select>
|
||||
|
||||
<gaia-dialog-menu>
|
||||
<button data-icon="firefox">Open in new window</button>
|
||||
<button data-icon="firefox">Add to Home Screen</button>
|
||||
<button data-icon="firefox">Share link</button>
|
||||
<button data-icon="firefox">Settings</button>
|
||||
</gaia-dialog-menu>
|
||||
|
||||
<gaia-dialog id="custom-dialog-1">
|
||||
<section>
|
||||
<h1>Application Download</h1>
|
||||
<p>Do you want to download and install this application?</p>
|
||||
</section>
|
||||
<fieldset>
|
||||
<button>Cancel</button>
|
||||
<button>Action</button>
|
||||
</fieldset>
|
||||
</gaia-dialog>
|
||||
|
||||
<gaia-dialog>
|
||||
<h1>Main Heading</h1>
|
||||
<h2>Sub Heading</h2>
|
||||
<hr></hr>
|
||||
<p>Lorem ipsum dolor sit amet, consecutor adipisicing elit, sed do eiusod tempor incidenti ut la et dolore magna...</p>
|
||||
<button>Action</button>
|
||||
<button>Cancel</button>
|
||||
</gaia-dialog>
|
||||
|
||||
<gaia-dialog>
|
||||
<h1>Confirmation</h1>
|
||||
<p>Lorem ipsum dolor sit amet, consecutor adipisicing elit, sed do eiusod tempor incidenti ut la et dolore magna...</p>
|
||||
<hr>
|
||||
<p>Lorem ipsum dolor sit amet, consecutor adipisicing elit, sed do eiusod tempor incidenti ut la et dolore magna...</p>
|
||||
<button>Action</button>
|
||||
<button>Action</button>
|
||||
<button>Cancel</button>
|
||||
</gaia-dialog>
|
||||
</div>
|
||||
<script>
|
||||
var buttons = document.querySelectorAll('gaia-button');
|
||||
[].forEach.call(buttons, function(button) {
|
||||
button.addEventListener('click', function(e) {
|
||||
var dialog = document.querySelector(button.dataset.for);
|
||||
dialog.open(e);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
134
gaia/distros/spark/apps/studio/bower_components/gaia-dialog/src/gaia-dialog.html
vendored
Executable file
|
|
@ -0,0 +1,134 @@
|
|||
|
||||
<template id="template">
|
||||
<style>
|
||||
|
||||
gaia-dialog.host {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 16px;
|
||||
font-size: 16px;
|
||||
font-style: italic;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.inner {
|
||||
max-height: 100%;
|
||||
overflow: auto;
|
||||
background: #F4F4F4;
|
||||
}
|
||||
|
||||
.content > *:not(section) {
|
||||
margin: 0 16px 16px;
|
||||
}
|
||||
|
||||
.content > :first-child {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.content h1,
|
||||
.content h2 {
|
||||
text-align: center;
|
||||
font-weight: lighter;
|
||||
color: #858585;
|
||||
}
|
||||
|
||||
.content h1 {
|
||||
font-size: 1.6em;
|
||||
}
|
||||
|
||||
.content h2 {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.content h1 + h2 {
|
||||
margin-top: -16px;
|
||||
}
|
||||
|
||||
.content hr {
|
||||
height: 1px;
|
||||
border: 0;
|
||||
background: #E7E7E7;
|
||||
}
|
||||
|
||||
.content button {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
border: none;
|
||||
outline: 0;
|
||||
padding: 16px;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
font: inherit;
|
||||
color: #1EADCB;
|
||||
}
|
||||
|
||||
.content button:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
margin: 0 8px;
|
||||
height: 2px;
|
||||
background: #f4f4f4
|
||||
}
|
||||
|
||||
.content button:first-child:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.content section {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.content section > button {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.content section > button:after {
|
||||
width: 2px;
|
||||
height: auto;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: auto;
|
||||
margin: 8px 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="inner">
|
||||
<content></content>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
var thisDoc = document.currentScript.ownerDocument;
|
||||
var template = thisDoc.getElementById('template');
|
||||
|
||||
proto.createdCallback = function() {
|
||||
var root = this.createShadowRoot();
|
||||
var html = template.content.cloneNode(true);
|
||||
root.appendChild(html);
|
||||
this.configureStyle();
|
||||
};
|
||||
|
||||
proto.configureStyle = function() {
|
||||
var style = this.shadowRoot.querySelector('style').cloneNode(true);
|
||||
this.classList.add('content', 'host');
|
||||
style.setAttribute('scoped', '');
|
||||
this.appendChild(style);
|
||||
};
|
||||
|
||||
document.registerElement('gaia-dialog', { prototype: proto });
|
||||
</script>
|
||||
27
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "gaia-fonts",
|
||||
"version": "0.2.1",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "style.css",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"homepage": "https://github.com/gaia-components/gaia-fonts",
|
||||
"_release": "0.2.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.2.1",
|
||||
"commit": "4472313b716a64d5c478cb9e236a60f0df8c5208"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-fonts.git",
|
||||
"_target": "~0.2.1",
|
||||
"_originalSource": "gaia-components/gaia-fonts",
|
||||
"_direct": true
|
||||
}
|
||||
16
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/bower.json
vendored
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "gaia-fonts",
|
||||
"version": "0.2.1",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "style.css",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/fonts/FiraSans-Bold.woff
vendored
Executable file
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/fonts/FiraSans-BoldItalic.woff
vendored
Executable file
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/fonts/FiraSans-Light.woff
vendored
Executable file
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/fonts/FiraSans-LightItalic.woff
vendored
Executable file
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/fonts/FiraSans-Medium.woff
vendored
Executable file
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/fonts/FiraSans-MediumItalic.woff
vendored
Executable file
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/fonts/FiraSans-Regular.woff
vendored
Executable file
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/fonts/FiraSans-RegularItalic.woff
vendored
Executable file
54
gaia/distros/spark/apps/studio/bower_components/gaia-fonts/style.css
vendored
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
@font-face {
|
||||
font-family: "FiraSans";
|
||||
src: url("fonts/FiraSans-Light.woff") format("woff");
|
||||
font-weight: 300; /* lighter */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "FiraSans";
|
||||
src: url("fonts/FiraSans-LightItalic.woff") format("woff");
|
||||
font-style: italic;
|
||||
font-weight: 300; /* lighter */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "FiraSans";
|
||||
src: url("fonts/FiraSans-Regular.woff") format("woff");
|
||||
font-style: normal;
|
||||
font-weight: normal; /* 400 */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "FiraSans";
|
||||
src: url("fonts/FiraSans-RegularItalic.woff") format("woff");
|
||||
font-style: italic;
|
||||
font-weight: normal; /* 400 */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "FiraSans";
|
||||
src: url("fonts/FiraSans-Medium.woff") format("woff");
|
||||
font-style: italic;
|
||||
font-weight: bold; /* 700 */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "FiraSans";
|
||||
src: url("fonts/FiraSans-MediumItalic.woff") format("woff");
|
||||
font-style: italic;
|
||||
font-weight: bold; /* 700 */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "FiraSans";
|
||||
src: url("fonts/FiraSans-Bold.woff") format("woff");
|
||||
font-weight: 800; /* bolder */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "FiraSans";
|
||||
src: url("fonts/FiraSans-BoldItalic.woff") format("woff");
|
||||
font-style: italic;
|
||||
font-weight: 800; /* bolder */
|
||||
}
|
||||
40
gaia/distros/spark/apps/studio/bower_components/gaia-header/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "gaia-header",
|
||||
"version": "0.8.2",
|
||||
"homepage": "https://github.com/gaia-components/gaia-header",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "gaia-header.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"!.jshintrc",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"index.html",
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"gaia-icons": "gaia-components/gaia-icons#~0.7.11",
|
||||
"gaia-component": "gaia-components/gaia-component#~0.3.0",
|
||||
"font-fit": "gaia-components/font-fit#~0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gaia-theme": "gaia-components/gaia-theme",
|
||||
"gaia-fonts": "gaia-components/gaia-fonts",
|
||||
"base": "gaia-components/base"
|
||||
},
|
||||
"_release": "0.8.2",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.8.2",
|
||||
"commit": "fe7647efe83e5669560fe07db05a397a22336546"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-header.git",
|
||||
"_target": "0.8.2",
|
||||
"_originalSource": "gaia-components/gaia-header",
|
||||
"_direct": true
|
||||
}
|
||||
6
gaia/distros/spark/apps/studio/bower_components/gaia-header/.jshintrc
vendored
Executable file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"laxbreak": true,
|
||||
"esnext": true,
|
||||
"boss": true,
|
||||
"node": true
|
||||
}
|
||||
30
gaia/distros/spark/apps/studio/bower_components/gaia-header/bower.json
vendored
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "gaia-header",
|
||||
"version": "0.8.2",
|
||||
"homepage": "https://github.com/gaia-components/gaia-header",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "gaia-header.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"!.jshintrc",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"index.html",
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"gaia-icons": "gaia-components/gaia-icons#~0.7.11",
|
||||
"gaia-component": "gaia-components/gaia-component#~0.3.0",
|
||||
"font-fit": "gaia-components/font-fit#~0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gaia-theme": "gaia-components/gaia-theme",
|
||||
"gaia-fonts": "gaia-components/gaia-fonts",
|
||||
"base": "gaia-components/base"
|
||||
}
|
||||
}
|
||||
1442
gaia/distros/spark/apps/studio/bower_components/gaia-header/dist/gaia-header-es5.js
vendored
Executable file
1598
gaia/distros/spark/apps/studio/bower_components/gaia-header/dist/gaia-header.js
vendored
Executable file
1015
gaia/distros/spark/apps/studio/bower_components/gaia-header/gaia-header.js
vendored
Executable file
39
gaia/distros/spark/apps/studio/bower_components/gaia-icons/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"name": "gaia-icons",
|
||||
"version": "0.7.12",
|
||||
"homepage": "https://github.com/wilsonpage/gaia-icons",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": [
|
||||
"gaia-icons.js",
|
||||
"gaia-icons.css",
|
||||
"fonts/gaia-icons.ttf",
|
||||
"gaia-icons-embedded.css"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"!.jshintrc",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"templates",
|
||||
"images",
|
||||
"test",
|
||||
"tests",
|
||||
"index.html",
|
||||
"create-svg-icon-set-file.py",
|
||||
"Gruntfile.js",
|
||||
"README.md",
|
||||
"package.json"
|
||||
],
|
||||
"_release": "0.7.12",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.7.12",
|
||||
"commit": "7ea11294813fcbab3248c315e140855b932919c4"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-icons.git",
|
||||
"_target": "~0.7.11",
|
||||
"_originalSource": "gaia-components/gaia-icons"
|
||||
}
|
||||
4
gaia/distros/spark/apps/studio/bower_components/gaia-icons/.jshintrc
vendored
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"strict": false,
|
||||
"node": true
|
||||
}
|
||||
118
gaia/distros/spark/apps/studio/bower_components/gaia-icons/bin/report.js
vendored
Executable file
|
|
@ -0,0 +1,118 @@
|
|||
'use strict';
|
||||
|
||||
// Create a report about unused icons in a project.
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var exec = require('child_process').exec;
|
||||
|
||||
var optimist = require('optimist');
|
||||
|
||||
var cli = optimist
|
||||
.usage('Create a report about unused icons in a project.' + '\n' +
|
||||
'Usage: $0 path/to/your/project/');
|
||||
var projectDir = cli.argv._[0];
|
||||
|
||||
// No folder passed? Show help message then.
|
||||
if (!projectDir) {
|
||||
cli.showHelp();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Check if the directory exist.
|
||||
var stats = fs.lstatSync(projectDir);
|
||||
if (!stats.isDirectory()) {
|
||||
console.log('\x1b[31mPlease provide a valid folder.\x1b[0m\n');
|
||||
cli.showHelp();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of all the icons in the font.
|
||||
* @returns {Array}
|
||||
*/
|
||||
function getIcons() {
|
||||
var icons = fs.readdirSync('./images/');
|
||||
|
||||
icons = icons.map(function(icon) {
|
||||
return path.basename(icon, '.svg');
|
||||
});
|
||||
|
||||
return icons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use a grep pattern to extract used icons from files.
|
||||
* @param {string} grep
|
||||
* @param {Function} callback
|
||||
*/
|
||||
function getUsedIcons(grep, callback) {
|
||||
exec(grep, function(err, stdout, stderr) {
|
||||
var usedIcons = stdout
|
||||
.trim()
|
||||
.split('\n')
|
||||
.map(function(icon) {
|
||||
// Take only the icon name.
|
||||
return icon.split(/["']/)[1];
|
||||
})
|
||||
.filter(function(icon) {
|
||||
// Remove non string items.
|
||||
return icon && icon.match(/^[a-z0-9-]+$/);
|
||||
});
|
||||
|
||||
callback(usedIcons);
|
||||
|
||||
if (err) {
|
||||
console.log(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of unused icons in a folder. The patterns of extraction are:
|
||||
* * data-icon="[^"]+"
|
||||
* * .dataset.icon ?= ?.+
|
||||
*/
|
||||
function getUnusedIcons() {
|
||||
var usedIcons = [];
|
||||
var length = 2;
|
||||
|
||||
var cb = function(icons) {
|
||||
usedIcons = usedIcons.concat(icons);
|
||||
length--;
|
||||
|
||||
if (length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var allIcons = getIcons();
|
||||
var unusedIcons = [];
|
||||
|
||||
allIcons.forEach(function(icon) {
|
||||
if (usedIcons.indexOf(icon) === -1) {
|
||||
unusedIcons.push(icon);
|
||||
}
|
||||
});
|
||||
|
||||
outputUnusedIcons(allIcons, unusedIcons);
|
||||
};
|
||||
|
||||
getUsedIcons('grep -rhoP \'data-icon="[^"]+"\' ' + projectDir, cb);
|
||||
getUsedIcons('grep -rhoP \'.dataset.icon ?= ?.+\' ' + projectDir, cb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the list of unused icons to the screen.
|
||||
* @param {Array.<string>} icons
|
||||
* @param {Array.<string>} unusedIcons
|
||||
*/
|
||||
function outputUnusedIcons(icons, unusedIcons) {
|
||||
console.log('\x1b[36mList of unused icons in %s (%d/%d):\x1b[0m',
|
||||
projectDir, unusedIcons.length, icons.length);
|
||||
|
||||
unusedIcons.forEach(function(icon) {
|
||||
console.log('* ' + icon);
|
||||
});
|
||||
}
|
||||
|
||||
getUnusedIcons();
|
||||
30
gaia/distros/spark/apps/studio/bower_components/gaia-icons/bower.json
vendored
Executable file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "gaia-icons",
|
||||
"version": "0.7.12",
|
||||
"homepage": "https://github.com/wilsonpage/gaia-icons",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": [
|
||||
"gaia-icons.js",
|
||||
"gaia-icons.css",
|
||||
"fonts/gaia-icons.ttf",
|
||||
"gaia-icons-embedded.css"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"!.jshintrc",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"templates",
|
||||
"images",
|
||||
"test",
|
||||
"tests",
|
||||
"index.html",
|
||||
"create-svg-icon-set-file.py",
|
||||
"Gruntfile.js",
|
||||
"README.md",
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
BIN
gaia/distros/spark/apps/studio/bower_components/gaia-icons/fonts/gaia-icons.ttf
vendored
Executable file
25
gaia/distros/spark/apps/studio/bower_components/gaia-icons/gaia-icons-embedded.css
vendored
Executable file
25
gaia/distros/spark/apps/studio/bower_components/gaia-icons/gaia-icons.css
vendored
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
/* Generated by grunt-webfont */
|
||||
/* Based on https://github.com/endtwist/fontcustom/blob/master/lib/fontcustom/templates/fontcustom.css */
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: "gaia-icons";
|
||||
src: url("fonts/gaia-icons.ttf") format("truetype");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
[data-icon]:before,
|
||||
.ligature-icons {
|
||||
font-family: "gaia-icons";
|
||||
content: attr(data-icon);
|
||||
display: inline-block;
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
text-decoration: inherit;
|
||||
text-transform: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 30px;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
38
gaia/distros/spark/apps/studio/bower_components/gaia-icons/gaia-icons.js
vendored
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
(function(define){define(function(require,exports,module){
|
||||
/*jshint laxbreak:true*/
|
||||
|
||||
/**
|
||||
* Exports
|
||||
*/
|
||||
|
||||
var base = window.GAIA_ICONS_BASE_URL
|
||||
|| window.COMPONENTS_BASE_URL
|
||||
|| 'bower_components/';
|
||||
|
||||
if (!document.documentElement) {
|
||||
window.addEventListener('load', load);
|
||||
} else {
|
||||
load();
|
||||
}
|
||||
|
||||
function load() {
|
||||
if (isLoaded()) { return; }
|
||||
|
||||
var link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.type = 'text/css';
|
||||
link.href = base + 'gaia-icons/gaia-icons.css';
|
||||
document.head.appendChild(link);
|
||||
exports.loaded = true;
|
||||
}
|
||||
|
||||
function isLoaded() {
|
||||
return exports.loaded ||
|
||||
document.querySelector('link[href*=gaia-icons]') ||
|
||||
document.documentElement.classList.contains('gaia-icons-loaded');
|
||||
}
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-icons',this));
|
||||
31
gaia/distros/spark/apps/studio/bower_components/gaia-list/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "gaia-list",
|
||||
"homepage": "https://github.com/gaia-components/gaia-list",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "script.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"devDependencies": {
|
||||
"gaia-theme": "gaia-components/gaia-theme#dev",
|
||||
"gaia-fonts": "gaia-components/gaia-fonts#~0.2.1",
|
||||
"gaia-icons": "gaia-components/gaia-icons#~0.6.1"
|
||||
},
|
||||
"_release": "2ef76bed70",
|
||||
"_resolution": {
|
||||
"type": "branch",
|
||||
"branch": "master",
|
||||
"commit": "2ef76bed70a7616b286786001a2e74d18cfb9a1a"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-list.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "gaia-components/gaia-list",
|
||||
"_direct": true
|
||||
}
|
||||
22
gaia/distros/spark/apps/studio/bower_components/gaia-list/bower.json
vendored
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "gaia-list",
|
||||
"version": "0.1.0",
|
||||
"homepage": "https://github.com/gaia-components/gaia-list",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "script.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"devDependencies": {
|
||||
"gaia-theme": "gaia-components/gaia-theme#dev",
|
||||
"gaia-fonts": "gaia-components/gaia-fonts#~0.2.1",
|
||||
"gaia-icons": "gaia-components/gaia-icons#~0.6.1"
|
||||
}
|
||||
}
|
||||
354
gaia/distros/spark/apps/studio/bower_components/gaia-list/gaia-list.js
vendored
Executable file
|
|
@ -0,0 +1,354 @@
|
|||
;(function(define){'use strict';define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
|
||||
/**
|
||||
* Pointer event abstraction to make
|
||||
* it work for touch and mouse.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var pointer = [
|
||||
{ down: 'touchstart', up: 'touchend', move: 'touchmove' },
|
||||
{ down: 'mousedown', up: 'mouseup', move: 'mousemove' }
|
||||
]['ontouchstart' in window ? 0 : 1];
|
||||
|
||||
/**
|
||||
* Detects presence of shadow-dom
|
||||
* CSS selectors.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
var hasShadowCSS = (function() {
|
||||
try { document.querySelector(':host'); return true; }
|
||||
catch (e) { return false; }
|
||||
})();
|
||||
|
||||
/**
|
||||
* Element prototype, extends from HTMLElement
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
|
||||
/**
|
||||
* Called when the element is first created.
|
||||
*
|
||||
* Here we create the shadow-root and
|
||||
* inject our template into it.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.createdCallback = function() {
|
||||
this.createShadowRoot().innerHTML = template;
|
||||
this.els = { inner: this.shadowRoot.querySelector('.inner') };
|
||||
this.addEventListener('click', this.onPointerDown.bind(this));
|
||||
this.shadowStyleHack();
|
||||
this.makeAccessible();
|
||||
};
|
||||
|
||||
proto.makeAccessible = function() {
|
||||
[].forEach.call(this.children, function(el) {
|
||||
el.tabIndex = 0;
|
||||
});
|
||||
};
|
||||
|
||||
proto.shadowStyleHack = function() {
|
||||
if (hasShadowCSS) { return; }
|
||||
var style = this.shadowRoot.querySelector('style').cloneNode(true);
|
||||
this.appendChild(style);
|
||||
};
|
||||
|
||||
proto.attachedCallback = function() {
|
||||
this.restyleShadowDom();
|
||||
//this.rerunFontFit();
|
||||
};
|
||||
|
||||
/**
|
||||
* Workaround for bug 1056783.
|
||||
*
|
||||
* Fixes shadow-dom stylesheets not applying
|
||||
* when shadow host node is detached on
|
||||
* shadow-root creation.
|
||||
*
|
||||
* TODO: Needs abstraction
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
proto.restyleShadowDom = function() {
|
||||
var style = this.shadowRoot.querySelector('style');
|
||||
this.shadowRoot.removeChild(style);
|
||||
this.shadowRoot.appendChild(style);
|
||||
};
|
||||
|
||||
proto.itemShouldRipple = function(el) {
|
||||
if (scrolling) { return false; }
|
||||
else if (el.classList.contains('ripple')) { return true; }
|
||||
else if (el.classList.contains('no-ripple')) { return false; }
|
||||
else if (this.classList.contains('ripple')){ return true; }
|
||||
else if (this.classList.contains('no-ripple')){ return false; }
|
||||
else if (el.tagName === 'A') { return true; }
|
||||
else { return false; }
|
||||
};
|
||||
|
||||
proto.onPointerDown = function(e) {
|
||||
var point = e.touches ? e.changedTouches[0] : e;
|
||||
var target = this.getChild(e.target);
|
||||
|
||||
if (!this.itemShouldRipple(target)) { return; }
|
||||
|
||||
var pos = {
|
||||
list: this.getBoundingClientRect(),
|
||||
item: target.getBoundingClientRect()
|
||||
};
|
||||
|
||||
var els = {
|
||||
container: document.createElement('div'),
|
||||
ripple: document.createElement('div')
|
||||
};
|
||||
|
||||
els.container.className = 'ripple-container';
|
||||
els.container.style.left = (pos.item.left - pos.list.left) + 'px';
|
||||
els.container.style.top = (pos.item.top - pos.list.top) + 'px';
|
||||
els.container.style.width = pos.item.width + 'px';
|
||||
els.container.style.height = pos.item.height + 'px';
|
||||
|
||||
var offset = {
|
||||
x: point.clientX - pos.item.left,
|
||||
y: point.clientY - pos.item.top
|
||||
};
|
||||
|
||||
els.ripple.className = 'ripple';
|
||||
els.ripple.style.left = offset.x + 'px';
|
||||
els.ripple.style.top = offset.y + 'px';
|
||||
els.ripple.style.visibility = 'hidden';
|
||||
|
||||
els.container.appendChild(els.ripple);
|
||||
this.els.inner.appendChild(els.container);
|
||||
|
||||
// var reflow = els.ripple.offsetTop;
|
||||
var scale = pos.item.width / 1.2;
|
||||
var duration = 500;
|
||||
|
||||
setTimeout(function() {
|
||||
els.ripple.style.visibility = '';
|
||||
els.ripple.style.transform = 'scale(' + scale + ')';
|
||||
els.ripple.style.transitionDuration = duration + 'ms';
|
||||
setTimeout(function() {
|
||||
els.ripple.style.transitionDuration = '1000ms';
|
||||
els.ripple.style.opacity = '0';
|
||||
setTimeout(function() {
|
||||
els.container.remove();
|
||||
}, 1000);
|
||||
}, duration);
|
||||
});
|
||||
};
|
||||
|
||||
proto.getChild = function(el) {
|
||||
return el.parentNode === this ? el : this.getChild(el.parentNode);
|
||||
};
|
||||
|
||||
var template = `
|
||||
<style>
|
||||
|
||||
/** Reset
|
||||
---------------------------------------------------------*/
|
||||
|
||||
label { background: none; }
|
||||
|
||||
/** Host
|
||||
---------------------------------------------------------*/
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
position: relative;
|
||||
font-size: 17px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/** Children
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::content > *:not(style) {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
min-height: 60px;
|
||||
padding: 9px 16px;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
|
||||
font-size: 18px;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
background: transparent;
|
||||
align-items: center;
|
||||
list-style-type: none;
|
||||
|
||||
color:
|
||||
var(--text-color);
|
||||
}
|
||||
|
||||
::content > a {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/** Titles
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::content h1,
|
||||
::content h2,
|
||||
::content h3,
|
||||
::content h4 {
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/** Layout Helpers
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* [flexbox]
|
||||
*
|
||||
* A helper attribute to allow users to
|
||||
* quickly define content as a flexbox.
|
||||
*/
|
||||
|
||||
::content [flexbox] {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/**
|
||||
* [flex]
|
||||
*
|
||||
* A helper attribute to allow users to
|
||||
* quickly define area as flexible.
|
||||
*/
|
||||
|
||||
::content [flex] {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/** Border
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::content > *:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
height: 1px;
|
||||
|
||||
background:
|
||||
var(--border-color,
|
||||
var(--background-plus));
|
||||
}
|
||||
|
||||
::content > :first-child:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/** Titles
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::content small,
|
||||
::content p {
|
||||
font-size: 0.7em;
|
||||
line-height: 1.35em;
|
||||
}
|
||||
|
||||
/** Icon
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::content i {
|
||||
display: inline-block;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
::content i:before {
|
||||
display: block;
|
||||
}
|
||||
|
||||
::content > * > i:last-child {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
[dir=rtl] ::content i:before {
|
||||
transform: scale(-1, 1);
|
||||
}
|
||||
|
||||
/** Divided
|
||||
---------------------------------------------------------*/
|
||||
|
||||
::content .divided {
|
||||
-moz-border-start: solid 1px;
|
||||
-moz-padding-start: 14px;
|
||||
|
||||
border-color:
|
||||
var(--border-color,
|
||||
var(--background-plus));
|
||||
}
|
||||
|
||||
/** Ripple Container
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.ripple-container.ripple-container {
|
||||
box-sizing: content-box;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
padding-top: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/** Ripple
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.ripple-container > .ripple {
|
||||
background: var(--border-color);
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
margin: -1px;
|
||||
border-radius: 50%;
|
||||
transition-property: transform, opacity;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="inner"><content></content></div>`;
|
||||
|
||||
// If the browser doesn't support shadow-css
|
||||
// selectors yet, we update the template
|
||||
// to use the shim classes instead.
|
||||
if (!hasShadowCSS) {
|
||||
template = template
|
||||
.replace('::content', 'gaia-list', 'g')
|
||||
.replace(':host', 'gaia-list', 'g');
|
||||
}
|
||||
|
||||
var scrolling = false;
|
||||
var scrollTimeout;
|
||||
|
||||
addEventListener('scroll', function() {
|
||||
scrolling = true;
|
||||
clearTimeout(scrollTimeout);
|
||||
scrollTimeout = setTimeout(function() {
|
||||
scrolling = false;
|
||||
}, 100);
|
||||
});
|
||||
|
||||
// Register and return the constructor
|
||||
// and expose `protoype` (bug 1048339)
|
||||
module.exports = document.registerElement('gaia-list', { prototype: proto });
|
||||
module.exports.proto = proto;
|
||||
|
||||
});})(typeof define=='function'&&define.amd?define
|
||||
:(function(n,w){'use strict';return typeof module=='object'?function(c){
|
||||
c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){
|
||||
return w[n];},m.exports,m);w[n]=m.exports;};})('gaia-list',this));
|
||||
166
gaia/distros/spark/apps/studio/bower_components/gaia-list/index.html
vendored
Executable file
|
|
@ -0,0 +1,166 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><gaia-list></title>
|
||||
<meta name="description" content="gaia-list example" />
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-theme/gaia-base.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-theme/gaia-theme.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-fonts/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-icons/style.css">
|
||||
<script src="bower_components/gaia-theme/lib/gaia-theme-selector.js"></script>
|
||||
<script src="bower_components/gaia-icons/gaia-icons.js"></script>
|
||||
<script src="gaia-list.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
padding: 16px;
|
||||
padding-top: 48px;
|
||||
}
|
||||
|
||||
gaia-list.settings [data-icon='forward'] {
|
||||
color: var(--text-color-minus);
|
||||
}
|
||||
|
||||
gaia-list .divided {
|
||||
border-left: solid 1px;
|
||||
padding-left: 14px;
|
||||
|
||||
border-color:
|
||||
var(--border-color,
|
||||
var(--background-plus));
|
||||
}
|
||||
|
||||
gaia-list.contacts .face {
|
||||
position: absolute;
|
||||
top: 50%; right: 16px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-top: -20px;
|
||||
border-radius: 50%;
|
||||
border: solid 2px;
|
||||
|
||||
border-color:
|
||||
var(--border-color,
|
||||
var(--background-minus));
|
||||
background: var(--background-plus);
|
||||
}
|
||||
|
||||
gaia-list.email > * {
|
||||
padding-left: 32px !important;
|
||||
}
|
||||
|
||||
gaia-list.email time {
|
||||
position: absolute;
|
||||
right: 0; top: 0;
|
||||
margin: 9px 16px;
|
||||
font-size: 0.7em;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
gaia-list.email p {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
gaia-list.email .unread:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 16px; top: 50%;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
margin-top: -4px;
|
||||
border-radius: 50%;
|
||||
|
||||
background:
|
||||
var(--highlight-color);
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body role="application">
|
||||
<gaia-theme-selector></gaia-theme-selector>
|
||||
<h1 class="large l-align-center l-mb-mega"><gaia-list></h1>
|
||||
<section>
|
||||
<gaia-list class="settings l-mb-mega">
|
||||
<a>
|
||||
<i data-icon="brightness"></i><h3>Menu 1</h3><i data-icon="forward-light"></i></a>
|
||||
<a><i data-icon="location"></i><h3>Menu 2</h3><i data-icon="forward-light"></i></a>
|
||||
<a><i data-icon="settings"></i>Menu 3<i data-icon="forward-light"></i></a>
|
||||
<li>
|
||||
<label class="l-flex l-flex-grow" for="wifi-switch">
|
||||
<i data-icon="wifi-4"></i><h3>Wifi</h3>
|
||||
</label>
|
||||
<gaia-switch id="wifi-switch" class="divided"></gaia-switch>
|
||||
</li>
|
||||
</gaia-list>
|
||||
|
||||
<gaia-list class="contacts l-mb-mega">
|
||||
<a>
|
||||
<div>
|
||||
<h3>Noah Green</h3>
|
||||
<p>Atsara Kitchens</p>
|
||||
<div class="face"></div>
|
||||
</div>
|
||||
</a>
|
||||
<a>
|
||||
<div>
|
||||
<h3>Will Grand</h3>
|
||||
<p>CBN Studio</p>
|
||||
<div class="face"></div>
|
||||
</div>
|
||||
</a>
|
||||
<a>
|
||||
<div>
|
||||
<h3>Carolina Grey</h3>
|
||||
<p>Mozilla</p>
|
||||
<div class="face"></div>
|
||||
</div>
|
||||
</a>
|
||||
</gaia-list>
|
||||
|
||||
<gaia-list class="email">
|
||||
<a class="unread">
|
||||
<div>
|
||||
<h3>Will Gordan</h3>
|
||||
<p>Send photos please!</p>
|
||||
<p>You're the best, thank you so much for all</p><time>11:30AM</time>
|
||||
</div>
|
||||
</a>
|
||||
<a class="unread">
|
||||
<div>
|
||||
<h3>Jennifer Liu</h3>
|
||||
<p>Road trip next weekend</p>
|
||||
<p>I've been wanting to visit that place for a</p>
|
||||
<time>11:30AM</time>
|
||||
</div>
|
||||
</a>
|
||||
<a>
|
||||
<div>
|
||||
<h3>Michael Stanford</h3>
|
||||
<p>You might like this or not?</p>
|
||||
<p>Great find, I definitely check with Brian if</p>
|
||||
<time>11:30AM</time>
|
||||
</div>
|
||||
</a>
|
||||
<a class="unread">
|
||||
<div>
|
||||
<h3>Jennifer Liu</h3>
|
||||
<p>Road trip next weekend</p>
|
||||
<p>I'vee been wanting to visit that place for a</p>
|
||||
<time>11:30AM</time>
|
||||
</div>
|
||||
</a>
|
||||
<a>
|
||||
<div>
|
||||
<h3>Michael Stanford</h3>
|
||||
<p>You might like this or not?</p>
|
||||
<p>Great find, I definitely check with Brian if</p>
|
||||
<time>11:30AM</time>
|
||||
</div>
|
||||
</a>
|
||||
</gaia-list>
|
||||
</section>
|
||||
</body>
|
||||
</html>
|
||||
33
gaia/distros/spark/apps/studio/bower_components/gaia-text-input/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "gaia-text-input",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "script.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"gaia-icons": "gaia-components/gaia-icons"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gaia-fonts": "gaia-components/gaia-fonts#~0.2.1"
|
||||
},
|
||||
"homepage": "https://github.com/gaia-components/gaia-text-input",
|
||||
"_release": "9074942ea8",
|
||||
"_resolution": {
|
||||
"type": "branch",
|
||||
"branch": "master",
|
||||
"commit": "9074942ea876aaf0706b2dc6d8e7d21f5b880f41"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-text-input.git",
|
||||
"_target": "*",
|
||||
"_originalSource": "gaia-components/gaia-text-input",
|
||||
"_direct": true
|
||||
}
|
||||
23
gaia/distros/spark/apps/studio/bower_components/gaia-text-input/bower.json
vendored
Executable file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "gaia-text-input",
|
||||
"version": "0.1.0",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"main": "script.js",
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"gaia-icons": "gaia-components/gaia-icons"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gaia-fonts": "gaia-components/gaia-fonts#~0.2.1"
|
||||
}
|
||||
}
|
||||
190
gaia/distros/spark/apps/studio/bower_components/gaia-text-input/gaia-base.css
vendored
Executable file
|
|
@ -0,0 +1,190 @@
|
|||
|
||||
/** Variables
|
||||
---------------------------------------------------------*/
|
||||
|
||||
:root {
|
||||
--color-alpha: #333333;
|
||||
--color-beta: #ffffff;
|
||||
--color-gamma: #4d4d4d;
|
||||
--color-delta: #5f5f5f;
|
||||
--color-epsilon: #858585;
|
||||
--color-zeta: #a6a6a6;
|
||||
--color-eta: #c7c7c7;
|
||||
--color-theta: #e7e7e7;
|
||||
--color-iota: #f4f4f4;
|
||||
--button-transition: all 0s;
|
||||
--button-transition-delay: 300ms;
|
||||
|
||||
--dim-micro: 6px;
|
||||
--dim-small: 14px;
|
||||
--dim-mega: 60px;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Apply a natural box layout
|
||||
* model to all elements
|
||||
*/
|
||||
|
||||
*,
|
||||
*:after,
|
||||
*:before {
|
||||
box-sizing: border-box; /* 1 */
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "FiraSans";
|
||||
font-weight: 300;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/** Document
|
||||
---------------------------------------------------------*/
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
color: var(--color-epsilon);
|
||||
font-weight: normal;
|
||||
line-height: 21px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
/** Tags
|
||||
---------------------------------------------------------*/
|
||||
|
||||
a {
|
||||
color: var(--highlight-color, var(--color-brand-blue));
|
||||
text-decoration: none;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
background: var(--color-theta);
|
||||
height: 1px;
|
||||
margin: var(--dim-small) 0 var(--dim-small) 0;
|
||||
}
|
||||
|
||||
em {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.alpha {
|
||||
font-size: 23px;
|
||||
font-weight: 200;
|
||||
font-style: italic;
|
||||
line-height: 26px;
|
||||
margin: 6px 0 24px 0;
|
||||
}
|
||||
|
||||
.beta {
|
||||
font-size: 17px;
|
||||
font-weight: 400;
|
||||
margin: 32px 0 16px 0;
|
||||
}
|
||||
|
||||
.gamma {
|
||||
font-size: 14px;
|
||||
font-style: bold;
|
||||
text-transform: uppercase;
|
||||
font-weight: normal;
|
||||
color: var(--color-gamma);
|
||||
margin: 32px 0 16px 0;
|
||||
}
|
||||
|
||||
.milli {
|
||||
font-size: 14px;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.large {
|
||||
font-size: 23px;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
.mega {
|
||||
font-size: 60px;
|
||||
line-height: 60px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.giga {}
|
||||
.kilo {}
|
||||
|
||||
/* alignment */
|
||||
.l-align-right { float: right; }
|
||||
.l-align-left { float: left; }
|
||||
.l-align-center { text-align: center; }
|
||||
.l-text-align-left { text-align: left; }
|
||||
.l-text-align-right { text-align: right; }
|
||||
.l-text-valign-top {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.l-width-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/** Flexbox
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/* flex-item */
|
||||
.l-flex-grow { flex-grow: 1; }
|
||||
|
||||
/** Margin
|
||||
---------------------------------------------------------*/
|
||||
|
||||
/* margin-top */
|
||||
.l-mt-small { margin-top: var(--dim-small); }
|
||||
.l-mt-med { margin-top: var(--dim-medium); }
|
||||
/* margin-bottom */
|
||||
.l-mb-small { margin-bottom: var(--dim-small); }
|
||||
.l-mb-med { margin-bottom: var(--dim-medium); }
|
||||
.l-mb-large {}
|
||||
.l-mb-mega { margin-bottom: var(--dim-mega); }
|
||||
/* margin-left */
|
||||
.l-ml-small { margin-left: var(--dim-small); }
|
||||
/* margin-right */
|
||||
.l-mr-small { margin-right: var(--dim-small); }
|
||||
/* margin-auto */
|
||||
.l-mlr-auto { margin-left: auto; margin-right: auto; }
|
||||
.l-m-auto { margin: auto; }
|
||||
/* margin */
|
||||
.l-m-small { margin: var(--dim-small); }
|
||||
.l-m-med { margin: var(--dim-medium); }
|
||||
.l-m-0 { margin: 0 ;}
|
||||
|
||||
/** Padding
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.l-p-small { padding: var(--dim-small); }
|
||||
.l-pl-small { padding-left: var(--dim-small); }
|
||||
.l-pr-small { padding-right: var(--dim-small); }
|
||||
.l-pb-small { padding-bottom: var(--dim-small); }
|
||||
.l-pt-small { padding-top: var(--dim-small); }
|
||||
.l-pt-micro { padding-top: var(--dim-micro); }
|
||||
.l-pb-micro { padding-bottom: var(--dim-micro); }
|
||||
.l-p-0 { padding: 0 ;}
|
||||
|
||||
/** Helpers
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.l-clearfix:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.l-inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.is-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.is-invisible {
|
||||
visibility: hidden !important;
|
||||
}
|
||||
273
gaia/distros/spark/apps/studio/bower_components/gaia-text-input/gaia-text-input.js
vendored
Executable file
|
|
@ -0,0 +1,273 @@
|
|||
(function(define){define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Locals
|
||||
*/
|
||||
|
||||
var baseComponents = window.COMPONENTS_BASE_URL || 'bower_components/';
|
||||
var base = window.GAIA_TEXT_INPUT_BASE_URL || baseComponents + 'gaia-text-input/';
|
||||
|
||||
// Load gaia-icons
|
||||
//require('gaia-icons')(baseComponents);
|
||||
|
||||
/**
|
||||
* Extend from the `HTMLElement` prototype
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
|
||||
proto.createdCallback = function() {
|
||||
var shadow = this.createShadowRoot();
|
||||
var tmpl = template.content.cloneNode(true);
|
||||
|
||||
this.els = {
|
||||
inner: tmpl.querySelector('.inner'),
|
||||
input: tmpl.querySelector('.input'),
|
||||
clear: tmpl.querySelector('.clear')
|
||||
};
|
||||
|
||||
this.placeholder = this.getAttribute('placeholder');
|
||||
this.required = this.getAttribute('required');
|
||||
this.value = this.getAttribute('value');
|
||||
this.type = this.getAttribute('type');
|
||||
|
||||
// Don't take focus from the input field
|
||||
this.els.clear.addEventListener('mousedown', function(e) { e.preventDefault(); });
|
||||
this.els.clear.addEventListener('click', this.clear.bind(this));
|
||||
|
||||
shadow.appendChild(tmpl);
|
||||
this.styleHack();
|
||||
};
|
||||
|
||||
proto.styleHack = function() {
|
||||
var style = this.shadowRoot.querySelector('style');
|
||||
style.setAttribute('scoped', '');
|
||||
this.appendChild(style.cloneNode(true));
|
||||
};
|
||||
|
||||
|
||||
Object.defineProperties(proto, {
|
||||
type: {
|
||||
get: function() { return this.els.input.type; },
|
||||
set: function(value) {
|
||||
if (!value) { return; }
|
||||
this.els.inner.setAttribute('type', value);
|
||||
this.els.input.type = value;
|
||||
}
|
||||
},
|
||||
placeholder: {
|
||||
get: function() { return this.els.input.placeholder; },
|
||||
set: function(value) {
|
||||
if (!value) { return; }
|
||||
this.els.input.placeholder = value;
|
||||
}
|
||||
},
|
||||
value: {
|
||||
get: function() { return this.els.input.value; },
|
||||
set: function(value) { this.els.input.value = value; }
|
||||
},
|
||||
required: {
|
||||
get: function() { return this.els.input.required; },
|
||||
set: function(value) { this.els.input.required = value; }
|
||||
}
|
||||
});
|
||||
|
||||
proto.clear = function(e) {
|
||||
this.els.input.value = '';
|
||||
};
|
||||
|
||||
// HACK: Create a <template> in memory at runtime.
|
||||
// When the custom-element is created we clone
|
||||
// this template and inject into the shadow-root.
|
||||
// Prior to this we would have had to copy/paste
|
||||
// the template into the <head> of every app that
|
||||
// wanted to use <gaia-textinput>, this would make
|
||||
// markup changes complicated, and could lead to
|
||||
// things getting out of sync. This is a short-term
|
||||
// hack until we can import entire custom-elements
|
||||
// using HTML Imports (bug 877072).
|
||||
var template = document.createElement('template');
|
||||
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
|
||||
/** Reset
|
||||
---------------------------------------------------------*/
|
||||
|
||||
input, button {
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
gaia-text-input {
|
||||
display: block;
|
||||
}
|
||||
|
||||
:host() {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/** Label
|
||||
---------------------------------------------------------*/
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
display: block;
|
||||
margin: 0 0 4px 16px;
|
||||
}
|
||||
|
||||
/** Inner
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.input-container {
|
||||
--gi-border-color:
|
||||
var(--input-border-color,
|
||||
var(--border-color,
|
||||
var(--background-plus,
|
||||
#e7e7e7)));
|
||||
|
||||
position: relative;
|
||||
border-color: --gi-border-color;
|
||||
border:
|
||||
var(--input-border,
|
||||
var(--border,
|
||||
1px solid var(--gi-border-color)));
|
||||
}
|
||||
|
||||
/**
|
||||
* [type="search"]
|
||||
*/
|
||||
|
||||
[type='search'] .input-container {
|
||||
border-radius: 30px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/** Input Field
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.input {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
font-size: inherit;
|
||||
width: 100%;
|
||||
border: none;
|
||||
padding: 0 16px;
|
||||
margin: 0;
|
||||
font: inherit;
|
||||
color: var(--input-color, #000);
|
||||
background:
|
||||
var(--input-background,
|
||||
var(--background-minus,
|
||||
#fff));
|
||||
}
|
||||
|
||||
/** Placeholder Text
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.input::-moz-placeholder {
|
||||
font-style: italic;
|
||||
color: var(--input-placeholder-color, #909ca7);
|
||||
}
|
||||
|
||||
/** Clear Button
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.clear {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 10px;
|
||||
background: var(--input-clear-background, #999);
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-radius: 50%;
|
||||
opacity: 0;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/**
|
||||
* input:focus
|
||||
*/
|
||||
|
||||
.input:focus ~ .clear {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/** Clear Icon
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.clear:before {
|
||||
font-family: 'gaia-icons';
|
||||
content: 'close';
|
||||
display: block;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 19px;
|
||||
line-height: 1;
|
||||
margin-top: -2px;
|
||||
}
|
||||
|
||||
/** Focus Bar
|
||||
---------------------------------------------------------*/
|
||||
|
||||
.focus {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
transition: all 200ms;
|
||||
transform: scaleX(0);
|
||||
visibility: hidden;
|
||||
background: var(--highlight-color, #000);
|
||||
}
|
||||
|
||||
/**
|
||||
* input:focus
|
||||
*/
|
||||
|
||||
.input:focus ~ .focus {
|
||||
transform: scaleX(1);
|
||||
transition-delay: var(--button-transition-delay, 200ms);
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* search */
|
||||
// .input-search-container {
|
||||
// border-radius: 30px;
|
||||
// overflow: hidden;
|
||||
// }
|
||||
|
||||
// .input-search {
|
||||
// border-radius: 20px;
|
||||
// }
|
||||
|
||||
// .input-passcode {
|
||||
// width: 40px;
|
||||
// }
|
||||
|
||||
</style>
|
||||
|
||||
<div class="inner">
|
||||
<content select="label"></content>
|
||||
<div class="input-container">
|
||||
<input class="input" type="text"/>
|
||||
<button class="clear"></button>
|
||||
<div class="focus"></div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
// Register and return the constructor
|
||||
module.exports = document.registerElement('gaia-text-input', { prototype: proto });
|
||||
|
||||
});})((function(n,w){return typeof define=='function'&&define.amd?
|
||||
define:typeof module=='object'?function(c){c(require,exports,module);}:function(c){
|
||||
var m={exports:{}},r=function(n){return w[n];};w[n]=c(r,m.exports,m)||m.exports;};})('gaia-text-input',this));
|
||||
42
gaia/distros/spark/apps/studio/bower_components/gaia-text-input/index.html
vendored
Executable file
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><gaia-text-input></title>
|
||||
<meta name="description" content="gaia-text-input demo" />
|
||||
<link rel="stylesheet" type="text/css" href="gaia-base.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-theme/gaia-theme.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-fonts/style.css">
|
||||
<script src="bower_components/gaia-theme/lib/gaia-theme-selector.js"></script>
|
||||
<script src="bower_components/gaia-icons/script.js"></script>
|
||||
<script src="script.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
font-family: 'FiraSans';
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 16px;
|
||||
padding-top: 48px;
|
||||
background-color: var(--background);
|
||||
}
|
||||
|
||||
body > * {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body role="application">
|
||||
<gaia-theme-selector></gaia-theme-selector>
|
||||
|
||||
<h1 class="large l-align-center"><gaia-text-input></h1>
|
||||
|
||||
<gaia-text-input placeholder="Default"><label>Input Label</label></gaia-text-input>
|
||||
<gaia-text-input type="password" placeholder="Password"><label>Password</label></gaia-text-input>
|
||||
<gaia-text-input type="search" placeholder="Search..."><label>Search</label></gaia-text-input>
|
||||
</body>
|
||||
</html>
|
||||
36
gaia/distros/spark/apps/studio/bower_components/gaia-theme/.bower.json
vendored
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "gaia-theme",
|
||||
"version": "0.4.5",
|
||||
"homepage": "https://github.com/gaia-components/gaia-theme",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"!.jshintrc",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"index.html",
|
||||
"README.md"
|
||||
],
|
||||
"devDependencies": {
|
||||
"gaia-icons": "gaia-components/gaia-icons",
|
||||
"gaia-header": "gaia-components/gaia-header",
|
||||
"gaia-button": "gaia-components/gaia-button",
|
||||
"gaia-switch": "gaia-components/gaia-switch",
|
||||
"gaia-checkbox": "gaia-components/gaia-checkbox"
|
||||
},
|
||||
"_release": "0.4.5",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.4.5",
|
||||
"commit": "21def88c4aede2d634889302cd00962e057282af"
|
||||
},
|
||||
"_source": "git://github.com/gaia-components/gaia-theme.git",
|
||||
"_target": "~0.4.5",
|
||||
"_originalSource": "gaia-components/gaia-theme",
|
||||
"_direct": true
|
||||
}
|
||||
4
gaia/distros/spark/apps/studio/bower_components/gaia-theme/.jshintrc
vendored
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"strict": false,
|
||||
"node": true
|
||||
}
|
||||
26
gaia/distros/spark/apps/studio/bower_components/gaia-theme/bower.json
vendored
Executable file
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"name": "gaia-theme",
|
||||
"version": "0.4.5",
|
||||
"homepage": "https://github.com/gaia-components/gaia-theme",
|
||||
"authors": [
|
||||
"Wilson Page <wilsonpage@me.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"!.jshintrc",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests",
|
||||
"index.html",
|
||||
"README.md"
|
||||
],
|
||||
"devDependencies": {
|
||||
"gaia-icons": "gaia-components/gaia-icons",
|
||||
"gaia-header": "gaia-components/gaia-header",
|
||||
"gaia-button": "gaia-components/gaia-button",
|
||||
"gaia-switch": "gaia-components/gaia-switch",
|
||||
"gaia-checkbox": "gaia-components/gaia-checkbox"
|
||||
}
|
||||
}
|
||||
234
gaia/distros/spark/apps/studio/bower_components/gaia-theme/gaia-theme.css
vendored
Executable file
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
Gaia theme variables
|
||||
*/
|
||||
|
||||
|
||||
:root {
|
||||
|
||||
/** Grey Colors
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--color-alpha: #333333;
|
||||
--color-beta: #ffffff;
|
||||
--color-gamma: #4d4d4d;
|
||||
--color-delta: #5f5f5f;
|
||||
--color-epsilon: #858585;
|
||||
--color-zeta: #a6a6a6;
|
||||
--color-eta: #c7c7c7;
|
||||
--color-theta: #e7e7e7;
|
||||
--color-iota: #f4f4f4;
|
||||
|
||||
/** Brand Colors
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--color-darkblue: #00539f;
|
||||
--color-blue: #00caf2;
|
||||
--color-turquoise: #27c8c2;
|
||||
--color-darkorange: #e66000;
|
||||
--color-orange: #ff9500;
|
||||
--color-yellow: #ffcb00;
|
||||
--color-violet: #c40c84;
|
||||
|
||||
--color-warning: #fbbd3c;
|
||||
--color-destructive: #e2443a;
|
||||
--color-preffered: #00ba91;
|
||||
|
||||
/** Background
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--background: var(--color-beta);
|
||||
--background-plus: var(--color-theta);
|
||||
--background-minus: var(--color-zeta);
|
||||
|
||||
/** Borders
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--border-color: var(--color-theta);
|
||||
|
||||
/** Text Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--text-color: var(--color-gamma);
|
||||
--text-color-minus: var(--color-eta);
|
||||
|
||||
/** Button
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-background: var(--color-iota);
|
||||
|
||||
/** Links
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--link-color: var(--highlight-color);
|
||||
|
||||
/** Inputs
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--input-background: var(--color-beta);
|
||||
--input-color: var(--color-alpha);
|
||||
--input-clear-background: #909ca7;
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-box-shadow:
|
||||
inset 0 -1px 0 #d8d8d8,
|
||||
inset 0 1px 0 #eeeeee;
|
||||
--button-box-shadow-active: var(--button-box-shadow);
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-disabled-button-color: rgba(255,255,255,0.3);
|
||||
}
|
||||
|
||||
|
||||
.theme-productivity {
|
||||
|
||||
/** Brand Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--highlight-color: var(--color-orange);
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-background: var(--highlight-color);
|
||||
--header-color: var(--color-beta);
|
||||
}
|
||||
|
||||
.theme-communications {
|
||||
|
||||
/** Brand Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--highlight-color: var(--color-turquoise);
|
||||
|
||||
/** Links
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--link-color: #177874;
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-background: var(--highlight-color);
|
||||
--header-color: var(--color-beta);
|
||||
--header-icon-color: var(--color-beta);
|
||||
--header-button-color: var(--link-color);
|
||||
}
|
||||
|
||||
.theme-settings {
|
||||
|
||||
/** Background
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--background: var(--color-iota);
|
||||
--background-plus: var(--color-beta);
|
||||
--background-minus: var(--color-epsilon);
|
||||
--background-minus-minus: var(--color-zeta);
|
||||
|
||||
/** Highlight
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--highlight-color: var(--color-blue);
|
||||
|
||||
/** Borders
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--border-color: var(--color-theta);
|
||||
|
||||
/** Titles
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--title-color: var(--background-minus);
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-background: var(--background-plus);
|
||||
|
||||
/** Switch
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--switch-background: var(--background-minus-minus);
|
||||
|
||||
/** Checkbox
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--checkbox-border-color: var(--background-minus-minus);
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-color: var(--title-color);
|
||||
--header-background: var(--background);
|
||||
--header-button-color: var(--highlight-color);
|
||||
--header-disabled-button-color: var(--color-theta);
|
||||
--header-action-button-color: var(--title-color);
|
||||
}
|
||||
|
||||
.theme-media {
|
||||
|
||||
/** Highlight Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--highlight-color: var(--color-blue);
|
||||
|
||||
/** Background
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--background: var(--color-alpha);
|
||||
--background-plus: var(--color-gamma);
|
||||
--background-minus: #2B2B2B;
|
||||
--background-minus-minus: #1a1a1a;
|
||||
|
||||
/** Text Color
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--text-color: var(--color-beta);
|
||||
|
||||
/** Button
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-background: var(--background-plus);
|
||||
|
||||
/** Header
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--header-background: var(--background);
|
||||
--header-icon-color: var(--text-color);
|
||||
--header-button-color: var(--highlight-color);
|
||||
|
||||
/** Borders
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--border-color: var(--color-gamma);
|
||||
|
||||
/** Inputs
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--input-background: var(--background-plus);
|
||||
|
||||
/** Text Input
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--text-input-background: var(--background-minus);
|
||||
|
||||
/** Switch
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--switch-head-border-color: var(--background-minus-minus);
|
||||
--switch-background: var(--background-minus-minus);
|
||||
|
||||
/** Checkbox
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--checkbox-border-color: var(--background-minus-minus);
|
||||
|
||||
/** Buttons
|
||||
---------------------------------------------------------*/
|
||||
|
||||
--button-box-shadow: none;
|
||||
--button-box-shadow-active: none;
|
||||
}
|
||||
111
gaia/distros/spark/apps/studio/bower_components/gaia-theme/lib/gaia-theme-selector.js
vendored
Executable file
|
|
@ -0,0 +1,111 @@
|
|||
(function(define){'use strict';define(function(require,exports,module){
|
||||
/*jshint esnext:true*/
|
||||
|
||||
/**
|
||||
* Extend from the `HTMLElement` prototype
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
var proto = Object.create(HTMLElement.prototype);
|
||||
|
||||
proto.createdCallback = function() {
|
||||
this.createShadowRoot().innerHTML = template;
|
||||
|
||||
this.els = {
|
||||
themes: this.shadowRoot.querySelector('.themes'),
|
||||
rtl: this.shadowRoot.querySelector('.toggle-rtl')
|
||||
};
|
||||
|
||||
this.els.rtl.addEventListener('click', this.onRtlClick.bind(this));
|
||||
this.els.themes.addEventListener('click', this.onThemeClick.bind(this));
|
||||
this.styleHack();
|
||||
this.set(localStorage.theme || 'settings');
|
||||
};
|
||||
|
||||
proto.styleHack = function() {
|
||||
var style = this.shadowRoot.querySelector('style');
|
||||
style.setAttribute('scoped', '');
|
||||
this.appendChild(style.cloneNode(true));
|
||||
};
|
||||
|
||||
proto.onThemeClick = function(e) {
|
||||
var theme = e.target.value;
|
||||
if (theme) { this.set(theme); }
|
||||
};
|
||||
|
||||
proto.onRtlClick = function() {
|
||||
document.dir = this.els.rtl.checked ? 'rtl' : 'ltr';
|
||||
};
|
||||
|
||||
proto.set = function(theme) {
|
||||
var radio = this.shadowRoot.querySelector('[value="' + theme + '"]');
|
||||
document.body.classList.remove('theme-' + this.theme);
|
||||
document.body.classList.add('theme-' + theme);
|
||||
radio.checked = true;
|
||||
this.theme = theme;
|
||||
localStorage.theme = theme;
|
||||
};
|
||||
|
||||
var template = `
|
||||
<style>
|
||||
|
||||
* { margin: 0; padding: 0; }
|
||||
|
||||
gaia-theme-selector {
|
||||
position: fixed;
|
||||
top: 0; left: 0;
|
||||
z-index: 101;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background: rgba(255,255,255,0.8);
|
||||
color: #000;
|
||||
font-size: 9px;
|
||||
text-align: center;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,0.1);
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
form label {
|
||||
-moz-margin-start: 9px;
|
||||
}
|
||||
|
||||
form input {
|
||||
-moz-margin-end: 6px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.rtl {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<form>
|
||||
<label class="rtl"><input type="checkbox" class="toggle-rtl" />RTL</label>
|
||||
<span class="themes">
|
||||
<label><input type="radio" name="theme" value="productivity"/>Prod</label>
|
||||
<label><input type="radio" name="theme" value="communications"/>Comms</label>
|
||||
<label><input type="radio" name="theme" value="media"/>Media</label>
|
||||
<label><input type="radio" name="theme" value="settings"/>Settings</label>
|
||||
</span>
|
||||
</form>`;
|
||||
|
||||
document.registerElement('gaia-theme-selector', { prototype: proto });
|
||||
|
||||
});})((function(n,w){'use strict';return typeof define=='function'&&define.amd?
|
||||
define:typeof module=='object'?function(c){c(require,exports,module);}:
|
||||
function(c){var m={exports:{}},r=function(n){return w[n];};
|
||||
w[n]=c(r,m.exports,m)||m.exports;};})('gaia-theme-selector',this));
|
||||
84
gaia/distros/spark/apps/studio/css/app.css
Executable file
|
|
@ -0,0 +1,84 @@
|
|||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
section {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
menu {
|
||||
display: block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
gaia-list h3 {
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
|
||||
gaia-list .action.disabled {
|
||||
pointer-events: none;
|
||||
color: var(--header-disabled-button-color);
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
/* gaia-button forces the min-width we need to override. */
|
||||
/* Hence the !important */
|
||||
gaia-button.single {
|
||||
min-width: 90% !important;
|
||||
}
|
||||
|
||||
gaia-button.primary {
|
||||
--button-background: var(--color-blue);
|
||||
--text-color: var(--color-gamma);
|
||||
}
|
||||
|
||||
gaia-button.destructive {
|
||||
--button-background: var(--color-destructive);
|
||||
--text-color: var(--color-beta);
|
||||
}
|
||||
|
||||
a.navigation *, a.action *, a.edit * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
gaia-list span.group {
|
||||
text-transform: capitalize;
|
||||
font-size: 0.8em;
|
||||
min-height: auto;
|
||||
|
||||
background: linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5)),
|
||||
var(--highlight-color);
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
gaia-list span.group::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
gaia-list a.first::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#main gaia-list,
|
||||
#details-content {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: calc(100% - 50px);
|
||||
overflow: scroll;
|
||||
}
|
||||
68
gaia/distros/spark/apps/studio/css/autotheme.css
Executable file
|
|
@ -0,0 +1,68 @@
|
|||
.autotheme {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.autotheme a {
|
||||
display: flex;
|
||||
flex: auto;
|
||||
align-items: center;
|
||||
|
||||
color: var(--text-color);
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.autotheme i {
|
||||
width: unset;
|
||||
height: 21px; /* same as lineheight */
|
||||
margin-left: 1em;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.autotheme-palette {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
body:not(.has-autotheme) .hide-when-no-autotheme {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.palette-item {
|
||||
flex: 0 1 50px;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
border: 1px solid #ddd;
|
||||
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.palette-item:before{
|
||||
content: "";
|
||||
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
|
||||
.new-theme-dialog-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.new-theme-dialog-main label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-theme-title-input {
|
||||
flex: auto;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.autotheme h3 {
|
||||
flex: auto;
|
||||
text-align: start;
|
||||
}
|
||||
BIN
gaia/distros/spark/apps/studio/css/blueprint.png
Executable file
|
After Width: | Height: | Size: 3.7 KiB |
96
gaia/distros/spark/apps/studio/css/edit.css
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
#edit-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#edit-color {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
align-content: space-around;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
overflow: hidden;
|
||||
z-index: 10;
|
||||
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
#edit-color #catcher {
|
||||
flex: 1 0 calc(50% - 6px);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
#edit-color #controls {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
align-content: space-around;
|
||||
|
||||
flex: 1 0 50%;
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
#edit-color.editing {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
#edit-color gaia-color-picker {
|
||||
flex: 1 1 70%;
|
||||
width: 70%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.buttons-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.buttons-bar > gaia-button {
|
||||
flex: 1 0 40%;
|
||||
margin: 5px !important;
|
||||
min-width: 30% !important;
|
||||
}
|
||||
|
||||
#edit-color .buttons-bar {
|
||||
flex: 0 0 60px;
|
||||
}
|
||||
|
||||
#edit gaia-list li * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#edit gaia-list li span {
|
||||
color: var(--text-color-minus);
|
||||
}
|
||||
|
||||
#edit iframe {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: calc(50% - 50px - 6px);
|
||||
|
||||
border-top: 2px var(--border-color) solid;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 2px var(--border-color) solid;
|
||||
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#edit gaia-header h1 {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
16
gaia/distros/spark/apps/studio/css/navigation.css
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
.panel {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
|
||||
.panel.next {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.panel.back {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
1
gaia/distros/spark/apps/studio/data/en-US.properties
Executable file
|
|
@ -0,0 +1 @@
|
|||
app_title = FxOS Studio
|
||||
1
gaia/distros/spark/apps/studio/data/locales.ini
Executable file
|
|
@ -0,0 +1 @@
|
|||
@import url(en-US.properties)
|
||||
BIN
gaia/distros/spark/apps/studio/img/creative-kind.png
Executable file
|
After Width: | Height: | Size: 7 KiB |
BIN
gaia/distros/spark/apps/studio/img/default_image.jpg
Executable file
|
After Width: | Height: | Size: 128 KiB |
BIN
gaia/distros/spark/apps/studio/img/icons/studio_126.png
Executable file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
gaia/distros/spark/apps/studio/img/icons/studio_142.png
Executable file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
gaia/distros/spark/apps/studio/img/icons/studio_189.png
Executable file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
gaia/distros/spark/apps/studio/img/icons/studio_84.png
Executable file
|
After Width: | Height: | Size: 6 KiB |
145
gaia/distros/spark/apps/studio/index.html
Executable file
|
|
@ -0,0 +1,145 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>FxOS Studio</title>
|
||||
<meta name="description" content="Make it your own, share it with everyone.">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
|
||||
<link rel="stylesheet" href="css/app.css">
|
||||
<link rel="stylesheet" href="css/navigation.css">
|
||||
<link rel="stylesheet" href="css/edit.css">
|
||||
<link rel="stylesheet" href="css/autotheme.css">
|
||||
|
||||
<script type="text/javascript" src="js/defer.js" defer></script>
|
||||
<script type="text/javascript" src="js/theme_creator.js" defer></script>
|
||||
<script type="text/javascript" src="js/storage.js" defer></script>
|
||||
<script type="text/javascript" src="js/generation.js" defer></script>
|
||||
<script type="text/javascript" src="js/color.js" defer></script>
|
||||
|
||||
<script type="text/javascript" src="js/libs/zip.js" defer></script>
|
||||
<script type="text/javascript" src="js/libs/appzip.js" defer></script>
|
||||
<script type="text/javascript" src="js/libs/mime_mapper.js" defer></script>
|
||||
|
||||
<script src="js/ext/color-thief.js" defer></script>
|
||||
<script src="js/autotheme.js" defer></script>
|
||||
|
||||
<script type="text/javascript" src="js/main.js" defer></script>
|
||||
<script type="text/javascript" src="js/details.js" defer></script>
|
||||
<script type="text/javascript" src="js/edit.js" defer></script>
|
||||
<script type="text/javascript" src="js/navigation.js" defer></script>
|
||||
<script type="text/javascript" src="js/activity_handler.js" defer></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/base/base.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-theme/gaia-theme.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-fonts/style.css">
|
||||
<link rel="stylesheet" type="text/css" href="bower_components/gaia-icons/gaia-icons.css">
|
||||
|
||||
<script src="bower_components/gaia-component/gaia-component.js"></script>
|
||||
<script src="bower_components/gaia-icons/gaia-icons.js"></script>
|
||||
<script src="bower_components/gaia-header/dist/gaia-header.js"></script>
|
||||
<script src="bower_components/gaia-list/gaia-list.js"></script>
|
||||
<script src="bower_components/gaia-button/gaia-button.js"></script>
|
||||
<script src="bower_components/gaia-color-picker/gaia-color-picker.js"></script>
|
||||
<script src="bower_components/gaia-dialog/gaia-dialog.js"></script>
|
||||
<script src="bower_components/fxos-dev-mode-dialog/fxos-dev-mode-dialog.js"></script>
|
||||
<script src="bower_components/fxos-achievements-service/dist/achievements-service.js"></script>
|
||||
|
||||
<link rel="localization" href="data/{locale}.properties" />
|
||||
<script type="text/javascript" src="js/libs/l10n.js" defer></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="app://theme.gaiamobile.org/shared/elements/gaia-theme/gaia-theme.css">
|
||||
<meta name="theme-color" content="var(--header-background)">
|
||||
<meta name="theme-group" content="theme-settings">
|
||||
</head>
|
||||
<body class="theme-settings">
|
||||
<section id="main" class="panel">
|
||||
<fxos-dev-mode-dialog></fxos-dev-mode-dialog>
|
||||
<gaia-header title-end="50">
|
||||
<h1 data-l10n-id="app_title">Studio</h1>
|
||||
<button id="add-theme-button" data-icon="add"></button>
|
||||
</gaia-header>
|
||||
</section>
|
||||
<section id="details" class="panel next">
|
||||
<gaia-header>
|
||||
<h1></h1>
|
||||
</gaia-header>
|
||||
<div id="details-content">
|
||||
<div class="controls">
|
||||
<gaia-button id="duplicate-theme-button" class="action"
|
||||
data-action="fork">Duplicate</gaia-button>
|
||||
<gaia-button id="enable-theme-button" class="action primary"
|
||||
data-action="install">Enable</gaia-button>
|
||||
</div>
|
||||
<gaia-list>
|
||||
</gaia-list>
|
||||
<div class="controls">
|
||||
<gaia-button id="delete-theme-button" class="single action destructive"
|
||||
data-action="remove">Delete Theme</gaia-button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="edit" class="panel next">
|
||||
<gaia-header>
|
||||
<h1></h1>
|
||||
</gaia-header>
|
||||
<iframe></iframe>
|
||||
<div id="edit-list">
|
||||
</div>
|
||||
</section>
|
||||
<div id="edit-color">
|
||||
<div id="catcher" class="cancel"></div>
|
||||
<div id="controls">
|
||||
<div class='autotheme-palette hide-when-no-autotheme'></div>
|
||||
<gaia-color-picker value="#fff"></gaia-color-picker>
|
||||
<menu class='buttons-bar'>
|
||||
<gaia-button class="cancel">Cancel</gaia-button>
|
||||
<gaia-button class="save">Save</gaia-button>
|
||||
</menu>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<gaia-dialog id='new-theme-dialog'>
|
||||
<h1>Create a new theme</h1>
|
||||
<section class='new-theme-dialog-main'>
|
||||
<label>Title: <input type='text' class='new-theme-title-input'/></label>
|
||||
<div class='autotheme'>
|
||||
<a class="autotheme-command-create">
|
||||
<h3>Autotheme</h3>
|
||||
<i data-icon="forward-light"></i>
|
||||
</a>
|
||||
<a class='hide-when-no-autotheme'>
|
||||
<div class='autotheme-palette'></div>
|
||||
<i data-icon="close" class='autotheme-command-cancel'></i>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
<fieldset>
|
||||
<button class='cancel'>Cancel</button>
|
||||
<button class='primary confirm' disabled>Create</button>
|
||||
</fieldset>
|
||||
</gaia-dialog>
|
||||
|
||||
<gaia-dialog id='delete-theme-dialog'>
|
||||
<h1>Delete theme</h1>
|
||||
<section class='delete-theme-dialog-main'>
|
||||
Are you sure you want to delete this theme?
|
||||
</section>
|
||||
<fieldset>
|
||||
<button class='cancel'>Cancel</button>
|
||||
<button class='primary confirm'>Delete</button>
|
||||
</fieldset>
|
||||
</gaia-dialog>
|
||||
|
||||
<gaia-dialog id='duplicate-theme-dialog'>
|
||||
<h1>Duplicate theme</h1>
|
||||
<section class='duplicate-theme-dialog-main'>
|
||||
<label>Title: <input type='text' class='duplicate-theme-title-input'/></label>
|
||||
</section>
|
||||
<fieldset>
|
||||
<button class='cancel'>Cancel</button>
|
||||
<button class='primary confirm' disabled>Duplicate</button>
|
||||
</fieldset>
|
||||
</gaia-dialog>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
40
gaia/distros/spark/apps/studio/js/activity_handler.js
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
/*global
|
||||
AutoTheme,
|
||||
Main
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
(function(exports) {
|
||||
if (!window.navigator.mozSetMessageHandler) {
|
||||
return;
|
||||
}
|
||||
|
||||
const ActivityDataType = {
|
||||
IMAGE: 'image/*'
|
||||
};
|
||||
|
||||
var ActivityHandler = {
|
||||
onShareActivity(activity) {
|
||||
var activityData = activity.source.data;
|
||||
|
||||
if (activityData.type !== ActivityDataType.IMAGE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!activityData.blobs.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var image = activityData.blobs[0];
|
||||
Navigation.popToRoot().then(() => {
|
||||
Main.createTheme();
|
||||
AutoTheme.load(image);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
window.navigator.mozSetMessageHandler(
|
||||
'activity', ActivityHandler.onShareActivity.bind(ActivityHandler)
|
||||
);
|
||||
|
||||
})(window);
|
||||