├── .eslintrc ├── .gitignore ├── CONTRIBUTING.md ├── DCO ├── LICENSE ├── NOTICE ├── README.md ├── bower.json ├── bump.sh ├── code-of-conduct.md ├── example ├── 404.html ├── app.js ├── css-modules-ctrl.js ├── css-modules.html ├── discovery.json ├── index.html ├── js-modules-ctrl.js ├── js-modules.html ├── services-ctrl.js └── services.html ├── ext └── style │ ├── bootstrap │ └── bootstrap.scss │ └── font-awesome │ └── font-awesome.scss ├── gulpfile.js ├── karma.conf.js ├── package.json ├── src ├── coreos.js ├── coreos.scss ├── filter │ ├── empty-number.js │ ├── empty-number.test.js │ ├── order-object-by.js │ └── utc.js ├── fonts │ ├── sourcesanspro-bold-webfont.eot │ ├── sourcesanspro-bold-webfont.svg │ ├── sourcesanspro-bold-webfont.ttf │ ├── sourcesanspro-bold-webfont.woff │ ├── sourcesanspro-bolditalic-webfont.eot │ ├── sourcesanspro-bolditalic-webfont.svg │ ├── sourcesanspro-bolditalic-webfont.ttf │ ├── sourcesanspro-bolditalic-webfont.woff │ ├── sourcesanspro-italic-webfont.eot │ ├── sourcesanspro-italic-webfont.svg │ ├── sourcesanspro-italic-webfont.ttf │ ├── sourcesanspro-italic-webfont.woff │ ├── sourcesanspro-light-webfont.eot │ ├── sourcesanspro-light-webfont.svg │ ├── sourcesanspro-light-webfont.ttf │ ├── sourcesanspro-light-webfont.woff │ ├── sourcesanspro-lightitalic-webfont.eot │ ├── sourcesanspro-lightitalic-webfont.svg │ ├── sourcesanspro-lightitalic-webfont.ttf │ ├── sourcesanspro-lightitalic-webfont.woff │ ├── sourcesanspro-regular-webfont.eot │ ├── sourcesanspro-regular-webfont.svg │ ├── sourcesanspro-regular-webfont.ttf │ ├── sourcesanspro-regular-webfont.woff │ ├── sourcesanspro-semibold-webfont.eot │ ├── sourcesanspro-semibold-webfont.svg │ ├── sourcesanspro-semibold-webfont.ttf │ ├── sourcesanspro-semibold-webfont.woff │ ├── sourcesanspro-semibolditalic-webfont.eot │ ├── sourcesanspro-semibolditalic-webfont.svg │ ├── sourcesanspro-semibolditalic-webfont.ttf │ └── sourcesanspro-semibolditalic-webfont.woff ├── img │ ├── apple-touch-icon-114-precomposed.png │ ├── apple-touch-icon-144-precomposed.png │ ├── apple-touch-icon-57-precomposed.png │ ├── apple-touch-icon-72-precomposed.png │ ├── cells.png │ ├── favicon.png │ ├── google-plus.png │ ├── hexagons.png │ ├── network-circles.png │ └── xyz-grid.png ├── module │ ├── api-client.js │ ├── api-client.test.js │ ├── breakpoint.js │ ├── config.js │ ├── const.js │ ├── cookie.js │ ├── document-visibility.js │ ├── event.js │ ├── highlighter.js │ ├── interceptor-error.js │ ├── interceptor-mutate.js │ ├── local-storage.js │ ├── poller.js │ ├── poller.test.js │ ├── scroller.js │ └── util │ │ ├── array.js │ │ ├── array.test.js │ │ ├── math.js │ │ ├── math.test.js │ │ ├── path.js │ │ ├── path.test.js │ │ ├── string.js │ │ ├── time.js │ │ ├── url.js │ │ └── url.test.js ├── sass │ ├── _color-pallette.scss │ ├── _config.scss │ ├── _path-config.scss │ ├── common │ │ ├── animation │ │ │ ├── _disable-transition.scss │ │ │ ├── _fade.scss │ │ │ └── _highlight.scss │ │ ├── base │ │ │ ├── _backgrounds.scss │ │ │ ├── _base.scss │ │ │ ├── _effects.scss │ │ │ ├── _fonts.scss │ │ │ ├── _graphs.scss │ │ │ ├── _icons.scss │ │ │ └── _text.scss │ │ ├── layout │ │ │ ├── _double-pane.scss │ │ │ ├── _flex.scss │ │ │ └── _page.scss │ │ └── overrides │ │ │ ├── _base.scss │ │ │ ├── _btn.scss │ │ │ ├── _container.scss │ │ │ ├── _dropdown.scss │ │ │ ├── _form.scss │ │ │ ├── _modal.scss │ │ │ ├── _nav.scss │ │ │ ├── _panel.scss │ │ │ ├── _table.scss │ │ │ └── _tooltip.scss │ ├── compass │ │ ├── _css3.scss │ │ ├── _layout.scss │ │ ├── _reset-legacy.scss │ │ ├── _reset.scss │ │ ├── _support.scss │ │ ├── _typography.scss │ │ ├── _utilities.scss │ │ ├── css3 │ │ │ ├── _appearance.scss │ │ │ ├── _background-clip.scss │ │ │ ├── _background-origin.scss │ │ │ ├── _background-size.scss │ │ │ ├── _border-radius.scss │ │ │ ├── _box-shadow.scss │ │ │ ├── _box-sizing.scss │ │ │ ├── _box.scss │ │ │ ├── _columns.scss │ │ │ ├── _filter.scss │ │ │ ├── _font-face.scss │ │ │ ├── _hyphenation.scss │ │ │ ├── _images.scss │ │ │ ├── _inline-block.scss │ │ │ ├── _opacity.scss │ │ │ ├── _pie.scss │ │ │ ├── _regions.scss │ │ │ ├── _shared.scss │ │ │ ├── _text-shadow.scss │ │ │ ├── _transform-legacy.scss │ │ │ ├── _transform.scss │ │ │ ├── _transition.scss │ │ │ └── _user-interface.scss │ │ ├── layout │ │ │ ├── _grid-background.scss │ │ │ ├── _sticky-footer.scss │ │ │ └── _stretching.scss │ │ ├── reset │ │ │ ├── _utilities-legacy.scss │ │ │ └── _utilities.scss │ │ ├── typography │ │ │ ├── _links.scss │ │ │ ├── _lists.scss │ │ │ ├── _text.scss │ │ │ ├── _vertical_rhythm.scss │ │ │ ├── links │ │ │ │ ├── _hover-link.scss │ │ │ │ ├── _link-colors.scss │ │ │ │ └── _unstyled-link.scss │ │ │ ├── lists │ │ │ │ ├── _bullets.scss │ │ │ │ ├── _horizontal-list.scss │ │ │ │ ├── _inline-block-list.scss │ │ │ │ └── _inline-list.scss │ │ │ └── text │ │ │ │ ├── _ellipsis.scss │ │ │ │ ├── _force-wrap.scss │ │ │ │ ├── _nowrap.scss │ │ │ │ └── _replacement.scss │ │ └── utilities │ │ │ ├── _color.scss │ │ │ ├── _general.scss │ │ │ ├── _links.scss │ │ │ ├── _lists.scss │ │ │ ├── _print.scss │ │ │ ├── _sprites.scss │ │ │ ├── _tables.scss │ │ │ ├── _text.scss │ │ │ ├── color │ │ │ └── _contrast.scss │ │ │ ├── general │ │ │ ├── _clearfix.scss │ │ │ ├── _float.scss │ │ │ ├── _hacks.scss │ │ │ ├── _min.scss │ │ │ ├── _reset.scss │ │ │ ├── _tabs.scss │ │ │ └── _tag-cloud.scss │ │ │ ├── links │ │ │ ├── _hover-link.scss │ │ │ ├── _link-colors.scss │ │ │ └── _unstyled-link.scss │ │ │ ├── lists │ │ │ ├── _bullets.scss │ │ │ ├── _horizontal-list.scss │ │ │ ├── _inline-block-list.scss │ │ │ └── _inline-list.scss │ │ │ ├── sprites │ │ │ ├── _base.scss │ │ │ └── _sprite-img.scss │ │ │ ├── tables │ │ │ ├── _alternating-rows-and-columns.scss │ │ │ ├── _borders.scss │ │ │ └── _scaffolding.scss │ │ │ └── text │ │ │ ├── _ellipsis.scss │ │ │ ├── _nowrap.scss │ │ │ └── _replacement.scss │ └── mixin │ │ ├── _animation.scss │ │ ├── _clearfix.scss │ │ ├── _custom-font.scss │ │ ├── _keyframes.scss │ │ ├── _media-query.scss │ │ └── _prefix.scss ├── svg │ ├── globe-only.svg │ ├── google-plus.png │ ├── icon-add.svg │ ├── icon-back.svg │ ├── icon-delete.svg │ ├── icon-reboot.svg │ ├── icon-right-arrow.svg │ └── logo.svg └── ui │ ├── btn-bar │ ├── btn-bar.html │ └── btn-bar.js │ ├── click-nav │ └── click-nav.js │ ├── cog │ ├── _cog.scss │ ├── cog.html │ └── cog.js │ ├── date-range │ ├── _date-range.scss │ ├── custom.html │ ├── date-range.html │ └── date-range.js │ ├── donut │ ├── donut.html │ └── donut.js │ ├── dropdown │ └── _dropdown.scss │ ├── error-message │ ├── error-message.html │ └── error-message.js │ ├── facet-menu │ ├── _facet-menu.scss │ ├── facet-menu-option.html │ ├── facet-menu.html │ └── facet-menu.js │ ├── favicons │ ├── favicons.html │ └── favicons.js │ ├── footer │ ├── _footer-link.scss │ ├── _footer.scss │ ├── footer-link.html │ ├── footer-wrapper.html │ ├── footer.html │ └── footer.js │ ├── forms │ └── _forms.scss │ ├── gauge │ └── _gauge.scss │ ├── highlight │ └── highlight.js │ ├── input │ └── _invisible-input.scss │ ├── link │ └── _modal-link.scss │ ├── loader │ ├── _loader.scss │ ├── inline-loader.html │ ├── loader.html │ └── loader.js │ ├── message │ └── _message.scss │ ├── nav-active │ └── nav-active.js │ ├── nav-title │ ├── _nav-title.scss │ ├── nav-title.html │ └── nav-title.js │ ├── navbar │ ├── _navbar-link.scss │ ├── _navbar.scss │ ├── navbar-dropdown.html │ ├── navbar-link.html │ ├── navbar.html │ └── navbar.js │ ├── notice │ └── _notice.scss │ ├── page-title │ └── _page-title.scss │ ├── pane │ └── _pane.scss │ ├── panel │ └── _panel.scss │ ├── pie │ ├── _pie.scss │ ├── pie.html │ └── pie.js │ ├── primary-action │ └── _primary-action.scss │ ├── signin │ └── _google.scss │ ├── svg │ ├── _svg.scss │ └── svg.js │ ├── table-grid │ └── _table-grid.scss │ ├── table │ └── _table.scss │ ├── text-copy │ └── text-copy.js │ ├── title │ └── title.js │ ├── toast │ ├── _toast.scss │ ├── toast.html │ └── toast.js │ └── toggle │ ├── _toggle.scss │ ├── toggle-btn.html │ ├── toggle.html │ └── toggle.js ├── test ├── mock │ ├── discovery.js │ ├── mocks.js │ └── promise.js └── util │ └── matchers.js └── upload-cdn /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | }, 5 | "rules": { 6 | "camelcase": 2, 7 | "curly": [2, "all"], 8 | "quotes": [2, "single"], 9 | "eqeqeq": 2, 10 | "no-eq-null": 2, 11 | "guard-for-in": 2, 12 | "wrap-iife": [2, "outside"], 13 | "max-len": [1, 100], 14 | "no-comma-dangle": 0, 15 | "no-underscore-dangle": 0, 16 | "consistent-return": 0, 17 | "no-use-before-define": 0, 18 | "no-global-strict": 0 19 | "no-console":1, 20 | "no-alert":1, 21 | "no-debugger":1, 22 | }, 23 | "globals": { 24 | "angular": true, 25 | "inject": true, 26 | "module": true, 27 | "describe": true, 28 | "spyOn": true, 29 | "beforeEach": true, 30 | "afterEach": true, 31 | "expect": true, 32 | "it": true 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | bower_components/ 4 | .bumpcfg 5 | -------------------------------------------------------------------------------- /DCO: -------------------------------------------------------------------------------- 1 | Developer Certificate of Origin 2 | Version 1.1 3 | 4 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 5 | 660 York Street, Suite 102, 6 | San Francisco, CA 94110 USA 7 | 8 | Everyone is permitted to copy and distribute verbatim copies of this 9 | license document, but changing it is not allowed. 10 | 11 | 12 | Developer's Certificate of Origin 1.1 13 | 14 | By making a contribution to this project, I certify that: 15 | 16 | (a) The contribution was created in whole or in part by me and I 17 | have the right to submit it under the open source license 18 | indicated in the file; or 19 | 20 | (b) The contribution is based upon previous work that, to the best 21 | of my knowledge, is covered under an appropriate open source 22 | license and I have the right under that license to submit that 23 | work with modifications, whether created in whole or in part 24 | by me, under the same open source license (unless I am 25 | permitted to submit under a different license), as indicated 26 | in the file; or 27 | 28 | (c) The contribution was provided directly to me by some other 29 | person who certified (a), (b) or (c) and I have not modified 30 | it. 31 | 32 | (d) I understand and agree that this project and the contribution 33 | are public and that a record of the contribution (including all 34 | personal information I submit with it, including my sign-off) is 35 | maintained indefinitely and may be redistributed consistent with 36 | this project or the open source license(s) involved. 37 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | CoreOS Project 2 | Copyright 2014 CoreOS, Inc 3 | 4 | This product includes software developed at CoreOS, Inc. 5 | (http://www.coreos.com/). 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CoreOS Web 2 | 3 | [![deprecated](http://badges.github.io/stability-badges/dist/deprecated.svg)](http://github.com/badges/stability-badges) 4 | 5 | Common stylesheets and AngularJS UI components for CoreOS web apps. 6 | 7 | ## Setup 8 | ``` 9 | npm install -g gulp 10 | npm install 11 | bower install 12 | ``` 13 | 14 | ## Build 15 | Simple build: 16 | - run `gulp` 17 | - copy all files out of `/dist` 18 | 19 | Build & bump other project: 20 | This will build everything, then copy the resulting assets to your project directory. 21 | 22 | - create/edit the `.bumpcfg` file to export your project names with their path to coreos-web. 23 | example: `export myproject=$GOPATH/src/github.com/myproject/web/coreos-web` 24 | - run `./bump.sh ` where project-name is the env var in `.bumpcfg` 25 | example: `./bump.sh myproject` 26 | 27 | 28 | ## Run Examples 29 | - Run `gulp dev` 30 | - Run `gulp serve` 31 | - Browse to `http://localhost:9001/examples` 32 | 33 | 34 | ## JavaScript Requirements 35 | This library depends on and assumes compatible versions of all external libraries included in [src/coreos.js](src/coreos.js). 36 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "coreos-web", 3 | "version": "2.1.0", 4 | "dependencies": { 5 | "angular-animate": "~1.4.8", 6 | "angular-bootstrap": "~0.14.3", 7 | "angular-route": "~1.4.8", 8 | "angular": "~1.4.8", 9 | "bootstrap-sass": "~3.3.3", 10 | "d3": "~3.5.3", 11 | "font-awesome": "~4.3.0", 12 | "jquery": "~2.1.3", 13 | "moment": "~2.9.0", 14 | "underscore": "~1.7.0" 15 | }, 16 | "devDependencies": { 17 | "angular-mocks": "1.4.8" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /bump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | DEST=$1 4 | 5 | function usage() { 6 | echo "usage: $0 from .bumpcfg" 7 | exit 1 8 | } 9 | 10 | if [ -z $DEST ]; then 11 | usage 12 | fi 13 | 14 | source .bumpcfg 15 | DIST_PATH=./dist/ 16 | DEST_PATH=${!DEST} 17 | 18 | echo Running gulp... 19 | gulp 20 | 21 | echo "Copying assets from $DIST_PATH to $DEST_PATH" 22 | cp -r $DIST_PATH $DEST_PATH 23 | -------------------------------------------------------------------------------- /code-of-conduct.md: -------------------------------------------------------------------------------- 1 | ## CoreOS Community Code of Conduct 2 | 3 | ### Contributor Code of Conduct 4 | 5 | As contributors and maintainers of this project, and in the interest of 6 | fostering an open and welcoming community, we pledge to respect all people who 7 | contribute through reporting issues, posting feature requests, updating 8 | documentation, submitting pull requests or patches, and other activities. 9 | 10 | We are committed to making participation in this project a harassment-free 11 | experience for everyone, regardless of level of experience, gender, gender 12 | identity and expression, sexual orientation, disability, personal appearance, 13 | body size, race, ethnicity, age, religion, or nationality. 14 | 15 | Examples of unacceptable behavior by participants include: 16 | 17 | * The use of sexualized language or imagery 18 | * Personal attacks 19 | * Trolling or insulting/derogatory comments 20 | * Public or private harassment 21 | * Publishing others' private information, such as physical or electronic addresses, without explicit permission 22 | * Other unethical or unprofessional conduct. 23 | 24 | Project maintainers have the right and responsibility to remove, edit, or 25 | reject comments, commits, code, wiki edits, issues, and other contributions 26 | that are not aligned to this Code of Conduct. By adopting this Code of Conduct, 27 | project maintainers commit themselves to fairly and consistently applying these 28 | principles to every aspect of managing this project. Project maintainers who do 29 | not follow or enforce the Code of Conduct may be permanently removed from the 30 | project team. 31 | 32 | This code of conduct applies both within project spaces and in public spaces 33 | when an individual is representing the project or its community. 34 | 35 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 36 | reported by contacting a project maintainer, Brandon Philips 37 | , and/or Rithu John . 38 | 39 | This Code of Conduct is adapted from the Contributor Covenant 40 | (http://contributor-covenant.org), version 1.2.0, available at 41 | http://contributor-covenant.org/version/1/2/0/ 42 | 43 | ### CoreOS Events Code of Conduct 44 | 45 | CoreOS events are working conferences intended for professional networking and 46 | collaboration in the CoreOS community. Attendees are expected to behave 47 | according to professional standards and in accordance with their employer’s 48 | policies on appropriate workplace behavior. 49 | 50 | While at CoreOS events or related social networking opportunities, attendees 51 | should not engage in discriminatory or offensive speech or actions including 52 | but not limited to gender, sexuality, race, age, disability, or religion. 53 | Speakers should be especially aware of these concerns. 54 | 55 | CoreOS does not condone any statements by speakers contrary to these standards. 56 | CoreOS reserves the right to deny entrance and/or eject from an event (without 57 | refund) any individual found to be engaging in discriminatory or offensive 58 | speech or actions. 59 | 60 | Please bring any concerns to the immediate attention of designated on-site 61 | staff, Brandon Philips , and/or Rithu John . 62 | -------------------------------------------------------------------------------- /example/404.html: -------------------------------------------------------------------------------- 1 |

404 - Not Found

-------------------------------------------------------------------------------- /example/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('app', []); 4 | 5 | // The main etcd dashboard module. 6 | var app = angular.module('app', [ 7 | 'coreos' 8 | ]); 9 | 10 | // Routes 11 | app.config(function($routeProvider, $locationProvider, $httpProvider, 12 | pollerSvcProvider, configSvcProvider, errorMessageSvcProvider, 13 | apiClientProvider) { 14 | 15 | // General configure for coreos-web library. 16 | configSvcProvider.config({ 17 | siteBasePath: '/example', 18 | libPath: '/../src' 19 | }); 20 | 21 | errorMessageSvcProvider.registerFormatter('foo', function(resp) { 22 | return resp.error; 23 | }); 24 | 25 | apiClientProvider.settings({ 26 | cache: false, 27 | apis: [{ 28 | name: 'mock', 29 | id: 'mock:v1', 30 | discoveryEndpoint: window.location.origin + '/example/discovery.json' 31 | }] 32 | }); 33 | 34 | // Configure poller service. 35 | pollerSvcProvider.settings({ 36 | interval: 5000, 37 | maxRetries: 5 38 | }); 39 | 40 | $locationProvider.html5Mode(true); 41 | //$httpProvider.interceptors.push('httpInterceptor'); 42 | 43 | $routeProvider 44 | .when('/example', { 45 | redirectTo: '/example/js-modules' 46 | }) 47 | .when('/example/page1', { 48 | controller: 'Page1Ctrl', 49 | templateUrl: '/example/page1.html', 50 | title: 'Page 1 Layout' 51 | }) 52 | .when('/example/js-modules', { 53 | controller: 'JsModulesCtrl', 54 | templateUrl: '/example/js-modules.html', 55 | title: 'JS Modules' 56 | }) 57 | .when('/example/css-modules', { 58 | controller: 'CssModulesCtrl', 59 | templateUrl: '/example/css-modules.html', 60 | title: 'CSS Modules' 61 | }) 62 | .when('/example/services', { 63 | controller: 'ServicesCtrl', 64 | templateUrl: '/example/services.html', 65 | title: 'Services' 66 | }) 67 | .when('/404', { 68 | templateUrl: '/example/404.html', 69 | title: 'Not Found' 70 | }).otherwise({ 71 | redirectTo: '/example' 72 | }); 73 | }) 74 | .run(function($rootScope, $location, CORE_EVENT) { 75 | 76 | $rootScope.$on(CORE_EVENT.NOT_FOUND, function() { 77 | $location.url('/404'); 78 | }); 79 | 80 | }); 81 | -------------------------------------------------------------------------------- /example/css-modules-ctrl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('app') 4 | .controller('CssModulesCtrl', function($scope) { 5 | }); 6 | -------------------------------------------------------------------------------- /example/discovery.json: -------------------------------------------------------------------------------- 1 | { 2 | "kind": "discovery#restDescription", 3 | "discoveryVersion": "v1", 4 | "id": "mock:v1", 5 | "name": "schema", 6 | "version": "v1", 7 | "title": "mock API", 8 | "description": "", 9 | "documentationLink": "http://github.com/sym3tri/mock", 10 | "protocol": "rest", 11 | "icons": { 12 | "x16": "", 13 | "x32": "" 14 | }, 15 | "labels": [], 16 | "rootUrl": "http://localhost:9001/example/", 17 | "servicePath": "mock/v1/", 18 | "batchPath": "batch", 19 | "parameters": {}, 20 | "auth": {}, 21 | "schemas": { 22 | "user": { 23 | "id": "user", 24 | "type": "object", 25 | "properties": { 26 | "id": { 27 | "type": "string" 28 | }, 29 | "firstName": { 30 | "type": "string" 31 | }, 32 | "lastName": { 33 | "type": "string" 34 | } 35 | } 36 | }, 37 | "userPage": { 38 | "id": "userPage", 39 | "type": "object", 40 | "properties": { 41 | "users": { 42 | "type": "array", 43 | "items": { 44 | "$ref": "user" 45 | } 46 | }, 47 | "nextPageToken": { 48 | "type": "string" 49 | } 50 | } 51 | } 52 | }, 53 | "resources": { 54 | 55 | 56 | "users": { 57 | "methods": { 58 | "list": { 59 | "id": "mock.users.list", 60 | "description": "Retrieve a page of Users.", 61 | "httpMethod": "GET", 62 | "path": "users", 63 | "parameters": { 64 | "nextPageToken": { 65 | "type": "string", 66 | "location": "query" 67 | } 68 | }, 69 | "response": { 70 | "$ref": "userPage" 71 | } 72 | }, 73 | "get": { 74 | "id": "mock.users.get", 75 | "description": "Retrieve a User.", 76 | "httpMethod": "GET", 77 | "path": "users/{id}", 78 | "parameterOrder": [ 79 | "id" 80 | ], 81 | "parameters": { 82 | "id": { 83 | "type": "string", 84 | "location": "path" 85 | } 86 | }, 87 | "response": { 88 | "$ref": "user" 89 | } 90 | }, 91 | "destroy": { 92 | "id": "mock.users.destroy", 93 | "description": "Destroy a User.", 94 | "httpMethod": "DELETE", 95 | "path": "users/{id}", 96 | "parameterOrder": [ 97 | "id" 98 | ], 99 | "parameters": { 100 | "id": { 101 | "type": "string", 102 | "location": "path" 103 | } 104 | } 105 | } 106 | } 107 | } 108 | 109 | 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /example/js-modules-ctrl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('app') 4 | .controller('JsModulesCtrl', function($scope, $q, $timeout, $interval, 5 | toastSvc, apiClient) { 6 | 7 | // toast 8 | $scope.toastSvc = toastSvc; 9 | 10 | // cog 11 | $scope.cogOptions = [ 12 | { 13 | 'label': 'css page link', 14 | 'href': '/example/css-modules', 15 | 'weight': 100 16 | }, 17 | { 18 | 'label': 'callback function', 19 | 'callback': function() { 20 | alert('executed callback'); 21 | }, 22 | 'weight': 200 23 | } 24 | ]; 25 | 26 | // for debugging evnet bubbling 27 | $scope.logClick = function(txt) { 28 | console.log(txt); 29 | }; 30 | 31 | // btn-bar 32 | $scope.generateBtnBarPromise = function() { 33 | var d = $q.defer(); 34 | $scope.btnBarPromise = d.promise; 35 | $timeout(d.reject, 2000); 36 | }; 37 | 38 | // error-message 39 | $scope.generateErrorMessagePromise = function() { 40 | var d = $q.defer(); 41 | $scope.errorMessagePromise = d.promise; 42 | $timeout(d.reject, 2000); 43 | }; 44 | 45 | $scope.pieData = [ 46 | { 47 | label: 'Amazon', 48 | count: 10 49 | }, 50 | { 51 | label: 'Google', 52 | count: 10 53 | }, 54 | { 55 | label: 'rackspace', 56 | count: 1 57 | }, 58 | { 59 | label: 'Random', 60 | count: 1 61 | }, 62 | { 63 | label: 'small value', 64 | count: 4 65 | }, 66 | { 67 | label: 'Big Value', 68 | count: 10 69 | }, 70 | { 71 | label: 'Ten 1', 72 | count: 10 73 | }, 74 | { 75 | label: 'Ten 2', 76 | count: 10 77 | }, 78 | { 79 | label: 'Ten 3', 80 | count: 10 81 | }, 82 | { 83 | label: 'Ten 4', 84 | count: 10 85 | }, 86 | { 87 | label: 'Ten 5', 88 | count: 10 89 | }, 90 | { 91 | label: 'Ten 6', 92 | count: 10 93 | }, 94 | ]; 95 | 96 | $interval(function() { 97 | $scope.pieData[0].count = Math.abs(Math.ceil(Math.random()*20) + 1); 98 | $scope.pieData[1].count = Math.abs(21 - $scope.pieData[0].count); 99 | }, 2000); 100 | 101 | //$interval(function() { 102 | //$scope.tmp = $scope.pieData.shift(); 103 | //$timeout(function() { 104 | //$scope.pieData.unshift($scope.tmp); 105 | //}, 2000); 106 | //}, 4000); 107 | 108 | 109 | $scope.toggleParam = 'A'; 110 | 111 | $scope.dateValues = { 112 | start: 1401984046467, 113 | end: null, 114 | period: 'custom', 115 | utc: false 116 | }; 117 | 118 | 119 | apiClient.get('mock') 120 | .then(function(client) { 121 | $scope.client = client; 122 | 123 | $scope.client.users.list() 124 | .success(function(data) { 125 | $scope.users = data.items || []; 126 | }) 127 | .catch(function(e) { 128 | console.log('error: ', e); 129 | }); 130 | }) 131 | .catch(function() { 132 | console.log('could not initialize client'); 133 | }); 134 | 135 | }); 136 | -------------------------------------------------------------------------------- /example/services-ctrl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('app') 4 | .controller('ServicesCtrl', function($scope, $q, $timeout, highlighterSvc, 5 | breakpointSvc, scrollerSvc, pollerSvc, documentVisibilitySvc, 6 | cookieSvc, CORE_EVENT) { 7 | 8 | // highlighter 9 | $scope.highlightMe = function($event) { 10 | highlighterSvc.highlight($event.target); 11 | }; 12 | 13 | // scroller 14 | $scope.scrollToMe = function($event) { 15 | scrollerSvc.scrollTo($event.target); 16 | }; 17 | 18 | // breakpoint 19 | $scope.windowSize = ''; 20 | $scope.$on(CORE_EVENT.BREAKPOINT, function(e, size) { 21 | $scope.$apply(function() { 22 | $scope.windowSize = size; 23 | }); 24 | }); 25 | 26 | // doc visibility 27 | $scope.visibilityHistory = []; 28 | $scope.$on(CORE_EVENT.DOC_VISIBILITY_CHANGE, function(e, isHidden) { 29 | $scope.$apply(function() { 30 | $scope.visibilityHistory.push(isHidden); 31 | }); 32 | }); 33 | 34 | // poller 35 | $scope.pollValue = ''; 36 | $scope.startPoller = function() { 37 | pollerSvc.register('examplePoller', { 38 | fn: function() { 39 | var d = $q.defer(); 40 | $timeout(function() { 41 | d.resolve(Date.now()); 42 | }, 0); 43 | return d.promise; 44 | }, 45 | then: function(result) { 46 | $scope.pollValue = result; 47 | }, 48 | scope: $scope, 49 | interval: 2000 50 | }); 51 | }; 52 | 53 | $scope.stopPoller = function() { 54 | pollerSvc.kill('examplePoller'); 55 | }; 56 | 57 | // cookie 58 | $scope.cookieValue = cookieSvc.get('example-cookie'); 59 | $scope.setCookie = function() { 60 | cookieSvc.create('example-cookie', $scope.cookieValue); 61 | }; 62 | 63 | $scope.removeCookie = function() { 64 | cookieSvc.remove('example-cookie'); 65 | $scope.cookieValue = ''; 66 | }; 67 | 68 | }); 69 | -------------------------------------------------------------------------------- /example/services.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
5 |
6 |
7 |

highlighterSvc

8 |
9 |
10 | highlight me 11 |
12 |
13 |
14 |
15 |
16 |
17 |

breakpointSvc

18 |
19 |
20 |

resize the window

21 |

current size: {{windowSize}}

22 |
23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 |

scrollerSvc

32 |
33 |
34 | scroll to me 35 |
36 |
37 |
38 |
39 |
40 |
41 |

documentVisibilitySvc

42 |
43 |
44 |

emits an event whenever the tab goes out of focus. try switching tabs.

45 |

"is hidden" history: {{visibilityHistory}}

46 |
47 |
48 |
49 |
50 | 51 | 52 |
53 |
54 |
55 |
56 |

pollerSvc

57 |
58 |
59 | poll result: {{pollValue}} 60 |
61 | start poller 62 | stop poller 63 |
64 |
65 |
66 |
67 |
68 | 83 |
84 |
85 | 86 | 87 | -------------------------------------------------------------------------------- /ext/style/bootstrap/bootstrap.scss: -------------------------------------------------------------------------------- 1 | // coreos-web static path config. 2 | @import "path-config"; 3 | 4 | 5 | // Core variables and mixins 6 | @import "variables"; 7 | @import "mixins"; 8 | 9 | // Reset 10 | @import "normalize"; 11 | @import "print"; 12 | 13 | // Core CSS 14 | @import "scaffolding"; 15 | @import "type"; 16 | @import "code"; 17 | @import "grid"; 18 | @import "tables"; 19 | @import "forms"; 20 | @import "buttons"; 21 | 22 | // Components 23 | @import "component-animations"; 24 | @import "glyphicons"; 25 | @import "dropdowns"; 26 | @import "button-groups"; 27 | @import "input-groups"; 28 | @import "navs"; 29 | @import "navbar"; 30 | @import "breadcrumbs"; 31 | @import "pagination"; 32 | @import "pager"; 33 | @import "labels"; 34 | @import "badges"; 35 | @import "jumbotron"; 36 | @import "thumbnails"; 37 | @import "alerts"; 38 | @import "progress-bars"; 39 | @import "media"; 40 | @import "list-group"; 41 | @import "panels"; 42 | @import "wells"; 43 | @import "close"; 44 | 45 | // Components w/ JavaScript 46 | @import "modals"; 47 | @import "tooltip"; 48 | @import "popovers"; 49 | @import "carousel"; 50 | 51 | // Utility classes 52 | @import "utilities"; 53 | @import "responsive-utilities"; 54 | -------------------------------------------------------------------------------- /ext/style/font-awesome/font-awesome.scss: -------------------------------------------------------------------------------- 1 | // coreos-web static path config. 2 | @import "path-config"; 3 | 4 | 5 | @import "variables"; 6 | @import "mixins"; 7 | @import "path"; 8 | @import "core"; 9 | @import "larger"; 10 | @import "fixed-width"; 11 | @import "list"; 12 | @import "bordered-pulled"; 13 | @import "animated"; 14 | @import "rotated-flipped"; 15 | @import "stacked"; 16 | @import "icons"; 17 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config) { 2 | 3 | config.set({ 4 | 5 | // Base path, that will be used to resolve files and exclude. 6 | basePath: __dirname, 7 | 8 | // Test framework to use. 9 | frameworks: ['jasmine'], 10 | 11 | // list of files / patterns to load in the browser 12 | files: [ 13 | 'bower_components/jquery/dist/jquery.js', 14 | 'bower_components/angular/angular.js', 15 | 'bower_components/angular-route/angular-route.js', 16 | 'bower_components/angular-animate/angular-animate.js', 17 | 'bower_components/angular-bootstrap/ui-bootstrap-tpls.js', 18 | 'bower_components/underscore/underscore.js', 19 | 'bower_components/d3/d3.js', 20 | 'bower_components/angular-mocks/angular-mocks.js', 21 | 22 | // Tests & test helper files. 23 | 'test/mock/mocks.js', 24 | 'test/**/*.js', 25 | 26 | // Actual code & tests. 27 | 'src/coreos.js', 28 | 'src/*.js', 29 | 'src/**/*.js', 30 | 31 | // compiled templates 32 | 'dist/templates*.js' 33 | ], 34 | 35 | reporters: ['progress'], 36 | 37 | // web server port 38 | port: 8100, 39 | 40 | // cli runner port 41 | runnerPort: 9100, 42 | 43 | colors: true, 44 | 45 | // LOG_DISABLE, LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DEBUG 46 | logLevel: config.LOG_INFO, 47 | 48 | autoWatch: false, 49 | 50 | browsers: ['Chrome'], 51 | 52 | // If browser does not capture in given timeout [ms], kill it 53 | captureTimeout: 5000, 54 | 55 | // Continuous Integration mode. 56 | // If true, it capture browsers, run tests and exit. 57 | singleRun: true 58 | 59 | }); 60 | 61 | }; 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "coreos-web", 3 | "version": "2.1.0", 4 | "dependencies": {}, 5 | "devDependencies": { 6 | "connect-livereload": "~0.5.0", 7 | "connect-modrewrite": "~0.7.9", 8 | "del": "~0.1.3", 9 | "karma-jasmine": "~0.1.5", 10 | "matchdep": "latest", 11 | "karma-chrome-launcher": "~0.1.2", 12 | "gulp": "~3.8.10", 13 | "gulp-concat": "~2.4.1", 14 | "gulp-connect": "~2.2.0", 15 | "gulp-ng-annotate": "~0.3.5", 16 | "gulp-ng-html2js": "~0.1.8", 17 | "gulp-rename": "~1.2.0", 18 | "gulp-eslint": "~0.2.0", 19 | "gulp-sass": "~2.1.1", 20 | "gulp-uglify": "~1.0.1", 21 | "merge-stream": "~0.1.6", 22 | "run-sequence": "~1.0.2" 23 | }, 24 | "engines": { 25 | "node": ">=0.10.0" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/coreos.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | // formally define non-angular external dependencies 5 | angular.module('underscore', []).factory('_', function($window) { 6 | return $window._; 7 | }); 8 | 9 | angular.module('jquery', []).factory('$', function($window) { 10 | return $window.$; 11 | }); 12 | 13 | angular.module('d3', []).factory('d3', function($window) { 14 | return $window.d3; 15 | }); 16 | 17 | angular.module('moment', []).factory('moment', function($window) { 18 | return $window.moment; 19 | }); 20 | 21 | angular.module('coreos.services', [ 22 | 'coreos.events', 23 | 'underscore', 24 | 'jquery', 25 | ]); 26 | angular.module('coreos.ui', [ 27 | 'coreos.events', 28 | 'underscore', 29 | 'jquery', 30 | 'd3', 31 | 'ui.bootstrap', 32 | 'moment' 33 | ]); 34 | angular.module('coreos.filters', ['underscore']); 35 | angular.module('coreos.events', []); 36 | angular.module('coreos', [ 37 | 'coreos.events', 38 | 'coreos.services', 39 | 'coreos.ui', 40 | 'coreos.filters', 41 | 'coreos-templates-html', 42 | 'coreos-templates-svg', 43 | 44 | // other external deps 45 | 'ngRoute', 46 | 'ngAnimate', 47 | ]) 48 | .config(function($compileProvider) { 49 | // Allow irc links. 50 | $compileProvider 51 | .aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|irc):/); 52 | }); 53 | 54 | }()); 55 | -------------------------------------------------------------------------------- /src/coreos.scss: -------------------------------------------------------------------------------- 1 | /* External Libraries */ 2 | @import "compass/css3"; 3 | @import "compass/layout/sticky-footer"; 4 | 5 | 6 | /* Config */ 7 | @import "color-pallette"; 8 | @import "config"; 9 | 10 | /* Mixins */ 11 | @import "mixin/media-query"; 12 | @import "mixin/keyframes"; 13 | @import "mixin/animation"; 14 | @import "mixin/custom-font"; 15 | @import "mixin/prefix"; 16 | @import "mixin/clearfix"; 17 | 18 | /* Bootstrap Overrides */ 19 | @import "common/overrides/base"; 20 | @import "common/overrides/btn"; 21 | @import "common/overrides/container"; 22 | @import "common/overrides/dropdown"; 23 | @import "common/overrides/form"; 24 | @import "common/overrides/modal"; 25 | @import "common/overrides/nav"; 26 | @import "common/overrides/panel"; 27 | @import "common/overrides/table"; 28 | @import "common/overrides/tooltip"; 29 | 30 | /* Base */ 31 | @import "common/base/base"; 32 | @import "common/base/backgrounds"; 33 | @import "common/base/fonts"; 34 | @import "common/base/effects"; 35 | @import "common/base/icons"; 36 | @import "common/base/text"; 37 | @import "common/base/graphs"; 38 | 39 | /* Animations */ 40 | @import "common/animation/fade"; 41 | @import "common/animation/highlight"; 42 | @import "common/animation/disable-transition"; 43 | 44 | /* Layouts */ 45 | @import "common/layout/page"; 46 | @import "common/layout/double-pane"; 47 | @import "common/layout/flex"; 48 | 49 | /* Reusable Modules */ 50 | @import "ui/forms/forms"; 51 | @import "ui/link/modal-link"; 52 | @import "ui/input/invisible-input"; 53 | @import "ui/signin/google"; 54 | @import "ui/primary-action/primary-action"; 55 | @import "ui/panel/panel"; 56 | @import "ui/pane/pane"; 57 | @import "ui/page-title/page-title"; 58 | @import "ui/message/message"; 59 | @import "ui/gauge/gauge"; 60 | @import "ui/dropdown/dropdown"; 61 | @import "ui/table/table"; 62 | @import "ui/table-grid/table-grid"; 63 | @import "ui/navbar/navbar"; 64 | @import "ui/notice/notice"; 65 | @import "ui/navbar/navbar-link"; 66 | @import "ui/footer/footer"; 67 | @import "ui/footer/footer-link"; 68 | @import "ui/nav-title/nav-title"; 69 | @import "ui/loader/loader"; 70 | @import "ui/toast/toast"; 71 | @import "ui/cog/cog"; 72 | @import "ui/svg/svg"; 73 | @import "ui/facet-menu/facet-menu"; 74 | @import "ui/pie/pie"; 75 | @import "ui/toggle/toggle"; 76 | @import "ui/date-range/date-range"; 77 | 78 | -------------------------------------------------------------------------------- /src/filter/empty-number.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.filters').filter('coEmptyNumber', function(_) { 2 | 'use strict'; 3 | 4 | /** 5 | * Replaces an expected numeric value with the default text if the value is 6 | * not a number. 7 | */ 8 | return function(val, text) { 9 | var defaultText = '–', 10 | replacementText = text || defaultText; 11 | if (_.isNaN(val) || _.isNull(val) || _.isUndefined(val)) { 12 | return replacementText; 13 | } 14 | return val.toString(); 15 | }; 16 | 17 | }); 18 | -------------------------------------------------------------------------------- /src/filter/empty-number.test.js: -------------------------------------------------------------------------------- 1 | describe('coreos.filters.coEmptyNumber', function() { 2 | 'use strict'; 3 | 4 | var coEmptyNumberFilter, 5 | defaultText = '–'; 6 | 7 | // Load the module. 8 | beforeEach(module('coreos.filters')); 9 | 10 | // Initialize the controller and a mock scope 11 | beforeEach(inject(function(_coEmptyNumberFilter_) { 12 | coEmptyNumberFilter = _coEmptyNumberFilter_; 13 | })); 14 | 15 | it('returns default text when null', function() { 16 | expect(coEmptyNumberFilter(null)).toBe(defaultText); 17 | }); 18 | 19 | it('returns default text when undefined', function() { 20 | expect(coEmptyNumberFilter(undefined)).toBe(defaultText); 21 | }); 22 | 23 | it('returns default text when NaN', function() { 24 | expect(coEmptyNumberFilter(NaN)).toBe(defaultText); 25 | }); 26 | 27 | it('returns actual value when zero', function() { 28 | expect(coEmptyNumberFilter(0)).toBe('0'); 29 | }); 30 | 31 | it('returns actual value when non-zero', function() { 32 | expect(coEmptyNumberFilter(1)).toBe('1'); 33 | }); 34 | 35 | it('returns actual value when less than zero', function() { 36 | expect(coEmptyNumberFilter(-1)).toBe('-1'); 37 | }); 38 | 39 | it('returns a custom default text', function() { 40 | expect(coEmptyNumberFilter(null, 'custom')).toBe('custom'); 41 | }); 42 | 43 | }); 44 | -------------------------------------------------------------------------------- /src/filter/order-object-by.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.filters') 2 | .filter('orderObjectBy', function() { 3 | 'use strict'; 4 | 5 | return function(items, field, reverse) { 6 | var filtered = []; 7 | angular.forEach(items, function(item) { 8 | filtered.push(item); 9 | }); 10 | filtered.sort(function (a, b) { 11 | return reverse ? (a[field] < b[field]) : (a[field] > b[field]); 12 | }); 13 | return filtered; 14 | }; 15 | }); 16 | -------------------------------------------------------------------------------- /src/filter/utc.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.filters') 2 | .filter('utc', function(_) { 3 | 'use strict'; 4 | 5 | function convertToUtc(date) { 6 | return new Date(date.getUTCFullYear(), 7 | date.getUTCMonth(), 8 | date.getUTCDate(), 9 | date.getUTCHours(), 10 | date.getUTCMinutes(), 11 | date.getUTCSeconds()); 12 | } 13 | 14 | return function(input) { 15 | if (_.isNumber(input)) { 16 | return convertToUtc(new Date(input)); 17 | } 18 | if (_.isString(input)) { 19 | return convertToUtc(new Date(Date.parse(input))); 20 | } 21 | if (_.isDate(input)) { 22 | return convertToUtc(input); 23 | } 24 | return ''; 25 | }; 26 | 27 | }); 28 | -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-bold-webfont.eot -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-bold-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-bold-webfont.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-bolditalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-bolditalic-webfont.eot -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-bolditalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-bolditalic-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-bolditalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-bolditalic-webfont.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-italic-webfont.eot -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-italic-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-italic-webfont.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-light-webfont.eot -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-light-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-light-webfont.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-lightitalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-lightitalic-webfont.eot -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-lightitalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-lightitalic-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-lightitalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-lightitalic-webfont.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-regular-webfont.eot -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-regular-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-regular-webfont.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-semibold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-semibold-webfont.eot -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-semibold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-semibold-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-semibold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-semibold-webfont.woff -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-semibolditalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-semibolditalic-webfont.eot -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-semibolditalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-semibolditalic-webfont.ttf -------------------------------------------------------------------------------- /src/fonts/sourcesanspro-semibolditalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/fonts/sourcesanspro-semibolditalic-webfont.woff -------------------------------------------------------------------------------- /src/img/apple-touch-icon-114-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/apple-touch-icon-114-precomposed.png -------------------------------------------------------------------------------- /src/img/apple-touch-icon-144-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/apple-touch-icon-144-precomposed.png -------------------------------------------------------------------------------- /src/img/apple-touch-icon-57-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/apple-touch-icon-57-precomposed.png -------------------------------------------------------------------------------- /src/img/apple-touch-icon-72-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/apple-touch-icon-72-precomposed.png -------------------------------------------------------------------------------- /src/img/cells.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/cells.png -------------------------------------------------------------------------------- /src/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/favicon.png -------------------------------------------------------------------------------- /src/img/google-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/google-plus.png -------------------------------------------------------------------------------- /src/img/hexagons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/hexagons.png -------------------------------------------------------------------------------- /src/img/network-circles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/network-circles.png -------------------------------------------------------------------------------- /src/img/xyz-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/img/xyz-grid.png -------------------------------------------------------------------------------- /src/module/api-client.test.js: -------------------------------------------------------------------------------- 1 | describe('coreos.services.apiClient', function () { 2 | 'use strict'; 3 | 4 | var $httpBackend, apiClientProvider, apiClient, 5 | mockDiscoJson, 6 | discoUrl = 'http://mock.com/example/discovery.json', 7 | settingsObj = { 8 | apis: [{ 9 | name: 'mockApi', 10 | id: 'mock:v1', 11 | discoveryEndpoint: discoUrl 12 | }] 13 | }; 14 | 15 | beforeEach(function () { 16 | // Initialize the service provider by injecting it to a fake module's 17 | // config block. 18 | angular.module('testApp', [], function () {}) 19 | .config(function(_apiClientProvider_) { 20 | apiClientProvider = _apiClientProvider_; 21 | apiClientProvider.settings(settingsObj); 22 | }); 23 | 24 | // Initialize coreos.services injector 25 | module('coreos.services', 'testApp', 'mocks'); 26 | 27 | // Kickstart the injectors previously registered with angular.mock.module. 28 | // Inject instance of service. 29 | inject(function($injector) { 30 | $httpBackend = $injector.get('$httpBackend'); 31 | mockDiscoJson = $injector.get('mocks.discovery'); 32 | apiClient = $injector.get('apiClient'); 33 | }); 34 | 35 | }); 36 | 37 | it('sets/gets the settings object on the provider', function () { 38 | expect(apiClientProvider.settings()).toBe(settingsObj); 39 | }); 40 | 41 | describe('get()', function() { 42 | var client; 43 | 44 | beforeEach(function() { 45 | $httpBackend.when('GET', discoUrl).respond(function() { 46 | return [200, mockDiscoJson]; 47 | }); 48 | apiClient.get('mockApi') 49 | .then(function(c) { 50 | client = c; 51 | }); 52 | }); 53 | 54 | afterEach(function() { 55 | client = null; 56 | $httpBackend.verifyNoOutstandingExpectation(); 57 | $httpBackend.verifyNoOutstandingRequest(); 58 | }); 59 | 60 | it('fetches the discovery json', function() { 61 | $httpBackend.expectGET(discoUrl); 62 | $httpBackend.flush(); 63 | }); 64 | 65 | it('builds the client with the correct methods', function() { 66 | $httpBackend.flush(); 67 | expect(client).toBeDefined(); 68 | expect(client.users.list).toBeDefined(); 69 | expect(client.users.get).toBeDefined(); 70 | expect(client.users.destroy).toBeDefined(); 71 | }); 72 | 73 | }); 74 | 75 | }); 76 | -------------------------------------------------------------------------------- /src/module/breakpoint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Broadcast when the window size breakpoints change. 3 | * TODO(sym3tri): change implementation to use window.matchMedia instead. 4 | */ 5 | 6 | angular.module('coreos.services') 7 | .factory('breakpointSvc', function(_, $window, $rootScope, CORE_CONST, 8 | CORE_EVENT) { 9 | 'use strict'; 10 | 11 | var previousName; 12 | 13 | function getSize() { 14 | var width = $window.innerWidth; 15 | return _.find(CORE_CONST.BREAKPOINTS, function(bp) { 16 | if (bp.min <= width && bp.max > width) { 17 | return true; 18 | } 19 | }).name; 20 | } 21 | 22 | function onResize() { 23 | var breakpointName = getSize(); 24 | if (breakpointName !== previousName) { 25 | $rootScope.$broadcast(CORE_EVENT.BREAKPOINT, breakpointName); 26 | previousName = breakpointName; 27 | } 28 | } 29 | 30 | // Broadcast initial size. 31 | $rootScope.$broadcast(CORE_EVENT.BREAKPOINT, getSize()); 32 | 33 | // Watch for resizes. 34 | angular.element($window).on('resize', _.debounce(onResize, 20, true)); 35 | 36 | return { 37 | getSize: getSize 38 | }; 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /src/module/config.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services').provider('configSvc', function() { 2 | 'use strict'; 3 | 4 | var configValues = {}; 5 | 6 | this.config = function(newConfig) { 7 | if (newConfig) { 8 | configValues = newConfig; 9 | } else { 10 | return configValues; 11 | } 12 | }; 13 | 14 | this.$get = function() { 15 | return { 16 | get: function(key) { 17 | if (key) { 18 | return configValues[key]; 19 | } else { 20 | return angular.copy(configValues); 21 | } 22 | }, 23 | 24 | set: function(key, value) { 25 | configValues[key] = value; 26 | } 27 | }; 28 | }; 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /src/module/const.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos').constant('CORE_CONST', { 2 | 3 | HIGHLIGHT_CSS_CLASS: 'co-an-highlight', 4 | 5 | BREAKPOINTS: [ 6 | { 7 | name: 'xs', 8 | min: 0, 9 | max: 480 10 | }, 11 | { 12 | name: 'sm', 13 | min: 480, 14 | max: 768 15 | }, 16 | { 17 | name: 'md', 18 | min: 768, 19 | max: 992 20 | }, 21 | { 22 | name: 'lg', 23 | min: 992, 24 | max: 1200 25 | }, 26 | { 27 | name: 'xl', 28 | min: 1200, 29 | max: Infinity 30 | } 31 | ] 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /src/module/cookie.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * 4 | * Service for working with cookies since angular's built-in cookie service 5 | * leaves much to be desired. 6 | */ 7 | 8 | angular.module('coreos.services').factory('cookieSvc', 9 | function($window, timeSvc) { 10 | 'use strict'; 11 | 12 | return { 13 | 14 | /** 15 | * Create a new cookie. 16 | */ 17 | create: function(name, value, daysUtilExpires) { 18 | var date, expires; 19 | if (daysUtilExpires) { 20 | date = new Date(); 21 | date.setTime(date.getTime() + 22 | (daysUtilExpires * timeSvc.ONE_DAY_IN_MS)); 23 | expires = '; expires=' + date.toGMTString(); 24 | } 25 | else { 26 | expires = ''; 27 | } 28 | $window.document.cookie = name + '=' + value + expires + '; path=/'; 29 | }, 30 | 31 | /** 32 | * Retrieve a cookie by name. 33 | */ 34 | get: function(name) { 35 | var nameEq, cookieList, i, cookieStr; 36 | nameEq = name + '='; 37 | cookieList = $window.document.cookie.split(';'); 38 | for (i = 0; i < cookieList.length; i++) { 39 | cookieStr = cookieList[i]; 40 | while (cookieStr.charAt(0) === ' ') { 41 | cookieStr = cookieStr.substring(1, cookieStr.length); 42 | } 43 | if (cookieStr.indexOf(nameEq) === 0) { 44 | return cookieStr.substring(nameEq.length, cookieStr.length); 45 | } 46 | } 47 | return null; 48 | }, 49 | 50 | /** 51 | * Delete a cookie by name. 52 | */ 53 | remove: function(name) { 54 | this.create(name, '', -1); 55 | } 56 | 57 | }; 58 | 59 | }); 60 | -------------------------------------------------------------------------------- /src/module/document-visibility.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * 4 | * Simply inject this service to start broadcasting events. 5 | * It will feature-detect any available browser visibility api. 6 | * If the feature exists it will broadcast an event when browser visibiltiy 7 | * changes. 8 | */ 9 | 10 | angular.module('coreos.services') 11 | .factory('documentVisibilitySvc', function($rootScope, $document, _, 12 | CORE_EVENT) { 13 | 'use strict'; 14 | 15 | var document = $document[0], 16 | features, 17 | detectedFeature; 18 | 19 | function broadcastChangeEvent() { 20 | $rootScope.$broadcast(CORE_EVENT.DOC_VISIBILITY_CHANGE, 21 | document[detectedFeature.propertyName]); 22 | } 23 | 24 | features = { 25 | standard: { 26 | eventName: 'visibilitychange', 27 | propertyName: 'hidden' 28 | }, 29 | moz: { 30 | eventName: 'mozvisibilitychange', 31 | propertyName: 'mozHidden' 32 | }, 33 | ms: { 34 | eventName: 'msvisibilitychange', 35 | propertyName: 'msHidden' 36 | }, 37 | webkit: { 38 | eventName: 'webkitvisibilitychange', 39 | propertyName: 'webkitHidden' 40 | } 41 | }; 42 | 43 | Object.keys(features).some(function(feature) { 44 | if (_.isBoolean(document[features[feature].propertyName])) { 45 | detectedFeature = features[feature]; 46 | return true; 47 | } 48 | }); 49 | 50 | if (detectedFeature) { 51 | $document.on(detectedFeature.eventName, broadcastChangeEvent); 52 | } 53 | 54 | return { 55 | 56 | /** 57 | * Is the window currently hidden or not. 58 | */ 59 | isHidden: function() { 60 | if (detectedFeature) { 61 | return document[detectedFeature.propertyName]; 62 | } 63 | } 64 | 65 | }; 66 | 67 | }); 68 | -------------------------------------------------------------------------------- /src/module/event.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.events').constant('CORE_EVENT', { 2 | PAGE_NOT_FOUND: 'core.event.page_not_found', 3 | BREAKPOINT: 'core.event.breakpoint', 4 | RESP_ERROR: 'core.event.resp_error', 5 | RESP_MUTATE: 'core.event.resp_mutate', 6 | DOC_VISIBILITY_CHANGE: 'core.event.doc_visibility_change', 7 | POLL_ERROR: 'core.event.poll_error', 8 | LOCAL_STORAGE_CHANGE: 'core.event.local_storage_change' 9 | }); 10 | -------------------------------------------------------------------------------- /src/module/highlighter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * 4 | * Utility service to highlight an element or selection of elements. 5 | * NOTE: Expects a [HIGHLIGHT_CSS_CLASS] class to be defined in constants. 6 | */ 7 | 8 | angular.module('coreos.services') 9 | .factory('highlighterSvc', function($timeout, $, CORE_CONST) { 10 | 'use strict'; 11 | 12 | var pendingTimeout; 13 | 14 | return { 15 | 16 | /** 17 | * Highlight an element in the DOM. 18 | * 19 | * @param {String|Element} elemOrSelector 20 | */ 21 | highlight: function(elemOrSelector) { 22 | var elem; 23 | if (!elemOrSelector) { 24 | return; 25 | } 26 | elem = $(elemOrSelector); 27 | if (elem.hasClass(CORE_CONST.HIGHLIGHT_CSS_CLASS)) { 28 | $timeout.cancel(pendingTimeout); 29 | elem.removeClass(CORE_CONST.HIGHLIGHT_CSS_CLASS); 30 | } 31 | elem.addClass(CORE_CONST.HIGHLIGHT_CSS_CLASS); 32 | pendingTimeout = $timeout( 33 | elem.removeClass.bind(elem, CORE_CONST.HIGHLIGHT_CSS_CLASS), 5000); 34 | } 35 | 36 | }; 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /src/module/interceptor-error.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services') 2 | .factory('interceptorErrorSvc', function($q, $rootScope, CORE_EVENT) { 3 | 'use strict'; 4 | 5 | function parseMessage(rejection) { 6 | var errorMsg; 7 | if (rejection.config.description) { 8 | errorMsg = 'Error attempting: ' + rejection.config.description; 9 | } else { 10 | errorMsg = 'A network error occurred.'; 11 | } 12 | return errorMsg; 13 | } 14 | 15 | return { 16 | 17 | /** 18 | * For every failing $http request: broadcast an error event. 19 | */ 20 | 'responseError': function(rejection) { 21 | if (!rejection.config.supressNotifications) { 22 | $rootScope.$broadcast(CORE_EVENT.RESP_ERROR, 23 | rejection, 24 | parseMessage(rejection)); 25 | } 26 | return $q.reject(rejection); 27 | } 28 | 29 | }; 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /src/module/interceptor-mutate.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services') 2 | .factory('interceptorMutateSvc', function($q, $rootScope, CORE_EVENT) { 3 | 'use strict'; 4 | 5 | // Remove last path segement of a url. 6 | function removeLastPath(url) { 7 | var newUrl = url.split('/'); 8 | newUrl.pop(); 9 | newUrl = newUrl.join('/'); 10 | return newUrl; 11 | } 12 | 13 | return { 14 | 15 | /** 16 | * For every successful mutating $http request broadcast the urls. 17 | * Useful for cache invalidation. 18 | */ 19 | 'response': function(response) { 20 | var method = response.config.method, 21 | url = response.config.url, 22 | cacheKeys; 23 | 24 | if (method !== 'GET') { 25 | cacheKeys = []; 26 | cacheKeys.push(url); 27 | if (method !== 'POST') { 28 | cacheKeys.push(removeLastPath(url)); 29 | } 30 | $rootScope.$broadcast(CORE_EVENT.RESP_MUTATE, response); 31 | } 32 | return response || $q.when(response); 33 | } 34 | 35 | }; 36 | 37 | }); 38 | -------------------------------------------------------------------------------- /src/module/local-storage.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services') 2 | .factory('coLocalStorage', function($rootScope, $window, CORE_EVENT) { 3 | 'use strict'; 4 | 5 | return { 6 | 7 | length: $window.localStorage.length, 8 | 9 | getItem: function(key) { 10 | return $window.localStorage.getItem(key); 11 | }, 12 | 13 | key: function(n) { 14 | return $window.localStorage.key(n); 15 | }, 16 | 17 | clear: function() { 18 | $window.localStorage.clear(); 19 | $rootScope.$broadcast(CORE_EVENT.LOCAL_STORAGE_CHANGE, { 20 | key: '*' 21 | }); 22 | }, 23 | 24 | removeItem: function(key) { 25 | $window.localStorage.removeItem(key); 26 | $rootScope.$broadcast(CORE_EVENT.LOCAL_STORAGE_CHANGE, { 27 | key: key 28 | }); 29 | }, 30 | 31 | setItem: function(key, value) { 32 | $window.localStorage.setItem(key, value); 33 | $rootScope.$broadcast(CORE_EVENT.LOCAL_STORAGE_CHANGE, { 34 | key: key, 35 | value: value 36 | }); 37 | } 38 | 39 | }; 40 | 41 | }); 42 | -------------------------------------------------------------------------------- /src/module/scroller.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * 4 | * Utility service that scrolls elements into view. 5 | */ 6 | 7 | angular.module('coreos.services') 8 | .factory('scrollerSvc', function($timeout, $) { 9 | 'use strict'; 10 | 11 | function scroll(elem) { 12 | elem.first()[0].scrollIntoView(); 13 | } 14 | 15 | var scrollerSvc = { 16 | 17 | /** 18 | * Scroll to the element on the page with matching id. 19 | * Adds and removes highlight classes too. 20 | * 21 | * @param {String|Element} elemOrSelector 22 | */ 23 | scrollTo: function(elemOrSelector) { 24 | var maxTries = 100, 25 | numTries = 0, 26 | interval = 10, 27 | elem; 28 | 29 | if (!elemOrSelector) { 30 | return; 31 | } 32 | 33 | // Wait for element to appear in DOM if it doesn't exist yet, 34 | // then scroll to it. 35 | function attemptScroll() { 36 | elem = $(elemOrSelector); 37 | if (numTries < maxTries) { 38 | if (!elem.length) { 39 | numTries++; 40 | $timeout(attemptScroll, interval); 41 | } else { 42 | scroll(elem); 43 | } 44 | } 45 | } 46 | 47 | $timeout(attemptScroll, 0); 48 | } 49 | 50 | }; 51 | 52 | return scrollerSvc; 53 | 54 | }); 55 | -------------------------------------------------------------------------------- /src/module/util/array.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services') 2 | .factory('arraySvc', function() { 3 | 'use strict'; 4 | 5 | return { 6 | 7 | /** 8 | * Remove first occurance of an item from an array in-place. 9 | * 10 | * @param {Arrray} ary Array to mutate. 11 | * @param {*} item Array item to remove. 12 | * @return {Array} The input array. 13 | */ 14 | remove: function(ary, item) { 15 | var index; 16 | if (!ary || !ary.length) { 17 | return []; 18 | } 19 | index = ary.indexOf(item); 20 | if (index > -1) { 21 | ary.splice(index, 1); 22 | } 23 | return ary; 24 | } 25 | 26 | }; 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /src/module/util/array.test.js: -------------------------------------------------------------------------------- 1 | describe('coreos.services.util.arraySvc', function() { 2 | 'use strict'; 3 | var arraySvc, testArray; 4 | 5 | // Load the module. 6 | beforeEach(module('coreos.services')); 7 | 8 | // Initialize the controller and a mock scope 9 | beforeEach(inject(function(_arraySvc_) { 10 | arraySvc = _arraySvc_; 11 | testArray = ['a', 'b', 'c', 'a']; 12 | })); 13 | 14 | it('returns an empty array if passed array is undefined', function() { 15 | expect(arraySvc.remove()).toEqual([]); 16 | }); 17 | 18 | it('returns an empty array if passed array is null', function() { 19 | expect(arraySvc.remove(null)).toEqual([]); 20 | }); 21 | 22 | it('removes the first occurance from the array', function() { 23 | expect(arraySvc.remove(testArray, 'a')).toEqual(['b', 'c', 'a']); 24 | }); 25 | 26 | it('maintains the object reference', function() { 27 | var result = arraySvc.remove(testArray, 'a'); 28 | expect(result).toBe(testArray); 29 | }); 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /src/module/util/math.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services') 2 | .factory('mathSvc', function(_) { 3 | 'use strict'; 4 | 5 | return { 6 | 7 | /** 8 | * If passed an array sums all items in the array. 9 | * Otherwise sums all arguments together. 10 | * 11 | * @param {Array|Number...} 12 | * @return {Number} 13 | */ 14 | sum: function() { 15 | var ary; 16 | if (_.isArray(arguments[0])) { 17 | ary = arguments[0]; 18 | } else { 19 | ary = _.toArray(arguments); 20 | } 21 | return ary.reduce(function(prev, curr) { 22 | return prev + curr; 23 | }, 0); 24 | } 25 | 26 | }; 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /src/module/util/math.test.js: -------------------------------------------------------------------------------- 1 | describe('coreos.services.util.mathSvc', function() { 2 | 'use strict'; 3 | var mathSvc; 4 | 5 | // Load the module. 6 | beforeEach(module('coreos.services')); 7 | 8 | // Initialize the controller and a mock scope 9 | beforeEach(inject(function(_mathSvc_) { 10 | mathSvc = _mathSvc_; 11 | })); 12 | 13 | it('adds arbitrary number arguments', function() { 14 | expect(mathSvc.sum(1, 2, 3)).toBe(6); 15 | }); 16 | 17 | it('adds an array of numbers', function() { 18 | expect(mathSvc.sum([1, 2, 3])).toBe(6); 19 | }); 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /src/module/util/path.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services') 2 | .factory('pathSvc', function(_, stringSvc) { 3 | 'use strict'; 4 | 5 | return { 6 | 7 | /** 8 | * Safely creates a path string. 9 | */ 10 | join: function() { 11 | var parts = _.toArray(arguments); 12 | parts = parts.map(function(p) { 13 | return stringSvc.trim(stringSvc.clean(p), '/'); 14 | }); 15 | return parts.join('/'); 16 | } 17 | 18 | }; 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /src/module/util/path.test.js: -------------------------------------------------------------------------------- 1 | describe('coreos.services.util.pathSvc', function() { 2 | 'use strict'; 3 | var pathSvc; 4 | 5 | // Load the module. 6 | beforeEach(module('coreos.services')); 7 | 8 | // Initialize the controller and a mock scope 9 | beforeEach(inject(function(_pathSvc_) { 10 | pathSvc = _pathSvc_; 11 | })); 12 | 13 | it('joins simple strings', function() { 14 | expect(pathSvc.join('a', 'b', 'c')).toEqual('a/b/c'); 15 | }); 16 | 17 | it('joins strings that are already paths', function() { 18 | expect(pathSvc.join('a/b/c', 'd', 'e')).toEqual('a/b/c/d/e'); 19 | }); 20 | 21 | it('trims excess slashes', function() { 22 | expect(pathSvc.join('/a/', '/b/', '/c/')).toEqual('a/b/c'); 23 | }); 24 | 25 | }); 26 | -------------------------------------------------------------------------------- /src/module/util/string.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services') 2 | .factory('stringSvc', function() { 3 | 'use strict'; 4 | 5 | function trim(str, characters) { 6 | var chars = characters || '\\s'; 7 | return str.replace(new RegExp('^' + chars + '+|' + chars + '+$', 'g'), ''); 8 | } 9 | 10 | return { 11 | 12 | // Trim beginning and trailing whitespace. 13 | trim: trim, 14 | 15 | // Trim and replace multiple spaces with a single space. 16 | clean: function(str) { 17 | return trim(str).replace(/\s+/g, ' '); 18 | }, 19 | 20 | }; 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /src/module/util/time.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.services') 2 | .factory('timeSvc', function(_, moment) { 3 | 'use strict'; 4 | 5 | var ONE_MINUTE_IN_MS = 60 * 1000, 6 | ONE_HOUR_IN_MS = ONE_MINUTE_IN_MS * 60, 7 | ONE_DAY_IN_MS = ONE_HOUR_IN_MS * 24, 8 | ONE_WEEK_IN_MS = ONE_DAY_IN_MS * 7, 9 | THIRTY_DAYS_IN_MS = ONE_DAY_IN_MS * 30; 10 | 11 | function getTimestamp(val) { 12 | if (val && _.isNumber(val)) { 13 | return val; 14 | } 15 | return Date.now(); 16 | } 17 | 18 | return { 19 | ONE_MINUTE_IN_MS: ONE_MINUTE_IN_MS, 20 | ONE_HOUR_IN_MS: ONE_HOUR_IN_MS, 21 | ONE_DAY_IN_MS: ONE_DAY_IN_MS, 22 | ONE_WEEK_IN_MS: ONE_WEEK_IN_MS, 23 | THIRTY_DAYS_IN_MS: THIRTY_DAYS_IN_MS, 24 | 25 | milliToSecs: function(ms) { 26 | return Math.floor(ms / 1000); 27 | }, 28 | 29 | secsToMins: function(secs) { 30 | return Math.floor(parseInt(secs, 10) / 60) || 0; 31 | }, 32 | 33 | minsToSecs: function(mins) { 34 | // TODO(sym3tri): why does this us abs? remove if safe. 35 | return Math.abs(parseInt(mins, 10) * 60) || 0; 36 | }, 37 | 38 | minsToMillis: function(mins) { 39 | return this.minsToSecs(mins) * 1000; 40 | }, 41 | 42 | oneHourAgo: function(ts) { 43 | return getTimestamp(ts) - this.ONE_HOUR_IN_MS; 44 | }, 45 | 46 | oneDayAgo: function(ts) { 47 | return getTimestamp(ts) - this.ONE_DAY_IN_MS; 48 | }, 49 | 50 | oneWeekAgo: function(ts) { 51 | return getTimestamp(ts) - this.ONE_WEEK_IN_MS; 52 | }, 53 | 54 | thirtyDaysAgo: function(ts) { 55 | return getTimestamp(ts) - this.THIRTY_DAYS_IN_MS; 56 | }, 57 | 58 | getRelativeTimestamp: function(term) { 59 | var now = Date.now(); 60 | switch(term) { 61 | case 'month': 62 | return this.thirtyDaysAgo(now); 63 | case 'week': 64 | return this.oneWeekAgo(now); 65 | case 'day': 66 | return this.oneDayAgo(now); 67 | case 'hour': 68 | return this.oneHourAgo(now); 69 | } 70 | }, 71 | 72 | // Get theoffset of the current users's timezone in milliseconds. 73 | getMsOffset: function() { 74 | return moment().zone() * 60 * 1000; 75 | }, 76 | 77 | utcToLocal: function(date) { 78 | // Parse a variety of input types via moment. 79 | var d = moment(date), 80 | offset = this.getMsOffset(), 81 | ts = d.valueOf(); 82 | 83 | if (offset > 0) { 84 | ts = ts + offset; 85 | } else { 86 | ts = ts - Math.abs(offset); 87 | } 88 | return new Date(ts); 89 | }, 90 | 91 | localToUtc: function(date) { 92 | // Parse a variety of input types via moment. 93 | var d = moment(date), 94 | offset = this.getMsOffset(), 95 | ts = d.valueOf(); 96 | 97 | if (offset > 0) { 98 | ts = ts - offset; 99 | } else { 100 | ts = ts + Math.abs(offset); 101 | } 102 | return new Date(ts); 103 | } 104 | 105 | }; 106 | 107 | }); 108 | -------------------------------------------------------------------------------- /src/module/util/url.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Good enough URL parser. 3 | * Currently does not handle query string params, user/pass, or fragments. 4 | */ 5 | angular.module('coreos.services') 6 | .factory('urlSvc', function() { 7 | 'use strict'; 8 | 9 | var urlSvc = {}; 10 | 11 | urlSvc.parse = function(str) { 12 | var s = str, 13 | empty = urlSvc.create(), 14 | url = urlSvc.create(); 15 | 16 | if (!str) { 17 | return empty; 18 | } 19 | 20 | // parse required scheme 21 | s = s.split('://'); 22 | if (s.length !== 2 || s[1] === '') { 23 | return empty; 24 | } 25 | url.scheme = s[0]; 26 | s = s[1]; 27 | 28 | function parsePath(partsAry) { 29 | if (!partsAry || !partsAry.length) { 30 | return ''; 31 | } 32 | return '/' + partsAry.join('/'); 33 | } 34 | 35 | // host + port 36 | s = s.split(':'); 37 | if (s.length === 2) { 38 | // hast port 39 | url.host = s[0]; 40 | s = s[1].split('/'); 41 | url.port = s.shift(); 42 | url.path = parsePath(s); 43 | } else { 44 | url.port = '80'; 45 | s = s[0].split('/'); 46 | url.host = s.shift(); 47 | url.path = parsePath(s); 48 | } 49 | 50 | url.valid = true; 51 | return url; 52 | }; 53 | 54 | urlSvc.create = function() { 55 | return { 56 | scheme: '', 57 | host: '', 58 | port: '', 59 | path: '', 60 | valid: false, 61 | }; 62 | }; 63 | 64 | return urlSvc; 65 | 66 | }); 67 | -------------------------------------------------------------------------------- /src/module/util/url.test.js: -------------------------------------------------------------------------------- 1 | describe('coreos.services.util.urlSvc', function() { 2 | 'use strict'; 3 | var urlSvc, 4 | tests; 5 | 6 | // Load the module. 7 | beforeEach(module('coreos.services')); 8 | 9 | beforeEach(inject(function(_urlSvc_) { 10 | var emptyURL; 11 | urlSvc = _urlSvc_; 12 | emptyURL = urlSvc.create(); 13 | 14 | tests = [ 15 | // has everything 16 | { 17 | url: 'http://example.com:8080/some/random/path', 18 | want: { 19 | scheme: 'http', 20 | host: 'example.com', 21 | port: '8080', 22 | path: '/some/random/path', 23 | valid: true, 24 | }, 25 | }, 26 | // no path 27 | { 28 | url: 'http://example.com:8080', 29 | want: { 30 | scheme: 'http', 31 | host: 'example.com', 32 | port: '8080', 33 | path: '', 34 | valid: true, 35 | }, 36 | }, 37 | // no path, default port 38 | { 39 | url: 'http://example.com', 40 | want: { 41 | scheme: 'http', 42 | host: 'example.com', 43 | port: '80', 44 | path: '', 45 | valid: true, 46 | }, 47 | }, 48 | // https 49 | { 50 | url: 'https://example.com', 51 | want: { 52 | scheme: 'https', 53 | host: 'example.com', 54 | port: '80', 55 | path: '', 56 | valid: true, 57 | }, 58 | }, 59 | // default port 60 | { 61 | url: 'http://example.com/some/random/path', 62 | want: { 63 | scheme: 'http', 64 | host: 'example.com', 65 | port: '80', 66 | path: '/some/random/path', 67 | valid: true, 68 | }, 69 | }, 70 | // invalid 71 | 72 | // empty 73 | { 74 | url: '', 75 | want: emptyURL, 76 | }, 77 | // garbage 78 | { 79 | url: 'asdfadsf', 80 | want: emptyURL, 81 | }, 82 | // missing host 83 | { 84 | url: 'http://', 85 | want: emptyURL, 86 | }, 87 | // missing scheme 88 | { 89 | url: 'example.com', 90 | want: emptyURL, 91 | }, 92 | ]; 93 | })); 94 | 95 | it('parses the url into the expected result', function() { 96 | tests.forEach(function(t) { 97 | expect(urlSvc.parse(t.url)).toEqual(t.want); 98 | }); 99 | }); 100 | 101 | }); 102 | -------------------------------------------------------------------------------- /src/sass/_color-pallette.scss: -------------------------------------------------------------------------------- 1 | /* COLORS */ 2 | $red: rgba(240,76,92,1); 3 | $red-light: lighten($red, 15%); 4 | $red-lighter: lighten($red, 30%); 5 | $red-dark: darken($red, 15%); 6 | $red-darker: darken($red, 30%); 7 | $red-invalid: #DD1327; 8 | 9 | $orange: rgba(240,142,78,1); 10 | $orange-light: lighten($orange, 15%); 11 | $orange-lighter:lighten($orange, 30%); 12 | $orange-dark: darken($orange, 15%); 13 | $orange-darker: darken($orange, 30%); 14 | 15 | $yellow: rgba(242,232,82,1); 16 | $yellow-light: lighten($yellow, 15%); 17 | $yellow-lighter:lighten($yellow, 30%); 18 | $yellow-dark: darken($yellow, 15%); 19 | $yellow-darker: darken($yellow, 30%); 20 | 21 | $green: rgba(110,198,84,1); 22 | $green-light: lighten($green, 15%); 23 | $green-lighter: lighten($green, 30%); 24 | $green-dark: darken($green, 15%); 25 | $green-darker: darken($green, 30%); 26 | 27 | $blue: rgba(65,158,218,1); 28 | $blue-light: lighten($blue, 15%); 29 | $blue-lighter: lighten($blue, 30%); 30 | $blue-bg: #EAF3FF; 31 | $blue-dark: darken($blue, 15%); 32 | $blue-darker: darken($blue, 30%); 33 | $blue-link: #428BCA; 34 | 35 | $purple: rgba(159,104,164,1); 36 | $purple-light: lighten($purple, 15%); 37 | $purple-lighter:lighten($purple, 30%); 38 | $purple-dark: darken($purple, 15%); 39 | $purple-darker: darken($purple, 30%); 40 | 41 | $gray: #999; 42 | $gray-light: #ccc; 43 | $gray-lighter: #eee; 44 | $gray-lightest: #f5f5f5; 45 | $gray-dark: #666; 46 | $gray-darker: #333; 47 | 48 | $black: rgba(0,0,0,1); 49 | $white: rgba(255,255,255,1); 50 | 51 | $highlight: rgba(255, 250, 170, 0.5); 52 | $translucent-black: rgba(33, 33, 33, 0.95); 53 | 54 | -------------------------------------------------------------------------------- /src/sass/_config.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Site-wide variables go here. 3 | */ 4 | 5 | // Configure static paths. 6 | @import "path-config"; 7 | 8 | /* LAYOUT DIMENSIONS */ 9 | $height-footer: 40px; 10 | 11 | /* MEDIA QUERY BREAKPOITNS */ 12 | $screen-xs: 480px !default; 13 | $screen-xs-min: $screen-xs !default; 14 | $screen-sm: 768px !default; 15 | $screen-sm-min: $screen-sm !default; 16 | $screen-md: 992px !default; 17 | $screen-md-min: $screen-md !default; 18 | $screen-lg: 1200px !default; 19 | $screen-lg-min: $screen-lg !default; 20 | 21 | /* THEME COLORS */ 22 | $color-bg-primary: $white; 23 | $color-bg-mute: $gray-lightest; 24 | $color-bg-highlight: $highlight; 25 | $color-icon-light: $white; 26 | $color-icon-dark: $black; 27 | $color-icon-gray: $gray; 28 | $color-text-light: $white; 29 | $color-text-muted: $gray; 30 | $color-border: $gray-lighter; 31 | $color-bg-translucent-dark: $translucent-black; 32 | $color-table-header: $gray; 33 | $color-table-active: $blue-bg; 34 | $color-table-border: $gray-lighter; 35 | $color-footer-icons: $blue-dark; 36 | $color-header-toggle: $gray-darker; 37 | $color-message-error-bg: $red-dark; 38 | $color-message-info-bg: $blue-dark; 39 | $color-cog-active: $blue-dark; 40 | $color-inline-loader: $blue; 41 | 42 | /* Fonts */ 43 | $font-family-primary: 'Source Sans Pro', Helvetica, sans-serif; 44 | $font-family-code: Monaco, Menlo, Consolas, 'Courier New', monospace; 45 | $font-size-base: 16px; 46 | $font-size-xs: 80%; 47 | $font-size-sm: 85%; 48 | $font-size-md: 90%; 49 | $font-size-lg: 110%; 50 | $font-size-xl: 120%; 51 | -------------------------------------------------------------------------------- /src/sass/_path-config.scss: -------------------------------------------------------------------------------- 1 | // Root path where you plan to host coreos-web. 2 | $coreosWebDistPath: './'; 3 | $coreosWebFontPath: $coreosWebDistPath + 'fonts'; 4 | 5 | 6 | // Override fontawesome font paths. 7 | $fa-font-path: $coreosWebFontPath; 8 | 9 | // Override bootstrap font paths. 10 | $icon-font-path: $coreosWebFontPath + '/'; 11 | 12 | // CoreOS-web font path. 13 | $font-path: $coreosWebFontPath; 14 | // CoreOS-web image path. 15 | $img-path: $coreosWebDistPath + 'img'; 16 | -------------------------------------------------------------------------------- /src/sass/common/animation/_disable-transition.scss: -------------------------------------------------------------------------------- 1 | .co-an-disable-transition { 2 | @include transition-property(opacity); 3 | @include transition-duration(0.2s); 4 | @include transition-timing-function(linear); 5 | opacity: 1; 6 | &.co-an-disable-transition--disabled { 7 | opacity: 0.25; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/sass/common/animation/_fade.scss: -------------------------------------------------------------------------------- 1 | .co-an-fade-in-out { 2 | @include transition-property(opacity); 3 | @include transition-duration(0.2s); 4 | @include transition-timing-function(linear); 5 | 6 | // For ng-show and ng-hide. 7 | 8 | &.ng-hide-add, 9 | &.ng-hide-remove { 10 | display: block!important; 11 | } 12 | 13 | &.ng-hide-add.ng-hide-add-active, 14 | &.ng-hide-remove { 15 | opacity: 0; 16 | } 17 | 18 | &.ng-hide-add, 19 | &.ng-hide-remove.ng-hide-remove-active { 20 | opacity: 1; 21 | } 22 | 23 | 24 | // For ng-repeat. 25 | 26 | &.ng-enter, 27 | &.ng-move { 28 | opacity: 0; 29 | } 30 | 31 | &.ng-enter.ng-enter-active, 32 | &.ng-move.ng-move-active { 33 | opacity: 1; 34 | } 35 | 36 | &.ng-leave { 37 | opacity: 1; 38 | } 39 | &.ng-leave.ng-leave-active { 40 | opacity: 0; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/sass/common/animation/_highlight.scss: -------------------------------------------------------------------------------- 1 | .co-an-highlight { 2 | @include co-x-animation( 3 | $name: highlightInOut, 4 | $duration: 4s, 5 | $timingFunction: linear, 6 | $delay: 0, 7 | $direction: normal, 8 | $iterationCount: 1, 9 | $fillMode: both 10 | ); 11 | outline-style: solid; 12 | outline-width: 5px; 13 | outline-color: transparent; 14 | } 15 | 16 | @include co-x-keyframes(highlightInOut) { 17 | 0%, 50% { 18 | outline-color: $color-bg-highlight; 19 | background-color: $color-bg-highlight; 20 | } 21 | 100% { 22 | background-color: inherit; 23 | outline-color: transparent; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/sass/common/base/_backgrounds.scss: -------------------------------------------------------------------------------- 1 | .co-img-bg-hexagons { 2 | background: url($img-path + '/hexagons.png') left top repeat, 3 | linear-gradient(30deg, $blue-dark, $green) no-repeat left top fixed; 4 | background-color: $blue-dark; 5 | background-size: auto, 100% 100%; 6 | } 7 | 8 | .co-img-bg-cells { 9 | background: url($img-path + '/cells.png') left top repeat, 10 | linear-gradient(30deg, $blue-dark, #144768) no-repeat left top fixed; 11 | background-color: $blue-dark; 12 | background-size: auto, 100% 100%; 13 | } 14 | 15 | .co-img-bg-network-circles { 16 | background: url($img-path + '/network-circles.png') left top repeat, 17 | linear-gradient(30deg, $blue-dark, #144768) no-repeat left top fixed; 18 | background-color: $blue-dark; 19 | background-size: auto, 100% 100%; 20 | } 21 | 22 | .co-img-bg-right-arrow { 23 | background: url($img-path + '/icon-right-arrow.svg'); 24 | } -------------------------------------------------------------------------------- /src/sass/common/base/_base.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: $color-bg-mute; 3 | font-family: $font-family-primary; 4 | font-size: $font-size-base; 5 | } 6 | 7 | a { 8 | color: $blue-link; 9 | } 10 | 11 | button:focus, 12 | a:focus { 13 | outline-style: none; 14 | } 15 | 16 | dt { 17 | text-transform: uppercase; 18 | color: $gray; 19 | font-weight: 300; 20 | font-size: 80%; 21 | } 22 | 23 | dd { 24 | margin-bottom: 15px; 25 | } 26 | dd:last-child { 27 | margin-bottom: 0px; 28 | } 29 | 30 | h2 { 31 | font-size: 110%; 32 | } 33 | 34 | kbd { 35 | @include border-radius(3px); 36 | background-color: $gray-lighter; 37 | border: solid 1px $gray-light; 38 | padding: 4px 8px; 39 | } 40 | -------------------------------------------------------------------------------- /src/sass/common/base/_effects.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * Reusable non-layout effects styles used across many modules. 3 | */ 4 | 5 | .co-fx-box-shadow { 6 | @include box-shadow(0 2px 2px rgba(0,0,0,0.2)); 7 | } 8 | 9 | .co-fx-box-shadow-heavy { 10 | @include box-shadow(0px 2px 2px rgba(0, 0, 0, 0.4)); 11 | } 12 | 13 | .co-fx-box-shadow-super-heavy { 14 | @include box-shadow(0px 5px 15px rgba(0, 0, 0, 0.5)); 15 | } 16 | 17 | .co-fx-text-shadow { 18 | @include text-shadow(rgba(0,0,0,0.25) 1px 1px 2px); 19 | } 20 | -------------------------------------------------------------------------------- /src/sass/common/base/_fonts.scss: -------------------------------------------------------------------------------- 1 | @include co-x-custom-font( 2 | 'Source Sans Pro', 3 | 'sourcesanspro-regular-webfont', 4 | 400, 5 | normal 6 | ); 7 | 8 | @include co-x-custom-font( 9 | 'Source Sans Pro', 10 | 'sourcesanspro-bold-webfont', 11 | 700, 12 | normal 13 | ); 14 | 15 | @include co-x-custom-font( 16 | 'Source Sans Pro', 17 | 'sourcesanspro-bolditalic-webfont', 18 | 700, 19 | italic 20 | ); 21 | 22 | @include co-x-custom-font( 23 | 'Source Sans Pro', 24 | 'sourcesanspro-italic-webfont', 25 | 400, 26 | italic 27 | ); 28 | 29 | @include co-x-custom-font( 30 | 'Source Sans Pro', 31 | 'sourcesanspro-light-webfont', 32 | 300, 33 | normal 34 | ); 35 | 36 | @include co-x-custom-font( 37 | 'Source Sans Pro', 38 | 'sourcesanspro-lightitalic-webfont', 39 | 300, 40 | italic 41 | ); 42 | 43 | @include co-x-custom-font( 44 | 'Source Sans Pro', 45 | 'sourcesanspro-semibold-webfont', 46 | 600, 47 | normal 48 | ); 49 | 50 | @include co-x-custom-font( 51 | 'Source Sans Pro', 52 | 'sourcesanspro-semibolditalic-webfont', 53 | 600, 54 | italic 55 | ); 56 | -------------------------------------------------------------------------------- /src/sass/common/base/_graphs.scss: -------------------------------------------------------------------------------- 1 | // Common styles for all d3 graphs 2 | 3 | svg { 4 | .axis path, 5 | .axis line { 6 | fill: none; 7 | stroke: #ccc; 8 | shape-rendering: crispEdges; 9 | } 10 | .axis .tick text { 11 | stroke: none; 12 | fill: #999; 13 | font-weight: 100; 14 | font-size: 80%; 15 | } 16 | .x-axis path { 17 | display: none; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/sass/common/base/_icons.scss: -------------------------------------------------------------------------------- 1 | .co-img-icon { 2 | position: relative; 3 | height: 24px; 4 | width: 24px; 5 | display: inline-block; 6 | margin-right: 5px; 7 | vertical-align: middle; 8 | } 9 | 10 | .co-img-icon > svg { 11 | @include translateY(-50%); 12 | position: absolute; 13 | top: 50%; 14 | left: 0; 15 | right: 0; 16 | margin: 0 auto; 17 | width: 24px; 18 | height: 24px; 19 | } 20 | 21 | .co-img-icon-light { 22 | fill: $color-icon-light; 23 | color: $color-icon-light; 24 | } 25 | 26 | .co-img-icon-dark { 27 | fill: $color-icon-dark; 28 | color: $color-icon-dark; 29 | } 30 | 31 | .co-img-icon-gray { 32 | fill: $color-icon-gray; 33 | color: $color-icon-gray; 34 | } 35 | 36 | .co-m-icon-inline { 37 | vertical-align: middle; 38 | margin-right: 2px; 39 | } 40 | -------------------------------------------------------------------------------- /src/sass/common/base/_text.scss: -------------------------------------------------------------------------------- 1 | .co-m-huge-text { 2 | font-size: 400%; 3 | vertical-align: baseline; 4 | } 5 | 6 | .co-m-red-head { 7 | color: $red; 8 | font-weight: 400; 9 | text-shadow: 0 1px 0 $white; 10 | } 11 | 12 | // Inline text next to buttons 13 | .co-btn-text { 14 | margin: 0 10px 0 0; 15 | } 16 | 17 | .co-m-field-head { 18 | color: $color-table-header; 19 | text-transform: uppercase; 20 | font-size: 13px; 21 | font-weight: 300; 22 | } 23 | 24 | .co-m-code, 25 | .co-m-code-box { 26 | background-color: #F9F2F4; 27 | color: #C7254E; 28 | font-family: $font-family-code; 29 | } 30 | 31 | .co-m-code-box { 32 | min-height: 300px; 33 | font-size: 12px; 34 | word-wrap: normal; 35 | white-space: pre; 36 | } 37 | 38 | .co-truncate { 39 | overflow: hidden; 40 | text-overflow: ellipsis; 41 | } 42 | 43 | .co-nowrap { 44 | white-space: nowrap; 45 | } 46 | -------------------------------------------------------------------------------- /src/sass/common/layout/_double-pane.scss: -------------------------------------------------------------------------------- 1 | .co-l-double-pane { 2 | .co-l-double-pane__col { 3 | padding: 30px; 4 | border-bottom: solid 1px $color-border; 5 | } 6 | } 7 | 8 | @include co-x-media-min($screen-md-min) { 9 | .co-l-double-pane { 10 | 11 | border-collapse: collapse; 12 | display: table; 13 | width: 100%; 14 | 15 | .co-l-double-pane__row { 16 | display: table-row; 17 | height: 100%; 18 | border-bottom: solid 1px $color-border; 19 | } 20 | 21 | .co-l-double-pane__col { 22 | display: table-cell; 23 | float: none; 24 | padding: 30px; 25 | width: 50%; 26 | border-bottom: none; 27 | + .co-l-double-pane__col { 28 | border-left: solid 1px $color-border; 29 | } 30 | } 31 | 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/sass/common/layout/_flex.scss: -------------------------------------------------------------------------------- 1 | // flex-group wraps flex-items 2 | .flex-group { 3 | } 4 | // flex-items are block elements that turn into flexbox layouts on large screens. 5 | .flex-item { 6 | display: block; 7 | } 8 | 9 | @media all and (min-width: 800px) { 10 | .flex-group { 11 | display: flex; 12 | flex-flow: row nowrap; 13 | } 14 | .flex-spacer { 15 | flex: 0 0 1px; 16 | background-color: $color-border; 17 | } 18 | .flex-item { 19 | flex: 1 1 0px; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/sass/common/layout/_page.scss: -------------------------------------------------------------------------------- 1 | #co-l-view-container { 2 | height: 100%; 3 | } 4 | 5 | .co-l-secondary-nav { 6 | line-height: 60px; 7 | } 8 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_base.scss: -------------------------------------------------------------------------------- 1 | h1, h2, h3, h4, h5, h6, 2 | .h1, .h2, .h3, .h4, .h5, .h6 { 3 | font-family: $font-family-primary; 4 | } 5 | 6 | h1, 7 | .h1 { 8 | font-size: 36px; 9 | } 10 | 11 | h2, 12 | .h2 { 13 | font-size: 30px; 14 | } 15 | 16 | h3, 17 | .h3 { 18 | font-size: 24px; 19 | } 20 | 21 | h4, 22 | .h4 { 23 | font-size: 18px; 24 | } 25 | 26 | h5, 27 | .h5 { 28 | font-size: 15px; 29 | } 30 | 31 | h5, 32 | .h5 { 33 | font-size: 14px; 34 | } 35 | 36 | small { 37 | font-size: 80%; 38 | } 39 | 40 | dl { 41 | margin: 0px; 42 | } 43 | 44 | .control-label { 45 | line-height: 30px; 46 | } 47 | 48 | .help-block { 49 | margin-bottom: 0px; 50 | } 51 | 52 | .glyphicon { 53 | color: $color-icon-light; 54 | } 55 | 56 | [ng-cloak] { 57 | display: none; 58 | } -------------------------------------------------------------------------------- /src/sass/common/overrides/_btn.scss: -------------------------------------------------------------------------------- 1 | .btn { 2 | border: none; 3 | box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 4 | 0 1px 2px rgba(0, 0, 0, 0.25), 5 | 0 0px 1px rgba(0, 0, 0, 0.25); 6 | margin-right: 10px; 7 | margin-top: 0px; 8 | &:active, 9 | &:focus, 10 | &:active:focus { 11 | outline: none; 12 | } 13 | } 14 | 15 | .btn-primary { 16 | color: $white; 17 | background-color: $red; 18 | text-shadow: 0 0 3px rgba(0, 0, 0, 0.25); 19 | &:hover, 20 | &:active, 21 | &:focus, 22 | &.active, 23 | &.disabled, 24 | &[disabled], 25 | &[disabled]:active, 26 | &[disabled]:hover, 27 | &[disabled]:focus { 28 | color: $white; 29 | background-color: $red-dark; 30 | } 31 | } 32 | 33 | .btn-default { 34 | color: $gray-dark; 35 | background-color: $white; 36 | &:hover, 37 | &:active, 38 | &.active, 39 | &.disabled, 40 | &[disabled] { 41 | color:$gray; 42 | background-color: $white; 43 | } 44 | } 45 | 46 | .btn-link { 47 | color: $blue-link; 48 | background: none; 49 | box-shadow: none; 50 | padding-right: 0px; 51 | padding-left: 0px; 52 | } 53 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_container.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | width: 100%; 3 | padding-left: 0px; 4 | padding-right: 0px; 5 | } 6 | 7 | @include co-x-media-min($screen-xs-min) { 8 | .container { 9 | width: 99%; 10 | padding-left: 15px; 11 | padding-right: 15px; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_dropdown.scss: -------------------------------------------------------------------------------- 1 | @import '_config'; 2 | 3 | .dropdown-menu { 4 | @include border-radius(1px); 5 | } 6 | 7 | .dropdown-menu > li > a { 8 | padding: 3px 20px 3px 10px; 9 | } 10 | 11 | .dropdown { 12 | @include co-x-media-max($screen-sm) { 13 | .dropdown-toggle { 14 | color: $gray; 15 | text-transform: uppercase; 16 | } 17 | 18 | .caret { 19 | display: none; 20 | } 21 | 22 | .dropdown-menu { 23 | position: static; 24 | float: none; 25 | width: auto; 26 | margin-top: 0px; 27 | background-color: transparent; 28 | border: 0px none; 29 | box-shadow: none; 30 | display: block; 31 | line-height: 16px; 32 | font-size: 16px; 33 | 34 | > li > a { 35 | line-height: 20px; 36 | padding: 5px 15px 5px 25px; 37 | } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_form.scss: -------------------------------------------------------------------------------- 1 | .form-control:focus { 2 | // Make focus shadow same as default. 3 | @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, 0.075)); 4 | } 5 | 6 | .control-label { 7 | font-size: 14px; 8 | } 9 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_modal.scss: -------------------------------------------------------------------------------- 1 | .modal-header { 2 | border-bottom: none; 3 | padding: 30px 30px 20px 30px; 4 | 5 | .modal-title { 6 | font-weight: 700; 7 | font-size: 100%; 8 | } 9 | } 10 | 11 | .modal-body { 12 | padding: 0px 30px; 13 | font-size: 90%; 14 | } 15 | 16 | .modal-footer { 17 | border-top: none; 18 | padding: 20px 30px 30px 30px; 19 | text-align: left; 20 | margin: 0px; 21 | } 22 | 23 | // HACK(sym3tri): fixes incompatibility between anguarl-bootstrap and latest bootstrap. 24 | .modal-backdrop { 25 | height: 10000px; 26 | } 27 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_nav.scss: -------------------------------------------------------------------------------- 1 | .navbar { 2 | min-height: 46px; 3 | border: 0px; 4 | border-radius: 0; 5 | } 6 | 7 | .navbar-nav > li > a { 8 | line-height: 16px; 9 | } 10 | 11 | .navbar-brand { 12 | padding: 0; 13 | position: relative; 14 | height: auto; 15 | } 16 | 17 | .navbar-toggle { 18 | margin-top: 0; 19 | margin-bottom: 0; 20 | padding: 8px; 21 | .glyphicon-align-justify { 22 | color: $color-header-toggle; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_panel.scss: -------------------------------------------------------------------------------- 1 | .panel, 2 | .modal-content { 3 | @include border-radius(0); 4 | } 5 | 6 | .panel { 7 | border: 0px; 8 | } 9 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_table.scss: -------------------------------------------------------------------------------- 1 | .table { 2 | margin-bottom: 0px; 3 | 4 | thead > tr > th { 5 | border-bottom: 0px; 6 | } 7 | 8 | th { 9 | color: $color-table-header; 10 | font-size: 80%; 11 | text-transform: uppercase; 12 | font-weight: 300; 13 | padding-top: 0px !important; 14 | } 15 | 16 | tr:last-child { 17 | border-bottom: 1px solid $color-table-border; 18 | } 19 | 20 | td { 21 | font-size: 80%; 22 | border-color: $color-table-border !important; 23 | vertical-align: middle !important; 24 | 25 | input[type="radio"], input[type="checkbox"] { 26 | margin-top: 0px; 27 | vertical-align: middle; 28 | } 29 | } 30 | 31 | } 32 | 33 | .table-hover > tbody > tr:hover > td, 34 | .table-hover > tbody > tr:hover > th { 35 | background-color: $color-table-active; 36 | } 37 | -------------------------------------------------------------------------------- /src/sass/common/overrides/_tooltip.scss: -------------------------------------------------------------------------------- 1 | $tooltip-color: rgba(0, 0, 0, 0.8); 2 | 3 | .tooltip-inner { 4 | background-color: $tooltip-color; 5 | } 6 | 7 | .tooltip { 8 | &.top .tooltip-arrow, 9 | &.top-left .tooltip-arrow, 10 | &.top-right .tooltip-arrow { 11 | border-top-color: $tooltip-color; 12 | } 13 | &.bottom .tooltip-arrow, 14 | &.bottom-left .tooltip-arrow, 15 | &.bottom-right .tooltip-arrow { 16 | border-bottom-color: $tooltip-color; 17 | } 18 | &.right .tooltip-arrow { 19 | border-right-color: $tooltip-color; 20 | } 21 | &.left .tooltip-arrow { 22 | border-left-color: $tooltip-color; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/sass/compass/_css3.scss: -------------------------------------------------------------------------------- 1 | @import "css3/border-radius"; 2 | @import "css3/inline-block"; 3 | @import "css3/opacity"; 4 | @import "css3/box-shadow"; 5 | @import "css3/text-shadow"; 6 | @import "css3/columns"; 7 | @import "css3/box-sizing"; 8 | @import "css3/box"; 9 | @import "css3/images"; 10 | @import "css3/background-clip"; 11 | @import "css3/background-origin"; 12 | @import "css3/background-size"; 13 | @import "css3/font-face"; 14 | @import "css3/transform"; 15 | @import "css3/transition"; 16 | @import "css3/appearance"; 17 | @import "css3/regions"; 18 | @import "css3/hyphenation"; 19 | @import "css3/filter"; 20 | @import "css3/user-interface"; 21 | -------------------------------------------------------------------------------- /src/sass/compass/_layout.scss: -------------------------------------------------------------------------------- 1 | @import "layout/grid-background"; 2 | @import "layout/sticky-footer"; 3 | @import "layout/stretching"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/_reset-legacy.scss: -------------------------------------------------------------------------------- 1 | @import "reset/utilities-legacy"; 2 | 3 | @include global-reset; 4 | -------------------------------------------------------------------------------- /src/sass/compass/_reset.scss: -------------------------------------------------------------------------------- 1 | @import "reset/utilities"; 2 | 3 | @include global-reset; 4 | -------------------------------------------------------------------------------- /src/sass/compass/_support.scss: -------------------------------------------------------------------------------- 1 | // Usually compass hacks apply to both ie6 & 7 -- set this to false to disable support for both. 2 | $legacy-support-for-ie: true !default; 3 | 4 | // Setting this to false will result in smaller output, but no support for ie6 hacks 5 | $legacy-support-for-ie6: $legacy-support-for-ie !default; 6 | 7 | // Setting this to false will result in smaller output, but no support for ie7 hacks 8 | $legacy-support-for-ie7: $legacy-support-for-ie !default; 9 | 10 | // Setting this to false will result in smaller output, but no support for legacy ie8 hacks 11 | $legacy-support-for-ie8: $legacy-support-for-ie !default; 12 | 13 | // @private 14 | // The user can simply set $legacy-support-for-ie and 6, 7, and 8 will be set accordingly, 15 | // But in case the user set each of those explicitly, we need to sync the value of 16 | // this combined variable. 17 | $legacy-support-for-ie: $legacy-support-for-ie6 or $legacy-support-for-ie7 or $legacy-support-for-ie8; 18 | 19 | // Whether to output legacy support for mozilla. 20 | // Usually this means hacks to support Firefox 3.6 or earlier. 21 | $legacy-support-for-mozilla: true; 22 | 23 | // Support for mozilla in experimental css3 properties (-moz). 24 | $experimental-support-for-mozilla : true !default; 25 | // Support for webkit in experimental css3 properties (-webkit). 26 | $experimental-support-for-webkit : true !default; 27 | // Support for webkit's original (non-standard) gradient syntax. 28 | $support-for-original-webkit-gradients : true !default; 29 | // Support for opera in experimental css3 properties (-o). 30 | $experimental-support-for-opera : true !default; 31 | // Support for microsoft in experimental css3 properties (-ms). 32 | $experimental-support-for-microsoft : true !default; 33 | // Support for khtml in experimental css3 properties (-khtml). 34 | $experimental-support-for-khtml : false !default; 35 | // Support for svg in experimental css3 properties. 36 | // Setting this to true might add significant size to your 37 | // generated stylesheets. 38 | $experimental-support-for-svg : false !default; 39 | // Support for CSS PIE in experimental css3 properties (-pie). 40 | $experimental-support-for-pie : false !default; 41 | -------------------------------------------------------------------------------- /src/sass/compass/_typography.scss: -------------------------------------------------------------------------------- 1 | @import "typography/links"; 2 | @import "typography/lists"; 3 | @import "typography/text"; 4 | @import "typography/vertical_rhythm"; 5 | -------------------------------------------------------------------------------- /src/sass/compass/_utilities.scss: -------------------------------------------------------------------------------- 1 | @import "utilities/color"; 2 | @import "utilities/general"; 3 | @import "utilities/sprites"; 4 | @import "utilities/tables"; 5 | 6 | // deprecated 7 | @import "typography/links"; 8 | @import "typography/lists"; 9 | @import "typography/text"; 10 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_appearance.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // Change the appearance for Mozilla, Webkit and possibly the future. 4 | // The appearance property is currently not present in any newer CSS specification. 5 | // 6 | // There is no official list of accepted values, but you might check these source: 7 | // 8 | // * [Mozilla](https://developer.mozilla.org/en/CSS/-moz-appearance) 9 | // * [Webkit](http://code.google.com/p/webkit-mirror/source/browse/Source/WebCore/css/CSSValueKeywords.in?spec=svnf1aea559dcd025a8946aa7da6e4e8306f5c1b604&r=63c7d1af44430b314233fea342c3ddb2a052e365) 10 | // (search for 'appearance' within the page) 11 | 12 | @mixin appearance($ap) { 13 | $ap: unquote($ap); 14 | @include experimental(appearance, $ap, 15 | -moz, -webkit, not -o, not -ms, not -khtml, official 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_background-clip.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // The default value is `padding-box` -- the box model used by modern browsers. 4 | // 5 | // If you wish to do so, you can override the default constant with `border-box` 6 | // 7 | // To override to the default border-box model, use this code: 8 | // $default-background-clip: border-box 9 | 10 | $default-background-clip: padding-box !default; 11 | 12 | // Clip the background (image and color) at the edge of the padding or border. 13 | // 14 | // Legal Values: 15 | // 16 | // * padding-box 17 | // * border-box 18 | // * text 19 | 20 | @mixin background-clip($clip: $default-background-clip) { 21 | // webkit and mozilla use the deprecated short [border | padding] 22 | $clip: unquote($clip); 23 | $deprecated: $clip; 24 | @if $clip == padding-box { $deprecated: padding; } 25 | @if $clip == border-box { $deprecated: border; } 26 | // Support for webkit and mozilla's use of the deprecated short form 27 | @include experimental(background-clip, $deprecated, 28 | -moz, 29 | -webkit, 30 | not -o, 31 | not -ms, 32 | not -khtml, 33 | not official 34 | ); 35 | @include experimental(background-clip, $clip, 36 | not -moz, 37 | not -webkit, 38 | not -o, 39 | not -ms, 40 | -khtml, 41 | official 42 | ); 43 | } 44 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_background-origin.scss: -------------------------------------------------------------------------------- 1 | // Override `$default-background-origin` to change the default. 2 | 3 | @import "shared"; 4 | 5 | $default-background-origin: content-box !default; 6 | 7 | // Position the background off the edge of the padding, border or content 8 | // 9 | // * Possible values: 10 | // * `padding-box` 11 | // * `border-box` 12 | // * `content-box` 13 | // * browser defaults to `padding-box` 14 | // * mixin defaults to `content-box` 15 | 16 | 17 | @mixin background-origin($origin: $default-background-origin) { 18 | $origin: unquote($origin); 19 | // webkit and mozilla use the deprecated short [border | padding | content] 20 | $deprecated: $origin; 21 | @if $origin == padding-box { $deprecated: padding; } 22 | @if $origin == border-box { $deprecated: border; } 23 | @if $origin == content-box { $deprecated: content; } 24 | 25 | // Support for webkit and mozilla's use of the deprecated short form 26 | @include experimental(background-origin, $deprecated, 27 | -moz, 28 | -webkit, 29 | not -o, 30 | not -ms, 31 | not -khtml, 32 | not official 33 | ); 34 | @include experimental(background-origin, $origin, 35 | not -moz, 36 | not -webkit, 37 | -o, 38 | -ms, 39 | -khtml, 40 | official 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_background-size.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // override to change the default 4 | $default-background-size: 100% auto !default; 5 | 6 | // Set the size of background images using px, width and height, or percentages. 7 | // Currently supported in: Opera, Gecko, Webkit. 8 | // 9 | // * percentages are relative to the background-origin (default = padding-box) 10 | // * mixin defaults to: `$default-background-size` 11 | @mixin background-size( 12 | $size-1: $default-background-size, 13 | $size-2: false, 14 | $size-3: false, 15 | $size-4: false, 16 | $size-5: false, 17 | $size-6: false, 18 | $size-7: false, 19 | $size-8: false, 20 | $size-9: false, 21 | $size-10: false 22 | ) { 23 | $size-1: if(type-of($size-1) == string, unquote($size-1), $size-1); 24 | $sizes: compact($size-1, $size-2, $size-3, $size-4, $size-5, $size-6, $size-7, $size-8, $size-9, $size-10); 25 | @include experimental(background-size, $sizes, -moz, -webkit, -o, not -ms, not -khtml); 26 | } 27 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_box-shadow.scss: -------------------------------------------------------------------------------- 1 | // @doc off 2 | // These defaults make the arguments optional for this mixin 3 | // If you like, set different defaults before importing. 4 | // @doc on 5 | 6 | @import "shared"; 7 | 8 | 9 | // The default color for box shadows 10 | $default-box-shadow-color: #333333 !default; 11 | 12 | // The default horizontal offset. Positive is to the right. 13 | $default-box-shadow-h-offset: 0px !default; 14 | 15 | // The default vertical offset. Positive is down. 16 | $default-box-shadow-v-offset: 0px !default; 17 | 18 | // The default blur length. 19 | $default-box-shadow-blur: 5px !default; 20 | 21 | // The default spread length. 22 | $default-box-shadow-spread : false !default; 23 | 24 | // The default shadow inset: inset or false (for standard shadow). 25 | $default-box-shadow-inset : false !default; 26 | 27 | // Provides cross-browser for Webkit, Gecko, and CSS3 box shadows when one or more box 28 | // shadows are needed. 29 | // Each shadow argument should adhere to the standard css3 syntax for the 30 | // box-shadow property. 31 | @mixin box-shadow( 32 | $shadow-1 : default, 33 | $shadow-2 : false, 34 | $shadow-3 : false, 35 | $shadow-4 : false, 36 | $shadow-5 : false, 37 | $shadow-6 : false, 38 | $shadow-7 : false, 39 | $shadow-8 : false, 40 | $shadow-9 : false, 41 | $shadow-10: false 42 | ) { 43 | @if $shadow-1 == default { 44 | $shadow-1 : -compass-space-list(compact(if($default-box-shadow-inset, inset, false), $default-box-shadow-h-offset, $default-box-shadow-v-offset, $default-box-shadow-blur, $default-box-shadow-spread, $default-box-shadow-color)); 45 | } 46 | $shadow : compact($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10); 47 | @include experimental(box-shadow, $shadow, 48 | -moz, -webkit, not -o, not -ms, not -khtml, official 49 | ); 50 | } 51 | 52 | // Provides a single cross-browser CSS box shadow for Webkit, Gecko, and CSS3. 53 | // Includes default arguments for color, horizontal offset, vertical offset, blur length, spread length, and inset. 54 | @mixin single-box-shadow( 55 | $color : $default-box-shadow-color, 56 | $hoff : $default-box-shadow-h-offset, 57 | $voff : $default-box-shadow-v-offset, 58 | $blur : $default-box-shadow-blur, 59 | $spread : $default-box-shadow-spread, 60 | $inset : $default-box-shadow-inset 61 | ) { 62 | @if not ($inset == true or $inset == false or $inset == inset) { 63 | @warn "$inset expected to be true or the inset keyword. Got #{$inset} instead. Using: inset"; 64 | } 65 | 66 | @if $color == none { 67 | @include box-shadow(none); 68 | } @else { 69 | $full : $hoff $voff; 70 | @if $blur { $full: $full $blur; } 71 | @if $spread { $full: $full $spread; } 72 | @if $color { $full: $full $color; } 73 | @if $inset { $full: inset $full; } 74 | @include box-shadow($full); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_box-sizing.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // Change the box model for Mozilla, Webkit, IE8 and the future 4 | // 5 | // @param $bs 6 | // [ content-box | border-box ] 7 | 8 | @mixin box-sizing($bs) { 9 | $bs: unquote($bs); 10 | @include experimental(box-sizing, $bs, 11 | -moz, -webkit, not -o, not -ms, not -khtml, official 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_filter.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // Provides cross-browser support for the upcoming (?) css3 filter property. 4 | // 5 | // Each filter argument should adhere to the standard css3 syntax for the 6 | // filter property. 7 | @mixin filter ( 8 | $filter-1, 9 | $filter-2 : false, 10 | $filter-3 : false, 11 | $filter-4 : false, 12 | $filter-5 : false, 13 | $filter-6 : false, 14 | $filter-7 : false, 15 | $filter-8 : false, 16 | $filter-9 : false, 17 | $filter-10: false 18 | ) { 19 | $filter : compact($filter-1, $filter-2, $filter-3, $filter-4, $filter-5, $filter-6, $filter-7, $filter-8, $filter-9, $filter-10); 20 | @include experimental(filter, $filter, 21 | -moz, -webkit, not -o, not -ms, not -khtml, official 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_font-face.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // Cross-browser support for @font-face. Supports IE, Gecko, Webkit, Opera. 4 | // 5 | // * $name is required, arbitrary, and what you will use in font stacks. 6 | // * $font-files is required using font-files('relative/location', 'format'). 7 | // for best results use this order: woff, opentype/truetype, svg 8 | // * $eot is required by IE, and is a relative location of the eot file. 9 | // * $weight shows if the font is bold, defaults to normal 10 | // * $style defaults to normal, might be also italic 11 | // * For android 2.2 Compatiblity, please ensure that your web page has 12 | // a meta viewport tag. 13 | // * To support iOS < 4.2, an SVG file must be provided 14 | // 15 | // If you need to generate other formats check out the Font Squirrel 16 | // [font generator](http://www.fontsquirrel.com/fontface/generator) 17 | // 18 | 19 | // In order to refer to a specific style of the font in your stylesheets as 20 | // e.g. "font-style: italic;", you may add a couple of @font-face includes 21 | // containing the respective font files for each style and specying 22 | // respective the $style parameter. 23 | 24 | // Order of the includes matters, and it is: normal, bold, italic, bold+italic. 25 | 26 | @mixin font-face( 27 | $name, 28 | $font-files, 29 | $eot: false, 30 | $weight: false, 31 | $style: false 32 | ) { 33 | $iefont: unquote("#{$eot}?#iefix"); 34 | @font-face { 35 | font-family: quote($name); 36 | @if $eot { 37 | src: font-url($eot); 38 | $font-files: font-url($iefont) unquote("format('embedded-opentype')"), $font-files; 39 | } 40 | src: $font-files; 41 | @if $weight { 42 | font-weight: $weight; 43 | } 44 | @if $style { 45 | font-style: $style; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_hyphenation.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // Mixins to support specific CSS Text Level 3 elements 4 | // 5 | // 6 | // 7 | // Mixin for word-break properties 8 | // http://www.w3.org/css3-text/#word-break 9 | // * legal values for $type : normal, keep-all, break-all 10 | // 11 | // Example: 12 | // p.wordBreak {@include word-break(break-all);} 13 | // 14 | // Which generates: 15 | // p.wordBreak { 16 | // -ms-word-break: break-all; 17 | // word-break: break-all; 18 | // word-break: break-word;} 19 | // 20 | @mixin word-break($value: normal){ 21 | @if $value == break-all { 22 | //Most browsers handle the break-all case the same... 23 | @include experimental(word-break, $value, 24 | not -moz, not -webkit, not -o, -ms, not -khtml, official 25 | ); 26 | //Webkit handles break-all differently... as break-word 27 | @include experimental(word-break, break-word, 28 | not -moz, not -webkit, not -o, not -ms, not -khtml, official 29 | ); 30 | } 31 | @else { 32 | @include experimental(word-break, $value, 33 | not -moz, not -webkit, not -o, -ms, not -khtml, official 34 | ); 35 | } 36 | } 37 | 38 | // Mixin for the hyphens property 39 | // 40 | // W3C specification: http://www.w3.org/TR/css3-text/#hyphens 41 | // * legal values for $type : auto, manual, none 42 | // 43 | // Example: 44 | // p { 45 | // @include hyphens(auto);} 46 | // Which generates: 47 | // p { 48 | // -moz-hyphens: auto; 49 | // -webkit-hyphens: auto; 50 | // hyphens: auto;} 51 | // 52 | @mixin hyphens($value: auto){ 53 | @include experimental(hyphens, $value, 54 | -moz, -webkit, not -o, not -ms, not -khtml, official 55 | ); 56 | } 57 | 58 | // Mixin for x-browser hyphenation based on @auchenberg's post: 59 | // Removes the need for the HTML tag 60 | // http://blog.kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css/ 61 | // 62 | // Example: 63 | // div {@include hyphenation;} 64 | // 65 | // Which generates: 66 | // div { 67 | // -ms-word-break: break-all; 68 | // word-break: break-all; 69 | // word-break: break-word; 70 | // -moz-hyphens: auto; 71 | // -webkit-hyphens: auto; 72 | // hyphens: auto;} 73 | // 74 | @mixin hyphenation{ 75 | @include word-break(break-all); 76 | @include hyphens; 77 | } 78 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_inline-block.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // Set `$inline-block-alignment` to `none` or `false` to disable the output 4 | // of a vertical-align property in the inline-block mixin. 5 | // Or set it to a legal value for `vertical-align` to change the default. 6 | $inline-block-alignment: middle !default; 7 | 8 | // Provides a cross-browser method to implement `display: inline-block;` 9 | @mixin inline-block($alignment: $inline-block-alignment) { 10 | @if $legacy-support-for-mozilla { 11 | display: -moz-inline-stack; 12 | } 13 | display: inline-block; 14 | @if $alignment and $alignment != none { 15 | vertical-align: $alignment; 16 | } 17 | @if $legacy-support-for-ie { 18 | *vertical-align: auto; 19 | zoom: 1; 20 | *display: inline; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_opacity.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // Provides cross-browser CSS opacity. Takes a number between 0 and 1 as the argument, e.g. 0.5 for 50% opacity. 4 | // 5 | // @param $opacity 6 | // A number between 0 and 1, where 0 is transparent and 1 is opaque. 7 | 8 | @mixin opacity($opacity) { 9 | @if $legacy-support-for-ie6 or $legacy-support-for-ie7 or $legacy-support-for-ie8 { 10 | filter: unquote("progid:DXImageTransform.Microsoft.Alpha(Opacity=#{round($opacity * 100)})"); 11 | } 12 | opacity: $opacity; 13 | } 14 | 15 | // Make an element completely transparent. 16 | @mixin transparent { @include opacity(0); } 17 | 18 | // Make an element completely opaque. 19 | @mixin opaque { @include opacity(1); } 20 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_pie.scss: -------------------------------------------------------------------------------- 1 | $experimental-support-for-pie: true; 2 | 3 | // It is recommended that you use Sass's @extend directive to apply the behavior 4 | // to your PIE elements. To assist you, Compass provides this variable. 5 | // When set, it will cause the `@include pie` mixin to extend this class. 6 | // The class name you provide should **not** include the `.`. 7 | $pie-base-class: false !default; 8 | 9 | // The default approach to using PIE. 10 | // Can be one of: 11 | // 12 | // * relative (default) 13 | // * z-index 14 | // * none 15 | $pie-default-approach: relative !default; 16 | 17 | // The location of your PIE behavior file 18 | // This should be root-relative to your web server 19 | // relative assets don't work. It is recommended that 20 | // you set this yourself. 21 | $pie-behavior: stylesheet-url("PIE.htc") !default; 22 | 23 | // When using the z-index approach, the 24 | // first ancestor of the PIE element at 25 | // or before the container's opaque background 26 | // should have a z-index set as well to ensure 27 | // propert z-index stacking. 28 | // 29 | // The `$position` argument must be some non-static 30 | // value (absolute, relative, etc.) 31 | @mixin pie-container($z-index: 0, $position: relative) { 32 | z-index: $z-index; 33 | position: $position; 34 | } 35 | 36 | // PIE elements must have this behavior attached to them. 37 | // IE is broken -- it doesn't think of behavior urls as 38 | // relative to the stylesheet. It considers them relative 39 | // to the webpage. As a result, you cannot reliably use 40 | // compass's relative_assets with PIE. 41 | // 42 | // * `$approach` - one of: relative, z-index, or none 43 | // * `$z-index` - when using the z-index approach, this 44 | // is the z-index that is applied. 45 | @mixin pie-element( 46 | $approach: $pie-default-approach, 47 | $z-index: 0 48 | ) { 49 | behavior: $pie-behavior; 50 | @if $approach == relative { 51 | position: relative; 52 | } 53 | @else if $approach == z-index { 54 | z-index: $z-index; 55 | } 56 | } 57 | 58 | // a smart mixin that knows to extend or include pie-element according 59 | // to your stylesheet's configuration variables. 60 | @mixin pie($base-class: $pie-base-class) { 61 | @if $base-class { 62 | @extend .#{$base-class}; 63 | } 64 | @else { 65 | @include pie-element; 66 | } 67 | } 68 | 69 | // Watch `$n` levels of ancestors for changes to their class attribute 70 | // So that cascading styles will work correctly on the PIE element. 71 | @mixin pie-watch-ancestors($n) { 72 | -pie-watch-ancestors: $n; 73 | } -------------------------------------------------------------------------------- /src/sass/compass/css3/_regions.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | // Webkit, IE10 and future support for [CSS Regions](http://dev.w3.org/csswg/css3-regions/) 4 | // 5 | // $target is a value you use to link two regions of your css. Give the source of your content the flow-into property, and give your target container the flow-from property. 6 | // 7 | // For a visual explanation, see the diagrams at Chris Coyier's 8 | // [CSS-Tricks](http://css-tricks.com/content-folding/) 9 | 10 | @mixin flow-into($target) { 11 | $target: unquote($target); 12 | @include experimental(flow-into, $target, 13 | not -moz, -webkit, not -o, -ms, not -khtml, not official 14 | ); 15 | } 16 | 17 | @mixin flow-from($target) { 18 | $target: unquote($target); 19 | @include experimental(flow-from, $target, 20 | not -moz, -webkit, not -o, -ms, not -khtml, not official 21 | ); 22 | } -------------------------------------------------------------------------------- /src/sass/compass/css3/_shared.scss: -------------------------------------------------------------------------------- 1 | @import "compass/support"; 2 | 3 | // This mixin provides basic support for CSS3 properties and 4 | // their corresponding experimental CSS2 properties when 5 | // the implementations are identical except for the property 6 | // prefix. 7 | @mixin experimental($property, $value, 8 | $moz : $experimental-support-for-mozilla, 9 | $webkit : $experimental-support-for-webkit, 10 | $o : $experimental-support-for-opera, 11 | $ms : $experimental-support-for-microsoft, 12 | $khtml : $experimental-support-for-khtml, 13 | $official : true 14 | ) { 15 | @if $webkit and $experimental-support-for-webkit { -webkit-#{$property} : $value; } 16 | @if $khtml and $experimental-support-for-khtml { -khtml-#{$property} : $value; } 17 | @if $moz and $experimental-support-for-mozilla { -moz-#{$property} : $value; } 18 | @if $ms and $experimental-support-for-microsoft { -ms-#{$property} : $value; } 19 | @if $o and $experimental-support-for-opera { -o-#{$property} : $value; } 20 | @if $official { #{$property} : $value; } 21 | } 22 | 23 | // Same as experimental(), but for cases when the property is the same and the value is vendorized 24 | @mixin experimental-value($property, $value, 25 | $moz : $experimental-support-for-mozilla, 26 | $webkit : $experimental-support-for-webkit, 27 | $o : $experimental-support-for-opera, 28 | $ms : $experimental-support-for-microsoft, 29 | $khtml : $experimental-support-for-khtml, 30 | $official : true 31 | ) { 32 | @if $webkit and $experimental-support-for-webkit { #{$property} : -webkit-#{$value}; } 33 | @if $khtml and $experimental-support-for-khtml { #{$property} : -khtml-#{$value}; } 34 | @if $moz and $experimental-support-for-mozilla { #{$property} : -moz-#{$value}; } 35 | @if $ms and $experimental-support-for-microsoft { #{$property} : -ms-#{$value}; } 36 | @if $o and $experimental-support-for-opera { #{$property} : -o-#{$value}; } 37 | @if $official { #{$property} : #{$value}; } 38 | } 39 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_transform-legacy.scss: -------------------------------------------------------------------------------- 1 | @import "shared"; 2 | 3 | @warn "This version of the transform module has been deprecated and will be removed."; 4 | 5 | // CSS Transform and Transform-Origin 6 | 7 | // Apply a transform sent as a complete string. 8 | 9 | @mixin apply-transform($transform) { 10 | @include experimental(transform, $transform, 11 | -moz, -webkit, -o, not -ms, not -khtml, official 12 | ); 13 | } 14 | 15 | // Apply a transform-origin sent as a complete string. 16 | 17 | @mixin apply-origin($origin) { 18 | @include experimental(transform-origin, $origin, 19 | -moz, -webkit, -o, not -ms, not -khtml, official 20 | ); 21 | } 22 | 23 | // transform-origin requires x and y coordinates 24 | // 25 | // * only applies the coordinates if they are there so that it can be called by scale, rotate and skew safely 26 | 27 | @mixin transform-origin($originx: 50%, $originy: 50%) { 28 | @if $originx or $originy { 29 | @if $originy { 30 | @include apply-origin($originx or 50% $originy); 31 | } @else { 32 | @include apply-origin($originx); 33 | } 34 | } 35 | } 36 | 37 | // A full transform mixin with everything you could want 38 | // 39 | // * including origin adjustments if you want them 40 | // * scale, rotate and skew require units of degrees(deg) 41 | // * scale takes a multiplier, rotate and skew take degrees 42 | 43 | @mixin transform( 44 | $scale: 1, 45 | $rotate: 0deg, 46 | $transx: 0, 47 | $transy: 0, 48 | $skewx: 0deg, 49 | $skewy: 0deg, 50 | $originx: false, 51 | $originy: false 52 | ) { 53 | $transform : scale($scale) rotate($rotate) translate($transx, $transy) skew($skewx, $skewy); 54 | @include apply-transform($transform); 55 | @include transform-origin($originx, $originy); 56 | } 57 | 58 | // Transform Partials 59 | // 60 | // These work well on their own, but they don't add to each other, they override. 61 | // Use them with extra origin args, or along side +transform-origin 62 | 63 | // Adjust only the scale, with optional origin coordinates 64 | 65 | @mixin scale($scale: 1.25, $originx: false, $originy: false) { 66 | @include apply-transform(scale($scale)); 67 | @include transform-origin($originx, $originy); 68 | } 69 | 70 | // Adjust only the rotation, with optional origin coordinates 71 | 72 | @mixin rotate($rotate: 45deg, $originx: false, $originy: false) { 73 | @include apply-transform(rotate($rotate)); 74 | @include transform-origin($originx, $originy); 75 | } 76 | 77 | // Adjust only the translation 78 | 79 | @mixin translate($transx: 0, $transy: 0) { 80 | @include apply-transform(translate($transx, $transy)); 81 | } 82 | 83 | // Adjust only the skew, with optional origin coordinates 84 | @mixin skew($skewx: 0deg, $skewy: 0deg, $originx: false, $originy: false) { 85 | @include apply-transform(skew($skewx, $skewy)); 86 | @include transform-origin($originx, $originy); 87 | } 88 | -------------------------------------------------------------------------------- /src/sass/compass/css3/_user-interface.scss: -------------------------------------------------------------------------------- 1 | // User Interface ------------------------------------------------------------ 2 | // This file can be expanded to handle all the user interface properties as 3 | // they become available in browsers: 4 | // http://www.w3.org/TR/2000/WD-css3-userint-20000216 5 | @import "shared"; 6 | 7 | 8 | // This property controls the selection model and granularity of an element. 9 | // 10 | // @param $select 11 | // [ none | text | toggle | element | elements | all | inherit ] 12 | @mixin user-select($select) { 13 | $select: unquote($select); 14 | @include experimental(user-select, $select, 15 | -moz, -webkit, not -o, not -ms, -khtml, official 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/sass/compass/layout/_sticky-footer.scss: -------------------------------------------------------------------------------- 1 | // Based on a [blog post by Ryan Fait](http://ryanfait.com/resources/footer-stick-to-bottom-of-page/). 2 | // 3 | // Must be mixed into the top level of your stylesheet. 4 | // 5 | // Footer element must be outside of root wrapper element. 6 | // 7 | // Footer must be a fixed height. 8 | 9 | @mixin sticky-footer($footer-height, $root-selector: unquote("#root"), $root-footer-selector: unquote("#root_footer"), $footer-selector: unquote("#footer")) { 10 | html, body { 11 | height: 100%; } 12 | #{$root-selector} { 13 | clear: both; 14 | min-height: 100%; 15 | height: auto !important; 16 | height: 100%; 17 | margin-bottom: -$footer-height; 18 | #{$root-footer-selector} { 19 | height: $footer-height; } } 20 | #{$footer-selector} { 21 | clear: both; 22 | position: relative; 23 | height: $footer-height; } } 24 | -------------------------------------------------------------------------------- /src/sass/compass/layout/_stretching.scss: -------------------------------------------------------------------------------- 1 | 2 | // stretch element height to specified top and bottom position 3 | 4 | @mixin stretch-y($offset-top:0, $offset-bottom:0) { 5 | @include stretch($offset-top, false, $offset-bottom, false); 6 | } 7 | 8 | 9 | // stretch element width to specified left and right position 10 | 11 | @mixin stretch-x($offset-left:0, $offset-right:0) { 12 | @include stretch(false, $offset-right, false, $offset-left); 13 | } 14 | 15 | 16 | // shorthand to stretch element height and width 17 | 18 | @mixin stretch($offset-top:0, $offset-right:0, $offset-bottom:0, $offset-left:0) { 19 | position: absolute; 20 | @if $offset-top { top: $offset-top; } 21 | @if $offset-bottom { bottom: $offset-bottom; } 22 | @if $offset-left { left: $offset-left; } 23 | @if $offset-right { right: $offset-right; } 24 | } -------------------------------------------------------------------------------- /src/sass/compass/typography/_links.scss: -------------------------------------------------------------------------------- 1 | @import "links/hover-link"; 2 | @import "links/link-colors"; 3 | @import "links/unstyled-link"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/typography/_lists.scss: -------------------------------------------------------------------------------- 1 | @import "lists/horizontal-list"; 2 | @import "lists/inline-list"; 3 | @import "lists/inline-block-list"; 4 | @import "lists/bullets"; 5 | -------------------------------------------------------------------------------- /src/sass/compass/typography/_text.scss: -------------------------------------------------------------------------------- 1 | @import "text/ellipsis"; 2 | @import "text/nowrap"; 3 | @import "text/replacement"; 4 | @import "text/force-wrap"; 5 | -------------------------------------------------------------------------------- /src/sass/compass/typography/links/_hover-link.scss: -------------------------------------------------------------------------------- 1 | // a link that only has an underline when you hover over it 2 | @mixin hover-link { 3 | text-decoration: none; 4 | &:hover { 5 | text-decoration: underline; } } 6 | -------------------------------------------------------------------------------- /src/sass/compass/typography/links/_link-colors.scss: -------------------------------------------------------------------------------- 1 | // Set all the colors for a link with one mixin call. 2 | // Order of arguments is: 3 | // 4 | // 1. normal 5 | // 2. hover 6 | // 3. active 7 | // 4. visited 8 | // 5. focus 9 | // 10 | // Those states not specified will inherit. 11 | // Mixin to an anchor link like so: 12 | // a 13 | // +link-colors(#00c, #0cc, #c0c, #ccc, #cc0) 14 | 15 | @mixin link-colors($normal, $hover: false, $active: false, $visited: false, $focus: false) { 16 | color: $normal; 17 | @if $visited { 18 | &:visited { 19 | color: $visited; } } 20 | @if $focus { 21 | &:focus { 22 | color: $focus; } } 23 | @if $hover { 24 | &:hover { 25 | color: $hover; } } 26 | @if $active { 27 | &:active { 28 | color: $active; } } } 29 | -------------------------------------------------------------------------------- /src/sass/compass/typography/links/_unstyled-link.scss: -------------------------------------------------------------------------------- 1 | // A link that looks and acts like the text it is contained within 2 | @mixin unstyled-link { 3 | color: inherit; 4 | text-decoration: inherit; 5 | cursor: inherit; 6 | &:active, &:focus { 7 | outline: none; } } 8 | -------------------------------------------------------------------------------- /src/sass/compass/typography/lists/_bullets.scss: -------------------------------------------------------------------------------- 1 | // Turn off the bullet for an element of a list 2 | @mixin no-bullet { 3 | list-style-image : none; 4 | list-style-type : none; 5 | margin-left : 0; 6 | } 7 | 8 | // turns off the bullets for an entire list 9 | @mixin no-bullets { 10 | list-style: none; 11 | li { @include no-bullet; } 12 | } 13 | 14 | // Make a list(ul/ol) have an image bullet. 15 | // 16 | // The mixin should be used like this for an icon that is 5x7: 17 | // 18 | // ul.pretty 19 | // +pretty-bullets("my-icon.png", 5px, 7px) 20 | // 21 | // Additionally, if the image dimensions are not provided, 22 | // The image dimensions will be extracted from the image itself. 23 | // 24 | // ul.pretty 25 | // +pretty-bullets("my-icon.png") 26 | // 27 | @mixin pretty-bullets($bullet-icon, $width: image-width($bullet-icon), $height: image-height($bullet-icon), $line-height: 18px, $padding: 14px) { 28 | margin-left: 0; 29 | li { 30 | padding-left: $padding; 31 | background: image-url($bullet-icon) no-repeat ($padding - $width) / 2 ($line-height - $height) / 2; 32 | list-style-type: none; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/sass/compass/typography/lists/_horizontal-list.scss: -------------------------------------------------------------------------------- 1 | // Horizontal list layout module. 2 | // 3 | // Easy mode using simple descendant li selectors: 4 | // 5 | // ul.nav 6 | // +horizontal-list 7 | // 8 | // Advanced mode: 9 | // If you need to target the list items using a different selector then use 10 | // +horizontal-list-container on your ul/ol and +horizontal-list-item on your li. 11 | // This may help when working on layouts involving nested lists. For example: 12 | // 13 | // ul.nav 14 | // +horizontal-list-container 15 | // > li 16 | // +horizontal-list-item 17 | 18 | @import "bullets"; 19 | @import "compass/utilities/general/clearfix"; 20 | @import "compass/utilities/general/reset"; 21 | @import "compass/utilities/general/float"; 22 | 23 | // Can be mixed into any selector that target a ul or ol that is meant 24 | // to have a horizontal layout. Used to implement +horizontal-list. 25 | @mixin horizontal-list-container { 26 | @include reset-box-model; 27 | @include clearfix; } 28 | 29 | // Can be mixed into any li selector that is meant to participate in a horizontal layout. 30 | // Used to implement +horizontal-list. 31 | // 32 | // :last-child is not fully supported 33 | // see http://www.quirksmode.org/css/contents.html#t29 for the support matrix 34 | // 35 | // IE8 ignores rules that are included on the same line as :last-child 36 | // see http://www.richardscarrott.co.uk/posts/view/ie8-last-child-bug for details 37 | // 38 | // Setting `$padding` to `false` disables the padding between list elements 39 | @mixin horizontal-list-item($padding: 4px, $direction: left) { 40 | @include no-bullet; 41 | white-space: nowrap; 42 | @include float($direction); 43 | @if $padding { 44 | padding: { 45 | left: $padding; 46 | right: $padding; 47 | } 48 | &:first-child, &.first { padding-#{$direction}: 0; } 49 | &:last-child { padding-#{opposite-position($direction)}: 0; } 50 | &.last { padding-#{opposite-position($direction)}: 0; } 51 | } 52 | } 53 | 54 | // A list(ol,ul) that is layed out such that the elements are floated left and won't wrap. 55 | // This is not an inline list. 56 | // 57 | // Setting `$padding` to `false` disables the padding between list elements 58 | @mixin horizontal-list($padding: 4px, $direction: left) { 59 | @include horizontal-list-container; 60 | li { 61 | @include horizontal-list-item($padding, $direction); } } 62 | -------------------------------------------------------------------------------- /src/sass/compass/typography/lists/_inline-block-list.scss: -------------------------------------------------------------------------------- 1 | // Inline-Block list layout module. 2 | // 3 | // Easy mode using simple descendant li selectors: 4 | // 5 | // ul.nav { 6 | // @import inline-block-list; 7 | // } 8 | // 9 | // Advanced mode: 10 | // If you need to target the list items using a different selector then use 11 | // `@include inline-block-list-container` on your ul/ol and 12 | // `@include inline-block-list-item` on your li. This may help when working 13 | // on layouts involving nested lists. For example: 14 | // 15 | // ul.nav { 16 | // @include inline-block-list-container; 17 | // > li { 18 | // @include inline-block-list-item; 19 | // } 20 | // } 21 | 22 | @import "bullets"; 23 | @import "horizontal-list"; 24 | @import "compass/utilities/general/float"; 25 | @import "compass/css3/inline-block"; 26 | 27 | // Can be mixed into any selector that target a ul or ol that is meant 28 | // to have an inline-block layout. Used to implement `inline-block-list`. 29 | @mixin inline-block-list-container { 30 | @include horizontal-list-container; } 31 | 32 | // Can be mixed into any li selector that is meant to participate in a horizontal layout. 33 | // Used to implement `inline-block-list`. 34 | @mixin inline-block-list-item($padding: false) { 35 | @include no-bullet; 36 | @include inline-block; 37 | white-space: nowrap; 38 | @if $padding { 39 | padding: { 40 | left: $padding; 41 | right: $padding; 42 | }; 43 | } 44 | } 45 | 46 | // A list(ol,ul) that is layed out such that the elements are inline-block and won't wrap. 47 | @mixin inline-block-list($padding: false) { 48 | @include inline-block-list-container; 49 | li { 50 | @include inline-block-list-item($padding); } } 51 | -------------------------------------------------------------------------------- /src/sass/compass/typography/lists/_inline-list.scss: -------------------------------------------------------------------------------- 1 | // makes a list inline. 2 | 3 | @mixin inline-list { 4 | list-style-type: none; 5 | &, & li { 6 | margin: 0px; 7 | padding: 0px; 8 | display: inline; 9 | } 10 | } 11 | 12 | // makes an inline list delimited with the passed string. 13 | // Defaults to making a comma-separated list. 14 | // 15 | // Please make note of the browser support issues before using this mixin: 16 | // 17 | // use of `content` and `:after` is not fully supported in all browsers. 18 | // See quirksmode for the [support matrix](http://www.quirksmode.org/css/contents.html#t15) 19 | // 20 | // `:last-child` is not fully supported. 21 | // see quirksmode for the [support matrix](http://www.quirksmode.org/css/contents.html#t29). 22 | // 23 | // IE8 ignores rules that are included on the same line as :last-child 24 | // see http://www.richardscarrott.co.uk/posts/view/ie8-last-child-bug for details 25 | 26 | @mixin delimited-list($separator: ", ") { 27 | @include inline-list; 28 | li { 29 | &:after { content: $separator; } 30 | &:last-child { 31 | &:after { content: ""; } 32 | } 33 | &.last { 34 | &:after { content: ""; } 35 | } 36 | } 37 | } 38 | 39 | // See [delimited-list](#mixin-delimited-list) 40 | // @deprecated 41 | @mixin comma-delimited-list { 42 | @warn "comma-delimited-list is deprecated. Please use delimited-list instead."; 43 | @include delimited-list; 44 | } 45 | -------------------------------------------------------------------------------- /src/sass/compass/typography/text/_ellipsis.scss: -------------------------------------------------------------------------------- 1 | @import "compass/css3/shared"; 2 | 3 | // To get full firefox support, you must install the ellipsis pattern: 4 | // 5 | // compass install compass/ellipsis 6 | $use-mozilla-ellipsis-binding: false !default; 7 | 8 | // This technique, by [Justin Maxwell](http://code404.com/), was originally 9 | // published [here](http://mattsnider.com/css/css-string-truncation-with-ellipsis/). 10 | // Firefox implementation by [Rikkert Koppes](http://www.rikkertkoppes.com/thoughts/2008/6/). 11 | @mixin ellipsis($no-wrap: true) { 12 | @if $no-wrap { white-space: nowrap; } 13 | overflow: hidden; 14 | @include experimental(text-overflow, ellipsis, 15 | not -moz, 16 | not -webkit, 17 | -o, 18 | -ms, 19 | not -khtml, 20 | official 21 | ); 22 | @if $experimental-support-for-mozilla and $use-mozilla-ellipsis-binding { 23 | -moz-binding: stylesheet-url(unquote("xml/ellipsis.xml#ellipsis")); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/sass/compass/typography/text/_force-wrap.scss: -------------------------------------------------------------------------------- 1 | // Prevent long urls and text from breaking layouts 2 | // [originally from perishablepress.com](http://perishablepress.com/press/2010/06/01/wrapping-content/) 3 | @mixin force-wrap { 4 | white-space: pre; // CSS 2.0 5 | white-space: pre-wrap; // CSS 2.1 6 | white-space: pre-line; // CSS 3.0 7 | white-space: -pre-wrap; // Opera 4-6 8 | white-space: -o-pre-wrap; // Opera 7 9 | white-space: -moz-pre-wrap; // Mozilla 10 | white-space: -hp-pre-wrap; // HP Printers 11 | word-wrap: break-word; // IE 5+ 12 | } 13 | -------------------------------------------------------------------------------- /src/sass/compass/typography/text/_nowrap.scss: -------------------------------------------------------------------------------- 1 | // When remembering whether or not there's a hyphen in white-space is too hard 2 | @mixin nowrap { white-space: nowrap; } 3 | -------------------------------------------------------------------------------- /src/sass/compass/typography/text/_replacement.scss: -------------------------------------------------------------------------------- 1 | // Indicates the direction you prefer to move your text 2 | // when hiding it. 3 | // 4 | // `left` is more robust, especially in older browsers. 5 | // `right` seems have better runtime performance. 6 | $hide-text-direction: left !default; 7 | 8 | // Hides html text and replaces it with an image. 9 | // If you use this on an inline element, you will need to change the display to block or inline-block. 10 | // Also, if the size of the image differs significantly from the font size, you'll need to set the width and/or height. 11 | // 12 | // Parameters: 13 | // 14 | // * `img` -- the relative path from the project image directory to the image, or a url literal. 15 | // * `x` -- the x position of the background image. 16 | // * `y` -- the y position of the background image. 17 | @mixin replace-text($img, $x: 50%, $y: 50%) { 18 | @include hide-text; 19 | background: { 20 | @if is-url($img) { 21 | image: $img; 22 | } @else { 23 | image: image-url($img); 24 | } 25 | repeat: no-repeat; 26 | position: $x $y; 27 | }; 28 | } 29 | 30 | // Like the `replace-text` mixin, but also sets the width 31 | // and height of the element according the dimensions of the image. 32 | // 33 | // If you set `$inline` to true, then an inline image (data uri) will be used. 34 | @mixin replace-text-with-dimensions($img, $x: 50%, $y: 50%, $inline: false) { 35 | @include replace-text(if($inline, inline-image($img), $img), $x, $y); 36 | width: image-width($img); 37 | height: image-height($img); 38 | } 39 | 40 | // Hides text in an element so you can see the background. 41 | // 42 | // The direction indicates how the text should be moved out of view. 43 | // 44 | // See `$hide-text-direction` for more information and to set this globally 45 | // for your application. 46 | @mixin hide-text($direction: $hide-text-direction) { 47 | @if $direction == left { 48 | $approximate-em-value: 12px / 1em; 49 | $wider-than-any-screen: -9999em; 50 | text-indent: $wider-than-any-screen * $approximate-em-value; 51 | overflow: hidden; 52 | text-align: left; 53 | } @else { 54 | // slightly wider than the box prevents issues with inline-block elements 55 | text-indent: 110%; 56 | white-space: nowrap; 57 | overflow: hidden; 58 | } 59 | } 60 | 61 | // Hides text in an element by squishing the text into oblivion. 62 | // Use this if you need to hide text contained in an inline element 63 | // but still have it read by a screen reader. 64 | @mixin squish-text { 65 | font: 0/0 serif; 66 | text-shadow: none; 67 | color: transparent; 68 | } 69 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/_color.scss: -------------------------------------------------------------------------------- 1 | @import "color/contrast"; -------------------------------------------------------------------------------- /src/sass/compass/utilities/_general.scss: -------------------------------------------------------------------------------- 1 | @import "general/reset"; 2 | @import "general/clearfix"; 3 | @import "general/float"; 4 | @import "general/tag-cloud"; 5 | @import "general/hacks"; 6 | @import "general/min"; 7 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/_links.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/links' instead."; 2 | 3 | @import "../typography/links/hover-link"; 4 | @import "../typography/links/link-colors"; 5 | @import "../typography/links/unstyled-link"; 6 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/_lists.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/lists' instead."; 2 | 3 | @import "../typography/lists/horizontal-list"; 4 | @import "../typography/lists/inline-list"; 5 | @import "../typography/lists/inline-block-list"; 6 | @import "../typography/lists/bullets"; 7 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/_print.scss: -------------------------------------------------------------------------------- 1 | // Classes that are useful for controlling what gets printed. 2 | // You must mix `+print-utilities` into your print stylesheet 3 | // and `+print-utilities(screen)` into your screen stylesheet. 4 | // Note: these aren't semantic. 5 | @mixin print-utilities($media: print) { 6 | @if $media == print { 7 | .noprint, .no-print { display: none; } 8 | #{elements-of-type(block)} { 9 | &.print-only { display: block; } 10 | } 11 | #{elements-of-type(inline)} { 12 | &.print-only { display: inline; } 13 | } 14 | } @else { 15 | .print-only { display: none; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/_sprites.scss: -------------------------------------------------------------------------------- 1 | @import "sprites/base"; 2 | @import "sprites/sprite-img"; 3 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/_tables.scss: -------------------------------------------------------------------------------- 1 | @import "tables/alternating-rows-and-columns"; 2 | @import "tables/borders"; 3 | @import "tables/scaffolding"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/_text.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/text' instead."; 2 | 3 | @import "../typography/text/ellipsis"; 4 | @import "../typography/text/nowrap"; 5 | @import "../typography/text/replacement"; 6 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/color/_contrast.scss: -------------------------------------------------------------------------------- 1 | $contrasted-dark-default: #000 !default; 2 | $contrasted-light-default: #fff !default; 3 | $contrasted-lightness-threshold: 30% !default; 4 | 5 | // Returns the `$light` color when the `$color` is dark 6 | // and the `$dark` color when the `$color` is light. 7 | // The `$threshold` is a percent between `0%` and `100%` and it determines 8 | // when the lightness of `$color` changes from "dark" to "light". 9 | @function contrast-color( 10 | $color, 11 | $dark: $contrasted-dark-default, 12 | $light: $contrasted-light-default, 13 | $threshold: $contrasted-lightness-threshold 14 | ) { 15 | @return if(lightness($color) < $threshold, $light, $dark) 16 | } 17 | 18 | // Sets the specified background color and calculates a dark or light contrasted text color. 19 | // The arguments are passed through to the [contrast-color function](#function-contrast-color). 20 | @mixin contrasted( 21 | $background-color, 22 | $dark: $contrasted-dark-default, 23 | $light: $contrasted-light-default, 24 | $threshold: $contrasted-lightness-threshold 25 | ) { 26 | background-color: $background-color; 27 | color: contrast-color($background-color, $dark, $light, $threshold); 28 | } -------------------------------------------------------------------------------- /src/sass/compass/utilities/general/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // @doc off 2 | // Extends the bottom of the element to enclose any floats it contains. 3 | // @doc on 4 | 5 | @import "hacks"; 6 | 7 | // This basic method is preferred for the usual case, when positioned 8 | // content will not show outside the bounds of the container. 9 | // 10 | // Recommendations include using this in conjunction with a width. 11 | // Credit: [quirksmode.org](http://www.quirksmode.org/blog/archives/2005/03/clearing_floats.html) 12 | @mixin clearfix { 13 | overflow: hidden; 14 | @include has-layout; 15 | } 16 | 17 | // This older method from Position Is Everything called 18 | // [Easy Clearing](http://www.positioniseverything.net/easyclearing.html) 19 | // has the advantage of allowing positioned elements to hang 20 | // outside the bounds of the container at the expense of more tricky CSS. 21 | @mixin legacy-pie-clearfix { 22 | &:after { 23 | content : "\0020"; 24 | display : block; 25 | height : 0; 26 | clear : both; 27 | overflow : hidden; 28 | visibility : hidden; 29 | } 30 | @include has-layout; 31 | } 32 | 33 | // This is an updated version of the PIE clearfix method that reduces the amount of CSS output. 34 | // If you need to support Firefox before 3.5 you need to use `legacy-pie-clearfix` instead. 35 | // 36 | // Adapted from: [A new micro clearfix hack](http://nicolasgallagher.com/micro-clearfix-hack/) 37 | @mixin pie-clearfix { 38 | &:after { 39 | content: ""; 40 | display: table; 41 | clear: both; 42 | } 43 | @include has-layout; 44 | } 45 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/general/_float.scss: -------------------------------------------------------------------------------- 1 | // Implementation of float:left with fix for the 2 | // [double-margin bug in IE5/6](http://www.positioniseverything.net/explorer/doubled-margin.html) 3 | @mixin float-left { 4 | @include float(left); } 5 | 6 | // Implementation of float:right with fix for the 7 | // [double-margin bug in IE5/6](http://www.positioniseverything.net/explorer/doubled-margin.html) 8 | @mixin float-right { 9 | @include float(right); } 10 | 11 | // Direction independent float mixin that fixes the 12 | // [double-margin bug in IE5/6](http://www.positioniseverything.net/explorer/doubled-margin.html) 13 | @mixin float($side: left) { 14 | display: inline; 15 | float: unquote($side); } 16 | 17 | // Resets floated elements back to their default of `float: none` and defaults 18 | // to `display: block` unless you pass `inline` as an argument 19 | // 20 | // Usage Example: 21 | // 22 | // body.homepage 23 | // #footer li 24 | // +float-left 25 | // body.signup 26 | // #footer li 27 | // +reset-float 28 | @mixin reset-float($display: block) { 29 | float: none; 30 | display: $display; } -------------------------------------------------------------------------------- /src/sass/compass/utilities/general/_hacks.scss: -------------------------------------------------------------------------------- 1 | @import "compass/support"; 2 | 3 | // The `zoom` approach generates less CSS but does not validate. 4 | // Set this to `block` to use the display-property to hack the 5 | // element to gain layout. 6 | $default-has-layout-approach: zoom !default; 7 | 8 | // This mixin causes an element matching the selector 9 | // to gain the "hasLayout" property in internet explorer. 10 | // More information on [hasLayout](http://reference.sitepoint.com/css/haslayout). 11 | @mixin has-layout($approach: $default-has-layout-approach) { 12 | @if $legacy-support-for-ie { 13 | @if $approach == zoom { 14 | @include has-layout-zoom; 15 | } @else if $approach == block { 16 | @include has-layout-block; 17 | } @else { 18 | @warn "Unknown has-layout approach: #{$approach}"; 19 | @include has-layout-zoom; 20 | } 21 | } 22 | } 23 | 24 | @mixin has-layout-zoom { 25 | @if $legacy-support-for-ie6 or $legacy-support-for-ie7 { 26 | *zoom: 1; 27 | } 28 | } 29 | 30 | @mixin has-layout-block { 31 | @if $legacy-support-for-ie { 32 | // This makes ie6 get layout 33 | display: inline-block; 34 | // and this puts it back to block 35 | & { display: block; } 36 | } 37 | } 38 | 39 | // A hack to supply IE6 (and below) with a different property value. 40 | // [Read more](http://www.cssportal.com/css-hacks/#in_css-important). 41 | @mixin bang-hack($property, $value, $ie6-value) { 42 | @if $legacy-support-for-ie6 { 43 | #{$property}: #{$value} !important; 44 | #{$property}: #{$ie6-value}; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/general/_min.scss: -------------------------------------------------------------------------------- 1 | @import "hacks"; 2 | 3 | //** 4 | // Cross browser min-height mixin. 5 | @mixin min-height($value) { 6 | @include hacked-minimum(height, $value); } 7 | 8 | //** 9 | // Cross browser min-width mixin. 10 | @mixin min-width($value) { 11 | @include hacked-minimum(width, $value); } 12 | 13 | // @private This mixin is not meant to be used directly. 14 | @mixin hacked-minimum($property, $value) { 15 | min-#{$property}: $value; 16 | @include bang-hack($property, auto, $value); } 17 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/general/_reset.scss: -------------------------------------------------------------------------------- 1 | // This module has moved. 2 | @import "compass/reset/utilities"; -------------------------------------------------------------------------------- /src/sass/compass/utilities/general/_tabs.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/general/_tag-cloud.scss: -------------------------------------------------------------------------------- 1 | // Emits styles for a tag cloud 2 | @mixin tag-cloud($base-size: 1em) { 3 | font-size: $base-size; 4 | line-height: 1.2 * $base-size; 5 | .xxs, .xs, .s, .l, .xl, .xxl { 6 | line-height: 1.2 * $base-size; } 7 | .xxs { 8 | font-size: $base-size / 2; } 9 | .xs { 10 | font-size: 2 * $base-size / 3; } 11 | .s { 12 | font-size: 3 * $base-size / 4; } 13 | .l { 14 | font-size: 4 * $base-size / 3; } 15 | .xl { 16 | font-size: 3 * $base-size / 2; } 17 | .xxl { 18 | font-size: 2 * $base-size; } } 19 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/links/_hover-link.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/links/hover-link' instead."; 2 | 3 | @import "../../typography/links/hover-link"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/links/_link-colors.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/links/link-colors' instead."; 2 | 3 | @import "../../typography/links/link-colors"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/links/_unstyled-link.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/links/unstyled-link' instead."; 2 | 3 | @import "../../typography/links/unstyled-link"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/lists/_bullets.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/lists/bullets' instead."; 2 | 3 | @import "../../typography/lists/bullets"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/lists/_horizontal-list.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/lists/horizontal-list' instead."; 2 | 3 | @import "../../typography/lists/horizontal-list"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/lists/_inline-block-list.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/lists/inline-block-list' instead."; 2 | 3 | @import "../../typography/lists/inline-block-list"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/lists/_inline-list.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/lists/inline-list' instead."; 2 | 3 | @import "../../typography/lists/inline-list"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/sprites/_base.scss: -------------------------------------------------------------------------------- 1 | // Determines those states for which you want to enable magic sprite selectors 2 | $sprite-selectors: hover, target, active !default; 3 | 4 | // Set the width and height of an element to the original 5 | // dimensions of an image before it was included in the sprite. 6 | @mixin sprite-dimensions($map, $sprite) { 7 | height: image-height(sprite-file($map, $sprite)); 8 | width: image-width(sprite-file($map, $sprite)); 9 | } 10 | 11 | // Set the background position of the given sprite `$map` to display the 12 | // sprite of the given `$sprite` name. You can move the image relative to its 13 | // natural position by passing `$offset-x` and `$offset-y`. 14 | @mixin sprite-background-position($map, $sprite, $offset-x: 0, $offset-y: 0) { 15 | background-position: sprite-position($map, $sprite, $offset-x, $offset-y); 16 | } 17 | 18 | 19 | // Determines if you want to include magic selectors in your sprites 20 | $disable-magic-sprite-selectors:false !default; 21 | 22 | // Include the position and (optionally) dimensions of this `$sprite` 23 | // in the given sprite `$map`. The sprite url should come from either a base 24 | // class or you can specify the `sprite-url` explicitly like this: 25 | // 26 | // background: $map no-repeat; 27 | @mixin sprite($map, $sprite, $dimensions: false, $offset-x: 0, $offset-y: 0) { 28 | @include sprite-background-position($map, $sprite, $offset-x, $offset-y); 29 | @if $dimensions { 30 | @include sprite-dimensions($map, $sprite); 31 | } 32 | @if not $disable-magic-sprite-selectors { 33 | @include sprite-selectors($map, $sprite, $sprite, $offset-x, $offset-y); 34 | } 35 | } 36 | 37 | // Include the selectors for the `$sprite` given the `$map` and the 38 | // `$full-sprite-name` 39 | // @private 40 | @mixin sprite-selectors($map, $sprite-name, $full-sprite-name, $offset-x: 0, $offset-y: 0) { 41 | @each $selector in $sprite-selectors { 42 | @if sprite_has_selector($map, $sprite-name, $selector) { 43 | &:#{$selector}, &.#{$full-sprite-name}_#{$selector}, &.#{$full-sprite-name}-#{$selector} { 44 | @include sprite-background-position($map, "#{$sprite-name}_#{$selector}", $offset-x, $offset-y); 45 | } 46 | } 47 | } 48 | } 49 | 50 | // Generates a class for each space separated name in `$sprite-names`. 51 | // The class will be of the form .-. 52 | // 53 | // If a base class is provided, then each class will extend it. 54 | // 55 | // If `$dimensions` is `true`, the sprite dimensions will specified. 56 | @mixin sprites($map, $sprite-names, $base-class: false, $dimensions: false, $prefix: sprite-map-name($map), $offset-x: 0, $offset-y: 0) { 57 | @each $sprite-name in $sprite-names { 58 | @if sprite_does_not_have_parent($map, $sprite-name) { 59 | $full-sprite-name: "#{$prefix}-#{$sprite-name}"; 60 | .#{$full-sprite-name} { 61 | @if $base-class { @extend #{$base-class}; } 62 | @include sprite($map, $sprite-name, $dimensions, $offset-x, $offset-y); 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /src/sass/compass/utilities/tables/_alternating-rows-and-columns.scss: -------------------------------------------------------------------------------- 1 | @mixin alternating-rows-and-columns($even-row-color, $odd-row-color, $dark-intersection, $header-color: white, $footer-color: white) { 2 | th { 3 | background-color: $header-color; 4 | &.even, &:nth-child(2n) { 5 | background-color: $header-color - $dark-intersection; } } 6 | tr { 7 | &.odd, &:nth-child(2n+1) { 8 | td { 9 | background-color: $odd-row-color; 10 | &.even, &:nth-child(2n) { 11 | background-color: $odd-row-color - $dark-intersection; } } } 12 | } 13 | tr.even { 14 | td { 15 | background-color: $even-row-color; 16 | &.even, &:nth-child(2n) { 17 | background-color: $even-row-color - $dark-intersection; } } } 18 | tfoot { 19 | th, td { 20 | background-color: $footer-color; 21 | &.even, &:nth-child(2n) { 22 | background-color: $footer-color - $dark-intersection; } } } } 23 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/tables/_borders.scss: -------------------------------------------------------------------------------- 1 | @mixin outer-table-borders($width: 2px, $color: black) { 2 | border: $width solid $color; 3 | thead { 4 | th { 5 | border-bottom: $width solid $color; } } 6 | tfoot { 7 | th, td { 8 | border-top: $width solid $color; } } 9 | th { 10 | &:first-child { 11 | border-right: $width solid $color; } } } 12 | 13 | @mixin inner-table-borders($width: 2px, $color: black) { 14 | th, td { 15 | border: { 16 | right: $width solid $color; 17 | bottom: $width solid $color; 18 | left-width: 0px; 19 | top-width: 0px; }; 20 | &:last-child, 21 | &.last { 22 | border-right-width: 0px; } } 23 | 24 | // IE8 ignores rules that are included on the same line as :last-child 25 | // see http://www.richardscarrott.co.uk/posts/view/ie8-last-child-bug for details 26 | 27 | tbody, tfoot { 28 | tr:last-child { 29 | th, td { 30 | border-bottom-width: 0px; } } 31 | tr.last { 32 | th, td { 33 | border-bottom-width: 0px; } } } } 34 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/tables/_scaffolding.scss: -------------------------------------------------------------------------------- 1 | @mixin table-scaffolding { 2 | th { 3 | text-align: center; 4 | font-weight: bold; } 5 | td, 6 | th { 7 | padding: 2px; 8 | &.numeric { 9 | text-align: right; } } } 10 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/text/_ellipsis.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/text/ellipsis' instead."; 2 | 3 | @import "../../typography/text/ellipsis"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/text/_nowrap.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/text/nowrap' instead."; 2 | 3 | @import "../../typography/text/nowrap"; 4 | -------------------------------------------------------------------------------- /src/sass/compass/utilities/text/_replacement.scss: -------------------------------------------------------------------------------- 1 | @warn "This import is deprecated. Use 'compass/typography/text/replacement' instead."; 2 | 3 | @import "../../typography/text/replacement"; 4 | -------------------------------------------------------------------------------- /src/sass/mixin/_animation.scss: -------------------------------------------------------------------------------- 1 | @mixin co-x-animation( 2 | $name, 3 | $duration: 1s, 4 | $timingFunction: linear, 5 | $delay: 0, 6 | $direction: normal, 7 | $iterationCount: 1, 8 | $fillMode: forwards, 9 | $playState: running) { 10 | 11 | animation-name: $name; 12 | animation-duration: $duration; 13 | animation-timing-function: $timingFunction; 14 | animation-delay: $delay; 15 | animation-direction: $direction; 16 | animation-iteration-count: $iterationCount; 17 | animation-fill-mode: $fillMode; 18 | animation-play-state: $playState; 19 | 20 | -webkit-animation-name: $name; 21 | -webkit-animation-duration: $duration; 22 | -webkit-animation-timing-function: $timingFunction; 23 | -webkit-animation-delay: $delay; 24 | -webkit-animation-direction: $direction; 25 | -webkit-animation-iteration-count: $iterationCount; 26 | -webkit-animation-fill-mode: $fillMode; 27 | -webkit-animation-play-state: $playState; 28 | 29 | -moz-animation-name: $name; 30 | -moz-animation-duration: $duration; 31 | -moz-animation-timing-function: $timingFunction; 32 | -moz-animation-delay: $delay; 33 | -moz-animation-direction: $direction; 34 | -moz-animation-iteration-count: $iterationCount; 35 | -moz-animation-fill-mode: $fillMode; 36 | -moz-animation-play-state: $playState; 37 | } 38 | 39 | @mixin co-x-animation-transform-origin( 40 | $x: 50%, 41 | $y: 50%) { 42 | -webkit-transform-origin: $x $y; 43 | -moz-transform-origin: $x $y; 44 | -ms-transform-origin: $x $y; 45 | -o-transform-origin: $x $y; 46 | } -------------------------------------------------------------------------------- /src/sass/mixin/_clearfix.scss: -------------------------------------------------------------------------------- 1 | // Clearfix 2 | // Source: https://github.com/twbs/bootstrap-sass/blob/master/assets/stylesheets/bootstrap/mixins/_clearfix.scss 3 | // 4 | // For modern browsers 5 | // 1. The space content is one way to avoid an Opera bug when the 6 | // contenteditable attribute is included anywhere else in the document. 7 | // Otherwise it causes space to appear at the top and bottom of elements 8 | // that are clearfixed. 9 | // 2. The use of `table` rather than `block` is only necessary if using 10 | // `:before` to contain the top-margins of child elements. 11 | @mixin clearfix() { 12 | &:before, 13 | &:after { 14 | content: " "; /* 1 */ 15 | display: table; /* 2 */ 16 | } 17 | &:after { 18 | clear: both; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/sass/mixin/_custom-font.scss: -------------------------------------------------------------------------------- 1 | @mixin co-x-custom-font( 2 | $font-family, 3 | $font-filename, 4 | $font-weight : normal, 5 | $font-style :normal, 6 | $font-stretch : normal 7 | ) { 8 | @font-face { 9 | font-family: '#{$font-family}'; 10 | src: url('#{$font-path}/#{$font-filename}.eot'); 11 | src: url('#{$font-path}/#{$font-filename}.eot?#iefix') format('embedded-opentype'), 12 | url('#{$font-path}/#{$font-filename}.woff') format('woff'), 13 | url('#{$font-path}/#{$font-filename}.ttf') format('truetype'), 14 | url('#{$font-path}/#{$font-filename}.svg##{$font-family}') format('svg'); 15 | font-weight: $font-weight; 16 | font-style: $font-style; 17 | font-stretch: $font-stretch; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/sass/mixin/_keyframes.scss: -------------------------------------------------------------------------------- 1 | // keyframes mixin 2 | @mixin co-x-keyframes($name) { 3 | @-webkit-keyframes #{$name} { 4 | @content; 5 | } 6 | @-moz-keyframes #{$name} { 7 | @content; 8 | } 9 | @-ms-keyframes #{$name} { 10 | @content; 11 | } 12 | @keyframes #{$name} { 13 | @content; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/sass/mixin/_media-query.scss: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * $size is one of: xs, sm, md, lg. 4 | * Use variables from _config.scss. 5 | */ 6 | @mixin co-x-media-min($size) { 7 | @media (min-width: $size) { 8 | @content; 9 | } 10 | } 11 | 12 | @mixin co-x-media-max($size) { 13 | @media (max-width: $size) { 14 | @content; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/sass/mixin/_prefix.scss: -------------------------------------------------------------------------------- 1 | // Generic mixin to apply vendor prefixes an arbitrary CSS properties. 2 | 3 | @mixin co-x-prefix($property, $value) { 4 | #{$property}: $value; 5 | -webkit-#{$property}: $value; 6 | -moz-#{$property}: $value; 7 | -ms-#{$property}: $value; 8 | -o-#{$property}: $value; 9 | } 10 | -------------------------------------------------------------------------------- /src/svg/globe-only.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 10 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/svg/google-plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/svg/google-plus.png -------------------------------------------------------------------------------- /src/svg/icon-add.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/svg/icon-back.svg: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /src/svg/icon-delete.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/svg/icon-reboot.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 9 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/svg/icon-right-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/ui/btn-bar/btn-bar.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | -------------------------------------------------------------------------------- /src/ui/btn-bar/btn-bar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Wrap buttons and automatically enable/disbale and show loading indicator. 4 | */ 5 | 6 | angular.module('coreos.ui') 7 | .directive('coBtnBar', function($, $timeout, $compile) { 8 | 'use strict'; 9 | 10 | return { 11 | templateUrl: '/coreos.ui/btn-bar/btn-bar.html', 12 | restrict: 'EA', 13 | transclude: true, 14 | replace: true, 15 | scope: { 16 | // A promise that indicates completion of async operation. 17 | 'completePromise': '=' 18 | }, 19 | link: function(scope, elem) { 20 | var linkButton, 21 | loaderDirectiveEl; 22 | 23 | linkButton = $('.btn-link', elem).last(); 24 | loaderDirectiveEl = 25 | angular.element(''); 26 | $compile(loaderDirectiveEl)(scope); 27 | 28 | function disableButtons() { 29 | elem.append(loaderDirectiveEl); 30 | $('button', elem).attr('disabled', 'disabled'); 31 | linkButton.addClass('hidden'); 32 | } 33 | 34 | function enableButtons() { 35 | loaderDirectiveEl.remove(); 36 | $('button', elem).removeAttr('disabled'); 37 | linkButton.removeClass('hidden'); 38 | } 39 | 40 | scope.$watch('completePromise', function(completePromise) { 41 | if (completePromise) { 42 | // Force async execution so disabling the button won't prevent form 43 | // submission. 44 | $timeout(disableButtons, 0); 45 | completePromise.finally(function() { 46 | // Also enable buttons asynchronously in case the request completes 47 | // before disableButtons() runs. 48 | $timeout(enableButtons, 0); 49 | }); 50 | } 51 | }); 52 | } 53 | 54 | }; 55 | 56 | }); 57 | -------------------------------------------------------------------------------- /src/ui/click-nav/click-nav.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple directive to navigate to a route when the 3 | * element is clicked on. 4 | */ 5 | 6 | angular.module('coreos.ui') 7 | .directive('coClickNav', function($location) { 8 | 'use strict'; 9 | 10 | return { 11 | restrict: 'A', 12 | link: function(scope, elem, attrs) { 13 | function onClickHandler(event) { 14 | $location.url(attrs.coClickNav); 15 | scope.$apply(); 16 | event.preventDefault(); 17 | event.stopPropagation(); 18 | } 19 | elem.on('click', onClickHandler); 20 | elem.on('$destroy', function() { 21 | elem.off('click', onClickHandler); 22 | }); 23 | } 24 | }; 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /src/ui/cog/_cog.scss: -------------------------------------------------------------------------------- 1 | .co-m-cog { 2 | position: relative; 3 | color: $gray; 4 | display: inline-block; 5 | &:hover { 6 | cursor: pointer; 7 | } 8 | &.open .co-m-cog__icon { 9 | color: $color-cog-active; 10 | } 11 | } 12 | 13 | .co-m-cog-wrapper { 14 | display: inline-block; 15 | } 16 | 17 | // icon 18 | .co-m-cog__icon { 19 | vertical-align: middle; 20 | } 21 | .co-m-cog__icon--size-large { 22 | font-size: 20px; 23 | } 24 | .co-m-cog__icon--size-small { 25 | font-size: 16px; 26 | } 27 | 28 | // dropdown. uib-dropdown and class templates clobber each other, so 29 | // we use a descendant tag here 30 | .co-m-cog--anchor-left .co-m-cog__dropdown { 31 | left: 0px; 32 | right: auto; 33 | } 34 | 35 | .co-m-cog--anchor-right .co-m-cog__dropdown { 36 | right: 0px; 37 | left: auto; 38 | } 39 | -------------------------------------------------------------------------------- /src/ui/cog/cog.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
    5 |
  • 6 | 7 |
  • 8 |
9 |
10 |
11 | -------------------------------------------------------------------------------- /src/ui/cog/cog.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Display a cog icon and construct dropdown menu. 4 | */ 5 | 6 | 7 | angular.module('coreos.ui') 8 | .directive('coCog', function($location) { 9 | 'use strict'; 10 | 11 | return { 12 | templateUrl: '/coreos.ui/cog/cog.html', 13 | restrict: 'E', 14 | replace: true, 15 | scope: { 16 | 'options': '=', 17 | 'size': '@', 18 | 'anchor': '@' 19 | }, 20 | controller: function($scope) { 21 | $scope.status = { 22 | isopen: false, 23 | }; 24 | 25 | // Capture all clicks on the cog to prevent bubbling. 26 | $scope.captureClick = function($event) { 27 | $event.stopPropagation(); 28 | }; 29 | 30 | // Handles dropdown item clicks. 31 | $scope.clickHandler = function($event, option) { 32 | $event.preventDefault(); 33 | $event.stopPropagation(); 34 | if (option.callback) { 35 | option.callback(); 36 | } else if (option.href) { 37 | $location.url(option.href); 38 | } 39 | $scope.status.isopen = false; 40 | }; 41 | } 42 | }; 43 | 44 | }); 45 | -------------------------------------------------------------------------------- /src/ui/date-range/_date-range.scss: -------------------------------------------------------------------------------- 1 | .co-m-date-range { 2 | margin: 10px 0; 3 | } 4 | 5 | .co-m-date-range-custom { 6 | .glyphicon { 7 | color: $color-icon-dark; 8 | } 9 | a .glyphicon { 10 | color: $blue-link; 11 | } 12 | } 13 | 14 | .co-m-date-range-custom__date-picker { 15 | tbody .btn { 16 | border-radius: 0; 17 | padding: 2px; 18 | width: 20px; 19 | } 20 | } 21 | 22 | .co-m-date-range-custom__utc-toggle { 23 | margin: 20px 0 10px 0; 24 | } 25 | 26 | .co-m-date-range__utc-toggle { 27 | display: inline-block; 28 | cursor: pointer; 29 | line-height: 30px; 30 | } 31 | 32 | .co-m-date-range-custom__selectors { 33 | .uib-dropdown-menu { 34 | margin: 0; 35 | padding: 5px; 36 | border: none; 37 | .btn { 38 | @include border-radius(0); 39 | @include box-shadow(none); 40 | padding: 0; 41 | } 42 | table { 43 | min-width: 185px; 44 | } 45 | th .btn-default.pull-left , 46 | th .btn-default.pull-right { 47 | margin: 0; 48 | padding: 0 4px; 49 | } 50 | th { 51 | font-weight: 400; 52 | padding: 4px 0; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/ui/date-range/date-range.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 7 | 12 |
13 | 14 |
15 | -------------------------------------------------------------------------------- /src/ui/donut/donut.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | -------------------------------------------------------------------------------- /src/ui/dropdown/_dropdown.scss: -------------------------------------------------------------------------------- 1 | @import '_config'; 2 | 3 | .co-m-dropdown--dark { 4 | background-color: $color-bg-translucent-dark; 5 | border: solid 1px $color-bg-translucent-dark; 6 | 7 | // Super-specific for bootstrap overrides. 8 | > li > a { 9 | color: $white; 10 | &:hover { 11 | background-color: $color-bg-translucent-dark; 12 | color: $white; 13 | } 14 | } 15 | 16 | // Mobile overrides 17 | @include co-x-media-max($screen-sm) { 18 | > li > a { 19 | color: $blue-link; 20 | &:hover { 21 | background-color: $color-bg-mute; 22 | color: $blue-link; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/ui/error-message/error-message.html: -------------------------------------------------------------------------------- 1 |
{{message}}
2 | -------------------------------------------------------------------------------- /src/ui/error-message/error-message.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Displays a message based on a promise. 4 | */ 5 | 6 | angular.module('coreos.ui') 7 | 8 | .provider('errorMessageSvc', function() { 9 | 'use strict'; 10 | 11 | var formatters = {}; 12 | 13 | this.registerFormatter = function(name, fn) { 14 | formatters[name] = fn; 15 | }; 16 | 17 | this.$get = function() { 18 | return { 19 | getFormatter: function(name) { 20 | return formatters[name] || angular.noop; 21 | } 22 | }; 23 | }; 24 | 25 | }) 26 | 27 | .directive('coErrorMessage', function(errorMessageSvc) { 28 | 'use strict'; 29 | 30 | return { 31 | templateUrl: '/coreos.ui/error-message/error-message.html', 32 | restrict: 'E', 33 | replace: true, 34 | scope: { 35 | promise: '=', 36 | formatter: '@', 37 | customMessage: '@message' 38 | }, 39 | controller: function postLink($scope) { 40 | $scope.show = false; 41 | 42 | function handler(resp) { 43 | if ($scope.formatter) { 44 | $scope.message = 45 | errorMessageSvc.getFormatter($scope.formatter)(resp); 46 | } else if ($scope.customMessage) { 47 | $scope.message = $scope.customMessage; 48 | } else { 49 | return; 50 | } 51 | $scope.show = true; 52 | } 53 | 54 | $scope.$watch('promise', function(promise) { 55 | $scope.show = false; 56 | if (promise && promise.catch) { 57 | promise.catch(handler); 58 | } 59 | }); 60 | 61 | } 62 | }; 63 | 64 | }); 65 | -------------------------------------------------------------------------------- /src/ui/facet-menu/_facet-menu.scss: -------------------------------------------------------------------------------- 1 | .co-m-facet-menu { 2 | margin-bottom: 30px; 3 | } 4 | 5 | .co-m-facet-menu__title, 6 | .co-m-facet-menu-option { 7 | font-size: 80%; 8 | } 9 | 10 | .co-m-facet-menu__title { 11 | text-transform: uppercase; 12 | color: $gray; 13 | padding: 4px; 14 | font-weight: 300; 15 | } 16 | 17 | .co-m-facet-menu__option-list { 18 | list-style: none; 19 | padding: 0; 20 | margin: 0; 21 | border-bottom: 1px solid $gray-lighter; 22 | max-height: 300px; 23 | overflow: scroll; 24 | } 25 | 26 | .co-m-facet-menu-option { 27 | padding: 8px 15px 8px 8px; 28 | cursor: pointer; 29 | border-top: 1px solid $gray-lighter; 30 | &.co-m-facet-option--active, 31 | &:hover { 32 | background-color: $color-table-active; 33 | } 34 | &.co-m-facet-option--active { 35 | background: url($img-path + '/icon-right-arrow.svg') right 10px center no-repeat $color-table-active; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ui/facet-menu/facet-menu-option.html: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 |
  • 4 | -------------------------------------------------------------------------------- /src/ui/facet-menu/facet-menu.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
      4 |
      5 | -------------------------------------------------------------------------------- /src/ui/facet-menu/facet-menu.js: -------------------------------------------------------------------------------- 1 | 2 | angular.module('coreos.ui') 3 | .directive('coFacetMenu', function() { 4 | 'use strict'; 5 | 6 | return { 7 | templateUrl: '/coreos.ui/facet-menu/facet-menu.html', 8 | transclude: true, 9 | restrict: 'E', 10 | replace: true, 11 | scope: { 12 | title: '@', 13 | model: '=' 14 | }, 15 | controller: function($scope) { 16 | this.getValue = function() { 17 | return $scope.model; 18 | }; 19 | this.setValue = function(val) { 20 | $scope.model = val; 21 | }; 22 | } 23 | }; 24 | }) 25 | 26 | 27 | .directive('coFacetMenuOption', function() { 28 | 'use strict'; 29 | 30 | return { 31 | templateUrl: '/coreos.ui/facet-menu/facet-menu-option.html', 32 | transclude: true, 33 | restrict: 'E', 34 | replace: true, 35 | require: '^coFacetMenu', 36 | scope: { 37 | value: '@' 38 | }, 39 | link: function(scope, elem, attr, facetMenuCtrl) { 40 | elem.on('click', function(e) { 41 | scope.$apply(function() { 42 | facetMenuCtrl.setValue(scope.value); 43 | }); 44 | e.preventDefault(); 45 | e.stopPropagation(); 46 | }); 47 | 48 | scope.$watch(function() { 49 | return facetMenuCtrl.getValue(); 50 | }, function(val) { 51 | scope.isActive = scope.value === val; 52 | }); 53 | } 54 | }; 55 | }); 56 | -------------------------------------------------------------------------------- /src/ui/favicons/favicons.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coreos/coreos-web/2807962ad887c94c5dcd6b009dd86cdaf8b25a58/src/ui/favicons/favicons.html -------------------------------------------------------------------------------- /src/ui/favicons/favicons.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Inject favicons into the . 4 | * Only use on tag. 5 | */ 6 | 7 | 8 | angular.module('coreos.ui') 9 | 10 | .directive('coFavicons', function($compile, $rootScope, configSvc) { 11 | 'use strict'; 12 | /*eslint max-len:0 */ 13 | 14 | return { 15 | restrict: 'A', 16 | replace: true, 17 | link: function postLink(scope, elem) { 18 | var newScope = $rootScope.$new(), 19 | htmlTemplate = 20 | '' + 21 | '' + 22 | '' + 23 | '' + 24 | ''; 25 | newScope.path = configSvc.get('libPath') + '/img'; 26 | elem.append($compile(htmlTemplate)(newScope)); 27 | } 28 | }; 29 | 30 | }); 31 | 32 | /* 33 | */ 34 | -------------------------------------------------------------------------------- /src/ui/footer/_footer-link.scss: -------------------------------------------------------------------------------- 1 | .co-m-footer-link { 2 | font-size: 81%; 3 | margin-right: 20px; 4 | line-height: 41px; 5 | &:hover { 6 | text-decoration: none; 7 | } 8 | } 9 | 10 | .co-m-footer-link--icon { 11 | padding-right: 5px; 12 | color: $color-footer-icons; 13 | } 14 | -------------------------------------------------------------------------------- /src/ui/footer/_footer.scss: -------------------------------------------------------------------------------- 1 | @include sticky-footer($height-footer, '#co-l-footer-wrapper', '#co-l-footer-push', '#co-l-footer'); 2 | 3 | #co-l-footer { 4 | background-color: $color-bg-primary; 5 | margin: 0; 6 | min-height: $height-footer; 7 | overflow: hidden; 8 | } 9 | -------------------------------------------------------------------------------- /src/ui/footer/footer-link.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/ui/footer/footer-wrapper.html: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /src/ui/footer/footer.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/ui/footer/footer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Standard CoreOS footer. 4 | * 5 | */ 6 | 7 | angular.module('coreos.ui') 8 | 9 | .directive('coFooter', function() { 10 | 'use strict'; 11 | 12 | return { 13 | templateUrl: '/coreos.ui/footer/footer.html', 14 | transclude: true, 15 | restrict: 'E', 16 | replace: true 17 | }; 18 | }) 19 | 20 | .directive('coFooterLink', function() { 21 | 'use strict'; 22 | 23 | return { 24 | templateUrl: '/coreos.ui/footer/footer-link.html', 25 | transclude: true, 26 | restrict: 'E', 27 | replace: true, 28 | scope: { 29 | href: '@', 30 | iconClass: '@' 31 | } 32 | }; 33 | }) 34 | 35 | 36 | /** 37 | * Convenience wrapper for doing sticky footers. 38 | */ 39 | .directive('coFooterWrapper', function() { 40 | 'use strict'; 41 | 42 | return { 43 | templateUrl: '/coreos.ui/footer/footer-wrapper.html', 44 | transclude: true, 45 | restrict: 'E', 46 | replace: true 47 | }; 48 | 49 | }); 50 | -------------------------------------------------------------------------------- /src/ui/forms/_forms.scss: -------------------------------------------------------------------------------- 1 | input[type="number"] { 2 | max-width: 100px; 3 | -moz-appearance: textfield; 4 | -webkit-appearance: textfield; 5 | appearance: textfield; 6 | &::-webkit-inner-spin-button, 7 | &::-webkit-outer-spin-button { 8 | margin: 0; 9 | } 10 | } 11 | 12 | input[type="radio"] { 13 | margin-right: 5px; 14 | } 15 | 16 | // angular-specific classes 17 | .ng-dirty.ng-invalid { 18 | border-color: $red; 19 | border-bottom-left-radius: 0px; 20 | border-bottom-right-radius: 0px; 21 | } 22 | 23 | .co-m-radio-desc { 24 | margin-left: 23px; 25 | } 26 | 27 | .co-m-inline-field { 28 | display: inline-block; 29 | margin-right: 15px; 30 | } 31 | 32 | .co-m-form-row, 33 | .form-row { 34 | margin-bottom: 20px; 35 | } 36 | 37 | .co-m-form-row:last-child { 38 | margin-bottom: 0px; 39 | } 40 | 41 | .co-m-form-col { 42 | max-width: 600px; 43 | } 44 | 45 | .co-m-form-field-xs { 46 | max-width: 100px; 47 | } 48 | 49 | .co-m-form-field-sm { 50 | max-width: 150px; 51 | } 52 | 53 | .co-m-form-field-md { 54 | max-width: 215px; 55 | } 56 | 57 | .co-m-form-field-lg { 58 | max-width: 300px; 59 | } 60 | -------------------------------------------------------------------------------- /src/ui/gauge/_gauge.scss: -------------------------------------------------------------------------------- 1 | .co-m-gauges { 2 | padding: 0 15px 20px 15px; 3 | } 4 | 5 | .co-m-gauge { 6 | display: inline-block; 7 | text-align: center; 8 | vertical-align: top; 9 | padding: 10px 20px; 10 | min-width: 145px; 11 | } 12 | 13 | .co-m-gauge__content { 14 | display: inline-block; 15 | min-height: 92px; 16 | } 17 | 18 | .co-m-gauge__label { 19 | text-align: center; 20 | line-height: 1.2em; 21 | font-size: 85%; 22 | } 23 | -------------------------------------------------------------------------------- /src/ui/highlight/highlight.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Highlight an item when its bound data changes. 4 | */ 5 | 6 | 7 | angular.module('coreos.ui') 8 | .directive('coHighlight', function(highlighterSvc) { 9 | 'use strict'; 10 | 11 | return { 12 | restrict: 'A', 13 | link: function(scope, elem, attrs) { 14 | 15 | scope.$watch(attrs.coHighlight, function(newValue, oldValue) { 16 | if (newValue !== oldValue) { 17 | highlighterSvc.highlight(elem); 18 | } 19 | }); 20 | 21 | } 22 | }; 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /src/ui/input/_invisible-input.scss: -------------------------------------------------------------------------------- 1 | .co-m-invisible-input { 2 | border: 0; 3 | background: none; 4 | width: 100%; 5 | outline: 0; 6 | &:hover { 7 | cursor: copy; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/ui/link/_modal-link.scss: -------------------------------------------------------------------------------- 1 | .co-m-modal-link { 2 | position: relative; 3 | padding-right: 9px; 4 | 5 | &:after { 6 | content: "\203a"; 7 | font-weight: 900; 8 | color: $gray; 9 | font-size: 112%; 10 | position: absolute; 11 | bottom: 0px; 12 | right: 0px; 13 | pointer-events: none; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/ui/loader/_loader.scss: -------------------------------------------------------------------------------- 1 | .co-m-loader, 2 | .co-m-inline-loader { 3 | min-width: 28px; 4 | } 5 | 6 | .co-m-loader { 7 | display: block; 8 | position: absolute; 9 | left: 50%; 10 | top: 50%; 11 | margin: -11px 0 0 -13px; 12 | } 13 | 14 | .co-m-inline-loader { 15 | display: inline-block; 16 | // For when combined with the [btn-link] class. 17 | cursor: default; 18 | &:hover { 19 | text-decoration: none; 20 | } 21 | } 22 | 23 | .co-m-loader-dot__one, 24 | .co-m-loader-dot__two, 25 | .co-m-loader-dot__three { 26 | @include border-radius(3px); 27 | // Prevent first frame from flickering when animation starts 28 | @include co-x-prefix(animation-fill-mode, both); 29 | @include co-x-animation( 30 | $name: bouncedelay, 31 | $duration: 1s, 32 | $timingFunction: ease-in-out, 33 | $delay: 0, 34 | $direction: normal, 35 | $iterationCount: infinite 36 | ); 37 | display: inline-block; 38 | height: 6px; 39 | width: 6px; 40 | background: $color-inline-loader; 41 | border-radius: 100%; 42 | display: inline-block; 43 | } 44 | 45 | .co-m-loader-dot__one { 46 | @include co-x-prefix(animation-delay, -0.32s); 47 | } 48 | 49 | .co-m-loader-dot__two { 50 | @include co-x-prefix(animation-delay, -0.16s); 51 | } 52 | 53 | @include co-x-keyframes(bouncedelay) { 54 | 0%, 80%, 100% { 55 | @include scale(0.25, 0.25); 56 | } 40% { 57 | @include scale(1.0, 1.0); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/ui/loader/inline-loader.html: -------------------------------------------------------------------------------- 1 |
      2 |
      3 |
      4 |
      5 |
      6 | -------------------------------------------------------------------------------- /src/ui/loader/loader.html: -------------------------------------------------------------------------------- 1 |
      2 |
      3 |
      4 |
      5 |
      6 | -------------------------------------------------------------------------------- /src/ui/loader/loader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * 4 | * Loading indicator that centers itself inside its parent. 5 | */ 6 | 7 | angular.module('coreos.ui') 8 | 9 | .directive('coLoader', function() { 10 | 'use strict'; 11 | 12 | return { 13 | templateUrl: '/coreos.ui/loader/loader.html', 14 | restrict: 'E', 15 | replace: true 16 | }; 17 | }) 18 | 19 | .directive('coInlineLoader', function() { 20 | 'use strict'; 21 | 22 | return { 23 | templateUrl: '/coreos.ui/loader/inline-loader.html', 24 | restrict: 'E', 25 | replace: true 26 | }; 27 | }); 28 | -------------------------------------------------------------------------------- /src/ui/message/_message.scss: -------------------------------------------------------------------------------- 1 | .co-m-message { 2 | @include border-radius(1px); 3 | padding: 5px 0px 5px 10px; 4 | color: $white; 5 | font-size: 81%; 6 | } 7 | 8 | .co-m-message__close { 9 | margin-top: 1px; 10 | margin-right: 8px; 11 | &:hover { 12 | cursor: pointer; 13 | } 14 | } 15 | 16 | .co-m-message--error { 17 | background-color: $color-message-error-bg; 18 | } 19 | 20 | .co-m-message--info { 21 | background-color: $color-message-info-bg; 22 | } 23 | -------------------------------------------------------------------------------- /src/ui/nav-active/nav-active.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Adds an active class to
    • tags where a[href], a[ng-href], or 3 | * a[co-active-match] matches the current url path. Removes any 4 | * angular interpolated values. 5 | * 6 | * Assumes a structure of: 7 | * 8 | * 13 | */ 14 | 15 | angular.module('coreos.ui') 16 | .directive('coNavActive', function($, _, $location) { 17 | 'use strict'; 18 | 19 | // Regex to match angular interpolation vlues. 20 | var ngVarMatchRE = /{{2}[^}]*}{2}/g; 21 | 22 | return { 23 | restrict: 'A', 24 | link: function postLink(scope, elem, attrs) { 25 | 26 | function isActive(href) { 27 | var hrefParts, currParts; 28 | currParts = $location.path().split('/'); 29 | hrefParts = href.replace(ngVarMatchRE, '').split('/'); 30 | if (currParts.length !== hrefParts.length) { 31 | return false; 32 | } 33 | return _.every(currParts, function(part, index) { 34 | return hrefParts[index] === '' || part === hrefParts[index]; 35 | }); 36 | } 37 | 38 | $('a', elem).each(function() { 39 | var a = $(this), 40 | href = a.attr('co-active-match') || a.attr('href') || a.attr('ng-href'); 41 | if (isActive(href)) { 42 | a.parent().addClass(attrs.coNavActive); 43 | return; 44 | } 45 | }); 46 | 47 | } 48 | }; 49 | 50 | }); 51 | -------------------------------------------------------------------------------- /src/ui/nav-title/_nav-title.scss: -------------------------------------------------------------------------------- 1 | .co-m-nav-title { 2 | line-height: 60px; 3 | margin: 0; 4 | } 5 | -------------------------------------------------------------------------------- /src/ui/nav-title/nav-title.html: -------------------------------------------------------------------------------- 1 |
      2 |
      3 |
      4 |

      5 |
      6 |
      7 | -------------------------------------------------------------------------------- /src/ui/nav-title/nav-title.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Display page title with primary action link. 4 | */ 5 | 6 | angular.module('coreos.ui') 7 | .directive('coNavTitle', function() { 8 | 'use strict'; 9 | 10 | return { 11 | templateUrl: '/coreos.ui/nav-title/nav-title.html', 12 | transclude: true, 13 | restrict: 'E', 14 | replace: true, 15 | scope: { 16 | title: '@' 17 | } 18 | }; 19 | }); 20 | -------------------------------------------------------------------------------- /src/ui/navbar/_navbar-link.scss: -------------------------------------------------------------------------------- 1 | .co-m-navbar-link { 2 | cursor: pointer; 3 | font-size: $font-size-lg; 4 | font-weight: 400; 5 | } 6 | -------------------------------------------------------------------------------- /src/ui/navbar/_navbar.scss: -------------------------------------------------------------------------------- 1 | .co-m-navbar { 2 | background-color: $color-bg-primary; 3 | margin: 0; 4 | padding-left: 10px; 5 | } 6 | 7 | .co-m-navbar__logo { 8 | width: 129px; 9 | height: 30px; 10 | line-height: 64px; 11 | } 12 | 13 | .co-m-navbar--right-dropdown:hover { 14 | cursor: pointer; 15 | } 16 | -------------------------------------------------------------------------------- /src/ui/navbar/navbar-dropdown.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /src/ui/navbar/navbar-link.html: -------------------------------------------------------------------------------- 1 |
    • 4 | -------------------------------------------------------------------------------- /src/ui/navbar/navbar.html: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /src/ui/navbar/navbar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Top navbar which inlcudes nav links. 4 | */ 5 | 6 | angular.module('coreos.ui') 7 | 8 | .directive('coNavbar', function(configSvc) { 9 | 'use strict'; 10 | 11 | return { 12 | templateUrl: '/coreos.ui/navbar/navbar.html', 13 | transclude: true, 14 | restrict: 'E', 15 | replace: true, 16 | scope: { 17 | logoSrc: '@', 18 | }, 19 | controller: function($scope) { 20 | $scope.config = configSvc.get(); 21 | $scope.isCollapsed = true; 22 | } 23 | }; 24 | 25 | }) 26 | 27 | 28 | /** 29 | * Simple directive to create bootstrap friendly navbar links. 30 | * Will automatically add the 'active' class based on the route. 31 | */ 32 | .directive('coNavbarLink', function($location) { 33 | 'use strict'; 34 | 35 | return { 36 | templateUrl: '/coreos.ui/navbar/navbar-link.html', 37 | transclude: true, 38 | restrict: 'E', 39 | replace: true, 40 | scope: { 41 | // The path to link to. 42 | 'href': '@' 43 | }, 44 | link: function(scope) { 45 | scope.isActive = function() { 46 | return $location.path() === scope.href; 47 | }; 48 | } 49 | }; 50 | 51 | }) 52 | 53 | /** 54 | * Optional dropdown menu to put in the right of the navbar. 55 | */ 56 | .directive('coNavbarDropdown', function() { 57 | 'use strict'; 58 | 59 | return { 60 | templateUrl: '/coreos.ui/navbar/navbar-dropdown.html', 61 | transclude: true, 62 | restrict: 'E', 63 | replace: true, 64 | scope: { 65 | text: '@', 66 | pullRight: '=', 67 | pullRightClass: '@' 68 | }, 69 | controller: function($scope) { 70 | if ($scope.pullRight) { 71 | $scope.pullRightClass = 'pull-right'; 72 | } 73 | }, 74 | }; 75 | 76 | }); 77 | -------------------------------------------------------------------------------- /src/ui/notice/_notice.scss: -------------------------------------------------------------------------------- 1 | .co-m-notice { 2 | min-height: 100px; 3 | } 4 | 5 | .co-m-notice__title { 6 | font-size: 18px; 7 | line-height: 18px; 8 | margin: 20px; 9 | text-align: center; 10 | } 11 | 12 | .co-m-notice__message { 13 | font-size: 14px; 14 | line-height: 14px; 15 | color: $color-text-muted; 16 | max-width: 500px; 17 | margin: 0 auto; 18 | } 19 | -------------------------------------------------------------------------------- /src/ui/page-title/_page-title.scss: -------------------------------------------------------------------------------- 1 | .co-m-page-title { 2 | color: $color-text-light; 3 | font-weight: 400; 4 | letter-spacing: -.03em; 5 | text-align: center; 6 | margin: 0; 7 | line-height: inherit; 8 | font-size: 225%; 9 | } 10 | -------------------------------------------------------------------------------- /src/ui/pane/_pane.scss: -------------------------------------------------------------------------------- 1 | // Use this instead of co-m-panel 2 | // See examples page for common usages. 3 | 4 | // Top-level pane element. 5 | .co-m-pane { 6 | @extend .co-fx-box-shadow-heavy; 7 | background-color: $color-bg-primary; 8 | margin-bottom: 20px; 9 | min-height: 200px; 10 | } 11 | 12 | // Common heading with full padding on all sides. 13 | .co-m-pane__heading, 14 | .co-m-pane__heading--bordered { 15 | padding: 30px; 16 | } 17 | 18 | // Same as 'heading' but with a border separator. 19 | .co-m-pane__heading--bordered { 20 | border-bottom: solid 1px $color-border; 21 | } 22 | 23 | // Heading when bottom padding is not desired. 24 | .co-m-pane__heading-short { 25 | padding: 30px 30px 0 30px; 26 | } 27 | 28 | // Title element. 29 | .co-m-pane__title { 30 | line-height: 24px; 31 | margin: 0; 32 | } 33 | 34 | // Standard body element with no inner sections. 35 | .co-m-pane__body, 36 | .co-m-pane__body--bordered { 37 | padding: 30px 30px 30px 30px; 38 | } 39 | 40 | .co-m-pane__body--bordered { 41 | border-bottom: solid 1px $color-border; 42 | } 43 | 44 | // Wrapper for 'body-section' elements. 45 | .co-m-pane__body-group { 46 | padding: 0 0 30px 0; 47 | 48 | .co-m-pane__body-section, 49 | .co-m-pane__body-section--bordered { 50 | padding: 15px 30px; 51 | &:first-child { 52 | padding-top: 0; 53 | } 54 | &:last-child { 55 | padding-bottom: 0; 56 | } 57 | } 58 | 59 | // Same as 'body-section' but with a border separator. 60 | .co-m-pane__body-section--bordered { 61 | border-top: solid 1px $color-border; 62 | &:first-child { 63 | border-top: none; 64 | } 65 | } 66 | 67 | } 68 | 69 | // If no heading is present, add top padding to body element. 70 | .co-m-pane__heading + .co-m-pane__body, 71 | .co-m-pane__heading--bordered + .co-m-pane__body { 72 | padding-top: 0; 73 | } 74 | 75 | // If the heading has a border make sure the first section gets top padding too. 76 | .co-m-pane__heading--bordered + .co-m-pane__body-group { 77 | > .co-m-pane__body-section:first-child, 78 | > .co-m-pane__body-section--bordered:first-child { 79 | padding-top: 15px; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/ui/panel/_panel.scss: -------------------------------------------------------------------------------- 1 | // DEPRECATED, use co-m-pane instead 2 | 3 | .co-m-panel, 4 | .co-m-panel-padded { 5 | min-height: 200px; 6 | 7 | h1, h2, h3, h4 { 8 | margin-top: 0; 9 | } 10 | 11 | .panel-heading { 12 | background-color: $color-bg-primary; 13 | padding: 30px; 14 | 15 | h1, h2, h3, h4 { 16 | margin: 0; 17 | } 18 | h4 { 19 | line-height: 24px; 20 | } 21 | } 22 | 23 | .co-m-panel-body-content { 24 | padding: 0 15px 30px 15px; 25 | } 26 | 27 | .co-m-panel-content-left { 28 | padding: 30px; 29 | border-bottom: solid 1px $color-border; 30 | } 31 | 32 | .co-m-panel-content-right { 33 | padding: 30px; 34 | } 35 | 36 | @include co-x-media-min($screen-lg-min) { 37 | .co-m-panel-content-right { 38 | border-left: solid 1px $color-border; 39 | } 40 | 41 | .co-m-panel-content-left { 42 | border-bottom: none; 43 | } 44 | } 45 | 46 | } 47 | 48 | .co-m-panel-padded { 49 | .panel-body { 50 | padding-top: 0px; 51 | padding-bottom: 0px; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/ui/pie/_pie.scss: -------------------------------------------------------------------------------- 1 | .co-m-pie { 2 | display: inline-block; 3 | } 4 | 5 | .co-m-pie__labels > text { 6 | font-size: 12px; 7 | } 8 | 9 | .co-m-pie__lines > polyline { 10 | fill: none; 11 | stroke-width: 1; 12 | stroke-linecap: round; 13 | stroke: $gray-darker; 14 | } 15 | -------------------------------------------------------------------------------- /src/ui/pie/pie.html: -------------------------------------------------------------------------------- 1 |
      2 |
      3 | -------------------------------------------------------------------------------- /src/ui/primary-action/_primary-action.scss: -------------------------------------------------------------------------------- 1 | .co-m-primary-action { 2 | color: $white; 3 | font-size: $font-size-md; 4 | font-weight: 200; 5 | white-space: nowrap; 6 | cursor: pointer; 7 | &:hover, 8 | &:visited { 9 | color: $white; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/ui/signin/_google.scss: -------------------------------------------------------------------------------- 1 | .co-m-google-signin { 2 | } 3 | 4 | .co-m-google-signin__btn { 5 | display: inline-block; 6 | background: #dd4b39; 7 | border: none; 8 | color: white; 9 | width: 120px; 10 | border-radius: 3px; 11 | white-space: nowrap; 12 | &:hover { 13 | background: #e74b37; 14 | cursor: hand; 15 | } 16 | } 17 | 18 | .co-m-google-signin__icon { 19 | background: url($img-path + '/google-plus.png') transparent 0 50% no-repeat; 20 | display: inline-block; 21 | vertical-align: middle; 22 | width: 40px; 23 | height: 24px; 24 | border-right: #bb3f30 1px solid; 25 | } 26 | 27 | .co-m-google-signin__btn-text { 28 | display: inline-block; 29 | vertical-align: middle; 30 | padding: 0 8px; 31 | font-size: 12px; 32 | font-family: 'Roboto',arial,sans-serif; 33 | } 34 | -------------------------------------------------------------------------------- /src/ui/svg/_svg.scss: -------------------------------------------------------------------------------- 1 | .co-m-svg { 2 | display: inline-block; 3 | > svg { 4 | width: 100%; 5 | height: 100%; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/ui/svg/svg.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Directive to easily inline svg images. 4 | * NOTE: kind of a hack to get ng-include to work properly within a directive 5 | * without wrapping it with an extra DOM element. 6 | */ 7 | 8 | angular.module('coreos.ui') 9 | .directive('coSvg', function($, $rootScope, $compile) { 10 | 'use strict'; 11 | 12 | return { 13 | template: '
      ', 14 | restrict: 'E', 15 | replace: true, 16 | scope: { 17 | src: '@', 18 | width: '@', 19 | height: '@' 20 | }, 21 | link: function(scope, elem, attrs) { 22 | var containerEl, html, newScope; 23 | newScope = $rootScope.$new(); 24 | html = '
      '; 26 | newScope.style = {}; 27 | if (scope.width) { 28 | newScope.style.width = scope.width + 'px'; 29 | } 30 | if (scope.height) { 31 | newScope.style.height = scope.height + 'px'; 32 | } 33 | if (attrs.class) { 34 | newScope.classes = attrs.class; 35 | } 36 | scope.$watch('src', function(src) { 37 | if (src) { 38 | newScope.src = src; 39 | containerEl = $compile(html)(newScope); 40 | elem.replaceWith(containerEl); 41 | } 42 | }); 43 | } 44 | }; 45 | 46 | }); 47 | -------------------------------------------------------------------------------- /src/ui/table-grid/_table-grid.scss: -------------------------------------------------------------------------------- 1 | .co-m-table-grid { 2 | // All table-grid "rows" 3 | .row { 4 | font-size: 13px; 5 | line-height: 13px; 6 | margin: 0; 7 | } 8 | 9 | // All table-grid "rows" & "cells" 10 | .row, 11 | [class*='col-'] { 12 | vertical-align: middle; 13 | } 14 | 15 | .row.co-m-table-grid--clickable:hover { 16 | background-color: $blue-bg; 17 | cursor: pointer; 18 | } 19 | 20 | // Recursively indent nested tables. 21 | .co-m-table-grid { 22 | padding-left: 20px; 23 | } 24 | } 25 | 26 | .co-m-table-grid__body { 27 | min-height: 50px; 28 | position: relative; 29 | width: 100%; 30 | } 31 | 32 | // Default row padding 33 | .co-m-table-grid .co-m-table-grid__body .row { 34 | padding: 10px 0; 35 | } 36 | 37 | .co-m-table-grid--compact .co-m-table-grid__body .row { 38 | padding: 5px 0; 39 | } 40 | 41 | .co-m-table-grid--scroll { 42 | border: solid 1px $color-table-border; 43 | padding: 5px 15px; 44 | overflow-y: scroll; 45 | } 46 | 47 | .co-m-table-grid--bordered { 48 | .co-m-table-grid__head, 49 | .co-m-table-grid__body .row { 50 | border-bottom: solid 1px $color-table-border; 51 | } 52 | } 53 | 54 | // Heading rows. 55 | .co-m-table-grid__head { 56 | @extend .co-m-field-head; 57 | padding: 10px 0; 58 | } 59 | -------------------------------------------------------------------------------- /src/ui/table/_table.scss: -------------------------------------------------------------------------------- 1 | .co-m-table-container { 2 | display: block; 3 | width: 100%; 4 | } 5 | 6 | // Set another max-width if desired. 7 | .co-m-table__constrain-content { 8 | max-width: 300px; 9 | display: block; 10 | overflow: hidden; 11 | white-space: nowrap; 12 | text-overflow: ellipsis; 13 | } 14 | 15 | .co-m-table { 16 | 17 | .co-m-table-selected-row { 18 | background-position: right 10px center; 19 | background-repeat: no-repeat; 20 | padding-right: 15px; 21 | background-color: $color-table-active; 22 | } 23 | 24 | .co-m-table-interact-entire-element:hover { 25 | cursor: pointer; 26 | } 27 | 28 | } 29 | 30 | .co-m-stacked-cell { 31 | 32 | .co-m-stacked-cell-secondary, .co-m-stacked-cell-primary { 33 | line-height: 20px; 34 | } 35 | .co-m-stacked-cell-secondary { 36 | color: $color-text-muted; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/ui/text-copy/text-copy.js: -------------------------------------------------------------------------------- 1 | angular.module('coreos.ui') 2 | .directive('coTextCopy', function() { 3 | 'use strict'; 4 | 5 | return { 6 | restrict: 'A', 7 | replace: true, 8 | link: function(scope, elem) { 9 | function onClickHandler(event) { 10 | elem.select(); 11 | event.preventDefault(); 12 | event.stopPropagation(); 13 | } 14 | elem.on('click', onClickHandler); 15 | elem.on('$destroy', function() { 16 | elem.off('click', onClickHandler); 17 | }); 18 | } 19 | }; 20 | 21 | }); 22 | -------------------------------------------------------------------------------- /src/ui/title/title.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * 4 | * Keeps the title tag updated. 5 | */ 6 | 7 | angular.module('coreos.ui') 8 | .directive('coTitle', function() { 9 | 'use strict'; 10 | 11 | return { 12 | transclude: false, 13 | restrict: 'A', 14 | scope: { 15 | suffix: '@coTitleSuffix' 16 | }, 17 | controller: function($scope, $rootScope, $route) { 18 | $scope.pageTitle = ''; 19 | $scope.defaultTitle = null; 20 | $rootScope.$on('$routeChangeSuccess', function() { 21 | if (!$route.current) { 22 | return; 23 | } 24 | if ($route.current.title) { 25 | $scope.pageTitle = $route.current.title; 26 | } 27 | if ($route.current.$$route && $route.current.$$route.title) { 28 | $scope.pageTitle = $route.current.$$route.title; 29 | } 30 | }); 31 | }, 32 | link: function(scope, elem) { 33 | scope.$watch('pageTitle', function(title) { 34 | if (title) { 35 | if (!scope.defaultTitle) { 36 | scope.defaultTitle = elem.text(); 37 | } 38 | elem.text(title + ' ' + scope.suffix); 39 | } else { 40 | if (scope.defaultTitle) { 41 | elem.text(scope.defaultTitle); 42 | } 43 | } 44 | }); 45 | } 46 | }; 47 | 48 | }); 49 | -------------------------------------------------------------------------------- /src/ui/toast/_toast.scss: -------------------------------------------------------------------------------- 1 | .co-m-toast { 2 | position: fixed; 3 | top: 48px; 4 | margin: 0 auto; 5 | width: 100%; 6 | z-index: 1000; 7 | } 8 | 9 | .co-m-toast__message { 10 | margin: 0 auto; 11 | margin-bottom: 3px; 12 | } 13 | 14 | @include co-x-media-min($screen-sm-min) { 15 | .co-m-toast__message { 16 | width: 300px; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/ui/toast/toast.html: -------------------------------------------------------------------------------- 1 |
      2 |
      4 | {{message.text}} 5 | 6 |
      7 |
      8 | -------------------------------------------------------------------------------- /src/ui/toast/toast.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * Directive to display global error or info messages. 4 | * Enqueue messages through the toastSvc. 5 | */ 6 | 7 | 8 | 9 | angular.module('coreos.ui') 10 | .directive('coToast', function() { 11 | 'use strict'; 12 | 13 | return { 14 | templateUrl: '/coreos.ui/toast/toast.html', 15 | restrict: 'E', 16 | replace: true, 17 | scope: true, 18 | controller: function($scope, toastSvc) { 19 | $scope.messages = toastSvc.messages; 20 | $scope.dismiss = toastSvc.dismiss; 21 | } 22 | }; 23 | }); 24 | 25 | 26 | angular.module('coreos.services') 27 | .factory('toastSvc', function($timeout) { 28 | 'use strict'; 29 | 30 | var AUTO_DISMISS_TIME = 5000, 31 | service, 32 | lastTimeoutPromise; 33 | 34 | function dequeue() { 35 | if (service.messages.length) { 36 | service.messages.shift(); 37 | } 38 | } 39 | 40 | function enqueue(type, text) { 41 | service.messages.push({ 42 | type: type, 43 | text: text 44 | }); 45 | lastTimeoutPromise = $timeout(dequeue, AUTO_DISMISS_TIME); 46 | } 47 | 48 | function cancelTimeout() { 49 | if (lastTimeoutPromise) { 50 | $timeout.cancel(lastTimeoutPromise); 51 | } 52 | } 53 | 54 | service = { 55 | 56 | messages: [], 57 | 58 | error: enqueue.bind(null, 'error'), 59 | 60 | info: enqueue.bind(null, 'info'), 61 | 62 | dismiss: function(index) { 63 | cancelTimeout(); 64 | service.messages.splice(index, 1); 65 | }, 66 | 67 | dismissAll: function() { 68 | cancelTimeout(); 69 | service.messages.length = 0; 70 | } 71 | 72 | }; 73 | 74 | return service; 75 | 76 | }); 77 | -------------------------------------------------------------------------------- /src/ui/toggle/_toggle.scss: -------------------------------------------------------------------------------- 1 | .co-m-toggle { 2 | button { 3 | margin-left: 0; 4 | margin-right: 0; 5 | } 6 | } 7 | 8 | .btn-toggle-off { 9 | margin-left: 0 !important; 10 | color: $gray-dark; 11 | background-color: $white; 12 | box-shadow: inset 0 1px 0px rgba(255, 255, 255, 0.2), 13 | 0 1px 1px rgba(0, 0, 0, 0.25), 14 | 0 0px 1px rgba(0, 0, 0, 0.25); 15 | &:hover, 16 | &:active, 17 | &:focus, 18 | &.active, 19 | &.disabled, 20 | &[disabled], 21 | &[disabled]:active, 22 | &[disabled]:hover, 23 | &[disabled]:focus { 24 | color:$gray; 25 | background-color: $white; 26 | } 27 | } 28 | 29 | .btn-toggle-on { 30 | color: $gray-darker; 31 | background-color: $gray-lighter; 32 | text-shadow: none; 33 | &:hover, 34 | &:active, 35 | &:focus, 36 | &.active, 37 | &.disabled, 38 | &[disabled], 39 | &[disabled]:active, 40 | &[disabled]:hover, 41 | &[disabled]:focus { 42 | color: $gray-darker; 43 | background-color: $gray-lighter; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/ui/toggle/toggle-btn.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/ui/toggle/toggle.html: -------------------------------------------------------------------------------- 1 |
      2 | -------------------------------------------------------------------------------- /src/ui/toggle/toggle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview 3 | * A toggle button. 4 | */ 5 | 6 | 7 | angular.module('coreos.ui') 8 | 9 | .directive('coToggle', function() { 10 | 'use strict'; 11 | 12 | return { 13 | templateUrl: '/coreos.ui/toggle/toggle.html', 14 | transclude: true, 15 | restrict: 'E', 16 | replace: true, 17 | scope: { 18 | value: '=' 19 | }, 20 | controller: function($scope) { 21 | this.setValue = function(val) { 22 | $scope.value = val; 23 | }; 24 | 25 | this.getValue = function() { 26 | return $scope.value; 27 | }; 28 | } 29 | }; 30 | 31 | }) 32 | 33 | .directive('coToggleBtn', function() { 34 | 'use strict'; 35 | 36 | return { 37 | templateUrl: '/coreos.ui/toggle/toggle-btn.html', 38 | transclude: true, 39 | restrict: 'E', 40 | replace: true, 41 | require: '^coToggle', 42 | scope: { 43 | value: '@' 44 | }, 45 | link: function(scope, elem, attrs, toggleCtrl) { 46 | 47 | elem.on('click', function(e) { 48 | scope.$apply(function() { 49 | toggleCtrl.setValue(scope.value); 50 | }); 51 | e.preventDefault(); 52 | e.stopPropagation(); 53 | }); 54 | 55 | scope.$watch(function() { 56 | return toggleCtrl.getValue(); 57 | }, function(val) { 58 | if (scope.value === val) { 59 | elem.addClass('active btn-toggle-on') 60 | .removeClass('btn-toggle-off'); 61 | } else { 62 | elem.removeClass('active btn-toggle-on') 63 | .addClass('btn-toggle-off'); 64 | } 65 | }); 66 | 67 | elem.on('$destroy', function() { 68 | elem.off('click'); 69 | }); 70 | 71 | } 72 | 73 | }; 74 | 75 | }); 76 | -------------------------------------------------------------------------------- /test/mock/discovery.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // a sample discovery json for testing 4 | angular.module('mocks').value('mocks.discovery', { 5 | "kind": "discovery#restDescription", 6 | "discoveryVersion": "v1", 7 | "id": "mock:v1", 8 | "name": "schema", 9 | "version": "v1", 10 | "title": "mock API", 11 | "description": "", 12 | "documentationLink": "http://github.com/sym3tri/mock", 13 | "protocol": "rest", 14 | "icons": { 15 | "x16": "", 16 | "x32": "" 17 | }, 18 | "labels": [], 19 | "rootUrl": "http://localhost:9090/", 20 | "servicePath": "mock/v1/", 21 | "batchPath": "batch", 22 | "parameters": {}, 23 | "auth": {}, 24 | "schemas": { 25 | "user": { 26 | "id": "user", 27 | "type": "object", 28 | "properties": { 29 | "id": { 30 | "type": "string" 31 | }, 32 | "firstName": { 33 | "type": "string" 34 | }, 35 | "lastName": { 36 | "type": "string" 37 | } 38 | } 39 | }, 40 | "userPage": { 41 | "id": "userPage", 42 | "type": "object", 43 | "properties": { 44 | "users": { 45 | "type": "array", 46 | "items": { 47 | "$ref": "user" 48 | } 49 | }, 50 | "nextPageToken": { 51 | "type": "string" 52 | } 53 | } 54 | } 55 | }, 56 | "resources": { 57 | 58 | 59 | "users": { 60 | "methods": { 61 | "list": { 62 | "id": "mock.users.list", 63 | "description": "Retrieve a page of Users.", 64 | "httpMethod": "GET", 65 | "path": "users", 66 | "parameters": { 67 | "nextPageToken": { 68 | "type": "string", 69 | "location": "query" 70 | } 71 | }, 72 | "response": { 73 | "$ref": "userPage" 74 | } 75 | }, 76 | "get": { 77 | "id": "mock.users.get", 78 | "description": "Retrieve a User.", 79 | "httpMethod": "GET", 80 | "path": "users/{id}", 81 | "parameterOrder": [ 82 | "id" 83 | ], 84 | "parameters": { 85 | "id": { 86 | "type": "string", 87 | "location": "path" 88 | } 89 | }, 90 | "response": { 91 | "$ref": "user" 92 | } 93 | }, 94 | "destroy": { 95 | "id": "mock.users.destroy", 96 | "description": "Destroy a User.", 97 | "httpMethod": "DELETE", 98 | "path": "users/{id}", 99 | "parameterOrder": [ 100 | "id" 101 | ], 102 | "parameters": { 103 | "id": { 104 | "type": "string", 105 | "location": "path" 106 | } 107 | } 108 | } 109 | } 110 | } 111 | } 112 | }); 113 | -------------------------------------------------------------------------------- /test/mock/mocks.js: -------------------------------------------------------------------------------- 1 | angular.module('mocks', []); 2 | -------------------------------------------------------------------------------- /test/mock/promise.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('mocks').value('mocks.promise', { 4 | catch: function() { 5 | return this; 6 | }, 7 | then: function() { 8 | return this; 9 | }, 10 | finally: function() { 11 | return this; 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /test/util/matchers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | beforeEach(function() { 4 | 5 | this.addMatchers({ 6 | 7 | toBeOfType: function(type) { 8 | this.message = function () { 9 | return [ 10 | 'Expected to be of type: ' + type + '.', 11 | 'Expected not to be of type: ' + type + '.' 12 | ]; 13 | }; 14 | return typeof this.actual === type; 15 | } 16 | 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /upload-cdn: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | bucket=cdn.core-os.net/coreos-web 4 | 5 | function upload { 6 | file=$1 7 | contentType=$2 8 | 9 | resource="/${bucket}/$(basename $file)" 10 | dateValue=`date -ju +"%a, %d %b %Y %H:%M:%S GMT"` 11 | stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}" 12 | 13 | signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${S3_CDN_SECRET} -binary | base64` 14 | 15 | curl --upload-file ${file} \ 16 | -H "Date: ${dateValue}" \ 17 | -H "Content-type: ${contentType}" \ 18 | -H "Authorization: AWS ${S3_CDN_KEY}:${signature}" \ 19 | http://s3.amazonaws.com${resource} 20 | 21 | echo uploaded to $resource 22 | } 23 | 24 | for filename in dist/*.js; do 25 | upload $filename "application/javascript" 26 | done 27 | 28 | for filename in dist/*.css; do 29 | upload $filename "text/css" 30 | done 31 | --------------------------------------------------------------------------------