├── www
├── .gitignore
├── css
│ └── style.css
├── img
│ └── ionic.png
├── lib
│ └── ionic
│ │ ├── fonts
│ │ ├── ionicons.eot
│ │ ├── ionicons.ttf
│ │ └── ionicons.woff
│ │ ├── version.json
│ │ ├── scss
│ │ ├── _progress.scss
│ │ ├── ionicons
│ │ │ ├── ionicons.scss
│ │ │ ├── _ionicons-font.scss
│ │ │ └── _ionicons-animation.scss
│ │ ├── _backdrop.scss
│ │ ├── _split-pane.scss
│ │ ├── ionic.scss
│ │ ├── _loading.scss
│ │ ├── _button-bar.scss
│ │ ├── _slide-box.scss
│ │ ├── _menu.scss
│ │ ├── _select.scss
│ │ ├── _radio.scss
│ │ ├── _badge.scss
│ │ ├── _action-sheet.scss
│ │ ├── _popup.scss
│ │ ├── _modal.scss
│ │ ├── _list.scss
│ │ ├── _range.scss
│ │ ├── _grid.scss
│ │ ├── _type.scss
│ │ ├── _platform.scss
│ │ ├── _checkbox.scss
│ │ ├── _toggle.scss
│ │ ├── _util.scss
│ │ ├── _form.scss
│ │ ├── _button.scss
│ │ ├── _scaffolding.scss
│ │ ├── _tabs.scss
│ │ ├── _reset.scss
│ │ ├── _bar.scss
│ │ ├── _mixins.scss
│ │ └── _items.scss
│ │ └── js
│ │ ├── angular
│ │ ├── angular-resource.min.js
│ │ ├── angular-sanitize.min.js
│ │ ├── angular-animate.min.js
│ │ └── angular-sanitize.js
│ │ └── angular-ui
│ │ └── angular-ui-router.min.js
├── templates
│ ├── tabs.html
│ ├── tab-scan.html
│ └── tab-about.html
├── js
│ ├── services.js
│ ├── controllers.js
│ └── app.js
├── README.md
├── index.html
└── config.xml
├── LICENSE
└── README.md
/www/.gitignore:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/www/css/style.css:
--------------------------------------------------------------------------------
1 | /* Empty. Add your own CSS if you like */
2 |
--------------------------------------------------------------------------------
/www/img/ionic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlinoff/PgBarcodeScanner/HEAD/www/img/ionic.png
--------------------------------------------------------------------------------
/www/lib/ionic/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlinoff/PgBarcodeScanner/HEAD/www/lib/ionic/fonts/ionicons.eot
--------------------------------------------------------------------------------
/www/lib/ionic/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlinoff/PgBarcodeScanner/HEAD/www/lib/ionic/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/www/lib/ionic/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jlinoff/PgBarcodeScanner/HEAD/www/lib/ionic/fonts/ionicons.woff
--------------------------------------------------------------------------------
/www/lib/ionic/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0.0-beta.9",
3 | "codename": "gadolinium-gator",
4 | "date": "2014-07-02",
5 | "time": "23:13:42"
6 | }
7 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_progress.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Progress
4 | * --------------------------------------------------
5 | */
6 |
7 | progress {
8 | display: block;
9 | margin: $progress-margin;
10 | width: $progress-width;
11 | }
12 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/ionicons/ionicons.scss:
--------------------------------------------------------------------------------
1 | @import "ionicons-variables";
2 | /*!
3 | Ionicons, v1.5.2
4 | Created by Ben Sperry for the Ionic Framework, http://ionicons.com/
5 | https://twitter.com/benjsperry https://twitter.com/ionicframework
6 | MIT License: https://github.com/driftyco/ionicons
7 | */
8 |
9 | @import "ionicons-font";
10 | @import "ionicons-animation";
11 | @import "ionicons-icons";
12 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_backdrop.scss:
--------------------------------------------------------------------------------
1 |
2 | .backdrop {
3 | position: fixed;
4 | top: 0;
5 | left: 0;
6 | z-index: $z-index-backdrop;
7 |
8 | width: 100%;
9 | height: 100%;
10 |
11 | background-color: rgba(0,0,0,0.4);
12 |
13 | visibility: hidden;
14 | opacity: 0;
15 |
16 | &.visible {
17 | visibility: visible;
18 | }
19 | &.active {
20 | opacity: 1;
21 | }
22 |
23 | @include transition(0.1s opacity linear);
24 | }
25 |
--------------------------------------------------------------------------------
/www/templates/tabs.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_split-pane.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Split Pane
4 | * --------------------------------------------------
5 | */
6 |
7 | .split-pane {
8 | @include display-flex();
9 | @include align-items(stretch);
10 | width: 100%;
11 | height: 100%;
12 | }
13 |
14 | .split-pane-menu {
15 | @include flex(0, 0, $split-pane-menu-width);
16 |
17 | overflow-y: auto;
18 | width: $split-pane-menu-width;
19 | height: 100%;
20 | border-right: 1px solid $split-pane-menu-border-color;
21 |
22 | @media all and (max-width: 568px) {
23 | border-right: none;
24 | }
25 | }
26 |
27 | .split-pane-content {
28 | @include flex(1, 0, auto);
29 | }
30 |
--------------------------------------------------------------------------------
/www/templates/tab-scan.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/ionic.scss:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 |
3 | @import
4 | // Ionicons
5 | "ionicons/ionicons.scss",
6 |
7 | // Variables
8 | "mixins",
9 | "variables",
10 |
11 | // Base
12 | "reset",
13 | "scaffolding",
14 | "type",
15 |
16 | // Components
17 | "action-sheet",
18 | "backdrop",
19 | "bar",
20 | "tabs",
21 | "menu",
22 | "modal",
23 | "popup",
24 | "loading",
25 | "items",
26 | "list",
27 | "badge",
28 | "slide-box",
29 | "split-pane",
30 |
31 | // Forms
32 | "form",
33 | "checkbox",
34 | "toggle",
35 | "radio",
36 | "range",
37 | "select",
38 | "progress",
39 |
40 | // Buttons
41 | "button",
42 | "button-bar",
43 |
44 | // Util
45 | "animations",
46 | "grid",
47 | "util",
48 | "platform";
49 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_loading.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Loading
4 | * --------------------------------------------------
5 | */
6 |
7 | .loading {
8 | @include transition(0.2s opacity linear);
9 |
10 | visibility: hidden;
11 | opacity: 0;
12 |
13 | &.visible {
14 | visibility: visible;
15 | }
16 | &.active {
17 | opacity: 1;
18 | }
19 |
20 | position: fixed;
21 | top: 50%;
22 | left: 50%;
23 |
24 | z-index: $z-index-loading;
25 | padding: $loading-padding;
26 |
27 | border-radius: $loading-border-radius;
28 | background-color: $loading-bg-color;
29 |
30 | color: $loading-text-color;
31 |
32 | text-align: center;
33 | text-overflow: ellipsis;
34 | font-size: $loading-font-size;
35 |
36 | h1, h2, h3, h4, h5, h6 {
37 | color: $loading-text-color;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/www/templates/tab-about.html:
--------------------------------------------------------------------------------
1 |
2 |
22 |
23 |
--------------------------------------------------------------------------------
/www/js/services.js:
--------------------------------------------------------------------------------
1 | angular.module('starter.services', [])
2 |
3 | .service('appServices', function appServices($q) {
4 | // Wrap the barcode scanner in a service so that it can be shared easily.
5 | this.scanBarcode = function() {
6 | // The plugin operates asynchronously so a promise
7 | // must be used to display the results correctly.
8 | var deferred = $q.defer();
9 | try {
10 | cordova.plugins.barcodeScanner.scan(
11 | function (result) { // success
12 | deferred.resolve({'error':false, 'result': result});
13 | },
14 | function (error) { // failure
15 | deferred.resolve({'error':true, 'result': error.toString()});
16 | }
17 | );
18 | }
19 | catch (exc) {
20 | deferred.resolve({'error':true, 'result': 'exception: ' + exc.toString()});
21 | }
22 | return deferred.promise;
23 | };
24 | });
25 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/ionicons/_ionicons-font.scss:
--------------------------------------------------------------------------------
1 | // Ionicons Font Path
2 | // --------------------------
3 |
4 | @font-face {
5 | font-family: $ionicons-font-family;
6 | src:url("#{$ionicons-font-path}/ionicons.eot?v=#{$ionicons-version}");
7 | src:url("#{$ionicons-font-path}/ionicons.eot?v=#{$ionicons-version}#iefix") format("embedded-opentype"),
8 | url("#{$ionicons-font-path}/ionicons.ttf?v=#{$ionicons-version}") format("truetype"),
9 | url("#{$ionicons-font-path}/ionicons.woff?v=#{$ionicons-version}") format("woff"),
10 | url("#{$ionicons-font-path}/ionicons.svg?v=#{$ionicons-version}#Ionicons") format("svg");
11 | font-weight: normal;
12 | font-style: normal;
13 | }
14 |
15 | .ion {
16 | display: inline-block;
17 | font-family: $ionicons-font-family;
18 | speak: none;
19 | font-style: normal;
20 | font-weight: normal;
21 | font-variant: normal;
22 | text-transform: none;
23 | text-rendering: auto;
24 | line-height: 1;
25 | -webkit-font-smoothing: antialiased;
26 | -moz-osx-font-smoothing: grayscale;
27 | }
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_button-bar.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Button Bar
4 | * --------------------------------------------------
5 | */
6 |
7 | .button-bar {
8 | @include display-flex();
9 | @include flex(1);
10 | width: 100%;
11 |
12 | &.button-bar-inline {
13 | display: block;
14 | width: auto;
15 |
16 | @include clearfix();
17 |
18 | > .button {
19 | width: auto;
20 | display: inline-block;
21 | float: left;
22 | }
23 | }
24 | }
25 |
26 | .button-bar > .button {
27 | @include flex(1);
28 | display: block;
29 |
30 | overflow: hidden;
31 |
32 | padding: 0 16px;
33 |
34 | width: 0;
35 |
36 | border-width: 1px 0px 1px 1px;
37 | border-radius: 0;
38 | text-align: center;
39 | text-overflow: ellipsis;
40 | white-space: nowrap;
41 |
42 | &:before,
43 | .icon:before {
44 | line-height: 44px;
45 | }
46 |
47 | &:first-child {
48 | border-radius: 2px 0px 0px 2px;
49 | }
50 | &:last-child {
51 | border-right-width: 1px;
52 | border-radius: 0px 2px 2px 0px;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_slide-box.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Slide Box
4 | * --------------------------------------------------
5 | */
6 |
7 | .slider {
8 | position: relative;
9 | visibility: hidden;
10 | // Make sure items don't scroll over ever
11 | overflow: hidden;
12 | }
13 |
14 | .slider-slides {
15 | position: relative;
16 | height: 100%;
17 | }
18 |
19 | .slider-slide {
20 | position: relative;
21 | display: block;
22 | float: left;
23 | width: 100%;
24 | height: 100%;
25 | vertical-align: top;
26 | }
27 |
28 | .slider-slide-image {
29 | > img {
30 | width: 100%;
31 | }
32 | }
33 |
34 | .slider-pager {
35 | position: absolute;
36 | bottom: 20px;
37 | z-index: $z-index-slider-pager;
38 | width: 100%;
39 | height: 15px;
40 | text-align: center;
41 |
42 | .slider-pager-page {
43 | display: inline-block;
44 | margin: 0px 3px;
45 | width: 15px;
46 | color: #000;
47 | text-decoration: none;
48 |
49 | opacity: 0.3;
50 |
51 | &.active {
52 | @include transition(opacity 0.4s ease-in);
53 | opacity: 1;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Joe Linoff
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_menu.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Menus
4 | * --------------------------------------------------
5 | * Side panel structure
6 | */
7 |
8 | .menu {
9 | position: absolute;
10 | top: 0;
11 | bottom: 0;
12 | z-index: $z-index-menu;
13 | overflow: hidden;
14 |
15 | min-height: 100%;
16 | max-height: 100%;
17 | width: $menu-width;
18 |
19 | background-color: $menu-bg;
20 |
21 | .scroll-content {
22 | z-index: $z-index-menu-scroll-content;
23 | }
24 |
25 | .bar-header {
26 | z-index: $z-index-menu-bar-header;
27 | }
28 | }
29 |
30 | .menu-content {
31 | @include transform(none);
32 | box-shadow: $menu-side-shadow;
33 | }
34 |
35 | .menu-open .menu-content .pane,
36 | .menu-open .menu-content .scroll-content {
37 | pointer-events: none;
38 | }
39 |
40 | .grade-b .menu-content,
41 | .grade-c .menu-content {
42 | @include box-sizing(content-box);
43 | right: -1px;
44 | left: -1px;
45 | border-right: 1px solid #ccc;
46 | border-left: 1px solid #ccc;
47 | box-shadow: none;
48 | }
49 |
50 | .menu-left {
51 | left: 0;
52 | }
53 |
54 | .menu-right {
55 | right: 0;
56 | }
57 |
58 | .menu-animated {
59 | @include transition-transform($menu-animation-speed ease);
60 | }
61 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_select.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Select
4 | * --------------------------------------------------
5 | */
6 |
7 | .item-select {
8 | position: relative;
9 |
10 | select {
11 | @include appearance(none);
12 | position: absolute;
13 | top: 0;
14 | right: 0;
15 | padding: ($item-padding - 2) ($item-padding * 3) ($item-padding) $item-padding;
16 | max-width: 65%;
17 |
18 | border: none;
19 | background: transparent;
20 | color: #333;
21 |
22 | // hack to hide default dropdown arrow in FF
23 | text-indent: .01px;
24 | text-overflow: '';
25 |
26 | white-space: nowrap;
27 | font-size: $font-size-base;
28 |
29 | cursor: pointer;
30 | direction: rtl; // right align the select text
31 | }
32 |
33 | select::-ms-expand {
34 | // hide default dropdown arrow in IE
35 | display: none;
36 | }
37 |
38 | option {
39 | direction: ltr;
40 | }
41 |
42 | &:after {
43 | position: absolute;
44 | top: 50%;
45 | right: $item-padding;
46 | margin-top: -3px;
47 | width: 0;
48 | height: 0;
49 | border-top: 5px solid;
50 | border-right: 5px solid rgba(0, 0, 0, 0);
51 | border-left: 5px solid rgba(0, 0, 0, 0);
52 | color: #999;
53 | content: "";
54 | pointer-events: none;
55 | }
56 | }
57 |
58 | select {
59 | &[multiple],
60 | &[size] {
61 | height: auto;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/www/README.md:
--------------------------------------------------------------------------------
1 | This is an addon starter template for the [Ionic Framework](http://ionicframework.com/).
2 |
3 | ## How to use this template
4 |
5 | *This template does not work on its own*. It is missing the Ionic library, and AngularJS.
6 |
7 | To use this, either create a new ionic project using the ionic node.js utility, or copy and paste this into an existing Cordova project and download a release of Ionic separately.
8 |
9 | ### With the Ionic tool:
10 |
11 | Take the name after `ionic-starter-`, and that is the name of the template to be used when using the `ionic start` command below:
12 |
13 | ```bash
14 | $ sudo npm install -g ionic cordova
15 | $ ionic start myApp tabs
16 | ```
17 |
18 | Then, to run it, cd into `myApp` and run:
19 |
20 | ```bash
21 | $ ionic platform add ios
22 | $ ionic build ios
23 | $ ionic emulate ios
24 | ```
25 |
26 | Substitute ios for android if not on a Mac, but if you can, the ios development toolchain is a lot easier to work with until you need to do anything custom to Android.
27 |
28 | ## Demo
29 | http://plnkr.co/edit/qYMCrt?p=preview
30 |
31 | ## Issues
32 | Issues have been disabled on this repo, if you do find an issue or have a question consider posting it on the [Ionic Forum](http://forum.ionicframework.com/). Or else if there is truly an error, follow our guidelines for [submitting an issue](http://ionicframework.com/contribute/#issues) to the main Ionic repository. On the other hand, pull requests are welcome here!
33 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_radio.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Radio Button Inputs
4 | * --------------------------------------------------
5 | */
6 |
7 | .item-radio {
8 | padding: 0;
9 |
10 | &:hover {
11 | cursor: pointer;
12 | }
13 | }
14 |
15 | .item-radio .item-content {
16 | /* give some room to the right for the checkmark icon */
17 | padding-right: $item-padding * 4;
18 | }
19 |
20 | .item-radio .radio-icon {
21 | /* checkmark icon will be hidden by default */
22 | position: absolute;
23 | top: 0;
24 | right: 0;
25 | z-index: $z-index-item-radio;
26 | visibility: hidden;
27 | padding: $item-padding - 2;
28 | height: 100%;
29 | font-size: 24px;
30 | }
31 |
32 | .item-radio input {
33 | /* hide any radio button inputs elements (the ugly circles) */
34 | position: absolute;
35 | left: -9999px;
36 |
37 | &:checked ~ .item-content {
38 | /* style the item content when its checked */
39 | background: #f7f7f7;
40 | }
41 |
42 | &:checked ~ .radio-icon {
43 | /* show the checkmark icon when its checked */
44 | visibility: visible;
45 | }
46 | }
47 |
48 | // Hack for Android to correctly display the checked item
49 | // http://timpietrusky.com/advanced-checkbox-hack
50 | .platform-android.grade-b .item-radio,
51 | .platform-android.grade-c .item-radio {
52 | -webkit-animation: androidCheckedbugfix infinite 1s;
53 | }
54 | @-webkit-keyframes androidCheckedbugfix {
55 | from { padding: 0; }
56 | to { padding: 0; }
57 | }
58 |
--------------------------------------------------------------------------------
/www/js/controllers.js:
--------------------------------------------------------------------------------
1 | angular.module('starter.controllers', [])
2 |
3 | .controller('ScanCtrl', function($scope, appServices) {
4 | $scope.message = '';
5 | $scope.click = function() {
6 | var promise = appServices.scanBarcode();
7 | promise.then(
8 | function(result) {
9 | if (result.error == false) {
10 | var d = new Date();
11 | $scope.message = '
' +
12 | '' +
13 | 'Timestamp: ' + d.toUTCString() + ' ' +
14 | 'Text: ' + result.result.text + ' ' +
15 | 'Format: ' + result.result.format + ' ' +
16 | 'Text: ' + result.result.cancelled + ' ' +
17 | ' ' +
18 | '
';
19 | }
20 | else {
21 | $scope.message = 'ERROR : ' + result;
22 | }
23 | },
24 | function(result) {
25 | $scope.message = '' + result.error;
26 | },
27 | function(result) {
28 | $scope.message = '' + result.error;
29 | });
30 | }
31 |
32 | $scope.clear = function() {
33 | $scope.message = '';
34 | }
35 | })
36 |
37 | .controller('AboutCtrl', function($scope) {
38 | })
39 |
40 |
--------------------------------------------------------------------------------
/www/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 | Back
33 |
34 |
35 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/www/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 | PgBarcodeScanner
8 |
9 | Demonstrate how the phonegap barcode scanner is used.
10 |
11 |
12 | Joe Linoff
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_badge.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Badges
4 | * --------------------------------------------------
5 | */
6 |
7 | .badge {
8 | @include badge-style($badge-default-bg, $badge-default-text);
9 | z-index: $z-index-badge;
10 | display: inline-block;
11 | padding: 3px 8px;
12 | min-width: 10px;
13 | border-radius: $badge-border-radius;
14 | vertical-align: baseline;
15 | text-align: center;
16 | white-space: nowrap;
17 | font-weight: $badge-font-weight;
18 | font-size: $badge-font-size;
19 | line-height: $badge-line-height;
20 |
21 | &:empty {
22 | display: none;
23 | }
24 | }
25 |
26 | //Be sure to override specificity of rule that 'badge color matches tab color by default'
27 | .tabs .tab-item .badge,
28 | .badge {
29 | &.badge-light {
30 | @include badge-style($badge-light-bg, $badge-light-text);
31 | }
32 | &.badge-stable {
33 | @include badge-style($badge-stable-bg, $badge-stable-text);
34 | }
35 | &.badge-positive {
36 | @include badge-style($badge-positive-bg, $badge-positive-text);
37 | }
38 | &.badge-calm {
39 | @include badge-style($badge-calm-bg, $badge-calm-text);
40 | }
41 | &.badge-assertive {
42 | @include badge-style($badge-assertive-bg, $badge-assertive-text);
43 | }
44 | &.badge-balanced {
45 | @include badge-style($badge-balanced-bg, $badge-balanced-text);
46 | }
47 | &.badge-energized {
48 | @include badge-style($badge-energized-bg, $badge-energized-text);
49 | }
50 | &.badge-royal {
51 | @include badge-style($badge-royal-bg, $badge-royal-text);
52 | }
53 | &.badge-dark {
54 | @include badge-style($badge-dark-bg, $badge-dark-text);
55 | }
56 | }
57 |
58 | // Quick fix for labels/badges in buttons
59 | .button .badge {
60 | position: relative;
61 | top: -1px;
62 | }
63 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_action-sheet.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Action Sheets
3 | * --------------------------------------------------
4 | */
5 |
6 | .action-sheet-backdrop {
7 | @include transition(background-color 300ms ease-in-out);
8 | position: fixed;
9 | top: 0;
10 | left: 0;
11 | z-index: $z-index-action-sheet;
12 | width: 100%;
13 | height: 100%;
14 | background-color: rgba(0,0,0,0);
15 |
16 | &.active {
17 | background-color: rgba(0,0,0,0.5);
18 | }
19 | }
20 |
21 | .action-sheet-wrapper {
22 | @include translate3d(0, 100%, 0);
23 | @include transition(all ease-in-out 300ms);
24 | position: absolute;
25 | bottom: 0;
26 | width: 100%;
27 | }
28 |
29 | .action-sheet-up {
30 | @include translate3d(0, 0, 0);
31 | }
32 |
33 | .action-sheet {
34 | margin-left: 15px;
35 | margin-right: 15px;
36 | width: auto;
37 | z-index: $z-index-action-sheet;
38 | overflow: hidden;
39 |
40 | .button {
41 | display: block;
42 | padding: 1px;
43 | width: 100%;
44 | border-radius: 0;
45 |
46 | background-color: transparent;
47 |
48 | color: $positive;
49 | font-size: 18px;
50 |
51 | &.destructive {
52 | color: $assertive;
53 | }
54 | }
55 | }
56 |
57 | .action-sheet-title {
58 | padding: 10px;
59 | color: lighten($base-color, 40%);
60 | text-align: center;
61 | font-size: 12px;
62 | }
63 |
64 | .action-sheet-group {
65 | margin-bottom: 5px;
66 | border-radius: $sheet-border-radius;
67 | background-color: #fff;
68 | .button {
69 | border-width: 1px 0px 0px 0px;
70 | border-radius: 0;
71 |
72 | &.active {
73 | background-color: transparent;
74 | color: inherit;
75 | }
76 | }
77 | .button:first-child:last-child {
78 | border-width: 0;
79 | }
80 | }
81 |
82 | .action-sheet-open {
83 | pointer-events: none;
84 |
85 | &.modal-open .modal {
86 | pointer-events: none;
87 | }
88 |
89 | .action-sheet-backdrop {
90 | pointer-events: auto;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_popup.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Popups
4 | * --------------------------------------------------
5 | */
6 |
7 | .popup {
8 | position: fixed;
9 | top: 50%;
10 | left: 50%;
11 | z-index: $z-index-popup;
12 |
13 | // Start hidden
14 | visibility: hidden;
15 |
16 | width: $popup-width;
17 | max-width: 100%;
18 |
19 | border-radius: $popup-border-radius;
20 | background-color: $popup-background-color;
21 |
22 | &.popup-hidden {
23 | @include animation-name(scaleOut);
24 | @include animation-duration($popup-leave-animation-duration);
25 | @include animation-timing-function(ease-in-out);
26 | @include animation-fill-mode(both);
27 | }
28 |
29 | &.popup-showing {
30 | visibility: visible;
31 | }
32 |
33 | &.active {
34 | @include animation-name(superScaleIn);
35 | @include animation-duration($popup-enter-animation-duration);
36 | @include animation-timing-function(ease-in-out);
37 | @include animation-fill-mode(both);
38 | }
39 | &.popup-tall{
40 | overflow:hidden;
41 | .popup-body{
42 | overflow:auto;
43 | }
44 | }
45 | }
46 |
47 | .popup-head {
48 | padding: 15px 0px;
49 | border-bottom: 1px solid #eee;
50 | text-align: center;
51 | }
52 | .popup-title {
53 | margin: 0;
54 | padding: 0;
55 | font-size: 15px;
56 | }
57 | .popup-sub-title {
58 | margin: 5px 0 0 0;
59 | padding: 0;
60 | font-weight: normal;
61 | font-size: 11px;
62 | }
63 | .popup-body {
64 | padding: 10px;
65 | }
66 |
67 | .popup-buttons {
68 | &.row {
69 | padding: 10px 10px;
70 | }
71 |
72 | .button {
73 | margin: 0px 5px;
74 | min-height: $popup-button-min-height;
75 | border-radius: $popup-button-border-radius;
76 | line-height: $popup-button-line-height;
77 |
78 | &:first-child {
79 | margin-left: 0px;
80 | }
81 | &:last-child {
82 | margin-right: 0px;
83 | }
84 | }
85 | }
86 |
87 | .popup-open {
88 | pointer-events: none;
89 |
90 | &.modal-open .modal {
91 | pointer-events: none;
92 | }
93 |
94 | .popup-backdrop, .popup {
95 | pointer-events: auto;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_modal.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Modals
4 | * --------------------------------------------------
5 | * Modals are independent windows that slide in from off-screen.
6 | */
7 |
8 | .modal-backdrop {
9 | @include transition(background-color 300ms ease-in-out);
10 | position: fixed;
11 | top: 0;
12 | left: 0;
13 | z-index: $z-index-modal;
14 | width: 100%;
15 | height: 100%;
16 | background-color: $modal-backdrop-bg-inactive;
17 |
18 | &.active {
19 | background-color: $modal-backdrop-bg-active;
20 | }
21 | }
22 |
23 | .modal {
24 | position: absolute;
25 | top: 0;
26 | z-index: $z-index-modal;
27 | overflow: hidden;
28 | min-height: 100%;
29 | width: 100%;
30 | background-color: $modal-bg-color;
31 | }
32 |
33 | @media (min-width: $modal-inset-mode-break-point) {
34 | // inset mode is when the modal doesn't fill the entire
35 | // display but instead is centered within a large display
36 | .modal {
37 | top: $modal-inset-mode-top;
38 | right: $modal-inset-mode-right;
39 | bottom: $modal-inset-mode-bottom;
40 | left: $modal-inset-mode-left;
41 | overflow: visible;
42 | min-height: $modal-inset-mode-min-height;
43 | width: (100% - $modal-inset-mode-left - $modal-inset-mode-right);
44 | }
45 |
46 | .modal.ng-leave-active {
47 | bottom: 0;
48 | }
49 |
50 | // remove ios header padding from inset header
51 | .platform-ios.platform-cordova .modal-wrapper .modal{
52 | .bar-header:not(.bar-subheader) {
53 | height: $bar-height;
54 | > * {
55 | margin-top: 0;
56 | }
57 | }
58 | .tabs-top > .tabs,
59 | .tabs.tabs-top {
60 | top: $bar-height;
61 | }
62 | .has-header,
63 | .bar-subheader {
64 | top: $bar-height;
65 | }
66 | .has-subheader {
67 | top: (2 * $bar-height);
68 | }
69 | .has-tabs-top {
70 | top: $bar-height + $tabs-height;
71 | }
72 | .has-header.has-subheader.has-tabs-top {
73 | top: 2 * $bar-height + $tabs-height;
74 | }
75 | }
76 | }
77 |
78 | .modal-open {
79 | pointer-events: none;
80 |
81 | .modal,
82 | .modal-backdrop {
83 | pointer-events: auto;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/ionicons/_ionicons-animation.scss:
--------------------------------------------------------------------------------
1 | // Animation Icons
2 | // --------------------------
3 |
4 | .#{$ionicons-prefix}spin {
5 | -webkit-animation: spin 1s infinite linear;
6 | -moz-animation: spin 1s infinite linear;
7 | -o-animation: spin 1s infinite linear;
8 | animation: spin 1s infinite linear;
9 | }
10 |
11 | @-moz-keyframes spin {
12 | 0% { -moz-transform: rotate(0deg); }
13 | 100% { -moz-transform: rotate(359deg); }
14 | }
15 | @-webkit-keyframes spin {
16 | 0% { -webkit-transform: rotate(0deg); }
17 | 100% { -webkit-transform: rotate(359deg); }
18 | }
19 | @-o-keyframes spin {
20 | 0% { -o-transform: rotate(0deg); }
21 | 100% { -o-transform: rotate(359deg); }
22 | }
23 | @-ms-keyframes spin {
24 | 0% { -ms-transform: rotate(0deg); }
25 | 100% { -ms-transform: rotate(359deg); }
26 | }
27 | @keyframes spin {
28 | 0% { transform: rotate(0deg); }
29 | 100% { transform: rotate(359deg); }
30 | }
31 |
32 |
33 | .#{$ionicons-prefix}loading-a,
34 | .#{$ionicons-prefix}loading-b,
35 | .#{$ionicons-prefix}loading-c,
36 | .#{$ionicons-prefix}loading-d,
37 | .#{$ionicons-prefix}looping,
38 | .#{$ionicons-prefix}refreshing,
39 | .#{$ionicons-prefix}ios7-reloading {
40 | @extend .ion;
41 | @extend .#{$ionicons-prefix}spin;
42 | }
43 |
44 | .#{$ionicons-prefix}loading-a {
45 | -webkit-animation-timing-function: steps(8, start);
46 | -moz-animation-timing-function: steps(8, start);
47 | animation-timing-function: steps(8, start);
48 | }
49 |
50 | .#{$ionicons-prefix}loading-a:before {
51 | @extend .#{$ionicons-prefix}load-a:before;
52 | }
53 |
54 | .#{$ionicons-prefix}loading-b:before {
55 | @extend .#{$ionicons-prefix}load-b:before;
56 | }
57 |
58 | .#{$ionicons-prefix}loading-c:before {
59 | @extend .#{$ionicons-prefix}load-c:before;
60 | }
61 |
62 | .#{$ionicons-prefix}loading-d:before {
63 | @extend .#{$ionicons-prefix}load-d:before;
64 | }
65 |
66 | .#{$ionicons-prefix}looping:before {
67 | @extend .#{$ionicons-prefix}loop:before;
68 | }
69 |
70 | .#{$ionicons-prefix}refreshing:before {
71 | @extend .#{$ionicons-prefix}refresh:before;
72 | }
73 |
74 | .#{$ionicons-prefix}ios7-reloading:before {
75 | @extend .#{$ionicons-prefix}ios7-reload:before;
76 | }
77 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_list.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Lists
4 | * --------------------------------------------------
5 | */
6 |
7 | .list {
8 | position: relative;
9 | padding-top: $item-border-width;
10 | padding-bottom: $item-border-width;
11 | padding-left: 0; // reset padding because ul and ol
12 | margin-bottom: 20px;
13 | }
14 | .list:last-child {
15 | margin-bottom: 0px;
16 | }
17 |
18 |
19 | /**
20 | * List Header
21 | * --------------------------------------------------
22 | */
23 |
24 | .list-header {
25 | margin-top: $list-header-margin-top;
26 | padding: $list-header-padding;
27 | background-color: $list-header-bg;
28 | color: $list-header-color;
29 | font-weight: bold;
30 | }
31 |
32 | // when its a card make sure it doesn't duplicate top and bottom borders
33 | .card.list .list-item {
34 | padding-right: 1px;
35 | padding-left: 1px;
36 | }
37 |
38 |
39 | /**
40 | * Cards and Inset Lists
41 | * --------------------------------------------------
42 | * A card and list-inset are close to the same thing, except a card as a box shadow.
43 | */
44 |
45 | .card,
46 | .list-inset {
47 | overflow: hidden;
48 | margin: ($content-padding * 2) $content-padding;
49 | border-radius: $card-border-radius;
50 | background-color: $card-body-bg;
51 | }
52 |
53 | .card {
54 | padding-top: $item-border-width;
55 | padding-bottom: $item-border-width;
56 | box-shadow: 0 1px 1px rgba(0, 0, 0, .1);
57 | }
58 |
59 | .card .item,
60 | .list-inset .item,
61 | .padding > .list .item
62 | {
63 | &:first-child {
64 | border-top-left-radius: $card-border-radius;
65 | border-top-right-radius: $card-border-radius;
66 |
67 | .item-content {
68 | border-top-left-radius: $card-border-radius;
69 | border-top-right-radius: $card-border-radius;
70 | }
71 | }
72 | &:last-child {
73 | border-bottom-right-radius: $card-border-radius;
74 | border-bottom-left-radius: $card-border-radius;
75 |
76 | .item-content {
77 | border-bottom-right-radius: $card-border-radius;
78 | border-bottom-left-radius: $card-border-radius;
79 | }
80 | }
81 | }
82 |
83 | .card .item:last-child,
84 | .list-inset .item:last-child {
85 | margin-bottom: $item-border-width * -1;
86 | }
87 |
88 | .card .item,
89 | .list-inset .item,
90 | .padding > .list .item,
91 | .padding-horizontal > .list .item {
92 | margin-right: 0;
93 | margin-left: 0;
94 |
95 | &.item-input input {
96 | padding-right: 44px;
97 | }
98 | }
99 | .padding-left > .list .item {
100 | margin-left: 0;
101 | }
102 | .padding-right > .list .item {
103 | margin-right: 0;
104 | }
105 |
--------------------------------------------------------------------------------
/www/js/app.js:
--------------------------------------------------------------------------------
1 | // Ionic Starter App
2 |
3 | // angular.module is a global place for creating, registering and retrieving Angular modules
4 | // 'starter' is the name of this angular module example (also set in a attribute in index.html)
5 | // the 2nd parameter is an array of 'requires'
6 | // 'starter.services' is found in services.js
7 | // 'starter.controllers' is found in controllers.js
8 | angular.module('starter', ['ionic',
9 | 'starter.controllers',
10 | 'starter.services'])
11 |
12 | .run(function($ionicPlatform) {
13 | $ionicPlatform.ready(function() {
14 | // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
15 | // for form inputs)
16 | // if(window.cordova && window.cordova.plugins.Keyboard) {
17 | // cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
18 | // }
19 | // if(window.StatusBar) {
20 | // // org.apache.cordova.statusbar required
21 | // StatusBar.styleDefault();
22 | // }
23 | if (!!navigator.splashscreen) {
24 | navigator.splashscreen.hide();
25 | }
26 |
27 | });
28 | })
29 |
30 | .config(function($stateProvider, $urlRouterProvider) {
31 |
32 | // Ionic uses AngularUI Router which uses the concept of states
33 | // Learn more here: https://github.com/angular-ui/ui-router
34 | // Set up the various states which the app can be in.
35 | // Each state's controller can be found in controllers.js
36 | $stateProvider
37 |
38 | // setup an abstract state for the tabs directive
39 | .state('tab', {
40 | url: "/tab",
41 | abstract: true,
42 | templateUrl: "templates/tabs.html"
43 | })
44 |
45 | // Each tab has its own nav history stack:
46 | .state('tab.scan', {
47 | url: '/scan',
48 | views: {
49 | 'tab-scan': {
50 | templateUrl: 'templates/tab-scan.html',
51 | controller: 'ScanCtrl'
52 | }
53 | }
54 | })
55 |
56 | .state('tab.about', {
57 | url: '/about',
58 | views: {
59 | 'tab-about': {
60 | templateUrl: 'templates/tab-about.html',
61 | controller: 'AboutCtrl'
62 | }
63 | }
64 | })
65 |
66 | // if none of the above states are matched, use this as the fallback
67 | $urlRouterProvider.otherwise('/tab/scan');
68 |
69 | });
70 |
71 |
--------------------------------------------------------------------------------
/www/lib/ionic/js/angular/angular-resource.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.17
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(H,a,A){'use strict';function D(p,g){g=g||{};a.forEach(g,function(a,c){delete g[c]});for(var c in p)!p.hasOwnProperty(c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(g[c]=p[c]);return g}var v=a.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;a.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(p,g){function c(a,c){this.template=a;this.defaults=c||{};this.urlParams={}}function t(n,w,l){function r(h,d){var e={};d=x({},w,d);s(d,function(b,d){u(b)&&(b=b());var k;if(b&&
7 | b.charAt&&"@"==b.charAt(0)){k=h;var a=b.substr(1);if(null==a||""===a||"hasOwnProperty"===a||!C.test("."+a))throw v("badmember",a);for(var a=a.split("."),f=0,c=a.length;f * {
112 | margin-top: $ios-statusbar-height;
113 | }
114 | }
115 | .tabs-top > .tabs,
116 | .tabs.tabs-top {
117 | top: $bar-height + $ios-statusbar-height;
118 | }
119 |
120 | .has-header,
121 | .bar-subheader {
122 | top: $bar-height + $ios-statusbar-height;
123 | }
124 | .has-subheader {
125 | top: (2 * $bar-height) + $ios-statusbar-height;
126 | }
127 | .has-tabs-top {
128 | top: $bar-height + $tabs-height + $ios-statusbar-height;
129 | }
130 | .has-header.has-subheader.has-tabs-top {
131 | top: 2 * $bar-height + $tabs-height + $ios-statusbar-height;
132 | }
133 | }
134 | &.status-bar-hide {
135 | // Cordova doesn't adjust the body height correctly, this makes up for it
136 | margin-bottom: 20px;
137 | }
138 | }
139 |
140 | @media (orientation:landscape) {
141 | .platform-ios.platform-browser.platform-ipad {
142 | position: fixed; // required for iPad 7 Safari
143 | }
144 | }
145 |
146 | .platform-c:not(.enable-transitions) * {
147 | // disable transitions on grade-c devices (Android 2)
148 | -webkit-transition: none !important;
149 | transition: none !important;
150 | }
151 |
152 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_checkbox.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Checkbox
4 | * --------------------------------------------------
5 | */
6 |
7 | .checkbox {
8 | // set the color defaults
9 | @include checkbox-style($checkbox-off-border-default, $checkbox-on-bg-default);
10 |
11 | position: relative;
12 | display: inline-block;
13 | padding: ($checkbox-height / 4) ($checkbox-width / 4);
14 | cursor: pointer;
15 |
16 | &.checkbox-light {
17 | @include checkbox-style($checkbox-off-border-light, $checkbox-on-bg-light);
18 | }
19 | &.checkbox-stable {
20 | @include checkbox-style($checkbox-off-border-stable, $checkbox-on-bg-stable);
21 | }
22 | &.checkbox-positive {
23 | @include checkbox-style($checkbox-off-border-positive, $checkbox-on-bg-positive);
24 | }
25 | &.checkbox-calm {
26 | @include checkbox-style($checkbox-off-border-calm, $checkbox-on-bg-calm);
27 | }
28 | &.checkbox-assertive {
29 | @include checkbox-style($checkbox-off-border-assertive, $checkbox-on-bg-assertive);
30 | }
31 | &.checkbox-balanced {
32 | @include checkbox-style($checkbox-off-border-balanced, $checkbox-on-bg-balanced);
33 | }
34 | &.checkbox-energized {
35 | @include checkbox-style($checkbox-off-border-energized, $checkbox-on-bg-energized);
36 | }
37 | &.checkbox-royal {
38 | @include checkbox-style($checkbox-off-border-royal, $checkbox-on-bg-royal);
39 | }
40 | &.checkbox-dark {
41 | @include checkbox-style($checkbox-off-border-dark, $checkbox-on-bg-dark);
42 | }
43 | }
44 |
45 | .checkbox.checkbox-input-hidden input {
46 | display: none !important;
47 | }
48 |
49 | .checkbox input,
50 | .checkbox-icon {
51 | position: relative;
52 | width: $checkbox-width;
53 | height: $checkbox-height;
54 | display: block;
55 | border: 0;
56 | background: transparent;
57 | cursor: pointer;
58 | -webkit-appearance: none;
59 |
60 | &:before {
61 | // what the checkbox looks like when its not checked
62 | display: table;
63 | width: 100%;
64 | height: 100%;
65 | border-width: $checkbox-border-width;
66 | border-style: solid;
67 | border-radius: $checkbox-border-radius;
68 | background: $checkbox-off-bg-color;
69 | content: ' ';
70 | transition: background-color 20ms ease-in-out;
71 | }
72 | }
73 |
74 | .checkbox input:checked:before,
75 | input:checked + .checkbox-icon:before {
76 | border-width: $checkbox-border-width + 1;
77 | }
78 |
79 | // the checkmark within the box
80 | .checkbox input:after,
81 | .checkbox-icon:after {
82 | @include transition(opacity .05s ease-in-out);
83 | @include rotate(-45deg);
84 | position: absolute;
85 | top: 30%;
86 | left: 26%;
87 | display: table;
88 | width: ($checkbox-width / 2) + 1;
89 | height: ($checkbox-width / 3) + 1;
90 | border: $checkbox-check-width solid $checkbox-check-color;
91 | border-top: 0;
92 | border-right: 0;
93 | content: ' ';
94 | opacity: 0;
95 | }
96 |
97 | .grade-c .checkbox input:after,
98 | .grade-c .checkbox-icon:after {
99 | @include rotate(0);
100 | top: 3px;
101 | left: 4px;
102 | border: none;
103 | color: $checkbox-check-color;
104 | content: '\2713';
105 | font-weight: bold;
106 | font-size: 20px;
107 | }
108 |
109 | // what the checkmark looks like when its checked
110 | .checkbox input:checked:after,
111 | input:checked + .checkbox-icon:after {
112 | opacity: 1;
113 | }
114 |
115 | // make sure item content have enough padding on left to fit the checkbox
116 | .item-checkbox {
117 | padding-left: ($item-padding * 2) + $checkbox-width;
118 |
119 | &.active {
120 | box-shadow: none;
121 | }
122 | }
123 |
124 | // position the checkbox to the left within an item
125 | .item-checkbox .checkbox {
126 | position: absolute;
127 | top: 50%;
128 | right: $item-padding / 2;
129 | left: $item-padding / 2;
130 | z-index: $z-index-item-checkbox;
131 | margin-top: (($checkbox-height + ($checkbox-height / 2)) / 2) * -1;
132 | }
133 |
134 |
135 | .item-checkbox.item-checkbox-right {
136 | padding-right: ($item-padding * 2) + $checkbox-width;
137 | padding-left: $item-padding;
138 | }
139 |
140 | .item-checkbox-right .checkbox input,
141 | .item-checkbox-right .checkbox-icon {
142 | float: right;
143 | }
--------------------------------------------------------------------------------
/www/lib/ionic/js/angular/angular-sanitize.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.17
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(p,h,q){'use strict';function E(a){var d=[];s(d,h.noop).chars(a);return d.join("")}function k(a){var d={};a=a.split(",");var b;for(b=0;b=b;e--)d.end&&d.end(f[e]);f.length=b}}var c,g,f=[],l=a;for(f.last=function(){return f[f.length-1]};a;){g=!0;if(f.last()&&x[f.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(c,a){a=a.replace(H,"$1").replace(I,"$1");d.chars&&d.chars(r(a));return""}),e("",f.last());else{if(0===a.indexOf("\x3c!--"))c=a.indexOf("--",4),0<=c&&a.lastIndexOf("--\x3e",c)===c&&(d.comment&&d.comment(a.substring(4,c)),a=a.substring(c+3),g=!1);else if(y.test(a)){if(c=a.match(y))a=
8 | a.replace(c[0],""),g=!1}else if(J.test(a)){if(c=a.match(z))a=a.substring(c[0].length),c[0].replace(z,e),g=!1}else K.test(a)&&(c=a.match(A))&&(a=a.substring(c[0].length),c[0].replace(A,b),g=!1);g&&(c=a.indexOf("<"),g=0>c?a:a.substring(0,c),a=0>c?"":a.substring(c),d.chars&&d.chars(r(g)))}if(a==l)throw L("badparse",a);l=a}e()}function r(a){if(!a)return"";var d=M.exec(a);a=d[1];var b=d[3];if(d=d[2])n.innerHTML=d.replace(//g,">")}function s(a,d){var b=!1,e=h.bind(a,a.push);return{start:function(a,g,f){a=h.lowercase(a);!b&&x[a]&&(b=a);b||!0!==C[a]||(e("<"),e(a),h.forEach(g,function(b,f){var g=h.lowercase(f),k="img"===a&&"src"===g||"background"===g;!0!==P[g]||!0===D[g]&&!d(b,k)||(e(" "),e(f),e('="'),e(B(b)),e('"'))}),
10 | e(f?"/>":">"))},end:function(a){a=h.lowercase(a);b||!0!==C[a]||(e(""),e(a),e(">"));a==b&&(b=!1)},chars:function(a){b||e(B(a))}}}var L=h.$$minErr("$sanitize"),A=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,z=/^<\s*\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^,J=/^<\s*\//,H=/\x3c!--(.*?)--\x3e/g,y=/]*?)>/i,I=/]/,b=/^mailto:/;return function(e,c){function g(a){a&&m.push(E(a))}function f(a,b){m.push("');g(b);m.push(" ")}if(!e)return e;
14 | for(var l,k=e,m=[],n,p;l=k.match(d);)n=l[0],l[2]==l[3]&&(n="mailto:"+n),p=l.index,g(k.substr(0,p)),f(n,l[0].replace(b,"")),k=k.substring(p+l[0].length);g(k);return a(m.join(""))}}])})(window,window.angular);
15 | //# sourceMappingURL=angular-sanitize.min.js.map
16 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_toggle.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Toggle
4 | * --------------------------------------------------
5 | */
6 |
7 | .item-toggle {
8 | pointer-events: none;
9 | }
10 |
11 | .toggle {
12 | // set the color defaults
13 | @include toggle-style($toggle-on-default-border, $toggle-on-default-bg);
14 |
15 | position: relative;
16 | display: inline-block;
17 | pointer-events: auto;
18 | margin: -$toggle-hit-area-expansion;
19 | padding: $toggle-hit-area-expansion;
20 |
21 | &.dragging {
22 | .handle {
23 | background-color: $toggle-handle-dragging-bg-color !important;
24 | }
25 | }
26 |
27 | &.toggle-light {
28 | @include toggle-style($toggle-on-light-border, $toggle-on-light-bg);
29 | }
30 | &.toggle-stable {
31 | @include toggle-style($toggle-on-stable-border, $toggle-on-stable-bg);
32 | }
33 | &.toggle-positive {
34 | @include toggle-style($toggle-on-positive-border, $toggle-on-positive-bg);
35 | }
36 | &.toggle-calm {
37 | @include toggle-style($toggle-on-calm-border, $toggle-on-calm-bg);
38 | }
39 | &.toggle-assertive {
40 | @include toggle-style($toggle-on-assertive-border, $toggle-on-assertive-bg);
41 | }
42 | &.toggle-balanced {
43 | @include toggle-style($toggle-on-balanced-border, $toggle-on-balanced-bg);
44 | }
45 | &.toggle-energized {
46 | @include toggle-style($toggle-on-energized-border, $toggle-on-energized-bg);
47 | }
48 | &.toggle-royal {
49 | @include toggle-style($toggle-on-royal-border, $toggle-on-royal-bg);
50 | }
51 | &.toggle-dark {
52 | @include toggle-style($toggle-on-dark-border, $toggle-on-dark-bg);
53 | }
54 | }
55 |
56 | .toggle input {
57 | // hide the actual input checkbox
58 | display: none;
59 | }
60 |
61 | /* the track appearance when the toggle is "off" */
62 | .toggle .track {
63 | @include transition-timing-function(ease-in-out);
64 | @include transition-duration($toggle-transition-duration);
65 | @include transition-property((background-color, border));
66 |
67 | display: inline-block;
68 | box-sizing: border-box;
69 | width: $toggle-width;
70 | height: $toggle-height;
71 | border: solid $toggle-border-width $toggle-off-border-color;
72 | border-radius: $toggle-border-radius;
73 | background-color: $toggle-off-bg-color;
74 | content: ' ';
75 | cursor: pointer;
76 | pointer-events: none;
77 | }
78 |
79 | /* Fix to avoid background color bleeding */
80 | /* (occured on (at least) Android 4.2, Asus MeMO Pad HD7 ME173X) */
81 | .platform-android4_2 .toggle .track {
82 | -webkit-background-clip: padding-box;
83 | }
84 |
85 | /* the handle (circle) thats inside the toggle's track area */
86 | /* also the handle's appearance when it is "off" */
87 | .toggle .handle {
88 | @include transition($toggle-transition-duration ease-in-out);
89 | position: absolute;
90 | display: block;
91 | width: $toggle-handle-width;
92 | height: $toggle-handle-height;
93 | border-radius: $toggle-handle-radius;
94 | background-color: $toggle-handle-off-bg-color;
95 | top: $toggle-border-width + $toggle-hit-area-expansion;
96 | left: $toggle-border-width + $toggle-hit-area-expansion;
97 |
98 | &:before {
99 | // used to create a larger (but hidden) hit area to slide the handle
100 | position: absolute;
101 | top: -4px;
102 | left: ( ($toggle-handle-width / 2) * -1) - 8;
103 | padding: ($toggle-handle-height / 2) + 5 ($toggle-handle-width + 7);
104 | content: " ";
105 | }
106 | }
107 |
108 | .toggle input:checked + .track .handle {
109 | // the handle when the toggle is "on"
110 | @include translate3d($toggle-width - $toggle-handle-width - ($toggle-border-width * 2), 0, 0);
111 | background-color: $toggle-handle-on-bg-color;
112 | }
113 |
114 | .item-toggle.active {
115 | box-shadow: none;
116 | }
117 |
118 | .item-toggle,
119 | .item-toggle.item-complex .item-content {
120 | // make sure list item content have enough padding on right to fit the toggle
121 | padding-right: ($item-padding * 3) + $toggle-width;
122 | }
123 |
124 | .item-toggle.item-complex {
125 | padding-right: 0;
126 | }
127 |
128 | .item-toggle .toggle {
129 | // position the toggle to the right within a list item
130 | position: absolute;
131 | top: $item-padding / 2;
132 | right: $item-padding;
133 | z-index: $z-index-item-toggle;
134 | }
135 |
136 | .toggle input:disabled + .track {
137 | opacity: .6;
138 | }
139 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_util.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Utility Classes
4 | * --------------------------------------------------
5 | */
6 |
7 | .hide {
8 | display: none;
9 | }
10 | .opacity-hide {
11 | opacity: 0;
12 | }
13 | .grade-b .opacity-hide,
14 | .grade-c .opacity-hide {
15 | opacity: 1;
16 | display: none;
17 | }
18 | .show {
19 | display: block;
20 | }
21 | .opacity-show {
22 | opacity: 1;
23 | }
24 | .invisible {
25 | visibility: hidden;
26 | }
27 |
28 | .keyboard-open .hide-on-keyboard-open {
29 | display: none;
30 | }
31 |
32 | .keyboard-open .tabs.hide-on-keyboard-open + .pane .has-tabs,
33 | .keyboard-open .bar-footer.hide-on-keyboard-open + .pane .has-footer {
34 | bottom: 0;
35 | }
36 |
37 | .inline {
38 | display: inline-block;
39 | }
40 |
41 | .disable-pointer-events {
42 | pointer-events: none;
43 | }
44 |
45 | .enable-pointer-events {
46 | pointer-events: auto;
47 | }
48 |
49 | .disable-user-behavior {
50 | // used to prevent the browser from doing its native behavior. this doesnt
51 | // prevent the scrolling, but cancels the contextmenu, tap highlighting, etc
52 |
53 | @include user-select(none);
54 | @include touch-callout(none);
55 | @include tap-highlight-transparent();
56 |
57 | -webkit-user-drag: none;
58 |
59 | -ms-touch-action: none;
60 | -ms-content-zooming: none;
61 | }
62 |
63 | .no-resize {
64 | resize: none;
65 | }
66 |
67 | .block {
68 | display: block;
69 | clear: both;
70 | &:after {
71 | display: block;
72 | visibility: hidden;
73 | clear: both;
74 | height: 0;
75 | content: ".";
76 | }
77 | }
78 |
79 | .full-image {
80 | width: 100%;
81 | }
82 |
83 | .clearfix {
84 | *zoom: 1;
85 | &:before,
86 | &:after {
87 | display: table;
88 | content: "";
89 | // Fixes Opera/contenteditable bug:
90 | // http://nicolasgallagher.com/micro-clearfix-hack/#comment-36952
91 | line-height: 0;
92 | }
93 | &:after {
94 | clear: both;
95 | }
96 | }
97 |
98 | /**
99 | * Content Padding
100 | * --------------------------------------------------
101 | */
102 |
103 | .padding {
104 | padding: $content-padding;
105 | }
106 |
107 | .padding-top,
108 | .padding-vertical {
109 | padding-top: $content-padding;
110 | }
111 |
112 | .padding-right,
113 | .padding-horizontal {
114 | padding-right: $content-padding;
115 | }
116 |
117 | .padding-bottom,
118 | .padding-vertical {
119 | padding-bottom: $content-padding;
120 | }
121 |
122 | .padding-left,
123 | .padding-horizontal {
124 | padding-left: $content-padding;
125 | }
126 |
127 |
128 | /**
129 | * Rounded
130 | * --------------------------------------------------
131 | */
132 |
133 | .rounded {
134 | border-radius: $border-radius-base;
135 | }
136 |
137 |
138 | /**
139 | * Utility Colors
140 | * --------------------------------------------------
141 | * Utility colors are added to help set a naming convention. You'll
142 | * notice we purposely do not use words like "red" or "blue", but
143 | * instead have colors which represent an emotion or generic theme.
144 | */
145 |
146 | .light, a.light {
147 | color: $light;
148 | }
149 | .light-bg {
150 | background-color: $light;
151 | }
152 | .light-border {
153 | border-color: $button-light-border;
154 | }
155 |
156 | .stable, a.stable {
157 | color: $stable;
158 | }
159 | .stable-bg {
160 | background-color: $stable;
161 | }
162 | .stable-border {
163 | border-color: $button-stable-border;
164 | }
165 |
166 | .positive, a.positive {
167 | color: $positive;
168 | }
169 | .positive-bg {
170 | background-color: $positive;
171 | }
172 | .positive-border {
173 | border-color: $button-positive-border;
174 | }
175 |
176 | .calm, a.calm {
177 | color: $calm;
178 | }
179 | .calm-bg {
180 | background-color: $calm;
181 | }
182 | .calm-border {
183 | border-color: $button-calm-border;
184 | }
185 |
186 | .assertive, a.assertive {
187 | color: $assertive;
188 | }
189 | .assertive-bg {
190 | background-color: $assertive;
191 | }
192 | .assertive-border {
193 | border-color: $button-assertive-border;
194 | }
195 |
196 | .balanced, a.balanced {
197 | color: $balanced;
198 | }
199 | .balanced-bg {
200 | background-color: $balanced;
201 | }
202 | .balanced-border {
203 | border-color: $button-balanced-border;
204 | }
205 |
206 | .energized, a.energized {
207 | color: $energized;
208 | }
209 | .energized-bg {
210 | background-color: $energized;
211 | }
212 | .energized-border {
213 | border-color: $button-energized-border;
214 | }
215 |
216 | .royal, a.royal {
217 | color: $royal;
218 | }
219 | .royal-bg {
220 | background-color: $royal;
221 | }
222 | .royal-border {
223 | border-color: $button-royal-border;
224 | }
225 |
226 | .dark, a.dark {
227 | color: $dark;
228 | }
229 | .dark-bg {
230 | background-color: $dark;
231 | }
232 | .dark-border {
233 | border-color: $button-dark-border;
234 | }
235 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | PgBarcodeScanner
2 | ================
3 |
4 | This is a full implementation of a phonegap barcode scanner app using the ionic and angularjs frameworks for the platforms supported by com.phonegap.plugins.barcodescanner. It includes the phonegap compatible config.xml that identifies the plug in.
5 |
6 | The app has some interesting features like using the $q promise/deferred implementation to capture the barcode scanner information for display in a table and the angularjs state routing that is the default in the ionic framework.
7 |
8 | To use it in phonegap, create a new, open-source project and provide this github repository. Phonegap knows how to deal with the www directory tree automatically.
9 |
10 | The app has not been fully tested so please beware. It is only meant to show the basic ideas so that you can easily incorporate the barcode scanner into your app.
11 |
12 | The source code is distributed under the MIT license so you are free to use it any way that you like.
13 |
14 | Here are the basic commands that I used to create it:
15 |
16 | $ cd ~/work/apps
17 | $ ionic state PgBarcodeScanner tabs
18 | $ cd PgBarcodeScanner
19 | $ # add the plugin
20 | $ cordova plugin add http://github.com/phonegap-build/BarcodeScanner.git
21 | $ edit config.xml # add in the plugin reference
22 | $ cp config.xml www/
23 | $ ionic platform add android
24 | $ ionic platform add ios
25 | $ cd www
26 | $ touch templates/tab-about.html
27 | $ touch templates/tab-scan.html
28 | $ open -a brackets index.html templates/*html js/*.js # create the app
29 | $ # remove the initialization cruft
30 | $ rm -f templates/friend* templates/tab-friends.html \
31 | templates/tab-dash.html templates/tab-accounts.html
32 | $ # compile and test
33 | $ ionic build android ios
34 | $ # use the new ripple: http://ripple.incubator.apache.org/
35 | $ # npm install -g ripple-emulator
36 | $ ripple emulate
37 |
38 | I was able to test it locally using the android emulator on my Mac like this because the "ionic emulate --target=gn1 android" command failed.
39 |
40 | $ # install the android SDK
41 | $ # update PATH to include the platforms-tools and tools directories:
42 | $ # ~/Development/adt-bundle-mac-x86_64-20140321/sdk/platform-tools
43 | $ # ~/Development/adt-bundle-mac-x86_64-20140321/sdk/tools
44 | $ # create at least one AVD (Android Virtual Device) under Tools --> Manage AVDs
45 | $ android avd list
46 | Available Android Virtual Devices:
47 | Name: galaxy_nexus
48 | Device: Galaxy Nexus (Google)
49 | Path: /Users/jlinoff/.android/avd/galaxy_nexus.avd
50 | Target: Android 4.4.2 (API level 19)
51 | Tag/ABI: default/armeabi-v7a
52 | Skin: 720x1280
53 | ---------
54 | Name: gn1
55 | Device: 4in WVGA (Nexus S) (Generic)
56 | Path: /Users/jlinoff/.android/avd/gn1.avd
57 | Target: Android 4.4.2 (API level 19)
58 | Tag/ABI: default/armeabi-v7a
59 | Skin: 480x800
60 | ---------
61 | Name: gn2
62 | Device: 4.65in 720p (Galaxy Nexus) (Generic)
63 | Path: /Users/jlinoff/.android/avd/gn2.avd
64 | Target: Android 4.4.2 (API level 19)
65 | Tag/ABI: default/x86
66 | Skin: 720x1280
67 |
68 |
69 | $ # Build the android APK
70 | $ ionic build android
71 |
72 | $ # Run the emulator with the camera enabled.
73 | $ emulator64-arm -camera-front on @gn1
74 |
75 | $ # Or, if you have HAX installed for much faster emulation use gn2.
76 | $ # Note that you must use the full path to the emulator to avoid a qemu "bios.bin" not found error.
77 | $ # Further note that you must update LD_LIBRARY_PATH so that the emulator finds the OpenGLES library.
78 | $ LD_LIBRARY_PATH=~/Development/adt-bundle-mac-x86_64-20140321/sdk/tools/lib \
79 | /Users/jlinoff/Development/adt-bundle-mac-x86_64-20140321/sdk/tools/emulator64-x86 \
80 | -camera-front webcam0 @gn2 &
81 |
82 | $ # Add the APK to the running emulator.
83 | $ adb -e install \
84 | /Users/jlinoff/work/apps/PgBarcodeScanner/platforms/android/ant-build/PgBarcodeScanner-debug-unaligned.apk
85 | 1289 KB/s (3983000 bytes in 3.016s)
86 | WARNING: linker: libdvm.so has text relocations. This is wasting memory and is a security risk. Please fix.
87 | pkg: /data/local/tmp/PgBarcodeScanner-debug-unaligned.apk
88 | Success
89 |
90 | $ # When finished uninstall the APK (unless you want to use it later).
91 | $ adb -e uninstall \
92 | /Users/jlinoff/work/apps/PgBarcodeScanner/platforms/android/ant-build/PgBarcodeScanner-debug-unaligned.apk
93 |
94 | $ # Kill the emulator
95 | $ kill -9 %1
96 |
97 | Here is the error that I saw when I tried to use the built-in emulation:
98 |
99 | $ ionic emulate --target=gn1 android
100 | .
101 | .
102 | BUILD SUCCESSFUL
103 | Total time: 9 seconds
104 | Waiting for emulator...
105 |
106 | events.js:72
107 | throw er; // Unhandled 'error' event
108 | ^
109 | Error: spawn ENOENT
110 | at errnoException (child_process.js:1001:11)
111 | at Process.ChildProcess._handle.onexit (child_process.js:792:34)
112 | Error: /Users/jlinoff/work/apps/PgBarcodeScanner/platforms/android/cordova/run: Command failed with exit code 8
113 | at ChildProcess.whenDone (/usr/local/lib/node_modules/cordova/node_modules/cordova-lib/src/cordova/superspawn.js:135:23)
114 | at ChildProcess.emit (events.js:98:17)
115 | at maybeClose (child_process.js:756:16)
116 | at Process.ChildProcess._handle.onexit (child_process.js:823:5)
117 |
118 | When the testing is complete, you can upload the project to http://build.phonegap.com using a zip file or from a github account. If you want to use a zip file create it as follows:
119 |
120 | $ cd ~/work/apps/PgBarcodeScanner
121 | $ zip -r PgBarcodeScanner.zip www # zip file to upload to phonegap
122 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_form.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Forms
3 | * --------------------------------------------------
4 | */
5 |
6 | // Make all forms have space below them
7 | form {
8 | margin: 0 0 $line-height-base;
9 | }
10 |
11 | // Groups of fields with labels on top (legends)
12 | legend {
13 | display: block;
14 | margin-bottom: $line-height-base;
15 | padding: 0;
16 | width: 100%;
17 | border: $input-border-width solid $input-border;
18 | color: $dark;
19 | font-size: $font-size-base * 1.5;
20 | line-height: $line-height-base * 2;
21 |
22 | small {
23 | color: $stable;
24 | font-size: $line-height-base * .75;
25 | }
26 | }
27 |
28 | // Set font for forms
29 | label,
30 | input,
31 | button,
32 | select,
33 | textarea {
34 | @include font-shorthand($font-size-base, normal, $line-height-base); // Set size, weight, line-height here
35 | }
36 | input,
37 | button,
38 | select,
39 | textarea {
40 | font-family: $font-family-base; // And only set font-family here for those that need it (note the missing label element)
41 | }
42 |
43 |
44 | // Input List
45 | // -------------------------------
46 |
47 | .item-input {
48 | @include display-flex();
49 | @include align-items(center);
50 | position: relative;
51 | overflow: hidden;
52 | padding: 6px 0 5px 8px;
53 |
54 | input {
55 | @include border-radius(0);
56 | @include flex(1, 0, 220px);
57 | @include appearance(none);
58 | margin: 0;
59 | padding-right: 24px;
60 | background-color: transparent;
61 | }
62 |
63 | .button .icon {
64 | @include flex(0, 0, 24px);
65 | position: static;
66 | display: inline-block;
67 | height: auto;
68 | text-align: center;
69 | font-size: 16px;
70 | }
71 |
72 | .button-bar {
73 | @include border-radius(0);
74 | @include flex(1, 0, 220px);
75 | @include appearance(none);
76 | }
77 |
78 | .icon {
79 | min-width: 14px;
80 | }
81 | }
82 |
83 | .item-input-inset {
84 | @include display-flex();
85 | @include align-items(center);
86 | position: relative;
87 | overflow: hidden;
88 | padding: ($item-padding / 3) * 2;
89 | }
90 |
91 | .item-input-wrapper {
92 | @include display-flex();
93 | @include flex(1, 0);
94 | @include align-items(center);
95 | @include border-radius(4px);
96 | padding-right: 8px;
97 | padding-left: 8px;
98 | background: #eee;
99 | }
100 |
101 | .item-input-inset .item-input-wrapper input {
102 | padding-left: 4px;
103 | height: 29px;
104 | background: transparent;
105 | line-height: 18px;
106 | }
107 |
108 | .item-input-wrapper ~ .button {
109 | margin-left: ($item-padding / 3) * 2;
110 | }
111 |
112 | .input-label {
113 | @include flex(1, 0, 100px);
114 | display: table;
115 | padding: 7px 10px 7px 3px;
116 | max-width: 200px;
117 | width: 35%;
118 | color: $input-label-color;
119 | font-weight: bold;
120 | font-size: $font-size-base;
121 | }
122 |
123 | .placeholder-icon {
124 | color: #aaa;
125 | &:first-child {
126 | padding-right: 6px;
127 | }
128 | &:last-child {
129 | padding-left: 6px;
130 | }
131 | }
132 |
133 | .item-stacked-label {
134 | display: block;
135 | background-color: transparent;
136 | box-shadow: none;
137 |
138 | .input-label, .icon {
139 | display: inline-block;
140 | padding: 4px 0;
141 | vertical-align: middle;
142 | }
143 | }
144 |
145 | .item-stacked-label input,
146 | .item-stacked-label textarea {
147 | @include border-radius(2px);
148 | padding: 4px 8px 3px;
149 | border: none;
150 | background-color: $input-bg;
151 | }
152 | .item-stacked-label input {
153 | overflow: hidden;
154 | height: $line-height-computed + $font-size-base + 12px;
155 | }
156 |
157 | .item-floating-label {
158 | display: block;
159 | background-color: transparent;
160 | box-shadow: none;
161 |
162 | .input-label {
163 | position: relative;
164 | padding: 5px 0 0 0;
165 | opacity: 0;
166 | top: 10px;
167 | @include transition(opacity .15s ease-in, top .2s linear);
168 |
169 | &.has-input {
170 | opacity: 1;
171 | top: 0;
172 | @include transition(opacity .15s ease-in, top .2s linear);
173 | }
174 | }
175 | }
176 |
177 |
178 | // Form Controls
179 | // -------------------------------
180 |
181 | // Shared size and type resets
182 | textarea,
183 | input[type="text"],
184 | input[type="password"],
185 | input[type="datetime"],
186 | input[type="datetime-local"],
187 | input[type="date"],
188 | input[type="month"],
189 | input[type="time"],
190 | input[type="week"],
191 | input[type="number"],
192 | input[type="email"],
193 | input[type="url"],
194 | input[type="search"],
195 | input[type="tel"],
196 | input[type="color"] {
197 | display: block;
198 | padding-top: 2px;
199 | height: $line-height-computed + $font-size-base;
200 | color: $input-color;
201 | vertical-align: middle;
202 | font-size: $font-size-base;
203 | line-height: $font-size-base + 2;
204 | }
205 |
206 | .platform-ios,
207 | .platform-android {
208 | input[type="datetime-local"],
209 | input[type="date"],
210 | input[type="month"],
211 | input[type="time"],
212 | input[type="week"] {
213 | padding-top: 8px;
214 | }
215 | }
216 |
217 | input,
218 | textarea {
219 | width: 100%;
220 | }
221 |
222 | // Reset height since textareas have rows
223 | textarea {
224 | height: auto;
225 | }
226 |
227 | // Everything else
228 | textarea,
229 | input[type="text"],
230 | input[type="password"],
231 | input[type="datetime"],
232 | input[type="datetime-local"],
233 | input[type="date"],
234 | input[type="month"],
235 | input[type="time"],
236 | input[type="week"],
237 | input[type="number"],
238 | input[type="email"],
239 | input[type="url"],
240 | input[type="search"],
241 | input[type="tel"],
242 | input[type="color"] {
243 | border: 0;
244 | }
245 |
246 | // Position radios and checkboxes better
247 | input[type="radio"],
248 | input[type="checkbox"] {
249 | margin: 0;
250 | line-height: normal;
251 | }
252 |
253 | // Reset width of input images, buttons, radios, checkboxes
254 | input[type="file"],
255 | input[type="image"],
256 | input[type="submit"],
257 | input[type="reset"],
258 | input[type="button"],
259 | input[type="radio"],
260 | input[type="checkbox"] {
261 | width: auto; // Override of generic input selector
262 | }
263 |
264 | // Set the height of file to match text inputs
265 | input[type="file"] {
266 | line-height: $input-height-base;
267 | }
268 |
269 | // Text input classes to hide text caret during scroll
270 | .previous-input-focus,
271 | .cloned-text-input + input,
272 | .cloned-text-input + textarea {
273 | position: absolute;
274 | left: -9999px;
275 | width: 200px;
276 | }
277 |
278 |
279 | // Placeholder
280 | // -------------------------------
281 | input,
282 | textarea {
283 | @include placeholder();
284 | }
285 |
286 |
287 | // DISABLED STATE
288 | // -------------------------------
289 |
290 | // Disabled and read-only inputs
291 | input[disabled],
292 | select[disabled],
293 | textarea[disabled],
294 | input[readonly]:not(.cloned-text-input),
295 | textarea[readonly]:not(.cloned-text-input),
296 | select[readonly] {
297 | background-color: $input-bg-disabled;
298 | cursor: not-allowed;
299 | }
300 | // Explicitly reset the colors here
301 | input[type="radio"][disabled],
302 | input[type="checkbox"][disabled],
303 | input[type="radio"][readonly],
304 | input[type="checkbox"][readonly] {
305 | background-color: transparent;
306 | }
307 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_button.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Buttons
4 | * --------------------------------------------------
5 | */
6 |
7 | .button {
8 | // set the color defaults
9 | @include button-style($button-default-bg, $button-default-border, $button-default-active-bg, $button-default-active-border, $button-default-text);
10 |
11 | position: relative;
12 | display: inline-block;
13 | margin: 0;
14 | padding: 0 $button-padding;
15 |
16 | min-width: ($button-padding * 3) + $button-font-size;
17 | min-height: $button-height + 5px;
18 |
19 | border-width: $button-border-width;
20 | border-style: solid;
21 | border-radius: $button-border-radius;
22 |
23 | vertical-align: top;
24 | text-align: center;
25 |
26 | text-overflow: ellipsis;
27 | font-size: $button-font-size;
28 | line-height: $button-height - $button-border-width + 1px;
29 |
30 | cursor: pointer;
31 |
32 | &:after {
33 | // used to create a larger button "hit" area
34 | position: absolute;
35 | top: -6px;
36 | right: -8px;
37 | bottom: -6px;
38 | left: -8px;
39 | content: ' ';
40 | }
41 |
42 | .icon {
43 | vertical-align: top;
44 | pointer-events: none;
45 | }
46 |
47 | .icon:before,
48 | &.icon:before,
49 | &.icon-left:before,
50 | &.icon-right:before {
51 | display: inline-block;
52 | padding: 0 0 $button-border-width 0;
53 | vertical-align: inherit;
54 | font-size: $button-icon-size;
55 | line-height: $button-height - $button-border-width;
56 | pointer-events: none;
57 | }
58 | &.icon-left:before {
59 | float: left;
60 | padding-right: .2em;
61 | padding-left: 0;
62 | }
63 | &.icon-right:before {
64 | float: right;
65 | padding-right: 0;
66 | padding-left: .2em;
67 | }
68 |
69 | &.button-block, &.button-full {
70 | margin-top: $button-block-margin;
71 | margin-bottom: $button-block-margin;
72 | }
73 |
74 | &.button-light {
75 | @include button-style($button-light-bg, $button-light-border, $button-light-active-bg, $button-light-active-border, $button-light-text);
76 | @include button-clear($button-light-border);
77 | @include button-outline($button-light-border);
78 | }
79 |
80 | &.button-stable {
81 | @include button-style($button-stable-bg, $button-stable-border, $button-stable-active-bg, $button-stable-active-border, $button-stable-text);
82 | @include button-clear($button-stable-border);
83 | @include button-outline($button-stable-border);
84 | }
85 |
86 | &.button-positive {
87 | @include button-style($button-positive-bg, $button-positive-border, $button-positive-active-bg, $button-positive-active-border, $button-positive-text);
88 | @include button-clear($button-positive-bg);
89 | @include button-outline($button-positive-bg);
90 | }
91 |
92 | &.button-calm {
93 | @include button-style($button-calm-bg, $button-calm-border, $button-calm-active-bg, $button-calm-active-border, $button-calm-text);
94 | @include button-clear($button-calm-bg);
95 | @include button-outline($button-calm-bg);
96 | }
97 |
98 | &.button-assertive {
99 | @include button-style($button-assertive-bg, $button-assertive-border, $button-assertive-active-bg, $button-assertive-active-border, $button-assertive-text);
100 | @include button-clear($button-assertive-bg);
101 | @include button-outline($button-assertive-bg);
102 | }
103 |
104 | &.button-balanced {
105 | @include button-style($button-balanced-bg, $button-balanced-border, $button-balanced-active-bg, $button-balanced-active-border, $button-balanced-text);
106 | @include button-clear($button-balanced-bg);
107 | @include button-outline($button-balanced-bg);
108 | }
109 |
110 | &.button-energized {
111 | @include button-style($button-energized-bg, $button-energized-border, $button-energized-active-bg, $button-energized-active-border, $button-energized-text);
112 | @include button-clear($button-energized-bg);
113 | @include button-outline($button-energized-bg);
114 | }
115 |
116 | &.button-royal {
117 | @include button-style($button-royal-bg, $button-royal-border, $button-royal-active-bg, $button-royal-active-border, $button-royal-text);
118 | @include button-clear($button-royal-bg);
119 | @include button-outline($button-royal-bg);
120 | }
121 |
122 | &.button-dark {
123 | @include button-style($button-dark-bg, $button-dark-border, $button-dark-active-bg, $button-dark-active-border, $button-dark-text);
124 | @include button-clear($button-dark-bg);
125 | @include button-outline($button-dark-bg);
126 | }
127 | }
128 |
129 | .button-small {
130 | padding: 2px $button-small-padding 1px;
131 | min-width: $button-small-height;
132 | min-height: $button-small-height + 2;
133 | font-size: $button-small-font-size;
134 | line-height: $button-small-height - $button-border-width - 1;
135 |
136 | .icon:before,
137 | &.icon:before,
138 | &.icon-left:before,
139 | &.icon-right:before {
140 | font-size: $button-small-icon-size;
141 | line-height: $button-small-icon-size + 3;
142 | margin-top: 3px;
143 | }
144 | }
145 |
146 | .button-large {
147 | padding: 0 $button-large-padding;
148 | min-width: ($button-large-padding * 3) + $button-large-font-size;
149 | min-height: $button-large-height + 5;
150 | font-size: $button-large-font-size;
151 | line-height: $button-large-height - $button-border-width;
152 |
153 | .icon:before,
154 | &.icon:before,
155 | &.icon-left:before,
156 | &.icon-right:before {
157 | padding-bottom: ($button-border-width * 2);
158 | font-size: $button-large-icon-size;
159 | line-height: $button-large-height - ($button-border-width * 2) - 1;
160 | }
161 | }
162 |
163 | .button-icon {
164 | @include transition(opacity .1s);
165 | padding: 0 6px;
166 | min-width: initial;
167 | border-color: transparent;
168 | background: none;
169 |
170 | &.button.active,
171 | &.button.activated {
172 | border-color: transparent;
173 | background: none;
174 | box-shadow: none;
175 | opacity: 0.3;
176 | }
177 |
178 | .icon:before,
179 | &.icon:before {
180 | font-size: $button-large-icon-size;
181 | }
182 | }
183 |
184 | .button-clear {
185 | @include button-clear($button-default-border);
186 | @include transition(opacity .1s);
187 | padding: 0 $button-clear-padding;
188 | max-height: $button-height;
189 | border-color: transparent;
190 | background: none;
191 | box-shadow: none;
192 |
193 | &.active,
194 | &.activated {
195 | opacity: 0.3;
196 | }
197 | }
198 |
199 | .button-outline {
200 | @include button-outline($button-default-border);
201 | @include transition(opacity .1s);
202 | background: none;
203 | box-shadow: none;
204 | }
205 |
206 | .padding > .button.button-block:first-child {
207 | margin-top: 0;
208 | }
209 |
210 | .button-block {
211 | display: block;
212 | clear: both;
213 |
214 | &:after {
215 | clear: both;
216 | }
217 | }
218 |
219 | .button-full,
220 | .button-full > .button {
221 | display: block;
222 | margin-right: 0;
223 | margin-left: 0;
224 | border-right-width: 0;
225 | border-left-width: 0;
226 | border-radius: 0;
227 | }
228 |
229 | button.button-block,
230 | button.button-full,
231 | .button-full > button.button,
232 | input.button.button-block {
233 | width: 100%;
234 | }
235 |
236 | a.button {
237 | text-decoration: none;
238 | }
239 |
240 | .button.disabled,
241 | .button[disabled] {
242 | opacity: .4;
243 | cursor: default !important;
244 | pointer-events: none;
245 | }
246 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_scaffolding.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Scaffolding
4 | * --------------------------------------------------
5 | */
6 |
7 | *,
8 | *:before,
9 | *:after {
10 | @include box-sizing(border-box);
11 | }
12 |
13 | html {
14 | overflow: hidden;
15 | -ms-touch-action: pan-y;
16 | touch-action: pan-y;
17 | }
18 |
19 | body,
20 | .ionic-body {
21 | @include touch-callout(none);
22 | @include font-smoothing(antialiased);
23 | @include text-size-adjust(none);
24 | @include tap-highlight-transparent();
25 | @include user-select(none);
26 |
27 | top: 0;
28 | right: 0;
29 | bottom: 0;
30 | left: 0;
31 | overflow: hidden;
32 |
33 | margin: 0;
34 | padding: 0;
35 |
36 | color: $base-color;
37 | word-wrap: break-word;
38 | font-size: $font-size-base;
39 | font-family: $font-family-base;
40 | line-height: $line-height-computed;
41 | text-rendering: optimizeLegibility;
42 | -webkit-backface-visibility: hidden;
43 | -webkit-user-drag: none;
44 | }
45 |
46 | body.grade-b,
47 | body.grade-c {
48 | // disable optimizeLegibility for low end devices
49 | text-rendering: auto;
50 | }
51 |
52 | .content {
53 | // used for content areas not using the content directive
54 | position: relative;
55 | }
56 |
57 | .scroll-content {
58 | position: absolute;
59 | top: 0;
60 | right: 0;
61 | bottom: 0;
62 | left: 0;
63 | overflow: hidden;
64 |
65 | // Hide the top border if any
66 | margin-top: -1px;
67 |
68 | width: auto;
69 | height: auto;
70 | }
71 |
72 | .scroll-content-false {
73 | z-index: $z-index-scroll-content-false;
74 | }
75 |
76 | .scroll-view {
77 | position: relative;
78 | display: block;
79 | overflow: hidden;
80 |
81 | // Hide the top border if any
82 | margin-top: -1px;
83 | }
84 |
85 | /**
86 | * Scroll is the scroll view component available for complex and custom
87 | * scroll view functionality.
88 | */
89 | .scroll {
90 | @include user-select(none);
91 | @include touch-callout(none);
92 | @include text-size-adjust(none);
93 | @include transform-origin(left, top);
94 | }
95 |
96 | // Scroll bar styles
97 | .scroll-bar {
98 | position: absolute;
99 | z-index: $z-index-scroll-bar;
100 | }
101 | // hide the scroll-bar during animations
102 | .ng-animate .scroll-bar {
103 | visibility: hidden;
104 | }
105 | .scroll-bar-h {
106 | right: 2px;
107 | bottom: 3px;
108 | left: 2px;
109 | height: 3px;
110 |
111 | .scroll-bar-indicator {
112 | height: 100%;
113 | }
114 | }
115 |
116 | .scroll-bar-v {
117 | top: 2px;
118 | right: 3px;
119 | bottom: 2px;
120 | width: 3px;
121 |
122 | .scroll-bar-indicator {
123 | width: 100%;
124 | }
125 | }
126 | .scroll-bar-indicator {
127 | position: absolute;
128 | border-radius: 4px;
129 | background: rgba(0,0,0,0.3);
130 | opacity: 1;
131 |
132 |
133 | &.scroll-bar-fade-out {
134 | @include transition(opacity 0.3s linear);
135 | opacity: 0;
136 | }
137 | }
138 | .grade-b .scroll-bar-indicator,
139 | .grade-c .scroll-bar-indicator {
140 | // disable rgba background and border radius for low end devices
141 | border-radius: 0;
142 | background: #aaa;
143 |
144 | &.scroll-bar-fade-out {
145 | @include transition(none);
146 | }
147 | }
148 |
149 | @keyframes refresh-spin {
150 | 0% { transform: translate3d(0,0,0) rotate(0); }
151 | 100% { transform: translate3d(0,0,0) rotate(-180deg); }
152 | }
153 |
154 | @-webkit-keyframes refresh-spin {
155 | 0% {-webkit-transform: translate3d(0,0,0) rotate(0); }
156 | 100% {-webkit-transform: translate3d(0,0,0) rotate(-180deg); }
157 | }
158 |
159 | @keyframes refresh-spin-back {
160 | 0% { transform: translate3d(0,0,0) rotate(-180deg); }
161 | 100% { transform: translate3d(0,0,0) rotate(0); }
162 | }
163 |
164 | @-webkit-keyframes refresh-spin-back {
165 | 0% {-webkit-transform: translate3d(0,0,0) rotate(-180deg); }
166 | 100% {-webkit-transform: translate3d(0,0,0) rotate(0); }
167 | }
168 |
169 | // Scroll refresher (for pull to refresh)
170 | .scroll-refresher {
171 | position: absolute;
172 | top: -60px;
173 | right: 0;
174 | left: 0;
175 | overflow: hidden;
176 | margin: auto;
177 | height: 60px;
178 |
179 | .ionic-refresher-content {
180 | position: absolute;
181 | bottom: 15px;
182 | left: 0;
183 | width: 100%;
184 | color: $scroll-refresh-icon-color;
185 | text-align: center;
186 |
187 | font-size: 30px;
188 |
189 | .text-refreshing,
190 | .text-pulling {
191 | font-size: 16px;
192 | line-height: 16px;
193 | }
194 | &.ionic-refresher-with-text {
195 | bottom: 10px;
196 | }
197 | }
198 |
199 | .icon-refreshing,
200 | .icon-pulling {
201 | width: 100%;
202 | -webkit-backface-visibility: hidden;
203 | -webkit-transform-style: preserve-3d;
204 | backface-visibility: hidden;
205 | transform-style: preserve-3d;
206 | }
207 | .icon-pulling {
208 | @include animation-name(refresh-spin-back);
209 | @include animation-duration(200ms);
210 | @include animation-timing-function(linear);
211 | @include animation-fill-mode(none);
212 | -webkit-transform: translate3d(0,0,0) rotate(0deg);
213 | transform: translate3d(0,0,0) rotate(0deg);
214 | }
215 | .icon-refreshing,
216 | .text-refreshing {
217 | display: none;
218 | }
219 | .icon-refreshing {
220 | @include animation-duration(1.5s);
221 | }
222 |
223 | &.active {
224 | .icon-pulling {
225 | @include animation-name(refresh-spin);
226 | -webkit-transform: translate3d(0,0,0) rotate(-180deg);
227 | transform: translate3d(0,0,0) rotate(-180deg);
228 | }
229 | &.refreshing {
230 | .icon-pulling,
231 | .text-pulling {
232 | display: none;
233 | }
234 | .icon-refreshing,
235 | .text-refreshing {
236 | display: block;
237 | }
238 | }
239 | }
240 | }
241 |
242 | .scroll-refresher-content {
243 | position: absolute;
244 | bottom: 15px;
245 | left: 0;
246 | width: 100%;
247 | color: $scroll-refresh-icon-color;
248 | text-align: center;
249 |
250 | font-size: 30px;
251 | }
252 |
253 | // Infinite scroll
254 | ion-infinite-scroll .scroll-infinite {
255 | position: relative;
256 | overflow: hidden;
257 | margin-top: -70px;
258 | height: 60px;
259 | }
260 |
261 | .scroll-infinite-content {
262 | position: absolute;
263 | bottom: -1px;
264 | left: 0;
265 | width: 100%;
266 | color: #666666;
267 | text-align: center;
268 | font-size: 30px; }
269 |
270 | ion-infinite-scroll.active .scroll-infinite {
271 | margin-top: -30px;
272 | }
273 |
274 | .overflow-scroll {
275 | overflow-x: hidden;
276 | overflow-y: scroll;
277 | -webkit-overflow-scrolling: touch;
278 |
279 | .scroll {
280 | position: static;
281 | height: 100%;
282 | -webkit-transform: translate3d(0, 0, 0); // fix iOS bug where relative children of scroller disapear while scrolling. see: http://stackoverflow.com/questions/9807620/ipad-safari-scrolling-causes-html-elements-to-disappear-and-reappear-with-a-dela
283 | }
284 | }
285 |
286 |
287 | // Pad top/bottom of content so it doesn't hide behind .bar-title and .bar-tab.
288 | // Note: For these to work, content must come after both bars in the markup
289 | /* If you change these, change platform.scss as well */
290 | .has-header {
291 | top: $bar-height;
292 | }
293 | // Force no header
294 | .no-header {
295 | top: 0;
296 | }
297 |
298 | .has-subheader {
299 | top: $bar-height * 2;
300 | }
301 | .has-tabs-top {
302 | top: $bar-height + $tabs-height;
303 | }
304 | .has-header.has-subheader.has-tabs-top {
305 | top: 2 * $bar-height + $tabs-height;
306 | }
307 |
308 | .has-footer {
309 | bottom: $bar-height;
310 | }
311 | .has-subfooter {
312 | bottom: $bar-height * 2;
313 | }
314 |
315 | .has-tabs,
316 | .bar-footer.has-tabs {
317 | bottom: $tabs-height;
318 | }
319 |
320 | .has-footer.has-tabs {
321 | bottom: $tabs-height + $bar-height;
322 | }
323 |
324 | // A full screen section with a solid background
325 | .pane {
326 | @include translate3d(0,0,0);
327 | z-index: $z-index-pane;
328 | }
329 | .view {
330 | z-index: $z-index-view;
331 | }
332 | .pane,
333 | .view {
334 | position: absolute;
335 | top: 0;
336 | right: 0;
337 | bottom: 0;
338 | left: 0;
339 | width: 100%;
340 | height: 100%;
341 | background-color: $base-background-color;
342 | overflow: hidden;
343 | }
344 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_tabs.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Tabs
3 | * --------------------------------------------------
4 | * A navigation bar with any number of tab items supported.
5 | */
6 |
7 | .tabs {
8 | @include display-flex();
9 | @include flex-direction(horizontal);
10 | @include justify-content(center);
11 | @include translate3d(0,0,0);
12 |
13 | @include tab-style($tabs-default-bg, $tabs-default-border, $tabs-default-text);
14 | @include tab-badge-style($tabs-default-text, $tabs-default-bg);
15 |
16 | position: absolute;
17 | bottom: 0;
18 |
19 | z-index: $z-index-tabs;
20 |
21 | width: 100%;
22 | height: $tabs-height;
23 |
24 | border-style: solid;
25 | border-top-width: 1px;
26 |
27 | background-size: 0;
28 | line-height: $tabs-height;
29 |
30 | @media (min--moz-device-pixel-ratio: 1.5),
31 | (-webkit-min-device-pixel-ratio: 1.5),
32 | (min-device-pixel-ratio: 1.5),
33 | (min-resolution: 144dpi),
34 | (min-resolution: 1.5dppx) {
35 | padding-top: 2px;
36 | border-top: none !important;
37 | border-bottom: none !important;
38 | background-position: top;
39 | background-size: 100% 1px;
40 | background-repeat: no-repeat;
41 | }
42 |
43 | }
44 | /* Allow parent element of tabs to define color, or just the tab itself */
45 | .tabs-light > .tabs,
46 | .tabs.tabs-light {
47 | @include tab-style($tabs-light-bg, $tabs-light-border, $tabs-light-text);
48 | @include tab-badge-style($tabs-light-text, $tabs-light-bg);
49 | }
50 | .tabs-stable > .tabs,
51 | .tabs.tabs-stable {
52 | @include tab-style($tabs-stable-bg, $tabs-stable-border, $tabs-stable-text);
53 | @include tab-badge-style($tabs-stable-text, $tabs-stable-bg);
54 | }
55 | .tabs-positive > .tabs,
56 | .tabs.tabs-positive {
57 | @include tab-style($tabs-positive-bg, $tabs-positive-border, $tabs-positive-text);
58 | @include tab-badge-style($tabs-positive-text, $tabs-positive-bg);
59 | }
60 | .tabs-calm > .tabs,
61 | .tabs.tabs-calm {
62 | @include tab-style($tabs-calm-bg, $tabs-calm-border, $tabs-calm-text);
63 | @include tab-badge-style($tabs-calm-text, $tabs-calm-bg);
64 | }
65 | .tabs-assertive > .tabs,
66 | .tabs.tabs-assertive {
67 | @include tab-style($tabs-assertive-bg, $tabs-assertive-border, $tabs-assertive-text);
68 | @include tab-badge-style($tabs-assertive-text, $tabs-assertive-bg);
69 | }
70 | .tabs-balanced > .tabs,
71 | .tabs.tabs-balanced {
72 | @include tab-style($tabs-balanced-bg, $tabs-balanced-border, $tabs-balanced-text);
73 | @include tab-badge-style($tabs-balanced-text, $tabs-balanced-bg);
74 | }
75 | .tabs-energized > .tabs,
76 | .tabs.tabs-energized {
77 | @include tab-style($tabs-energized-bg, $tabs-energized-border, $tabs-energized-text);
78 | @include tab-badge-style($tabs-energized-text, $tabs-energized-bg);
79 | }
80 | .tabs-royal > .tabs,
81 | .tabs.tabs-royal {
82 | @include tab-style($tabs-royal-bg, $tabs-royal-border, $tabs-royal-text);
83 | @include tab-badge-style($tabs-royal-text, $tabs-royal-bg);
84 | }
85 | .tabs-dark > .tabs,
86 | .tabs.tabs-dark {
87 | @include tab-style($tabs-dark-bg, $tabs-dark-border, $tabs-dark-text);
88 | @include tab-badge-style($tabs-dark-text, $tabs-dark-bg);
89 | }
90 |
91 | @mixin tabs-striped($style, $color) {
92 | &.#{$style} {
93 | .tab-item.tab-item-active,
94 | .tab-item.active,
95 | .tab-item.activated {
96 | margin-top: -4px;
97 | color: $color;
98 | border-style: solid;
99 | border-width: $tabs-striped-border-width 0 0 0;
100 | border-color: $color;
101 | }
102 | }
103 | }
104 |
105 | .tabs-striped {
106 |
107 | .tabs {
108 | background-color: white;
109 | background-image: none;
110 | border: none;
111 | }
112 |
113 | @include tabs-striped('tabs-light', $light);
114 | @include tabs-striped('tabs-stable', $stable);
115 | @include tabs-striped('tabs-positive', $positive);
116 | @include tabs-striped('tabs-calm', $calm);
117 | @include tabs-striped('tabs-assertive', $assertive);
118 | @include tabs-striped('tabs-balanced', $balanced);
119 | @include tabs-striped('tabs-energized', $energized);
120 | @include tabs-striped('tabs-royal', $royal);
121 | @include tabs-striped('tabs-dark', $dark);
122 |
123 | &.tabs-icon-only .icon {
124 | }
125 |
126 | .tab-item {
127 | color: $tabs-striped-off-color;
128 | opacity: $tabs-striped-off-opacity;
129 | }
130 | .tab-item + .tab-item:before {
131 | border-left: 1px solid #ccc;
132 | display: block;
133 | float: left;
134 | width: 2px;
135 | height: 26px;
136 | margin: 11px auto;
137 | content: " ";
138 | }
139 |
140 | }
141 |
142 | .tabs-top {
143 | &.tabs-striped {
144 | .tab-item.tab-item-active,
145 | .tab-item.active,
146 | .tab-item.activated {
147 | margin-top: 0;
148 | margin-bottom: -4px;
149 | border-width: 0px 0px $tabs-striped-border-width 0px !important;
150 | }
151 | }
152 | }
153 |
154 | /* Allow parent element to have tabs-top */
155 | /* If you change this, change platform.scss as well */
156 | .tabs-top > .tabs,
157 | .tabs.tabs-top {
158 | top: $bar-height;
159 | padding-top: 0;
160 | padding-bottom: 2px;
161 | background-position: bottom;
162 |
163 | }
164 |
165 | .tab-item {
166 | @include flex(1);
167 | display: block;
168 | overflow: hidden;
169 |
170 | max-width: $tab-item-max-width;
171 | height: 100%;
172 |
173 | color: inherit;
174 | text-align: center;
175 | text-decoration: none;
176 | text-overflow: ellipsis;
177 | white-space: nowrap;
178 |
179 | font-weight: 400;
180 | font-size: $tabs-text-font-size;
181 | font-family: $font-family-light-sans-serif;
182 |
183 | opacity: 0.7;
184 |
185 | &:hover {
186 | cursor: pointer;
187 | }
188 | }
189 |
190 | .tabs-item-hide > .tabs,
191 | .tabs.tabs-item-hide {
192 | display: none;
193 | }
194 |
195 | .tabs-icon-top > .tabs .tab-item,
196 | .tabs-icon-top.tabs .tab-item,
197 | .tabs-icon-bottom > .tabs .tab-item,
198 | .tabs-icon-bottom.tabs .tab-item {
199 | font-size: $tabs-text-font-size-side-icon;
200 | line-height: $tabs-text-font-size;
201 | }
202 |
203 | .tab-item .icon {
204 | display: block;
205 | margin: 0 auto;
206 | height: $tabs-icon-size;
207 | font-size: $tabs-icon-size;
208 | }
209 |
210 | .tabs-icon-left.tabs .tab-item,
211 | .tabs-icon-left > .tabs .tab-item,
212 | .tabs-icon-right.tabs .tab-item,
213 | .tabs-icon-right > .tabs .tab-item {
214 | font-size: $tabs-text-font-size-side-icon;
215 |
216 | .icon {
217 | display: inline-block;
218 | vertical-align: top;
219 |
220 | &:before {
221 | font-size: $tabs-icon-size - 8;
222 | line-height: $tabs-height;
223 | }
224 | }
225 | }
226 |
227 | .tabs-icon-left > .tabs .tab-item .icon,
228 | .tabs-icon-left.tabs .tab-item .icon {
229 | padding-right: 3px;
230 | }
231 |
232 | .tabs-icon-right > .tabs .tab-item .icon,
233 | .tabs-icon-right.tabs .tab-item .icon {
234 | padding-left: 3px;
235 | }
236 |
237 | .tabs-icon-only > .tabs .icon,
238 | .tabs-icon-only.tabs .icon {
239 | line-height: inherit;
240 | }
241 |
242 |
243 | .tab-item.has-badge {
244 | position: relative;
245 | }
246 |
247 | .tab-item .badge {
248 | position: absolute;
249 | top: 4%;
250 | right: 33%; // fallback
251 | right: calc(50% - 26px);
252 | padding: $tabs-badge-padding;
253 | height: auto;
254 | font-size: $tabs-badge-font-size;
255 | line-height: $tabs-badge-font-size + 4;
256 | }
257 |
258 |
259 | /* Navigational tab */
260 |
261 | /* Active state for tab */
262 | .tab-item.tab-item-active,
263 | .tab-item.active,
264 | .tab-item.activated {
265 | opacity: 1;
266 |
267 | &.tab-item-light {
268 | color: $light;
269 | }
270 | &.tab-item-stable {
271 | color: $stable;
272 | }
273 | &.tab-item-positive {
274 | color: $positive;
275 | }
276 | &.tab-item-calm {
277 | color: $calm;
278 | }
279 | &.tab-item-assertive {
280 | color: $assertive;
281 | }
282 | &.tab-item-balanced {
283 | color: $balanced;
284 | }
285 | &.tab-item-energized {
286 | color: $energized;
287 | }
288 | &.tab-item-royal {
289 | color: $royal;
290 | }
291 | &.tab-item-dark {
292 | color: $dark;
293 | }
294 | }
295 |
296 | .item.tabs {
297 | @include display-flex();
298 | padding: 0;
299 |
300 | .icon:before {
301 | position: relative;
302 | }
303 | }
304 |
305 | .tab-item.disabled,
306 | .tab-item[disabled] {
307 | opacity: .4;
308 | cursor: default;
309 | pointer-events: none;
310 | }
311 |
312 | /** Platform styles **/
313 |
314 | .tab-item.tab-item-ios {
315 | }
316 | .tab-item.tab-item-android {
317 | border-top: 2px solid inherit;
318 | }
319 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_reset.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Resets
4 | * --------------------------------------------------
5 | * Adapted from normalize.css and some reset.css. We don't care even one
6 | * bit about old IE, so we don't need any hacks for that in here.
7 | *
8 | * There are probably other things we could remove here, as well.
9 | *
10 | * normalize.css v2.1.2 | MIT License | git.io/normalize
11 |
12 | * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
13 | * http://cssreset.com
14 | */
15 |
16 | html, body, div, span, applet, object, iframe,
17 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
18 | a, abbr, acronym, address, big, cite, code,
19 | del, dfn, em, img, ins, kbd, q, s, samp,
20 | small, strike, strong, sub, sup, tt, var,
21 | b, i, u, center,
22 | dl, dt, dd, ol, ul, li,
23 | fieldset, form, label, legend,
24 | table, caption, tbody, tfoot, thead, tr, th, td,
25 | article, aside, canvas, details, embed, fieldset,
26 | figure, figcaption, footer, header, hgroup,
27 | menu, nav, output, ruby, section, summary,
28 | time, mark, audio, video {
29 | margin: 0;
30 | padding: 0;
31 | border: 0;
32 | vertical-align: baseline;
33 | font: inherit;
34 | font-size: 100%;
35 | }
36 |
37 | ol, ul {
38 | list-style: none;
39 | }
40 | blockquote, q {
41 | quotes: none;
42 | }
43 | blockquote:before, blockquote:after,
44 | q:before, q:after {
45 | content: '';
46 | content: none;
47 | }
48 |
49 | /**
50 | * Prevent modern browsers from displaying `audio` without controls.
51 | * Remove excess height in iOS 5 devices.
52 | */
53 |
54 | audio:not([controls]) {
55 | display: none;
56 | height: 0;
57 | }
58 |
59 | /**
60 | * Hide the `template` element in IE, Safari, and Firefox < 22.
61 | */
62 |
63 | [hidden],
64 | template {
65 | display: none;
66 | }
67 |
68 | script {
69 | display: none !important;
70 | }
71 |
72 | /* ==========================================================================
73 | Base
74 | ========================================================================== */
75 |
76 | /**
77 | * 1. Set default font family to sans-serif.
78 | * 2. Prevent iOS text size adjust after orientation change, without disabling
79 | * user zoom.
80 | */
81 |
82 | html {
83 | @include user-select(none);
84 | font-family: sans-serif; /* 1 */
85 | -webkit-text-size-adjust: 100%;
86 | -ms-text-size-adjust: 100%; /* 2 */
87 | -webkit-text-size-adjust: 100%; /* 2 */
88 | }
89 |
90 | /**
91 | * Remove default margin.
92 | */
93 |
94 | body {
95 | margin: 0;
96 | line-height: 1;
97 | }
98 |
99 |
100 | /**
101 | * Remove default outlines.
102 | */
103 | a,
104 | button,
105 | :focus,
106 | a:focus,
107 | button:focus,
108 | a:active,
109 | a:hover {
110 | outline: 0;
111 | }
112 |
113 | /* *
114 | * Remove tap highlight color
115 | */
116 |
117 | a {
118 | -webkit-user-drag: none;
119 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
120 | -webkit-tap-highlight-color: transparent;
121 |
122 | &[href]:hover {
123 | cursor: pointer;
124 | }
125 | }
126 |
127 | /* ==========================================================================
128 | Typography
129 | ========================================================================== */
130 |
131 |
132 | /**
133 | * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
134 | */
135 |
136 | b,
137 | strong {
138 | font-weight: bold;
139 | }
140 |
141 | /**
142 | * Address styling not present in Safari 5 and Chrome.
143 | */
144 |
145 | dfn {
146 | font-style: italic;
147 | }
148 |
149 | /**
150 | * Address differences between Firefox and other browsers.
151 | */
152 |
153 | hr {
154 | -moz-box-sizing: content-box;
155 | box-sizing: content-box;
156 | height: 0;
157 | }
158 |
159 |
160 | /**
161 | * Correct font family set oddly in Safari 5 and Chrome.
162 | */
163 |
164 | code,
165 | kbd,
166 | pre,
167 | samp {
168 | font-size: 1em;
169 | font-family: monospace, serif;
170 | }
171 |
172 | /**
173 | * Improve readability of pre-formatted text in all browsers.
174 | */
175 |
176 | pre {
177 | white-space: pre-wrap;
178 | }
179 |
180 | /**
181 | * Set consistent quote types.
182 | */
183 |
184 | q {
185 | quotes: "\201C" "\201D" "\2018" "\2019";
186 | }
187 |
188 | /**
189 | * Address inconsistent and variable font size in all browsers.
190 | */
191 |
192 | small {
193 | font-size: 80%;
194 | }
195 |
196 | /**
197 | * Prevent `sub` and `sup` affecting `line-height` in all browsers.
198 | */
199 |
200 | sub,
201 | sup {
202 | position: relative;
203 | vertical-align: baseline;
204 | font-size: 75%;
205 | line-height: 0;
206 | }
207 |
208 | sup {
209 | top: -0.5em;
210 | }
211 |
212 | sub {
213 | bottom: -0.25em;
214 | }
215 |
216 | /**
217 | * Define consistent border, margin, and padding.
218 | */
219 |
220 | fieldset {
221 | margin: 0 2px;
222 | padding: 0.35em 0.625em 0.75em;
223 | border: 1px solid #c0c0c0;
224 | }
225 |
226 | /**
227 | * 1. Correct `color` not being inherited in IE 8/9.
228 | * 2. Remove padding so people aren't caught out if they zero out fieldsets.
229 | */
230 |
231 | legend {
232 | padding: 0; /* 2 */
233 | border: 0; /* 1 */
234 | }
235 |
236 | /**
237 | * 1. Correct font family not being inherited in all browsers.
238 | * 2. Correct font size not being inherited in all browsers.
239 | * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
240 | * 4. Remove any default :focus styles
241 | * 5. Make sure webkit font smoothing is being inherited
242 | * 6. Remove default gradient in Android Firefox / FirefoxOS
243 | */
244 |
245 | button,
246 | input,
247 | select,
248 | textarea {
249 | margin: 0; /* 3 */
250 | font-size: 100%; /* 2 */
251 | font-family: inherit; /* 1 */
252 | outline-offset: 0; /* 4 */
253 | outline-style: none; /* 4 */
254 | outline-width: 0; /* 4 */
255 | -webkit-font-smoothing: inherit; /* 5 */
256 | background-image: none; /* 6 */
257 | }
258 |
259 | /**
260 | * Address Firefox 4+ setting `line-height` on `input` using `importnt` in
261 | * the UA stylesheet.
262 | */
263 |
264 | button,
265 | input {
266 | line-height: normal;
267 | }
268 |
269 | /**
270 | * Address inconsistent `text-transform` inheritance for `button` and `select`.
271 | * All other form control elements do not inherit `text-transform` values.
272 | * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
273 | * Correct `select` style inheritance in Firefox 4+ and Opera.
274 | */
275 |
276 | button,
277 | select {
278 | text-transform: none;
279 | }
280 |
281 | /**
282 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
283 | * and `video` controls.
284 | * 2. Correct inability to style clickable `input` types in iOS.
285 | * 3. Improve usability and consistency of cursor style between image-type
286 | * `input` and others.
287 | */
288 |
289 | button,
290 | html input[type="button"], /* 1 */
291 | input[type="reset"],
292 | input[type="submit"] {
293 | cursor: pointer; /* 3 */
294 | -webkit-appearance: button; /* 2 */
295 | }
296 |
297 | /**
298 | * Re-set default cursor for disabled elements.
299 | */
300 |
301 | button[disabled],
302 | html input[disabled] {
303 | cursor: default;
304 | }
305 |
306 | /**
307 | * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
308 | * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
309 | * (include `-moz` to future-proof).
310 | */
311 |
312 | input[type="search"] {
313 | -webkit-box-sizing: content-box; /* 2 */
314 | -moz-box-sizing: content-box;
315 | box-sizing: content-box;
316 | -webkit-appearance: textfield; /* 1 */
317 | }
318 |
319 | /**
320 | * Remove inner padding and search cancel button in Safari 5 and Chrome
321 | * on OS X.
322 | */
323 |
324 | input[type="search"]::-webkit-search-cancel-button,
325 | input[type="search"]::-webkit-search-decoration {
326 | -webkit-appearance: none;
327 | }
328 |
329 | /**
330 | * Remove inner padding and border in Firefox 4+.
331 | */
332 |
333 | button::-moz-focus-inner,
334 | input::-moz-focus-inner {
335 | padding: 0;
336 | border: 0;
337 | }
338 |
339 | /**
340 | * 1. Remove default vertical scrollbar in IE 8/9.
341 | * 2. Improve readability and alignment in all browsers.
342 | */
343 |
344 | textarea {
345 | overflow: auto; /* 1 */
346 | vertical-align: top; /* 2 */
347 | }
348 |
349 |
350 | img {
351 | -webkit-user-drag: none;
352 | }
353 |
354 | /* ==========================================================================
355 | Tables
356 | ========================================================================== */
357 |
358 | /**
359 | * Remove most spacing between table cells.
360 | */
361 |
362 | table {
363 | border-spacing: 0;
364 | border-collapse: collapse;
365 | }
366 |
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_bar.scss:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Bar (Headers and Footers)
4 | * --------------------------------------------------
5 | */
6 |
7 | .bar {
8 | @include display-flex();
9 | @include translate3d(0,0,0);
10 | @include user-select(none);
11 | position: absolute;
12 | right: 0;
13 | left: 0;
14 | z-index: $z-index-bar;
15 |
16 | box-sizing: border-box;
17 | padding: $bar-padding-portrait;
18 |
19 | width: 100%;
20 | height: $bar-height;
21 | border-width: 0;
22 | border-style: solid;
23 | border-top: 1px solid transparent;
24 | border-bottom: 1px solid $bar-default-border;
25 |
26 | background-color: $bar-default-bg;
27 |
28 | /* border-width: 1px will actually create 2 device pixels on retina */
29 | /* this nifty trick sets an actual 1px border on hi-res displays */
30 | background-size: 0;
31 | @media (min--moz-device-pixel-ratio: 1.5),
32 | (-webkit-min-device-pixel-ratio: 1.5),
33 | (min-device-pixel-ratio: 1.5),
34 | (min-resolution: 144dpi),
35 | (min-resolution: 1.5dppx) {
36 | border: none;
37 | background-image: linear-gradient(0deg, $bar-default-border, $bar-default-border 50%, transparent 50%);
38 | background-position: bottom;
39 | background-size: 100% 1px;
40 | background-repeat: no-repeat;
41 | }
42 |
43 | &.bar-clear {
44 | border: none;
45 | background: none;
46 | color: #fff;
47 |
48 | .button {
49 | color: #fff;
50 | }
51 | .title {
52 | color: #fff;
53 | }
54 | }
55 |
56 | &.item-input-inset {
57 | .item-input-wrapper {
58 | margin-top: -1px;
59 |
60 | input {
61 | padding-left: 8px;
62 | width: 94%;
63 | height: 28px;
64 | background: transparent;
65 | }
66 | }
67 | }
68 |
69 | &.bar-light {
70 | @include bar-style($bar-light-bg, $bar-light-border, $bar-light-text);
71 | &.bar-footer{
72 | background-image: linear-gradient(180deg, $bar-light-border, $bar-light-border 50%, transparent 50%);
73 | }
74 | }
75 | &.bar-stable {
76 | @include bar-style($bar-stable-bg, $bar-stable-border, $bar-stable-text);
77 | &.bar-footer{
78 | background-image: linear-gradient(180deg, $bar-stable-border, $bar-stable-border 50%, transparent 50%);
79 | }
80 | }
81 | &.bar-positive {
82 | @include bar-style($bar-positive-bg, $bar-positive-border, $bar-positive-text);
83 | &.bar-footer{
84 | background-image: linear-gradient(180deg, $bar-positive-border, $bar-positive-border 50%, transparent 50%);
85 | }
86 | }
87 | &.bar-calm {
88 | @include bar-style($bar-calm-bg, $bar-calm-border, $bar-calm-text);
89 | &.bar-footer{
90 | background-image: linear-gradient(180deg, $bar-calm-border, $bar-calm-border 50%, transparent 50%);
91 | }
92 | }
93 | &.bar-assertive {
94 | @include bar-style($bar-assertive-bg, $bar-assertive-border, $bar-assertive-text);
95 | &.bar-footer{
96 | background-image: linear-gradient(180deg, $bar-assertive-border, $bar-assertive-border 50%, transparent 50%);
97 | }
98 | }
99 | &.bar-balanced {
100 | @include bar-style($bar-balanced-bg, $bar-balanced-border, $bar-balanced-text);
101 | &.bar-footer{
102 | background-image: linear-gradient(180deg, $bar-balanced-border, $bar-positive-border 50%, transparent 50%);
103 | }
104 | }
105 | &.bar-energized {
106 | @include bar-style($bar-energized-bg, $bar-energized-border, $bar-energized-text);
107 | &.bar-footer{
108 | background-image: linear-gradient(180deg, $bar-energized-border, $bar-energized-border 50%, transparent 50%);
109 | }
110 | }
111 | &.bar-royal {
112 | @include bar-style($bar-royal-bg, $bar-royal-border, $bar-royal-text);
113 | &.bar-footer{
114 | background-image: linear-gradient(180deg, $bar-royal-border, $bar-royal-border 50%, transparent 50%);
115 | }
116 | }
117 | &.bar-dark {
118 | @include bar-style($bar-dark-bg, $bar-dark-border, $bar-dark-text);
119 | &.bar-footer{
120 | background-image: linear-gradient(180deg, $bar-dark-border, $bar-dark-border 50%, transparent 50%);
121 | }
122 | }
123 |
124 | // Title inside of a bar is centered
125 | .title {
126 | position: absolute;
127 |
128 | top: 0;
129 | right: 0;
130 | left: 0;
131 | z-index: $z-index-bar-title;
132 | overflow: hidden;
133 |
134 | margin: 0 10px;
135 |
136 | min-width: 30px;
137 | height: $bar-height - 1;
138 |
139 | text-align: center;
140 |
141 | // Go into ellipsis if too small
142 | text-overflow: ellipsis;
143 | white-space: nowrap;
144 |
145 | font-size: $bar-title-font-size;
146 |
147 | line-height: $bar-height;
148 |
149 | &.title-left {
150 | text-align: left;
151 | }
152 | &.title-right {
153 | text-align: right;
154 | }
155 | }
156 |
157 | .title a {
158 | color: inherit;
159 | }
160 |
161 | .button {
162 | z-index: $z-index-bar-button;
163 | padding: 0 $button-bar-button-padding;
164 | min-width: initial;
165 | min-height: $button-bar-button-height - 1;
166 | font-weight: 400;
167 | font-size: $button-bar-button-font-size;
168 | line-height: $button-bar-button-height;
169 |
170 | &.button-icon:before,
171 | .icon:before,
172 | &.icon:before,
173 | &.icon-left:before,
174 | &.icon-right:before {
175 | padding-right: 2px;
176 | padding-left: 2px;
177 | font-size: $button-bar-button-icon-size;
178 | line-height: $button-bar-button-height;
179 | }
180 |
181 | &.button-icon {
182 | font-size: $bar-title-font-size;
183 | .icon:before,
184 | &:before,
185 | &.icon-left:before,
186 | &.icon-right:before {
187 | vertical-align: top;
188 | font-size: $button-large-icon-size;
189 | line-height: $button-bar-button-height;
190 | }
191 | }
192 | &.button-clear {
193 | padding-right: 2px;
194 | padding-left: 2px;
195 | font-weight: 300;
196 | font-size: $bar-title-font-size;
197 |
198 | .icon:before,
199 | &.icon:before,
200 | &.icon-left:before,
201 | &.icon-right:before {
202 | font-size: $button-large-icon-size;
203 | line-height: $button-bar-button-height;
204 | }
205 | }
206 |
207 | &.back-button {
208 | padding: 0;
209 | opacity: 0.8;
210 | .back-button-title {
211 | display: inline-block;
212 | vertical-align: middle;
213 | margin-left: 4px;
214 | }
215 | }
216 |
217 | &.back-button.active,
218 | &.back-button.activated {
219 | opacity: 1;
220 | }
221 | }
222 |
223 | .button-bar > .button,
224 | .buttons > .button {
225 | min-height: $button-bar-button-height - 1;
226 | line-height: $button-bar-button-height;
227 | }
228 |
229 | .button-bar + .button,
230 | .button + .button-bar {
231 | margin-left: 5px;
232 | }
233 |
234 | // Android 4.4 messes with the display property
235 | .buttons,
236 | .buttons.left-buttons,
237 | .buttons.right-buttons {
238 | display: inherit;
239 | }
240 | // Place the last button in a bar on the right of the bar
241 | .title + .button:last-child,
242 | > .button + .button:last-child,
243 | > .button.pull-right,
244 | .buttons.pull-right,
245 | .title + .buttons {
246 | position: absolute;
247 | top: 5px;
248 | right: 5px;
249 | bottom: 5px;
250 | }
251 |
252 | }
253 |
254 | // Default styles for buttons inside of styled bars
255 | .bar-light {
256 | .button {
257 | @include button-style($bar-light-bg, $bar-light-border, $bar-light-active-bg, $bar-light-active-border, $bar-light-text);
258 | @include button-clear($bar-light-text, $bar-title-font-size);
259 | }
260 | }
261 | .bar-stable {
262 | .button {
263 | @include button-style($bar-stable-bg, $bar-stable-border, $bar-stable-active-bg, $bar-stable-active-border, $bar-stable-text);
264 | @include button-clear($bar-stable-text, $bar-title-font-size);
265 | }
266 | }
267 | .bar-positive {
268 | .button {
269 | @include button-style($bar-positive-bg, $bar-positive-border, $bar-positive-active-bg, $bar-positive-active-border, $bar-positive-text);
270 | @include button-clear(#fff, $bar-title-font-size);
271 | }
272 | }
273 | .bar-calm {
274 | .button {
275 | @include button-style($bar-calm-bg, $bar-calm-border, $bar-calm-active-bg, $bar-calm-active-border, $bar-calm-text);
276 | @include button-clear(#fff, $bar-title-font-size);
277 | }
278 | }
279 | .bar-assertive {
280 | .button {
281 | @include button-style($bar-assertive-bg, $bar-assertive-border, $bar-assertive-active-bg, $bar-assertive-active-border, $bar-assertive-text);
282 | @include button-clear(#fff, $bar-title-font-size);
283 | }
284 | }
285 | .bar-balanced {
286 | .button {
287 | @include button-style($bar-balanced-bg, $bar-balanced-border, $bar-balanced-active-bg, $bar-balanced-active-border, $bar-balanced-text);
288 | @include button-clear(#fff, $bar-title-font-size);
289 | }
290 | }
291 | .bar-energized {
292 | .button {
293 | @include button-style($bar-energized-bg, $bar-energized-border, $bar-energized-active-bg, $bar-energized-active-border, $bar-energized-text);
294 | @include button-clear(#fff, $bar-title-font-size);
295 | }
296 | }
297 | .bar-royal {
298 | .button {
299 | @include button-style($bar-royal-bg, $bar-royal-border, $bar-royal-active-bg, $bar-royal-active-border, $bar-royal-text);
300 | @include button-clear(#fff, $bar-title-font-size);
301 | }
302 | }
303 | .bar-dark {
304 | .button {
305 | @include button-style($bar-dark-bg, $bar-dark-border, $bar-dark-active-bg, $bar-dark-active-border, $bar-dark-text);
306 | @include button-clear(#fff, $bar-title-font-size);
307 | }
308 | }
309 |
310 | // Header at top
311 | .bar-header {
312 | top: 0;
313 | border-top-width: 0;
314 | border-bottom-width: 1px;
315 | }
316 |
317 | // Footer at bottom
318 | .bar-footer {
319 | bottom: 0;
320 | border-top-width: 1px;
321 | border-bottom-width: 0;
322 | background-position: top;
323 |
324 | &.item-input-inset {
325 | position: absolute;
326 | }
327 | }
328 |
329 | // Don't render padding if the bar is just for tabs
330 | .bar-tabs {
331 | padding: 0;
332 | }
333 |
334 | .bar-subheader {
335 | top: $bar-height;
336 | display: block;
337 | }
338 | .bar-subfooter {
339 | bottom: $bar-height;
340 | display: block;
341 | }
342 |
--------------------------------------------------------------------------------
/www/lib/ionic/js/angular/angular-animate.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | AngularJS v1.2.17
3 | (c) 2010-2014 Google, Inc. http://angularjs.org
4 | License: MIT
5 | */
6 | (function(u,f,P){'use strict';f.module("ngAnimate",["ng"]).factory("$$animateReflow",["$$rAF","$document",function(f,u){return function(e){return f(function(){e()})}}]).config(["$provide","$animateProvider",function(W,H){function e(f){for(var e=0;e=x&&b>=u&&f()}var k=e(b);a=b.data(m);if(-1!=k.getAttribute("class").indexOf(c)&&a){var p="";h(c.split(" "),function(a,b){p+=(0>>0,d=Number(arguments[2])||0;for(d=0>d?Math.ceil(d):Math.floor(d),0>d&&(d+=c);c>d;d++)if(d in a&&a[d]===b)return d;return-1}function h(a,b,c,d){var e,h=f(c,d),i={},j=[];for(var k in h)if(h[k].params&&h[k].params.length){e=h[k].params;for(var l in e)g(j,e[l])>=0||(j.push(e[l]),i[e[l]]=a[e[l]])}return I({},i,b)}function i(a,b){var c={};return H(a,function(a){var d=b[a];c[a]=null!=d?String(d):null}),c}function j(a,b,c){if(!c){c=[];for(var d in a)c.push(d)}for(var e=0;e "));if(o[c]=d,E(a))m.push(c,[function(){return b.get(a)}],h);else{var e=b.annotate(a);H(e,function(a){a!==c&&g.hasOwnProperty(a)&&k(g[a],a)}),m.push(c,a,e)}n.pop(),o[c]=f}}function l(a){return F(a)&&a.then&&a.$$promises}if(!F(g))throw new Error("'invocables' must be an object");var m=[],n=[],o={};return H(g,k),g=n=o=null,function(d,f,g){function h(){--s||(t||e(r,f.$$values),p.$$values=r,p.$$promises=!0,o.resolve(r))}function k(a){p.$$failure=a,o.reject(a)}function n(c,e,f){function i(a){l.reject(a),k(a)}function j(){if(!C(p.$$failure))try{l.resolve(b.invoke(e,g,r)),l.promise.then(function(a){r[c]=a,h()},i)}catch(a){i(a)}}var l=a.defer(),m=0;H(f,function(a){q.hasOwnProperty(a)&&!d.hasOwnProperty(a)&&(m++,q[a].then(function(b){r[a]=b,--m||j()},i))}),m||j(),q[c]=l.promise}if(l(d)&&g===c&&(g=f,f=d,d=null),d){if(!F(d))throw new Error("'locals' must be an object")}else d=i;if(f){if(!l(f))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else f=j;var o=a.defer(),p=o.promise,q=p.$$promises={},r=I({},d),s=1+m.length/3,t=!1;if(C(f.$$failure))return k(f.$$failure),p;f.$$values?(t=e(r,f.$$values),h()):(I(q,f.$$promises),f.then(h,k));for(var u=0,v=m.length;v>u;u+=3)d.hasOwnProperty(m[u])?h():n(m[u],m[u+1],m[u+2]);return p}},this.resolve=function(a,b,c,d){return this.study(a)(b,c,d)}}function m(a,b,c){this.fromConfig=function(a,b,c){return C(a.template)?this.fromString(a.template,b):C(a.templateUrl)?this.fromUrl(a.templateUrl,b):C(a.templateProvider)?this.fromProvider(a.templateProvider,b,c):null},this.fromString=function(a,b){return D(a)?a(b):a},this.fromUrl=function(c,d){return D(c)&&(c=c(d)),null==c?null:a.get(c,{cache:b}).then(function(a){return a.data})},this.fromProvider=function(a,b,d){return c.invoke(a,null,d||{params:b})}}function n(a){function b(b){if(!/^\w+(-+\w+)*$/.test(b))throw new Error("Invalid parameter name '"+b+"' in pattern '"+a+"'");if(f[b])throw new Error("Duplicate parameter name '"+b+"' in pattern '"+a+"'");f[b]=!0,j.push(b)}function c(a){return a.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&")}var d,e=/([:*])(\w+)|\{(\w+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,f={},g="^",h=0,i=this.segments=[],j=this.params=[];this.source=a;for(var k,l,m;(d=e.exec(a))&&(k=d[2]||d[3],l=d[4]||("*"==d[1]?".*":"[^/]*"),m=a.substring(h,d.index),!(m.indexOf("?")>=0));)g+=c(m)+"("+l+")",b(k),i.push(m),h=e.lastIndex;m=a.substring(h);var n=m.indexOf("?");if(n>=0){var o=this.sourceSearch=m.substring(n);m=m.substring(0,n),this.sourcePath=a.substring(0,h+n),H(o.substring(1).split(/[&?]/),b)}else this.sourcePath=a,this.sourceSearch="";g+=c(m)+"$",i.push(m),this.regexp=new RegExp(g),this.prefix=i[0]}function o(){this.compile=function(a){return new n(a)},this.isMatcher=function(a){return F(a)&&D(a.exec)&&D(a.format)&&D(a.concat)},this.$get=function(){return this}}function p(a){function b(a){var b=/^\^((?:\\[^a-zA-Z0-9]|[^\\\[\]\^$*+?.()|{}]+)*)/.exec(a.source);return null!=b?b[1].replace(/\\(.)/g,"$1"):""}function c(a,b){return a.replace(/\$(\$|\d{1,2})/,function(a,c){return b["$"===c?0:Number(c)]})}function d(a,b,c){if(!c)return!1;var d=a.invoke(b,b,{$match:c});return C(d)?d:!0}var e=[],f=null;this.rule=function(a){if(!D(a))throw new Error("'rule' must be a function");return e.push(a),this},this.otherwise=function(a){if(E(a)){var b=a;a=function(){return b}}else if(!D(a))throw new Error("'rule' must be a function");return f=a,this},this.when=function(e,f){var g,h=E(f);if(E(e)&&(e=a.compile(e)),!h&&!D(f)&&!G(f))throw new Error("invalid 'handler' in when()");var i={matcher:function(b,c){return h&&(g=a.compile(c),c=["$match",function(a){return g.format(a)}]),I(function(a,e){return d(a,c,b.exec(e.path(),e.search()))},{prefix:E(b.prefix)?b.prefix:""})},regex:function(a,e){if(a.global||a.sticky)throw new Error("when() RegExp must not be global or sticky");return h&&(g=e,e=["$match",function(a){return c(g,a)}]),I(function(b,c){return d(b,e,a.exec(c.path()))},{prefix:b(a)})}},j={matcher:a.isMatcher(e),regex:e instanceof RegExp};for(var k in j)if(j[k])return this.rule(i[k](e,f));throw new Error("invalid 'what' in when()")},this.$get=["$location","$rootScope","$injector",function(a,b,c){function d(b){function d(b){var d=b(c,a);return d?(E(d)&&a.replace().url(d),!0):!1}if(!b||!b.defaultPrevented){var g,h=e.length;for(g=0;h>g;g++)if(d(e[g]))return;f&&d(f)}}return b.$on("$locationChangeSuccess",d),{sync:function(){d()}}}]}function q(a,e,f){function g(a){return 0===a.indexOf(".")||0===a.indexOf("^")}function l(a,b){var d=E(a),e=d?a:a.name,f=g(e);if(f){if(!b)throw new Error("No reference point given for path '"+e+"'");for(var h=e.split("."),i=0,j=h.length,k=b;j>i;i++)if(""!==h[i]||0!==i){if("^"!==h[i])break;if(!k.parent)throw new Error("Path '"+e+"' not valid for state '"+b.name+"'");k=k.parent}else k=b;h=h.slice(i).join("."),e=k.name+(k.name&&h?".":"")+h}var l=w[e];return!l||!d&&(d||l!==a&&l.self!==a)?c:l}function m(a,b){x[a]||(x[a]=[]),x[a].push(b)}function n(b){b=d(b,{self:b,resolve:b.resolve||{},toString:function(){return this.name}});var c=b.name;if(!E(c)||c.indexOf("@")>=0)throw new Error("State must have a valid name");if(w.hasOwnProperty(c))throw new Error("State '"+c+"'' is already defined");var e=-1!==c.indexOf(".")?c.substring(0,c.lastIndexOf(".")):E(b.parent)?b.parent:"";if(e&&!w[e])return m(e,b.self);for(var f in z)D(z[f])&&(b[f]=z[f](b,z.$delegates[f]));if(w[c]=b,!b[y]&&b.url&&a.when(b.url,["$match","$stateParams",function(a,c){v.$current.navigable==b&&j(a,c)||v.transitionTo(b,a,{location:!1})}]),x[c])for(var g=0;g-1}function p(a){var b=a.split("."),c=v.$current.name.split(".");if("**"===b[0]&&(c=c.slice(c.indexOf(b[1])),c.unshift("**")),"**"===b[b.length-1]&&(c.splice(c.indexOf(b[b.length-2])+1,Number.MAX_VALUE),c.push("**")),b.length!=c.length)return!1;for(var d=0,e=b.length;e>d;d++)"*"===b[d]&&(c[d]="*");return c.join("")===b.join("")}function q(a,b){return E(a)&&!C(b)?z[a]:D(b)&&E(a)?(z[a]&&!z.$delegates[a]&&(z.$delegates[a]=z[a]),z[a]=b,this):this}function r(a,b){return F(a)?b=a:b.name=a,n(b),this}function s(a,e,g,m,n,q,r,s,x){function z(){r.url()!==M&&(r.url(M),r.replace())}function A(a,c,d,f,h){var i=d?c:k(a.params,c),j={$stateParams:i};h.resolve=n.resolve(a.resolve,j,h.resolve,a);var l=[h.resolve.then(function(a){h.globals=a})];return f&&l.push(f),H(a.views,function(c,d){var e=c.resolve&&c.resolve!==a.resolve?c.resolve:{};e.$template=[function(){return g.load(d,{view:c,locals:j,params:i,notify:!1})||""}],l.push(n.resolve(e,j,h.resolve,a).then(function(f){if(D(c.controllerProvider)||G(c.controllerProvider)){var g=b.extend({},e,j);f.$$controller=m.invoke(c.controllerProvider,null,g)}else f.$$controller=c.controller;f.$$state=a,f.$$controllerAs=c.controllerAs,h[d]=f}))}),e.all(l).then(function(){return h})}var B=e.reject(new Error("transition superseded")),F=e.reject(new Error("transition prevented")),K=e.reject(new Error("transition aborted")),L=e.reject(new Error("transition failed")),M=r.url(),N=x.baseHref();return u.locals={resolve:null,globals:{$stateParams:{}}},v={params:{},current:u.self,$current:u,transition:null},v.reload=function(){v.transitionTo(v.current,q,{reload:!0,inherit:!1,notify:!1})},v.go=function(a,b,c){return this.transitionTo(a,b,I({inherit:!0,relative:v.$current},c))},v.transitionTo=function(b,c,f){c=c||{},f=I({location:!0,inherit:!1,relative:null,notify:!0,reload:!1,$retry:!1},f||{});var g,k=v.$current,n=v.params,o=k.path,p=l(b,f.relative);if(!C(p)){var s={to:b,toParams:c,options:f};if(g=a.$broadcast("$stateNotFound",s,k.self,n),g.defaultPrevented)return z(),K;if(g.retry){if(f.$retry)return z(),L;var w=v.transition=e.when(g.retry);return w.then(function(){return w!==v.transition?B:(s.options.$retry=!0,v.transitionTo(s.to,s.toParams,s.options))},function(){return K}),z(),w}if(b=s.to,c=s.toParams,f=s.options,p=l(b,f.relative),!C(p)){if(f.relative)throw new Error("Could not resolve '"+b+"' from state '"+f.relative+"'");throw new Error("No such state '"+b+"'")}}if(p[y])throw new Error("Cannot transition to abstract state '"+b+"'");f.inherit&&(c=h(q,c||{},v.$current,p)),b=p;var x,D,E=b.path,G=u.locals,H=[];for(x=0,D=E[x];D&&D===o[x]&&j(c,n,D.ownParams)&&!f.reload;x++,D=E[x])G=H[x]=D.locals;if(t(b,k,G,f))return b.self.reloadOnSearch!==!1&&z(),v.transition=null,e.when(v.current);if(c=i(b.params,c||{}),f.notify&&(g=a.$broadcast("$stateChangeStart",b.self,c,k.self,n),g.defaultPrevented))return z(),F;for(var N=e.when(G),O=x;O=x;d--)g=o[d],g.self.onExit&&m.invoke(g.self.onExit,g.self,g.locals.globals),g.locals=null;for(d=x;d1||b.ctrlKey||b.metaKey||b.shiftKey||f.attr("target")||(c(function(){a.go(i.state,j,o)}),b.preventDefault())})}}}function y(a,b,c){return{restrict:"A",controller:["$scope","$element","$attrs",function(d,e,f){function g(){a.$current.self===i&&h()?e.addClass(l):e.removeClass(l)}function h(){return!k||j(k,b)}var i,k,l;l=c(f.uiSrefActive||"",!1)(d),this.$$setStateInfo=function(b,c){i=a.get(b,w(e)),k=c,g()},d.$on("$stateChangeSuccess",g)}]}}function z(a){return function(b){return a.is(b)}}function A(a){return function(b){return a.includes(b)}}function B(a,b){function e(a){this.locals=a.locals.globals,this.params=this.locals.$stateParams}function f(){this.locals=null,this.params=null}function g(c,g){if(null!=g.redirectTo){var h,j=g.redirectTo;if(E(j))h=j;else{if(!D(j))throw new Error("Invalid 'redirectTo' in when()");h=function(a,b){return j(a,b.path(),b.search())}}b.when(c,h)}else a.state(d(g,{parent:null,name:"route:"+encodeURIComponent(c),url:c,onEnter:e,onExit:f}));return i.push(g),this}function h(a,b,d){function e(a){return""!==a.name?a:c}var f={routes:i,params:d,current:c};return b.$on("$stateChangeStart",function(a,c,d,f){b.$broadcast("$routeChangeStart",e(c),e(f))}),b.$on("$stateChangeSuccess",function(a,c,d,g){f.current=e(c),b.$broadcast("$routeChangeSuccess",e(c),e(g)),J(d,f.params)}),b.$on("$stateChangeError",function(a,c,d,f,g,h){b.$broadcast("$routeChangeError",e(c),e(f),h)}),f}var i=[];e.$inject=["$$state"],this.when=g,this.$get=h,h.$inject=["$state","$rootScope","$routeParams"]}var C=b.isDefined,D=b.isFunction,E=b.isString,F=b.isObject,G=b.isArray,H=b.forEach,I=b.extend,J=b.copy;b.module("ui.router.util",["ng"]),b.module("ui.router.router",["ui.router.util"]),b.module("ui.router.state",["ui.router.router","ui.router.util"]),b.module("ui.router",["ui.router.state"]),b.module("ui.router.compat",["ui.router"]),l.$inject=["$q","$injector"],b.module("ui.router.util").service("$resolve",l),m.$inject=["$http","$templateCache","$injector"],b.module("ui.router.util").service("$templateFactory",m),n.prototype.concat=function(a){return new n(this.sourcePath+a+this.sourceSearch)},n.prototype.toString=function(){return this.source},n.prototype.exec=function(a,b){var c=this.regexp.exec(a);if(!c)return null;var d,e=this.params,f=e.length,g=this.segments.length-1,h={};if(g!==c.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");for(d=0;g>d;d++)h[e[d]]=c[d+1];for(;f>d;d++)h[e[d]]=b[e[d]];return h},n.prototype.parameters=function(){return this.params},n.prototype.format=function(a){var b=this.segments,c=this.params;if(!a)return b.join("");var d,e,f,g=b.length-1,h=c.length,i=b[0];for(d=0;g>d;d++)f=a[c[d]],null!=f&&(i+=encodeURIComponent(f)),i+=b[d+1];for(;h>d;d++)f=a[c[d]],null!=f&&(i+=(e?"&":"?")+c[d]+"="+encodeURIComponent(f),e=!0);return i},b.module("ui.router.util").provider("$urlMatcherFactory",o),p.$inject=["$urlMatcherFactoryProvider"],b.module("ui.router.router").provider("$urlRouter",p),q.$inject=["$urlRouterProvider","$urlMatcherFactoryProvider","$locationProvider"],b.module("ui.router.state").value("$stateParams",{}).provider("$state",q),r.$inject=[],b.module("ui.router.state").provider("$view",r),b.module("ui.router.state").provider("$uiViewScroll",s),t.$inject=["$state","$injector","$uiViewScroll"],u.$inject=["$compile","$controller","$state"],b.module("ui.router.state").directive("uiView",t),b.module("ui.router.state").directive("uiView",u),x.$inject=["$state","$timeout"],y.$inject=["$state","$stateParams","$interpolate"],b.module("ui.router.state").directive("uiSref",x).directive("uiSrefActive",y),z.$inject=["$state"],A.$inject=["$state"],b.module("ui.router.state").filter("isState",z).filter("includedByState",A),B.$inject=["$stateProvider","$urlRouterProvider"],b.module("ui.router.compat").provider("$route",B).directive("ngView",t)}(window,window.angular);
--------------------------------------------------------------------------------
/www/lib/ionic/scss/_items.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Items
3 | * --------------------------------------------------
4 | */
5 |
6 | .item {
7 | @include item-style($item-default-bg, $item-default-border, $item-default-text);
8 |
9 | position: relative;
10 | z-index: $z-index-item; // Make sure the borders and stuff don't get hidden by children
11 | display: block;
12 |
13 | margin: $item-border-width * -1;
14 | padding: $item-padding;
15 |
16 | border-width: $item-border-width;
17 | border-style: solid;
18 | font-size: $item-font-size;
19 |
20 | h2 {
21 | margin: 0 0 4px 0;
22 | font-size: 16px;
23 | }
24 | h3 {
25 | margin: 0 0 4px 0;
26 | font-size: 14px;
27 | }
28 | h4 {
29 | margin: 0 0 4px 0;
30 | font-size: 12px;
31 | }
32 | h5, h6 {
33 | margin: 0 0 3px 0;
34 | font-size: 10px;
35 | }
36 | p {
37 | color: #666;
38 | font-size: 14px;
39 | }
40 |
41 | h1:last-child,
42 | h2:last-child,
43 | h3:last-child,
44 | h4:last-child,
45 | h5:last-child,
46 | h6:last-child,
47 | p:last-child {
48 | margin-bottom: 0;
49 | }
50 |
51 | // Align badges within items
52 | .badge {
53 | @include display-flex();
54 | position: absolute;
55 | top: $item-padding;
56 | right: ($item-padding * 2);
57 | }
58 | &.item-button-right .badge {
59 | right: ($item-padding * 2) + 35;
60 | }
61 | &.item-divider .badge {
62 | top: ceil($item-padding / 2);
63 | }
64 | .badge + .badge {
65 | margin-right: 5px;
66 | }
67 |
68 | // Different themes for items
69 | &.item-light {
70 | @include item-style($item-light-bg, $item-light-border, $item-light-text);
71 | }
72 | &.item-stable {
73 | @include item-style($item-stable-bg, $item-stable-border, $item-stable-text);
74 | }
75 | &.item-positive {
76 | @include item-style($item-positive-bg, $item-positive-border, $item-positive-text);
77 | }
78 | &.item-calm {
79 | @include item-style($item-calm-bg, $item-calm-border, $item-calm-text);
80 | }
81 | &.item-assertive {
82 | @include item-style($item-assertive-bg, $item-assertive-border, $item-assertive-text);
83 | }
84 | &.item-balanced {
85 | @include item-style($item-balanced-bg, $item-balanced-border, $item-balanced-text);
86 | }
87 | &.item-energized {
88 | @include item-style($item-energized-bg, $item-energized-border, $item-energized-text);
89 | }
90 | &.item-royal {
91 | @include item-style($item-royal-bg, $item-royal-border, $item-royal-text);
92 | }
93 | &.item-dark {
94 | @include item-style($item-dark-bg, $item-dark-border, $item-dark-text);
95 | }
96 |
97 | &[ng-click]:hover {
98 | cursor: pointer;
99 | }
100 |
101 | }
102 |
103 | // Link and Button Active States
104 | .item.active,
105 | .item.activated,
106 | .item-complex.active .item-content,
107 | .item-complex.activated .item-content,
108 | .item .item-content.active,
109 | .item .item-content.activated {
110 | @include item-active-style($item-default-active-bg, $item-default-active-border);
111 |
112 | // Different active themes for and items
113 | &.item-light {
114 | @include item-active-style($item-light-active-bg, $item-light-active-border);
115 | }
116 | &.item-stable {
117 | @include item-active-style($item-stable-active-bg, $item-stable-active-border);
118 | }
119 | &.item-positive {
120 | @include item-active-style($item-positive-active-bg, $item-positive-active-border);
121 | }
122 | &.item-calm {
123 | @include item-active-style($item-calm-active-bg, $item-calm-active-border);
124 | }
125 | &.item-assertive {
126 | @include item-active-style($item-assertive-active-bg, $item-assertive-active-border);
127 | }
128 | &.item-balanced {
129 | @include item-active-style($item-balanced-active-bg, $item-balanced-active-border);
130 | }
131 | &.item-energized {
132 | @include item-active-style($item-energized-active-bg, $item-energized-active-border);
133 | }
134 | &.item-royal {
135 | @include item-active-style($item-royal-active-bg, $item-royal-active-border);
136 | }
137 | &.item-dark {
138 | @include item-active-style($item-dark-active-bg, $item-dark-active-border);
139 | }
140 | }
141 |
142 | // Handle text overflow
143 | .item,
144 | .item h1,
145 | .item h2,
146 | .item h3,
147 | .item h4,
148 | .item h5,
149 | .item h6,
150 | .item p,
151 | .item-content,
152 | .item-content h1,
153 | .item-content h2,
154 | .item-content h3,
155 | .item-content h4,
156 | .item-content h5,
157 | .item-content h6,
158 | .item-content p {
159 | overflow: hidden;
160 | text-overflow: ellipsis;
161 | white-space: nowrap;
162 | }
163 |
164 | // Linked list items
165 | a.item {
166 | color: inherit;
167 | text-decoration: none;
168 |
169 | &:hover,
170 | &:focus {
171 | text-decoration: none;
172 | }
173 | }
174 |
175 |
176 | /**
177 | * Complex Items
178 | * --------------------------------------------------
179 | * Adding .item-complex allows the .item to be slidable and
180 | * have options underneath the button, but also requires an
181 | * additional .item-content element inside .item.
182 | * Basically .item-complex removes any default settings which
183 | * .item added, so that .item-content looks them as just .item.
184 | */
185 |
186 | .item-complex,
187 | a.item.item-complex,
188 | button.item.item-complex {
189 | padding: 0;
190 | }
191 | .item-complex .item-content,
192 | .item-radio .item-content {
193 | position: relative;
194 | z-index: $z-index-item;
195 | padding: $item-padding (ceil( ($item-padding * 3) + ($item-padding / 3) ) - 5) $item-padding $item-padding;
196 | border: none;
197 | background-color: white;
198 | }
199 |
200 | a.item-content {
201 | display: block;
202 | color: inherit;
203 | text-decoration: none;
204 | }
205 |
206 | .item-text-wrap .item,
207 | .item-text-wrap .item-content,
208 | .item-text-wrap,
209 | .item-text-wrap h1,
210 | .item-text-wrap h2,
211 | .item-text-wrap h3,
212 | .item-text-wrap h4,
213 | .item-text-wrap h5,
214 | .item-text-wrap h6,
215 | .item-text-wrap p,
216 | .item-complex.item-text-wrap .item-content,
217 | .item-body h1,
218 | .item-body h2,
219 | .item-body h3,
220 | .item-body h4,
221 | .item-body h5,
222 | .item-body h6,
223 | .item-body p {
224 | overflow: visible;
225 | white-space: normal;
226 | }
227 | .item-complex.item-text-wrap,
228 | .item-complex.item-text-wrap h1,
229 | .item-complex.item-text-wrap h2,
230 | .item-complex.item-text-wrap h3,
231 | .item-complex.item-text-wrap h4,
232 | .item-complex.item-text-wrap h5,
233 | .item-complex.item-text-wrap h6,
234 | .item-complex.item-text-wrap p {
235 | overflow: visible;
236 | white-space: normal;
237 | }
238 |
239 | // Link and Button Active States
240 |
241 | .item-complex{
242 | // Stylized items
243 | &.item-light > .item-content{
244 | @include item-style($item-light-bg, $item-light-border, $item-light-text);
245 | &.active, &:active {
246 | @include item-active-style($item-light-active-bg, $item-light-active-border);
247 | }
248 | }
249 | &.item-stable > .item-content{
250 | @include item-style($item-stable-bg, $item-stable-border, $item-stable-text);
251 | &.active, &:active {
252 | @include item-active-style($item-stable-active-bg, $item-stable-active-border);
253 | }
254 | }
255 | &.item-positive > .item-content{
256 | @include item-style($item-positive-bg, $item-positive-border, $item-positive-text);
257 | &.active, &:active {
258 | @include item-active-style($item-positive-active-bg, $item-positive-active-border);
259 | }
260 | }
261 | &.item-calm > .item-content{
262 | @include item-style($item-calm-bg, $item-calm-border, $item-calm-text);
263 | &.active, &:active {
264 | @include item-active-style($item-calm-active-bg, $item-calm-active-border);
265 | }
266 | }
267 | &.item-assertive > .item-content{
268 | @include item-style($item-assertive-bg, $item-assertive-border, $item-assertive-text);
269 | &.active, &:active {
270 | @include item-active-style($item-assertive-active-bg, $item-assertive-active-border);
271 | }
272 | }
273 | &.item-balanced > .item-content{
274 | @include item-style($item-balanced-bg, $item-balanced-border, $item-balanced-text);
275 | &.active, &:active {
276 | @include item-active-style($item-balanced-active-bg, $item-balanced-active-border);
277 | }
278 | }
279 | &.item-energized > .item-content{
280 | @include item-style($item-energized-bg, $item-energized-border, $item-energized-text);
281 | &.active, &:active {
282 | @include item-active-style($item-energized-active-bg, $item-energized-active-border);
283 | }
284 | }
285 | &.item-royal > .item-content{
286 | @include item-style($item-royal-bg, $item-royal-border, $item-royal-text);
287 | &.active, &:active {
288 | @include item-active-style($item-royal-active-bg, $item-royal-active-border);
289 | }
290 | }
291 | &.item-dark > .item-content{
292 | @include item-style($item-dark-bg, $item-dark-border, $item-dark-text);
293 | &.active, &:active {
294 | @include item-active-style($item-dark-active-bg, $item-dark-active-border);
295 | }
296 | }
297 | }
298 |
299 |
300 | /**
301 | * Item Icons
302 | * --------------------------------------------------
303 | */
304 |
305 | .item-icon-left .icon,
306 | .item-icon-right .icon {
307 | @include display-flex();
308 | @include align-items(center);
309 | position: absolute;
310 | top: 0;
311 | height: 100%;
312 | font-size: $item-icon-font-size;
313 |
314 | &:before {
315 | display: block;
316 | width: $item-icon-font-size;
317 | text-align: center;
318 | }
319 | }
320 |
321 | .item .fill-icon {
322 | min-width: $item-icon-fill-font-size + 2;
323 | min-height: $item-icon-fill-font-size + 2;
324 | font-size: $item-icon-fill-font-size;
325 | }
326 |
327 | .item-icon-left {
328 | padding-left: ceil( ($item-padding * 3) + ($item-padding / 3) );
329 |
330 | .icon {
331 | left: ceil( ($item-padding / 3) * 2);
332 | }
333 | }
334 | .item-complex.item-icon-left {
335 | padding-left: 0;
336 |
337 | .item-content {
338 | padding-left: ceil( ($item-padding * 3) + ($item-padding / 3) );
339 | }
340 | }
341 |
342 | .item-icon-right {
343 | padding-right: ceil( ($item-padding * 3) + ($item-padding / 3) );
344 |
345 | .icon {
346 | right: ceil( ($item-padding / 3) * 2);
347 | }
348 | }
349 | .item-complex.item-icon-right {
350 | padding-right: 0;
351 |
352 | .item-content {
353 | padding-right: ceil( ($item-padding * 3) + ($item-padding / 3) );
354 | }
355 | }
356 |
357 | .item-icon-left.item-icon-right .icon:first-child {
358 | right: auto;
359 | }
360 | .item-icon-left.item-icon-right .icon:last-child,
361 | .item-icon-left .item-delete .icon {
362 | left: auto;
363 | }
364 |
365 | .item-icon-left .icon-accessory,
366 | .item-icon-right .icon-accessory {
367 | color: $item-icon-accessory-color;
368 | font-size: $item-icon-accessory-font-size;
369 | }
370 | .item-icon-left .icon-accessory {
371 | left: floor($item-padding / 5);
372 | }
373 | .item-icon-right .icon-accessory {
374 | right: floor($item-padding / 5);
375 | }
376 |
377 |
378 | /**
379 | * Item Button
380 | * --------------------------------------------------
381 | * An item button is a child button inside an .item (not the entire .item)
382 | */
383 |
384 | .item-button-left {
385 | padding-left: ceil($item-padding * 4.5);
386 | }
387 |
388 | .item-button-left > .button,
389 | .item-button-left .item-content > .button {
390 | @include display-flex();
391 | @include align-items(center);
392 | position: absolute;
393 | top: ceil($item-padding / 2);
394 | left: ceil( ($item-padding / 3) * 2);
395 | min-width: $item-icon-font-size + ($button-border-width * 2);
396 | min-height: $item-icon-font-size + ($button-border-width * 2);
397 | font-size: $item-button-font-size;
398 | line-height: $item-button-line-height;
399 |
400 | .icon:before {
401 | position: relative;
402 | left: auto;
403 | width: auto;
404 | line-height: $item-icon-font-size - 1;
405 | }
406 |
407 | > .button {
408 | margin: 0px 2px;
409 | min-height: $item-icon-font-size + ($button-border-width * 2);
410 | font-size: $item-button-font-size;
411 | line-height: $item-button-line-height;
412 | }
413 | }
414 |
415 | .item-button-right,
416 | a.item.item-button-right,
417 | button.item.item-button-right {
418 | padding-right: $item-padding * 5;
419 | }
420 |
421 | .item-button-right > .button,
422 | .item-button-right .item-content > .button,
423 | .item-button-right > .buttons,
424 | .item-button-right .item-content > .buttons {
425 | @include display-flex();
426 | @include align-items(center);
427 | position: absolute;
428 | top: ceil($item-padding / 2);
429 | right: $item-padding;
430 | min-width: $item-icon-font-size + ($button-border-width * 2);
431 | min-height: $item-icon-font-size + ($button-border-width * 2);
432 | font-size: $item-button-font-size;
433 | line-height: $item-button-line-height;
434 |
435 | .icon:before {
436 | position: relative;
437 | left: auto;
438 | width: auto;
439 | line-height: $item-icon-font-size - 1;
440 | }
441 |
442 | > .button {
443 | margin: 0px 2px;
444 | min-width: $item-icon-font-size + ($button-border-width * 2);
445 | min-height: $item-icon-font-size + ($button-border-width * 2);
446 | font-size: $item-button-font-size;
447 | line-height: $item-button-line-height;
448 | }
449 | }
450 |
451 |
452 | // Item Avatar
453 | // -------------------------------
454 |
455 | .item-avatar,
456 | .item-avatar .item-content,
457 | .item-avatar-left,
458 | .item-avatar-left .item-content {
459 | padding-left: $item-avatar-width + ($item-padding * 2);
460 | min-height: $item-avatar-width + ($item-padding * 2);
461 |
462 | > img:first-child,
463 | .item-image {
464 | position: absolute;
465 | top: $item-padding;
466 | left: $item-padding;
467 | max-width: $item-avatar-width;
468 | max-height: $item-avatar-height;
469 | width: 100%;
470 | border-radius: $item-avatar-border-radius;
471 | }
472 | }
473 |
474 | .item-avatar-right,
475 | .item-avatar-right .item-content {
476 | padding-right: $item-avatar-width + ($item-padding * 2);
477 | min-height: $item-avatar-width + ($item-padding * 2);
478 |
479 | > img:first-child,
480 | .item-image {
481 | position: absolute;
482 | top: $item-padding;
483 | right: $item-padding;
484 | max-width: $item-avatar-width;
485 | max-height: $item-avatar-height;
486 | width: 100%;
487 | border-radius: $item-avatar-border-radius;
488 | }
489 | }
490 |
491 |
492 | // Item Thumbnails
493 | // -------------------------------
494 |
495 | .item-thumbnail-left,
496 | .item-thumbnail-left .item-content {
497 | padding-left: $item-thumbnail-width + $item-thumbnail-margin + $item-padding;
498 | min-height: $item-thumbnail-height + ($item-thumbnail-margin * 2);
499 |
500 | > img:first-child,
501 | .item-image {
502 | position: absolute;
503 | top: $item-thumbnail-margin;
504 | left: $item-thumbnail-margin;
505 | max-width: $item-thumbnail-width;
506 | max-height: $item-thumbnail-height;
507 | width: 100%;
508 | }
509 | }
510 | .item-avatar.item-complex,
511 | .item-avatar-left.item-complex,
512 | .item-thumbnail-left.item-complex {
513 | padding-left: 0;
514 | }
515 |
516 | .item-thumbnail-right,
517 | .item-thumbnail-right .item-content {
518 | padding-right: $item-thumbnail-width + $item-thumbnail-margin + $item-padding;
519 | min-height: $item-thumbnail-height + ($item-thumbnail-margin * 2);
520 |
521 | > img:first-child,
522 | .item-image {
523 | position: absolute;
524 | top: $item-thumbnail-margin;
525 | right: $item-thumbnail-margin;
526 | max-width: $item-thumbnail-width;
527 | max-height: $item-thumbnail-height;
528 | width: 100%;
529 | }
530 | }
531 | .item-avatar-right.item-complex,
532 | .item-thumbnail-right.item-complex {
533 | padding-right: 0;
534 | }
535 |
536 |
537 | // Item Image
538 | // -------------------------------
539 |
540 | .item-image {
541 | padding: 0;
542 | text-align: center;
543 |
544 | img:first-child, .list-img {
545 | width: 100%;
546 | vertical-align: middle;
547 | }
548 | }
549 |
550 |
551 | // Item Body
552 | // -------------------------------
553 |
554 | .item-body {
555 | overflow: auto;
556 | padding: $item-padding;
557 | text-overflow: inherit;
558 | white-space: normal;
559 |
560 | h1, h2, h3, h4, h5, h6, p {
561 | margin-top: $item-padding;
562 | margin-bottom: $item-padding;
563 | }
564 | }
565 |
566 |
567 | // Item Divider
568 | // -------------------------------
569 |
570 | .item-divider {
571 | padding-top: ceil($item-padding / 2);
572 | padding-bottom: ceil($item-padding / 2);
573 | min-height: 30px;
574 | background-color: $item-divider-bg;
575 | color: $item-divider-color;
576 | font-weight: bold;
577 | }
578 |
579 |
580 | // Item Note
581 | // -------------------------------
582 |
583 | .item-note {
584 | float: right;
585 | color: #aaa;
586 | font-size: 14px;
587 | }
588 |
589 |
590 | // Item Editing
591 | // -------------------------------
592 |
593 | .item-left-editable .item-content,
594 | .item-right-editable .item-content {
595 | // setup standard transition settings
596 | @include transition-duration( $item-edit-transition-duration );
597 | @include transition-timing-function( $item-edit-transition-function );
598 | @include transition-property( none );
599 | }
600 |
601 | .item-left-editable .item-content {
602 | // set transition property for an item just left editable
603 | -webkit-transition-property: -webkit-transform;
604 | -moz-transition-property: -moz-transform;
605 | transition-property: transform;
606 | }
607 |
608 | .item-right-editable .item-content {
609 | // set transition property for an item just right editable
610 | @include transition-property(margin-right);
611 | }
612 |
613 | .item-left-editable.item-right-editable .item-content {
614 | // set transition property for an item that's both left/right editable
615 | -webkit-transition-property: -webkit-transform, margin-right;
616 | -moz-transition-property: -moz-transform, margin-right;
617 | transition-property: transform, margin-right;
618 | }
619 |
620 | .list-left-editing .item-left-editable .item-content,
621 | .item-left-editing.item-left-editable .item-content {
622 | // actively editing the left side of the item
623 | @include translate3d($item-left-edit-open-width, 0, 0);
624 | }
625 |
626 | .list-right-editing .item-right-editable .item-content,
627 | .item-right-editing.item-right-editable .item-content {
628 | // actively editing the right side of the item
629 | margin-right: $item-right-edit-open-width;
630 | }
631 |
632 |
633 | // Item Left Edit Button
634 | // -------------------------------
635 |
636 | .item-left-edit {
637 | @include transition(all $item-edit-transition-function $item-edit-transition-duration);
638 | @include translate3d( $item-left-edit-left - $item-left-edit-open-width, 0, 0);
639 | position: absolute;
640 | top: 0;
641 | left: 0;
642 | z-index: $z-index-item-edit;
643 | width: $item-left-edit-open-width;
644 | height: 100%;
645 | line-height: 100%;
646 |
647 | .button {
648 | height: 100%;
649 |
650 | &.icon {
651 | @include display-flex();
652 | @include align-items(center);
653 | position: absolute;
654 | top: 0;
655 | height: 100%;
656 | }
657 | }
658 | }
659 |
660 | .list-left-editing .item-left-edit,
661 | .item-left-editing .item-left-edit {
662 | @include translate3d($item-left-edit-left, 0, 0);
663 | }
664 |
665 |
666 | // Item Delete (Left side edit button)
667 | // -------------------------------
668 |
669 | .item-delete .button.icon {
670 | color: $item-delete-icon-color;
671 | font-size: $item-delete-icon-size;
672 |
673 | &:hover {
674 | opacity: .7;
675 | }
676 | }
677 |
678 |
679 | // Item Right Edit Button
680 | // -------------------------------
681 |
682 | .item-right-edit {
683 | @include transition(all $item-edit-transition-function $item-edit-transition-duration);
684 | position: absolute;
685 | top: 0;
686 | right: 0;
687 | z-index: 0;
688 | width: $item-right-edit-open-width;
689 | height: 100%;
690 | background: inherit;
691 |
692 | .button {
693 | min-width: $item-right-edit-open-width;
694 | height: 100%;
695 |
696 | &.icon {
697 | @include display-flex();
698 | @include align-items(center);
699 | position: absolute;
700 | top: 0;
701 | height: 100%;
702 | font-size: $item-reorder-icon-size;
703 | }
704 | }
705 | }
706 |
707 |
708 | // Item Reordering (Right side edit button)
709 | // -------------------------------
710 |
711 | .item-reorder .button.icon {
712 | color: $item-reorder-icon-color;
713 | font-size: $item-reorder-icon-size;
714 | }
715 |
716 | .item-reordering {
717 | // item is actively being reordered
718 | position: absolute;
719 | left: 0;
720 | top: 0;
721 | z-index: $z-index-item-reordering;
722 | width: 100%;
723 | box-shadow: 0px 0px 10px 0px #aaa;
724 |
725 | .item-reorder {
726 | z-index: 1;
727 | }
728 | }
729 |
730 | .item-placeholder {
731 | // placeholder for the item that's being reordered
732 | opacity: 0.7;
733 | }
734 |
735 | .item-left-edit.item-delete,
736 | .item-right-edit.item-reorder {
737 | opacity: 1;
738 | &.ng-hide {
739 | opacity: 0;
740 | }
741 | &.ng-hide-add,
742 | &.ng-hide-remove {
743 | display: block !important;
744 | }
745 | }
746 |
747 |
748 | /**
749 | * The hidden right-side buttons that can be exposed under a list item
750 | * with dragging.
751 | */
752 | .item-options {
753 | position: absolute;
754 | top: 0;
755 | right: 0;
756 | z-index: $z-index-item-options;
757 | height: 100%;
758 |
759 | .button {
760 | height: 100%;
761 | border: none;
762 | border-radius: 0;
763 | }
764 | }
765 |
--------------------------------------------------------------------------------
/www/lib/ionic/js/angular/angular-sanitize.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license AngularJS v1.2.17
3 | * (c) 2010-2014 Google, Inc. http://angularjs.org
4 | * License: MIT
5 | */
6 | (function(window, angular, undefined) {'use strict';
7 |
8 | var $sanitizeMinErr = angular.$$minErr('$sanitize');
9 |
10 | /**
11 | * @ngdoc module
12 | * @name ngSanitize
13 | * @description
14 | *
15 | * # ngSanitize
16 | *
17 | * The `ngSanitize` module provides functionality to sanitize HTML.
18 | *
19 | *
20 | *
21 | *
22 | * See {@link ngSanitize.$sanitize `$sanitize`} for usage.
23 | */
24 |
25 | /*
26 | * HTML Parser By Misko Hevery (misko@hevery.com)
27 | * based on: HTML Parser By John Resig (ejohn.org)
28 | * Original code by Erik Arvidsson, Mozilla Public License
29 | * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
30 | *
31 | * // Use like so:
32 | * htmlParser(htmlString, {
33 | * start: function(tag, attrs, unary) {},
34 | * end: function(tag) {},
35 | * chars: function(text) {},
36 | * comment: function(text) {}
37 | * });
38 | *
39 | */
40 |
41 |
42 | /**
43 | * @ngdoc service
44 | * @name $sanitize
45 | * @kind function
46 | *
47 | * @description
48 | * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are
49 | * then serialized back to properly escaped html string. This means that no unsafe input can make
50 | * it into the returned string, however, since our parser is more strict than a typical browser
51 | * parser, it's possible that some obscure input, which would be recognized as valid HTML by a
52 | * browser, won't make it through the sanitizer.
53 | * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and
54 | * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}.
55 | *
56 | * @param {string} html Html input.
57 | * @returns {string} Sanitized html.
58 | *
59 | * @example
60 |
61 |
62 |
73 |
74 | Snippet:
75 |
76 |
77 | Directive
78 | How
79 | Source
80 | Rendered
81 |
82 |
83 | ng-bind-html
84 | Automatically uses $sanitize
85 | <div ng-bind-html="snippet"> </div>
86 |
87 |
88 |
89 | ng-bind-html
90 | Bypass $sanitize by explicitly trusting the dangerous value
91 |
92 | <div ng-bind-html="deliberatelyTrustDangerousSnippet()">
93 | </div>
94 |
95 |
96 |
97 |
98 | ng-bind
99 | Automatically escapes
100 | <div ng-bind="snippet"> </div>
101 |
102 |
103 |
104 |
105 |
106 |
107 | it('should sanitize the html snippet by default', function() {
108 | expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
109 | toBe('an html\nclick here \nsnippet
');
110 | });
111 |
112 | it('should inline raw snippet if bound to a trusted value', function() {
113 | expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
114 | toBe("an html\n" +
115 | "click here \n" +
116 | "snippet
");
117 | });
118 |
119 | it('should escape snippet without any filter', function() {
120 | expect(element(by.css('#bind-default div')).getInnerHtml()).
121 | toBe("<p style=\"color:blue\">an html\n" +
122 | "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
123 | "snippet</p>");
124 | });
125 |
126 | it('should update', function() {
127 | element(by.model('snippet')).clear();
128 | element(by.model('snippet')).sendKeys('new text ');
129 | expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
130 | toBe('new text ');
131 | expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
132 | 'new text ');
133 | expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
134 | "new <b onclick=\"alert(1)\">text</b>");
135 | });
136 |
137 |
138 | */
139 | function $SanitizeProvider() {
140 | this.$get = ['$$sanitizeUri', function($$sanitizeUri) {
141 | return function(html) {
142 | var buf = [];
143 | htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) {
144 | return !/^unsafe/.test($$sanitizeUri(uri, isImage));
145 | }));
146 | return buf.join('');
147 | };
148 | }];
149 | }
150 |
151 | function sanitizeText(chars) {
152 | var buf = [];
153 | var writer = htmlSanitizeWriter(buf, angular.noop);
154 | writer.chars(chars);
155 | return buf.join('');
156 | }
157 |
158 |
159 | // Regular Expressions for parsing tags and attributes
160 | var START_TAG_REGEXP =
161 | /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
162 | END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/,
163 | ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
164 | BEGIN_TAG_REGEXP = /^,
165 | BEGING_END_TAGE_REGEXP = /^<\s*\//,
166 | COMMENT_REGEXP = //g,
167 | DOCTYPE_REGEXP = /]*?)>/i,
168 | CDATA_REGEXP = //g,
169 | SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
170 | // Match everything outside of normal chars and " (quote character)
171 | NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
172 |
173 |
174 | // Good source of info about elements and attributes
175 | // http://dev.w3.org/html5/spec/Overview.html#semantics
176 | // http://simon.html5.org/html-elements
177 |
178 | // Safe Void Elements - HTML5
179 | // http://dev.w3.org/html5/spec/Overview.html#void-elements
180 | var voidElements = makeMap("area,br,col,hr,img,wbr");
181 |
182 | // Elements that you can, intentionally, leave open (and which close themselves)
183 | // http://dev.w3.org/html5/spec/Overview.html#optional-tags
184 | var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"),
185 | optionalEndTagInlineElements = makeMap("rp,rt"),
186 | optionalEndTagElements = angular.extend({},
187 | optionalEndTagInlineElements,
188 | optionalEndTagBlockElements);
189 |
190 | // Safe Block Elements - HTML5
191 | var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
192 | "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
193 | "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
194 |
195 | // Inline Elements - HTML5
196 | var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
197 | "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
198 | "samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
199 |
200 |
201 | // Special Elements (can contain anything)
202 | var specialElements = makeMap("script,style");
203 |
204 | var validElements = angular.extend({},
205 | voidElements,
206 | blockElements,
207 | inlineElements,
208 | optionalEndTagElements);
209 |
210 | //Attributes that have href and hence need to be sanitized
211 | var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap");
212 | var validAttrs = angular.extend({}, uriAttrs, makeMap(
213 | 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+
214 | 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+
215 | 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+
216 | 'scope,scrolling,shape,size,span,start,summary,target,title,type,'+
217 | 'valign,value,vspace,width'));
218 |
219 | function makeMap(str) {
220 | var obj = {}, items = str.split(','), i;
221 | for (i = 0; i < items.length; i++) obj[items[i]] = true;
222 | return obj;
223 | }
224 |
225 |
226 | /**
227 | * @example
228 | * htmlParser(htmlString, {
229 | * start: function(tag, attrs, unary) {},
230 | * end: function(tag) {},
231 | * chars: function(text) {},
232 | * comment: function(text) {}
233 | * });
234 | *
235 | * @param {string} html string
236 | * @param {object} handler
237 | */
238 | function htmlParser( html, handler ) {
239 | var index, chars, match, stack = [], last = html;
240 | stack.last = function() { return stack[ stack.length - 1 ]; };
241 |
242 | while ( html ) {
243 | chars = true;
244 |
245 | // Make sure we're not in a script or style element
246 | if ( !stack.last() || !specialElements[ stack.last() ] ) {
247 |
248 | // Comment
249 | if ( html.indexOf("", index) === index) {
254 | if (handler.comment) handler.comment( html.substring( 4, index ) );
255 | html = html.substring( index + 3 );
256 | chars = false;
257 | }
258 | // DOCTYPE
259 | } else if ( DOCTYPE_REGEXP.test(html) ) {
260 | match = html.match( DOCTYPE_REGEXP );
261 |
262 | if ( match ) {
263 | html = html.replace( match[0], '');
264 | chars = false;
265 | }
266 | // end tag
267 | } else if ( BEGING_END_TAGE_REGEXP.test(html) ) {
268 | match = html.match( END_TAG_REGEXP );
269 |
270 | if ( match ) {
271 | html = html.substring( match[0].length );
272 | match[0].replace( END_TAG_REGEXP, parseEndTag );
273 | chars = false;
274 | }
275 |
276 | // start tag
277 | } else if ( BEGIN_TAG_REGEXP.test(html) ) {
278 | match = html.match( START_TAG_REGEXP );
279 |
280 | if ( match ) {
281 | html = html.substring( match[0].length );
282 | match[0].replace( START_TAG_REGEXP, parseStartTag );
283 | chars = false;
284 | }
285 | }
286 |
287 | if ( chars ) {
288 | index = html.indexOf("<");
289 |
290 | var text = index < 0 ? html : html.substring( 0, index );
291 | html = index < 0 ? "" : html.substring( index );
292 |
293 | if (handler.chars) handler.chars( decodeEntities(text) );
294 | }
295 |
296 | } else {
297 | html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'),
298 | function(all, text){
299 | text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1");
300 |
301 | if (handler.chars) handler.chars( decodeEntities(text) );
302 |
303 | return "";
304 | });
305 |
306 | parseEndTag( "", stack.last() );
307 | }
308 |
309 | if ( html == last ) {
310 | throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " +
311 | "of html: {0}", html);
312 | }
313 | last = html;
314 | }
315 |
316 | // Clean up any remaining tags
317 | parseEndTag();
318 |
319 | function parseStartTag( tag, tagName, rest, unary ) {
320 | tagName = angular.lowercase(tagName);
321 | if ( blockElements[ tagName ] ) {
322 | while ( stack.last() && inlineElements[ stack.last() ] ) {
323 | parseEndTag( "", stack.last() );
324 | }
325 | }
326 |
327 | if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) {
328 | parseEndTag( "", tagName );
329 | }
330 |
331 | unary = voidElements[ tagName ] || !!unary;
332 |
333 | if ( !unary )
334 | stack.push( tagName );
335 |
336 | var attrs = {};
337 |
338 | rest.replace(ATTR_REGEXP,
339 | function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {
340 | var value = doubleQuotedValue
341 | || singleQuotedValue
342 | || unquotedValue
343 | || '';
344 |
345 | attrs[name] = decodeEntities(value);
346 | });
347 | if (handler.start) handler.start( tagName, attrs, unary );
348 | }
349 |
350 | function parseEndTag( tag, tagName ) {
351 | var pos = 0, i;
352 | tagName = angular.lowercase(tagName);
353 | if ( tagName )
354 | // Find the closest opened tag of the same type
355 | for ( pos = stack.length - 1; pos >= 0; pos-- )
356 | if ( stack[ pos ] == tagName )
357 | break;
358 |
359 | if ( pos >= 0 ) {
360 | // Close all the open elements, up the stack
361 | for ( i = stack.length - 1; i >= pos; i-- )
362 | if (handler.end) handler.end( stack[ i ] );
363 |
364 | // Remove the open elements from the stack
365 | stack.length = pos;
366 | }
367 | }
368 | }
369 |
370 | var hiddenPre=document.createElement("pre");
371 | var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/;
372 | /**
373 | * decodes all entities into regular string
374 | * @param value
375 | * @returns {string} A string with decoded entities.
376 | */
377 | function decodeEntities(value) {
378 | if (!value) { return ''; }
379 |
380 | // Note: IE8 does not preserve spaces at the start/end of innerHTML
381 | // so we must capture them and reattach them afterward
382 | var parts = spaceRe.exec(value);
383 | var spaceBefore = parts[1];
384 | var spaceAfter = parts[3];
385 | var content = parts[2];
386 | if (content) {
387 | hiddenPre.innerHTML=content.replace(//g, '>');
418 | }
419 |
420 | /**
421 | * create an HTML/XML writer which writes to buffer
422 | * @param {Array} buf use buf.jain('') to get out sanitized html string
423 | * @returns {object} in the form of {
424 | * start: function(tag, attrs, unary) {},
425 | * end: function(tag) {},
426 | * chars: function(text) {},
427 | * comment: function(text) {}
428 | * }
429 | */
430 | function htmlSanitizeWriter(buf, uriValidator){
431 | var ignore = false;
432 | var out = angular.bind(buf, buf.push);
433 | return {
434 | start: function(tag, attrs, unary){
435 | tag = angular.lowercase(tag);
436 | if (!ignore && specialElements[tag]) {
437 | ignore = tag;
438 | }
439 | if (!ignore && validElements[tag] === true) {
440 | out('<');
441 | out(tag);
442 | angular.forEach(attrs, function(value, key){
443 | var lkey=angular.lowercase(key);
444 | var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background');
445 | if (validAttrs[lkey] === true &&
446 | (uriAttrs[lkey] !== true || uriValidator(value, isImage))) {
447 | out(' ');
448 | out(key);
449 | out('="');
450 | out(encodeEntities(value));
451 | out('"');
452 | }
453 | });
454 | out(unary ? '/>' : '>');
455 | }
456 | },
457 | end: function(tag){
458 | tag = angular.lowercase(tag);
459 | if (!ignore && validElements[tag] === true) {
460 | out('');
461 | out(tag);
462 | out('>');
463 | }
464 | if (tag == ignore) {
465 | ignore = false;
466 | }
467 | },
468 | chars: function(chars){
469 | if (!ignore) {
470 | out(encodeEntities(chars));
471 | }
472 | }
473 | };
474 | }
475 |
476 |
477 | // define ngSanitize module and register $sanitize service
478 | angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
479 |
480 | /* global sanitizeText: false */
481 |
482 | /**
483 | * @ngdoc filter
484 | * @name linky
485 | * @kind function
486 | *
487 | * @description
488 | * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and
489 | * plain email address links.
490 | *
491 | * Requires the {@link ngSanitize `ngSanitize`} module to be installed.
492 | *
493 | * @param {string} text Input text.
494 | * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in.
495 | * @returns {string} Html-linkified text.
496 | *
497 | * @usage
498 |
499 | *
500 | * @example
501 |
502 |
503 |
514 |
515 | Snippet:
516 |
517 |
518 | Filter
519 | Source
520 | Rendered
521 |
522 |
523 | linky filter
524 |
525 | <div ng-bind-html="snippet | linky"> </div>
526 |
527 |
528 |
529 |
530 |
531 |
532 | linky target
533 |
534 | <div ng-bind-html="snippetWithTarget | linky:'_blank'"> </div>
535 |
536 |
537 |
538 |
539 |
540 |
541 | no filter
542 | <div ng-bind="snippet"> </div>
543 |
544 |
545 |
546 |
547 |
548 | it('should linkify the snippet with urls', function() {
549 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
550 | toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
551 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
552 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
553 | });
554 |
555 | it('should not linkify snippet without the linky filter', function() {
556 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
557 | toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
558 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
559 | expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
560 | });
561 |
562 | it('should update', function() {
563 | element(by.model('snippet')).clear();
564 | element(by.model('snippet')).sendKeys('new http://link.');
565 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
566 | toBe('new http://link.');
567 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
568 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
569 | .toBe('new http://link.');
570 | });
571 |
572 | it('should work with the target property', function() {
573 | expect(element(by.id('linky-target')).
574 | element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
575 | toBe('http://angularjs.org/');
576 | expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
577 | });
578 |
579 |
580 | */
581 | angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
582 | var LINKY_URL_REGEXP =
583 | /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/,
584 | MAILTO_REGEXP = /^mailto:/;
585 |
586 | return function(text, target) {
587 | if (!text) return text;
588 | var match;
589 | var raw = text;
590 | var html = [];
591 | var url;
592 | var i;
593 | while ((match = raw.match(LINKY_URL_REGEXP))) {
594 | // We can not end in these as they are sometimes found at the end of the sentence
595 | url = match[0];
596 | // if we did not match ftp/http/mailto then assume mailto
597 | if (match[2] == match[3]) url = 'mailto:' + url;
598 | i = match.index;
599 | addText(raw.substr(0, i));
600 | addLink(url, match[0].replace(MAILTO_REGEXP, ''));
601 | raw = raw.substring(i + match[0].length);
602 | }
603 | addText(raw);
604 | return $sanitize(html.join(''));
605 |
606 | function addText(text) {
607 | if (!text) {
608 | return;
609 | }
610 | html.push(sanitizeText(text));
611 | }
612 |
613 | function addLink(url, text) {
614 | html.push('
');
623 | addText(text);
624 | html.push(' ');
625 | }
626 | };
627 | }]);
628 |
629 |
630 | })(window, window.angular);
631 |
--------------------------------------------------------------------------------