diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000000..d8e5c91b68cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.sass-cache +.jekyll-metadata +_site/ +node_modules/* +results/*/* \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 000000000000..3333efe27b02 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +demo.speedtracker.org \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000000..109959e849cd --- /dev/null +++ b/Gemfile @@ -0,0 +1,24 @@ +source "https://rubygems.org" +ruby RUBY_VERSION + +# Hello! This is where you manage which Jekyll version is used to run. +# When you want to use a different version, change it below, save the +# file and run `bundle install`. Run Jekyll with `bundle exec`, like so: +# +# bundle exec jekyll serve +# +# This will help ensure the proper Jekyll version is running. +# Happy Jekylling! +gem "jekyll", "3.2.1" + +# This is the default theme for new Jekyll sites. You may change this to anything you like. +gem "minima" + +# If you want to use GitHub Pages, remove the "gem "jekyll"" above and +# uncomment the line below. To upgrade, run `bundle update github-pages`. +# gem "github-pages", group: :jekyll_plugins + +# If you have any plugins, put them here! +# group :jekyll_plugins do +# gem "jekyll-github-metadata", "~> 1.0" +# end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000000..1d894a3423cf --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,42 @@ +GEM + remote: https://rubygems.org/ + specs: + colorator (1.1.0) + ffi (1.9.14) + forwardable-extended (2.6.0) + jekyll (3.2.1) + colorator (~> 1.0) + jekyll-sass-converter (~> 1.0) + jekyll-watch (~> 1.1) + kramdown (~> 1.3) + liquid (~> 3.0) + mercenary (~> 0.3.3) + pathutil (~> 0.9) + rouge (~> 1.7) + safe_yaml (~> 1.0) + jekyll-sass-converter (1.4.0) + sass (~> 3.4) + jekyll-watch (1.5.0) + listen (~> 3.0, < 3.1) + kramdown (1.12.0) + liquid (3.0.6) + listen (3.0.8) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + mercenary (0.3.6) + minima (1.0.1) + pathutil (0.14.0) + forwardable-extended (~> 2.6) + rb-fsevent (0.9.7) + rb-inotify (0.9.7) + ffi (>= 0.5.0) + rouge (1.11.1) + safe_yaml (1.0.4) + sass (3.4.22) + +PLATFORMS + ruby + +DEPENDENCIES + jekyll (= 3.2.1) + minima diff --git a/README.md b/README.md new file mode 100644 index 000000000000..40fe81b750dd --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +![SpeedTracker logo](https://speedtracker.org/assets/images/logo-square-inverted-128.png) + +# SpeedTracker front-end \ No newline at end of file diff --git a/_config.yml b/_config.yml new file mode 100644 index 000000000000..1a40a95ca930 --- /dev/null +++ b/_config.yml @@ -0,0 +1,25 @@ +detach: false +port: 4820 +host: 0.0.0.0 + +exclude: + - app + - node_modules + - src/results + - public + - Gemfile* + - package.json + - speedtracker.yml + - webpack.config.js + +collections: + profiles: + output: true + +defaults: + - scope: + path: "" + type: "profiles" + values: + layout: data + permalink: /:path/ diff --git a/_includes/getCurrentProfile b/_includes/getCurrentProfile new file mode 100644 index 000000000000..52521058018d --- /dev/null +++ b/_includes/getCurrentProfile @@ -0,0 +1 @@ +{% assign currentProfile = '' %}{% for profile in site.profiles %}{% if page.slug %}{% if page.slug == profile.slug %}{% assign currentProfile = profile.slug %}{% endif %}{% else %}{% if profile.default %}{% assign currentProfile = profile.slug %}{% endif %}{% endif %}{% endfor %}{{ currentProfile }} \ No newline at end of file diff --git a/_includes/listAllProfiles b/_includes/listAllProfiles new file mode 100644 index 000000000000..42abd8a7b28b --- /dev/null +++ b/_includes/listAllProfiles @@ -0,0 +1 @@ +{% capture currentProfile %}{% include getCurrentProfile %}{% endcapture %}[{% for profile in site.profiles %}{slug:{{ profile.slug | jsonify }},name:{{ profile.name | jsonify }},budgets:{{ profile.budgets | jsonify }}{% if profile.slug == currentProfile %},active:true{% endif %}},{% endfor %}] \ No newline at end of file diff --git a/_includes/listProfileTests b/_includes/listProfileTests new file mode 100644 index 000000000000..598e7490e505 --- /dev/null +++ b/_includes/listProfileTests @@ -0,0 +1 @@ +{% assign paths = '' | split: '/' %}{% for file in site.static_files %}{% assign filePath = file.path | split: '/' %}{% if filePath[2] == include.profile %}{% assign filename = filePath[4] | split: '.' %}{% assign date = filePath[3] | append: filename[0] | plus: 0 %}{% assign paths = paths | push: date %}{% endif %}{% endfor %}{{ paths | jsonify }} \ No newline at end of file diff --git a/_includes/meta.html b/_includes/meta.html new file mode 100644 index 000000000000..e0d1f6c7f46f --- /dev/null +++ b/_includes/meta.html @@ -0,0 +1,37 @@ + + + + +{% assign currentProfile = '' %}{% for profile in site.profiles %}{% if page.slug %}{% if page.slug == profile.slug %}{% assign currentProfile = profile.name %}{% endif %}{% else %}{% if profile.default %}{% assign currentProfile = profile.name %}{% endif %}{% endif %}{% endfor %} + +{% assign pageTitle = 'SpeedTracker' %} + +{% if currentProfile != '' %} + {% assign pageTitle = pageTitle | append: ' - ' | append: currentProfile %} +{% endif %} + +{{ pageTitle }} + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_layouts/base.html b/_layouts/base.html new file mode 100644 index 000000000000..128b6e3e4cb4 --- /dev/null +++ b/_layouts/base.html @@ -0,0 +1,20 @@ +--- +layout: null +--- + + + + {% include meta.html %} + + + + +
+ + {% capture currentProfile %}{% include getCurrentProfile %}{% endcapture %} + + + + + + diff --git a/_layouts/data.html b/_layouts/data.html new file mode 100644 index 000000000000..88f00efb234e --- /dev/null +++ b/_layouts/data.html @@ -0,0 +1,3 @@ +--- +layout: base +--- \ No newline at end of file diff --git a/_profiles/css-tricks-cable.html b/_profiles/css-tricks-cable.html new file mode 100644 index 000000000000..e60235c0c66a --- /dev/null +++ b/_profiles/css-tricks-cable.html @@ -0,0 +1,21 @@ +--- +default: true +interval: 12 +budgets: + - + metric: TTFB + max: 2 + alerts: ['mainAlert', 'slackAlert'] + - + metric: firstPaint + max: 2 + alerts: ['mainAlert', 'slackAlert'] +name: 'CSS Tricks (Cable)' +parameters: + connectivity: 'Cable' + location: 'Dulles:Chrome' + firstViewOnly: true + runs: 1 + url: "https://css-tricks.com" + video: true +--- diff --git a/_sass/_config.scss b/_sass/_config.scss new file mode 100644 index 000000000000..0b108f30f910 --- /dev/null +++ b/_sass/_config.scss @@ -0,0 +1,177 @@ +/* + ____ ______ ____ ______ +/\ _`\ /\ _ \/\ _`\ /\__ _\ +\ \ \/\ \ \ \L\ \ \ \/\ \/_/\ \/ + \ \ \ \ \ \ __ \ \ \ \ \ \ \ \ + \ \ \_\ \ \ \/\ \ \ \_\ \ \_\ \__ + \ \____/\ \_\ \_\ \____/ /\_____\ + \/___/ \/_/\/_/\/___/ \/_____/ + + + ____ ______ ____ ______ ____ +/\ _`\ /\ _ \/\ _`\ /\__ _\/\ _`\ +\ \ \L\ \ \ \L\ \ \ \L\ \/_/\ \/\ \,\L\_\ + \ \ ,__/\ \ __ \ \ , / \ \ \ \/_\__ \ + \ \ \/ \ \ \/\ \ \ \\ \ \ \ \ /\ \L\ \ + \ \_\ \ \_\ \_\ \_\ \_\ \ \_\ \ `\____\ + \/_/ \/_/\/_/\/_/\/ / \/_/ \/_____/ + + + https://github.com/dadi/parts +*/ + +// ----------------------------------------------------------------------------- +// Global sizes +// +// -> Size units are relative to the base size. For example, if the base size is +// set to 16px, then: +// +// $dp-size-units: ( +// 'small': 0.5, +// 'normal': 1, +// 'large': 2 +// ); +// +// Will mean that `small` is 8px and `large` is 32px. +// +// You *always* need to include a unit called `normal` (typically set to 1). +// ----------------------------------------------------------------------------- + +$dp-base-size: 18px; + +$dp-base-line-height: 1.375; + +$dp-size-units:( + 'tiny': 0.25, + 'small': 0.5, + 'normal': 1, + 'large': 1.5, + 'larger': 2.25, + 'huge': 3, + 'massive': 4 +); + +// ----------------------------------------------------------------------------- +// Spacing +// +// -> `$dp-room` is the equivalent of `$dp-base-size` for spacing. It's used with +// margin/padding. Utility classes will be created automatically for every +// unit defined in `$dp-size-units`, always relative to `$dp-room`. +// +// Example: +// +// .u-padding {} +// .u-padding-large {} +// .u-margin-small {} +// +// See utilities/_utilities.size.scss for more information. +// +// ----------------------------------------------------------------------------- + +$dp-room: 15px; + +// ----------------------------------------------------------------------------- +// Roundness +// +// -> Uses globally in `border-radius`. Optional. +// +// ----------------------------------------------------------------------------- + +$dp-roundness: 5px; + +// ----------------------------------------------------------------------------- +// Global maximum width +// +// -> The default value to be used by utilities/_utilities.wrapper to create +// a wrapper container. +// +// ----------------------------------------------------------------------------- + +$dp-max-width: 900px; + +// ----------------------------------------------------------------------------- +// Global font smoothing +// +// -> Whether to enable font smoothing globally. If set to `false` (default), +// font smoothing can still be enabled individually on any element by using +// tools/_tools.font-smoothing. +// +// ----------------------------------------------------------------------------- + +$dp-global-font-smoothing: true; + +// ----------------------------------------------------------------------------- +// Responsive breakpoints +// +// -> Used by include-media (http://include-media.com). Allows the definition of +// media queries using any of the breakpoints defined using a syntax like: +// +// @include media('>=medium') {} +// @include media('>medium', 'large', '<2300px') {} +// @include media('retina2x', ' To be used with the dp-color() function. +// +// body { +// background-color: dp-color('background'); +// } +// +// ----------------------------------------------------------------------------- + +$dp-colors: ( + 'background': #FAFAFA, + 'primary': #000000, + 'accent': #EA8C55 +); + +// ----------------------------------------------------------------------------- +// Global typography settings +// ----------------------------------------------------------------------------- + +$dp-fonts: ( + 'primary': ('Roboto Condensed', 'Helvetica Neue', Arial, Helvetica, Geneva, sans-serif), + 'secondary': (Helvetica, Arial, sans-serif) +); + +// ----------------------------------------------------------------------------- +// Custom font declarations +// ----------------------------------------------------------------------------- + +@import 'https://fonts.googleapis.com/css?family=Roboto+Condensed'; + +// ----------------------------------------------------------------------------- +// Grid classes +// +// -> Used by include-media to generate column classes. It uses the breakpoints +// defined in `$breakpoints` and the number of subdivisions below to create +// classes like .col--{part}-{total} and .col--{part}-{total}@{breakpoint} +// +// -> Example: Build an element that takes full width on small screens, 1/2 of +// the width on `medium` and 1/3 of the width on `large` +// +//
+// +// ----------------------------------------------------------------------------- + +$im-columns-subdivisions: 1, 2, 3, 4, 5, 6; +$im-columns-class: '.u-col'; + +// ----------------------------------------------------------------------------- +// Grid mode +// +// -> Whether to define grid classes as `float` (default) or `inline-block` +// +// ----------------------------------------------------------------------------- + +$dp-grid-mode: 'flex'; \ No newline at end of file diff --git a/_sass/_main.scss b/_sass/_main.scss new file mode 100644 index 000000000000..abd27f424ef3 --- /dev/null +++ b/_sass/_main.scss @@ -0,0 +1,15 @@ +@import 'config'; + +@import 'vendor/@dadi/parts/main'; +@import 'vendor/balloon'; + +@import 'components/components.Chart'; +@import 'components/components.Filmstrip'; +@import 'components/components.Footer'; +@import 'components/components.Indicator'; +@import 'components/components.Info'; +@import 'components/components.Loader'; +@import 'components/components.Logo'; +@import 'components/components.LogoTitle'; +@import 'components/components.Section'; +@import 'components/components.TopBar'; \ No newline at end of file diff --git a/_sass/components/_components.Chart.scss b/_sass/components/_components.Chart.scss new file mode 100644 index 000000000000..368c74b54a62 --- /dev/null +++ b/_sass/components/_components.Chart.scss @@ -0,0 +1,24 @@ +.c-Chart { + position: relative; +} + +.c-Chart--placeholder { + &:before { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + content: ' '; + background-color: rgba(255, 255, 255, 0.8); + } + + &:after { + position: absolute; + left: 0; + right: 0; + top: 50%; + text-align: center; + content: 'We need some more tests results to draw a chart.' + } +} \ No newline at end of file diff --git a/_sass/components/_components.Filmstrip.scss b/_sass/components/_components.Filmstrip.scss new file mode 100644 index 000000000000..cb9851af640d --- /dev/null +++ b/_sass/components/_components.Filmstrip.scss @@ -0,0 +1,22 @@ +.c-Filmstrip { + overflow: scroll; + white-space: nowrap; + -webkit-overflow-scrolling: touch; +} + +.c-Filmstrip__item { + display: inline-block; + + & + & { + margin-left: 10px; + } +} + +.c-Filmstrip__image { + border: 1px solid #E8E8E8; + width: 270px; +} + +.c-Filmstrip__progress { + text-align: center; +} \ No newline at end of file diff --git a/_sass/components/_components.Footer.scss b/_sass/components/_components.Footer.scss new file mode 100644 index 000000000000..001101d982a2 --- /dev/null +++ b/_sass/components/_components.Footer.scss @@ -0,0 +1,35 @@ +.c-Footer { + background-color: #E8E8E8; + font-size: 0.7em; + margin-top: 80px; + overflow: hidden; + padding: 20px; + text-align: center; + + a { + color: dp-color('accent'); + text-decoration: underline; + } +} + +.c-Footer__inner { + @include dp-wrapper-gutter; +} + +.c-Footer__logo { + display: inline-block; + color: dp-color('accent'); + margin-bottom: 20px; +} + +.c-Footer__links { + margin: 30px 0 0 0; +} + +.c-Footer__link { + display: inline-block; + + & + & { + margin-left: 20px; + } +} \ No newline at end of file diff --git a/_sass/components/_components.Indicator.scss b/_sass/components/_components.Indicator.scss new file mode 100644 index 000000000000..f9be8a132569 --- /dev/null +++ b/_sass/components/_components.Indicator.scss @@ -0,0 +1,23 @@ +.c-Indicator { + display: inline-block; +} + +.c-Indicator__key { + font-size: 0.9em; + margin-bottom: -7px; +} + +.c-Indicator__value { + font-family: dp-font('secondary'); + font-size: 1.5em; + font-weight: bold; + margin: 0; + + .c-Indicator--success & { + color: #7CAE7A; + } + + .c-Indicator--danger & { + color: red; + } +} diff --git a/_sass/components/_components.Info.scss b/_sass/components/_components.Info.scss new file mode 100644 index 000000000000..7d9c812782a2 --- /dev/null +++ b/_sass/components/_components.Info.scss @@ -0,0 +1,14 @@ +.c-Info { + display: inline-block; + vertical-align: top; + width: 14px; + height: 14px; + margin-left: 5px; + margin-top: 2px; + color: dp-color('accent'); + + svg { + width: 100%; + height: 100%; + } +} \ No newline at end of file diff --git a/_sass/components/_components.Loader.scss b/_sass/components/_components.Loader.scss new file mode 100644 index 000000000000..04080f1417e2 --- /dev/null +++ b/_sass/components/_components.Loader.scss @@ -0,0 +1,16 @@ +.c-Loader { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: rgba(255, 255, 255, 0.9); + color: #EA8C55; + text-align: center; +} + +.c-Loader__content { + position: relative; + top: 50%; + transform: translateY(-50%); +} \ No newline at end of file diff --git a/_sass/components/_components.Logo.scss b/_sass/components/_components.Logo.scss new file mode 100644 index 000000000000..d683e0d478b4 --- /dev/null +++ b/_sass/components/_components.Logo.scss @@ -0,0 +1,42 @@ +.c-Logo { + display: inline-block; + vertical-align: middle; + + &:hover { + .c-Logo__stripe { + opacity: 0.3; + } + } +} + +@keyframes cLogoAnimation { + 0%, 100% { + opacity: 0; + } + + 50% { + opacity: 1; + } +} + +@for $i from 1 through 5 { + .c-Logo__stripe--#{$i} { + opacity: (6 - $i) * 0.25; + animation-delay: $i * 0.07s !important; + } +} + +.c-Logo__stripe { + fill: currentColor; + transition: all 1.2s ease-out; + transform-origin: 50% 50%; + + &:not(.c-Logo--animate):hover { + opacity: 1 !important; + transition: all 0.15s ease-out; + } + + .c-Logo--animate & { + animation: cLogoAnimation 1s infinite; + } +} \ No newline at end of file diff --git a/_sass/components/_components.LogoTitle.scss b/_sass/components/_components.LogoTitle.scss new file mode 100644 index 000000000000..a5eaa2e01065 --- /dev/null +++ b/_sass/components/_components.LogoTitle.scss @@ -0,0 +1,4 @@ +.c-LogoTitle { + display: inline-block; + vertical-align: middle; +} \ No newline at end of file diff --git a/_sass/components/_components.Section.scss b/_sass/components/_components.Section.scss new file mode 100644 index 000000000000..f25ee234db82 --- /dev/null +++ b/_sass/components/_components.Section.scss @@ -0,0 +1,24 @@ +.c-Section { + & + & { + margin-top: 80px; + } +} + +.c-Section__title { + background-color: #E8E8E8; + border-radius: 10px; + color: #EA8C55; + font-size: 1.6em; + margin-bottom: dp-spacing('large'); + padding: 10px 20px; +} + +.c-Section__indicators { + margin-bottom: dp-spacing('large'); + margin: -10px 0 20px -30px; + padding: 0 10px; + + .c-Indicator { + margin: 10px 0 0 30px; + } +} \ No newline at end of file diff --git a/_sass/components/_components.TopBar.scss b/_sass/components/_components.TopBar.scss new file mode 100644 index 000000000000..f264382d0611 --- /dev/null +++ b/_sass/components/_components.TopBar.scss @@ -0,0 +1,48 @@ +.c-TopBar { + background-color: #EA8C55; + box-shadow: 0px 1px 5px 0px rgba(0, 0, 0, 0.45); + color: white; + margin-bottom: 40px; + text-align: center; + + @include media('>=medium') { + text-align: left; + } +} + +.c-TopBar__inner { + @include dp-wrapper-gutter; + + padding: 6px; +} + +.c-TopBar__select { + -webkit-appearance: none; + background-color: transparent; + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTUgNmgxMGwtNSA5LTUtOXoiPjwvcGF0aD48L3N2Zz4=); + background-origin: border-box; + background-position: right -5px center; + background-repeat: no-repeat; + background-size: 20px; + border: 0; + border-bottom: 2px solid white; + border-radius: 0; + color: inherit; + font: inherit; + margin: 0 6px; + outline: 0; + padding-right: 20px; + + &:focus { + border-bottom-color: rgba(white, 0.5); + } +} + +.c-TopBar__nav { + margin-top: 20px; + + @include media('>=medium') { + float: right; + margin-top: 8px; + } +} \ No newline at end of file diff --git a/_sass/vendor/@dadi/parts/.npmignore b/_sass/vendor/@dadi/parts/.npmignore new file mode 100644 index 000000000000..c2658d7d1b31 --- /dev/null +++ b/_sass/vendor/@dadi/parts/.npmignore @@ -0,0 +1 @@ +node_modules/ diff --git a/_sass/vendor/@dadi/parts/README.md b/_sass/vendor/@dadi/parts/README.md new file mode 100644 index 000000000000..2bdf254a071f --- /dev/null +++ b/_sass/vendor/@dadi/parts/README.md @@ -0,0 +1,112 @@ + + +# Parts + +> A foundation for front-end projects + +## Table of contents +1. [Introduction](#introduction) +2. [Installation](#installation) +3. [Usage](#usage) + - [Components](#components) + - [Utilities](#utilities) + - [Tools](#tools) + - [Generic](#generic) + - [Settings](#settings) + +--- + +## Introduction + +DADI Parts is a CSS framework and a set of guidelines to kickstart a new front-end project. It draws inspiration from key references in the industry, such as Harry Robert's [inuitcss](https://github.com/inuitcss) and [Airbnb's CSS/Sass Styleguide](https://github.com/airbnb/css). + +It's built on three core principles: + +- **Modularity**: Approach UIs as a group of modular, self-contained and reusable components as opposed to monolithic pages +- **Separation of concerns**: A front-end component is typically made up of markup (HTML), styling (CSS) and functionality (JavaScript), and it must be built in such a way that allows any of those parts to change (or be removed) without that affecting the others +- **Self-explanation**: Developers should be able to clearly understand the behaviour of a component and all the forces acting on it without requiring any previous exposure to the project or understanding of its inner workings. The structure of the project should give new developers a high level of confidence when commiting changes or new features, providing mechanisms to reduce the risk of unwanted side effects <-- needs review + +## Installation + +1. Install via npm + + ```shell + npm install @dadi/parts --save + ``` + +1. Create a `components` folder in your project's Sass directory + +1. Grab a [sample config file](_config.scss.sample), copy it to your project and start editing the settings + +1. Create a loader file where you'll load the config file, the DADI Parts core, the components and any other third-party library you wish to use + + ```scss + // Load config + @import 'config'; + + // Load core + @import '../path/to/node_modules/@dadi/parts/main'; + + // Load components + @import 'components/components.button.scss'; + ``` + +## Usage + +Styles are applied against DOM elements that are targeted using classes and **never** IDs or tags. This ensures that the HTML markup,which conveys semantics, stays completely decoupled from CSS, which is purely visual. For example, you should be able to create a *button* component that can work as a ``, `