├── CHANGELOG.md
├── ROADMAP.md
├── .nvmrc
├── .babelrc
├── src
├── views
│ ├── mixins
│ │ ├── mixins.pug
│ │ ├── m-icon.pug
│ │ └── m-checklist-section.pug
│ ├── components
│ │ ├── c-sponsor.pug
│ │ ├── c-top-alert.pug
│ │ ├── c-search.pug
│ │ ├── c-progress.pug
│ │ ├── svg
│ │ │ ├── bullet.pug
│ │ │ ├── checkbox.pug
│ │ │ ├── collapse.pug
│ │ │ ├── expand.pug
│ │ │ ├── arrow.pug
│ │ │ ├── check.pug
│ │ │ ├── checked.pug
│ │ │ ├── eye.pug
│ │ │ ├── code.pug
│ │ │ ├── print.pug
│ │ │ └── reset.pug
│ │ ├── c-nav.pug
│ │ ├── checklist
│ │ │ ├── checkbox.pug
│ │ │ ├── dropdown.pug
│ │ │ ├── priority.pug
│ │ │ ├── class.pug
│ │ │ └── label.pug
│ │ ├── s-section-top.pug
│ │ ├── s-section-bottom.pug
│ │ ├── c-tools.pug
│ │ ├── c-new-form.pug
│ │ ├── c-newsletter.pug
│ │ ├── c-corner.pug
│ │ ├── c-tag-filter.pug
│ │ ├── c-checklist.pug
│ │ └── c-notation.pug
│ ├── base
│ │ ├── before-scripts.pug
│ │ ├── after-scripts.pug
│ │ ├── layout.pug
│ │ ├── social.pug
│ │ ├── footer.pug
│ │ └── header.pug
│ ├── index-en.pug
│ └── index-jp.pug
├── favicon.ico
├── favicon-16x16.png
├── favicon-32x32.png
├── img
│ ├── icons
│ │ └── 1x1.png
│ ├── social
│ │ └── facebook-banner.jpg
│ ├── logos
│ │ ├── logo-front-end-checklist.jpg
│ │ └── logo-front-end-checklist.webp
│ ├── banners
│ │ ├── logo-front-end-checklist.jpg
│ │ ├── front-end-checklist-banner-dark.jpg
│ │ └── front-end-checklist-banner-light.jpg
│ └── flags
│ │ ├── ru.svg
│ │ ├── fr.svg
│ │ ├── jp.svg
│ │ ├── vn.svg
│ │ ├── tr.svg
│ │ ├── cn.svg
│ │ └── kr.svg
├── mstile-150x150.png
├── robots.txt
├── apple-touch-icon.png
├── styles
│ ├── base
│ │ ├── _typography.scss
│ │ ├── _media.scss
│ │ ├── _headings.scss
│ │ ├── _form.scss
│ │ ├── _generic.scss
│ │ ├── _fonts.scss
│ │ ├── _links.scss
│ │ ├── _print.scss
│ │ └── _icons.scss
│ ├── utilities
│ │ ├── functions
│ │ │ └── _functions.scss
│ │ ├── _utilities.scss
│ │ └── mixins
│ │ │ ├── _mixins.scss
│ │ │ └── _m-breakpoints.scss
│ ├── components
│ │ ├── _c-sponsor.scss
│ │ ├── _c-dropdown.scss
│ │ ├── _c-tools.scss
│ │ ├── _c-top-alert.scss
│ │ ├── _c-tags.scss
│ │ ├── _c-github.scss
│ │ ├── _c-progress.scss
│ │ ├── _c-notation.scss
│ │ ├── _c-newsletter.scss
│ │ ├── _c-list.scss
│ │ ├── _c-nav.scss
│ │ └── _c-button.scss
│ ├── config
│ │ ├── _variables.scss
│ │ ├── _v-namespaces.scss
│ │ ├── _v-typography.scss
│ │ └── _v-colors.scss
│ ├── layout
│ │ ├── _s-footer.scss
│ │ ├── _page.scss
│ │ ├── _s-main.scss
│ │ ├── _s-checklist.scss
│ │ ├── _s-aside.scss
│ │ └── _s-header.scss
│ └── main.scss
├── android-chrome-192x192.png
├── scripts
│ ├── main.js
│ ├── components
│ │ ├── Analytics.js
│ │ ├── ProgressBar.js
│ │ ├── Notation.js
│ │ ├── Filter.js
│ │ ├── Report.js
│ │ ├── Init.js
│ │ ├── Checkboxes.js
│ │ ├── Ui.js
│ │ ├── Dropdown.js
│ │ ├── Tools.js
│ │ └── Storage.js
│ └── Utils.js
├── browserconfig.xml
├── humans.txt
├── sitemap.xml
├── manifest.json
├── _headers
├── safari-pinned-tab.svg
├── service-worker.js
├── precache-config.js
└── modernizr-custom.min.js
├── test
├── notation.test.js
├── localstorage.test.js
└── reports.test.js
├── data
├── jp
│ ├── project
│ │ ├── introductions.json
│ │ └── translation.json
│ ├── _items.json
│ ├── items
│ │ └── 利用方法.json
│ └── _project.json
└── en
│ ├── project
│ ├── introductions.json
│ └── translation.json
│ └── items
│ ├── webfonts.json
│ ├── images.json
│ ├── html.json
│ ├── javascript.json
│ ├── accessibility.json
│ ├── seo.json
│ ├── performance.json
│ └── css.json
├── .github
├── ISSUE_TEMPLATE.md
├── stale.yml
├── PULL_REQUEST_TEMPLATE.md
└── CONTRIBUTING.md
├── .editorconfig
├── .prettierrc
├── wallaby.js
├── .codeclimate.yml
├── .gitignore
├── modernizr-config.json
├── .travis.yml
├── webpack.config.js
├── .stylelintrc
├── .eslintrc.js
├── package.json
├── CODE_OF_CONDUCT.md
└── README_APP.md
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ROADMAP.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 8.11.3
2 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/views/mixins/mixins.pug:
--------------------------------------------------------------------------------
1 | include m-checklist-section
2 | include m-icon
3 |
--------------------------------------------------------------------------------
/src/views/components/c-sponsor.pug:
--------------------------------------------------------------------------------
1 | .c-sponsor
2 | .cs__wrapper
3 | #codefund_ad
4 |
--------------------------------------------------------------------------------
/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/favicon.ico
--------------------------------------------------------------------------------
/test/notation.test.js:
--------------------------------------------------------------------------------
1 | let expect = require('chai').expect;
2 | let assert = require('assert');
3 |
--------------------------------------------------------------------------------
/data/jp/project/introductions.json:
--------------------------------------------------------------------------------
1 | [{
2 | "head": {
3 | "introduction": ""
4 | }
5 | }]
6 |
--------------------------------------------------------------------------------
/test/localstorage.test.js:
--------------------------------------------------------------------------------
1 | let expect = require('chai').expect;
2 | let assert = require('assert');
3 |
--------------------------------------------------------------------------------
/src/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/favicon-16x16.png
--------------------------------------------------------------------------------
/src/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/favicon-32x32.png
--------------------------------------------------------------------------------
/src/img/icons/1x1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/img/icons/1x1.png
--------------------------------------------------------------------------------
/src/mstile-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/mstile-150x150.png
--------------------------------------------------------------------------------
/src/robots.txt:
--------------------------------------------------------------------------------
1 | # www.robotstxt.org/
2 |
3 | # Allow crawling of all content
4 | User-agent: *
5 | Disallow:
6 |
--------------------------------------------------------------------------------
/src/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/apple-touch-icon.png
--------------------------------------------------------------------------------
/src/styles/base/_typography.scss:
--------------------------------------------------------------------------------
1 | p {
2 | font-size: 1.2rem;
3 | line-height: 1.5;
4 | margin-top: 0;
5 | }
6 |
--------------------------------------------------------------------------------
/src/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/android-chrome-192x192.png
--------------------------------------------------------------------------------
/src/views/components/c-top-alert.pug:
--------------------------------------------------------------------------------
1 | .c-top-alert
2 | .c-top-alert--alert
3 | p= translation.alert.JAVASCRIPT_DESACTIVATE
4 |
--------------------------------------------------------------------------------
/src/img/social/facebook-banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/img/social/facebook-banner.jpg
--------------------------------------------------------------------------------
/data/en/project/introductions.json:
--------------------------------------------------------------------------------
1 | [{
2 | "head": {
3 | "introduction": ""
4 | },
5 | "html": {
6 | "introduction": ""
7 | }
8 | }]
9 |
--------------------------------------------------------------------------------
/src/img/logos/logo-front-end-checklist.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/img/logos/logo-front-end-checklist.jpg
--------------------------------------------------------------------------------
/src/img/logos/logo-front-end-checklist.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/img/logos/logo-front-end-checklist.webp
--------------------------------------------------------------------------------
/src/img/banners/logo-front-end-checklist.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/img/banners/logo-front-end-checklist.jpg
--------------------------------------------------------------------------------
/src/scripts/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | import Init from './components/Init';
4 |
5 | document.addEventListener('DOMContentLoaded', () => new Init());
6 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/img/banners/front-end-checklist-banner-dark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/img/banners/front-end-checklist-banner-dark.jpg
--------------------------------------------------------------------------------
/src/img/banners/front-end-checklist-banner-light.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TheLarkInn/Front-End-Checklist/HEAD/src/img/banners/front-end-checklist-banner-light.jpg
--------------------------------------------------------------------------------
/src/styles/utilities/functions/_functions.scss:
--------------------------------------------------------------------------------
1 | // Function to choose colors in CSS variables
2 | @function color($color-name) {
3 | @return var(--color-#{$color-name});
4 | }
5 |
--------------------------------------------------------------------------------
/src/styles/components/_c-sponsor.scss:
--------------------------------------------------------------------------------
1 | .c-sponsor {
2 | width: 100%;
3 | }
4 |
5 | .cs {
6 | &__wrapper {
7 | min-width: 320px;
8 | overflow: hidden;
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/views/components/c-search.pug:
--------------------------------------------------------------------------------
1 | .c-search
2 | .form
3 | .form-group
4 | input.search(type="search" id="search")
5 | label(for="search")= translation.form.LABEL_SEARCH
6 |
--------------------------------------------------------------------------------
/src/styles/utilities/_utilities.scss:
--------------------------------------------------------------------------------
1 |
2 | main [data-body-visibility='hide'] * {
3 | display: none;
4 | }
5 |
6 |
7 | [data-body-visbility='hide'] {
8 | display: none;
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "flow",
3 | "useTabs": false,
4 | "printWidth": 80,
5 | "tabWidth": 2,
6 | "singleQuote": true,
7 | "trailingComma": "all",
8 | "bracketSpacing": false
9 | }
10 |
--------------------------------------------------------------------------------
/wallaby.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = function (wallaby) {
3 | return {
4 | files: [
5 | './src/scripts/**/*.js'
6 | ],
7 |
8 | tests: [
9 | 'test/**/*.js'
10 | ]
11 | };
12 | };
13 |
--------------------------------------------------------------------------------
/src/views/components/c-progress.pug:
--------------------------------------------------------------------------------
1 | .c-progress
2 | progress.c-progress__bar.js-progress(value="0", max="100")
3 | .c-progress__counter
4 | span.c-progress__label 0 %
5 | span.c-progress__text #[=sectionTitle] #[=translation.PERCENTAGE_CHECKED]
6 |
--------------------------------------------------------------------------------
/src/views/components/svg/bullet.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 510 510" aria-hidden="true")&attributes(attributes)
2 | path(d="M255 0C114.75 0 0 114.75 0 255s114.75 255 255 255 255-114.75 255-255S395.25 0 255 0z")
3 |
--------------------------------------------------------------------------------
/src/styles/components/_c-dropdown.scss:
--------------------------------------------------------------------------------
1 | @if $use-dropdown == true {
2 | [data-item-dropdown='open'] .c-checklist__details {
3 | display: block;
4 | }
5 |
6 | [data-item-dropdown='close'] .c-checklist__details {
7 | display: none;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/views/components/svg/checkbox.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns="http://www.w3.org/2000/svg" width='30', height='30' viewBox="0 0 94 94" aria-hidden="true")&attributes(attributes)
2 | path(d="M94 88c0 3.312-2.688 6-6 6H6c-3.314 0-6-2.688-6-6V6c0-3.313 2.686-6 6-6h82c3.312 0 6 2.687 6 6v82z")
3 |
--------------------------------------------------------------------------------
/src/styles/components/_c-tools.scss:
--------------------------------------------------------------------------------
1 | .c-tools {
2 | display: flex;
3 |
4 | @include mq('print') {
5 | display: none;
6 | }
7 |
8 | .is-active {
9 | border-color: #415257;
10 | }
11 |
12 | .c-button__group:first-child {
13 | margin-left: 0;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/views/components/c-nav.pug:
--------------------------------------------------------------------------------
1 | nav.c-nav
2 | ul.c-nav__list.c-nav--inline
3 |
4 | each item, i in listSections
5 | li.c-nav__item
6 | a.c-button.js-scroll(href=`#section-${item}`)
7 | span.c-nav__status(id=`js-nav-${item}`, data-notation="0")
8 | span= item
9 |
--------------------------------------------------------------------------------
/src/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | #da532c
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.codeclimate.yml:
--------------------------------------------------------------------------------
1 | ---
2 | engines:
3 | eslint:
4 | enabled: true
5 | channel: eslint-3
6 | stylelint:
7 | enabled: true
8 | ratings:
9 | paths:
10 | - src/**
11 | - "**.scss"
12 | - "**.js"
13 | exclude_paths:
14 | - "test"
15 | - "data"
16 | - "dist"
17 | - "gulpfile.babel.js"
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | npm-debug.log*
4 | yarn-debug.log*
5 | yarn-error.log*
6 | test/unit/coverage
7 | test/e2e/reports
8 | selenium-debug.log
9 | dist/
10 | .tmp/
11 |
12 | # Editor directories and files
13 | .idea
14 | .vscode
15 | *.suo
16 | *.ntvs*
17 | *.njsproj
18 | *.sln
19 |
--------------------------------------------------------------------------------
/src/styles/config/_variables.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Spacing
3 | //
4 | $spacing-super: 24px !default;
5 | $spacing-xlarge: 18px !default;
6 | $spacing-large: 16px !default;
7 | $spacing-medium: 14px !default;
8 | $spacing-small: .7px !default;
9 | $spacing-xsmall: 3px !default;
10 | $spacing-tiny: 1px !default;
11 |
--------------------------------------------------------------------------------
/test/reports.test.js:
--------------------------------------------------------------------------------
1 | const chai = require('chai');
2 | const assert = chai.assert; // Using Assert style
3 | const expect = chai.expect; // Using Expect style
4 | const should = chai.should(); // Using Should style
5 |
6 | const sinon = require('sinon');
7 | const EventEmitter = require('events').EventEmitter;
8 |
--------------------------------------------------------------------------------
/src/views/components/svg/collapse.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns='http://www.w3.org/2000/svg', width='30', height='30', viewbox='0 0 510 510' aria-hidden="true")&attributes(attributes)
2 | title Minus Collapse
3 | path(d='M255 0C114.75 0 0 114.75 0 255s114.75 255 255 255 255-114.75 255-255S395.25 0 255 0zm127.5 280.5h-255v-51h255v51z')
4 |
--------------------------------------------------------------------------------
/src/humans.txt:
--------------------------------------------------------------------------------
1 | # humanstxt.org/
2 | # The humans responsible & technology colophon
3 |
4 | # TEAM
5 |
6 | David Dias -- Front-End Developer -- @thedaviddias
7 |
8 | # THANKS
9 |
10 |
11 |
12 | # TECHNOLOGY COLOPHON
13 |
14 | CSS3, HTML5, Pug, Git, ES6, Webpack, Gulp, Modernizr, Normalize.css
15 |
--------------------------------------------------------------------------------
/modernizr-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "minify": true,
3 | "options": [
4 | "domPrefixes",
5 | "prefixes",
6 | "mq",
7 | "prefixedCSSValue",
8 | "testStyles",
9 | "setClasses"
10 | ],
11 | "feature-detects": [
12 | "test/history",
13 | "test/css/flexbox",
14 | "test/workers/webworkers"
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/src/views/components/checklist/checkbox.pug:
--------------------------------------------------------------------------------
1 | .c-checklist__column.c-checklist__checkbox
2 | input.checkbox(type="checkbox" name=`c-checklist__item-${sectionTitle.toLowerCase()}-${i}` id=`c-checklist__item-${sectionTitle.toLowerCase()}-${i}`)
3 | +svg-icon.icon.icon-checkbox(data-icon-name='check')
4 | +svg-icon.icon.icon-checked(data-icon-name='check')
5 |
--------------------------------------------------------------------------------
/src/img/flags/ru.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/img/flags/fr.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/styles/utilities/mixins/_mixins.scss:
--------------------------------------------------------------------------------
1 | @import 'm-breakpoints';
2 |
3 | @mixin unselectable {
4 | -webkit-touch-callout: none;
5 | -webkit-user-select: none;
6 | -moz-user-select: none;
7 | -ms-user-select: none;
8 | user-select: none;
9 | }
10 |
11 | ol,
12 | ul {
13 | list-style: none;
14 | }
15 |
16 | .sr-only {
17 | display: none;
18 | }
19 |
--------------------------------------------------------------------------------
/src/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | https://frontendchecklist.io/
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/views/components/checklist/dropdown.pug:
--------------------------------------------------------------------------------
1 | .c-checklist__column.c-checklist__dropdown
2 |
3 | //- Check if the item has content, if not hide the button
4 | if item.tools || item.documentation || item.code
5 | button.button-icon.js-dropdown.c-checklist__dropdown__button(aria-label="Open the description section")
6 | +svg-icon.icon.icon-arrow(data-icon-name='arrow')
7 |
--------------------------------------------------------------------------------
/src/views/base/before-scripts.pug:
--------------------------------------------------------------------------------
1 | script.
2 | (function(d, s, id) {
3 | var js, fjs = d.getElementsByTagName(s)[0];
4 | if (d.getElementById(id)) return;
5 | js = d.createElement(s); js.id = id;
6 | js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.10&appId=1824577741189279";
7 | fjs.parentNode.insertBefore(js, fjs);
8 | }(document, 'script', 'facebook-jssdk'));
9 |
--------------------------------------------------------------------------------
/data/jp/_items.json:
--------------------------------------------------------------------------------
1 | {"利用方法":[{"title":"Doctype","priority":"High","description":"The Doctype is HTML5 and is at the top of all your HTML pages.","code":"https://gist.github.com/thedaviddias/bccee9f4dfa728830cf38bb83838d2d3.js","documentation":[{"title":"Determining the character encoding - HTML5 W3C","url":"https://www.w3.org/TR/html5/syntax.html#determining-the-character-encoding"}],"tags":["all","Meta tag"]}]}
--------------------------------------------------------------------------------
/src/views/components/svg/expand.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns='http://www.w3.org/2000/svg', width='30', height='30', viewbox='0 0 510 510' aria-hidden="true")&attributes(attributes)
2 | title Plus Expand
3 | path(d='M280.5 127.5h-51v102h-102v51h102v102h51v-102h102v-51h-102v-102zM255 0C114.75 0 0 114.75 0 255s114.75 255 255 255 255-114.75 255-255S395.25 0 255 0zm0 459c-112.2 0-204-91.8-204-204S142.8 51 255 51s204 91.8 204 204-91.8 204-204 204z')
4 |
--------------------------------------------------------------------------------
/src/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "FE Checklist",
3 | "name": "Front-End Checklist",
4 | "start_url": "http://frontendchecklist.com/?utm_source=homescreen",
5 | "icons": [
6 | {
7 | "src": "/android-chrome-192x192.png",
8 | "sizes": "192x192",
9 | "type": "image/png"
10 | }
11 | ],
12 | "theme_color": "#ffffff",
13 | "background_color": "#ffffff",
14 | "display": "standalone"
15 | }
16 |
--------------------------------------------------------------------------------
/src/views/components/svg/arrow.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns="http://www.w3.org/2000/svg" width='30', height='30' viewBox="0 0 98.148 98.149" aria-hidden="true")&attributes(attributes)
2 | title Arrow
3 | path(d="M97.562 64.692L50.49 17.618c-.75-.75-2.078-.75-2.828 0L.586 64.693C.21 65.068 0 65.577 0 66.106c0 .53.21 1.04.586 1.414l12.987 12.987c.39.39.902.586 1.414.586.512 0 1.023-.195 1.414-.586l32.675-32.674L81.75 80.506c.75.75 2.078.75 2.828 0L97.562 67.52c.782-.78.782-2.048 0-2.828z")
4 |
--------------------------------------------------------------------------------
/src/styles/base/_media.scss:
--------------------------------------------------------------------------------
1 | .media {
2 | align-items: flex-start;
3 | display: flex;
4 | text-align: left;
5 | }
6 |
7 | .img-logo {
8 | width: 85px;
9 | height: 85px;
10 |
11 | @include mq('handheld-and-up') {
12 | width: 100px;
13 | height: 100px;
14 | }
15 | }
16 |
17 | // frameborder="0"
18 | // allowtransparency="true"
19 | // scrolling="no"
20 | iframe {
21 | background: transparent;
22 | margin: 0;
23 | padding: 0;
24 | border: 0;
25 | }
26 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: false
3 | node_js:
4 | - "7.1.0"
5 | cache:
6 | directories:
7 | - node_modules
8 | install:
9 | - npm install
10 | script:
11 | - gulp build
12 | notifications:
13 | email:
14 | recipients:
15 | - thedaviddias@gmail.com
16 | branches:
17 | only:
18 | - master
19 | - /^greenkeeper/.*$/
20 | deploy:
21 | local_dir: dist
22 | provider: pages
23 | skip_cleanup: true
24 | github_token: $GITHUB_TOKEN
25 | on:
26 | branch: master
27 |
--------------------------------------------------------------------------------
/src/styles/components/_c-top-alert.scss:
--------------------------------------------------------------------------------
1 | @if $use-top-alert == true {
2 | #{$namespace-top-alert} {
3 | display: none;
4 |
5 | .no-js & {
6 | &--alert {
7 | min-height: 35px;
8 | background: orange;
9 | width: 100%;
10 | text-align: center;
11 | font-weight: bold;
12 | color: white;
13 | font-size: 1.3rem;
14 | padding: 5px 0;
15 |
16 | p {
17 | margin: 0;
18 | }
19 | }
20 | }
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/src/views/components/checklist/priority.pug:
--------------------------------------------------------------------------------
1 | .c-checklist__column.c-checklist__priority
2 |
3 | if item.priority == "High"
4 | +svg-icon.icon.icon--small.icon-priority--high(aria-label="High priority item" data-icon-name='bullet')
5 |
6 | else if item.priority == "Medium"
7 | +svg-icon.icon.icon--small.icon-priority--medium(aria-label="Medium priority item" data-icon-name='bullet')
8 |
9 | else
10 | +svg-icon.icon.icon--small.icon-priority--low(aria-label="Low priority item", data-icon-name='bullet')
11 |
--------------------------------------------------------------------------------
/src/views/components/svg/check.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns='http://www.w3.org/2000/svg', width='30', height='30' viewbox='-432 234 94 94' aria-hidden="true")&attributes(attributes)
2 | title Check
3 | path(d='M-349 245v72h-72v-72h72m5-11h-82c-3.3 0-6 2.7-6 6v82c0 3.3 2.7 6 6 6h82c3.3 0 6-2.7 6-6v-82c0-3.3-2.7-6-6-6z')
4 | path.path-check(d='M-349.2 261.1l-7.2-7.2c-.8-.8-2-.8-2.8 0l-37.3 37.3-13.3-13.3c-.8-.8-2-.8-2.8 0l-7.2 7.2c-.4.4-.6.9-.6 1.4s.2 1 .6 1.4l21.9 21.9c.4.4.9.6 1.4.6.5 0 1-.2 1.4-.6l45.9-45.9c.4-.4.6-.9.6-1.4 0-.5-.2-1-.6-1.4z')
5 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | daysUntilStale: 60
2 | daysUntilClose: 15
3 | exemptLabels:
4 | - pinned
5 | - security
6 | staleLabel: wontfix
7 | markComment: >
8 | This issue has been automatically marked as stale because it has not had
9 | recent activity. It will be closed if no further activity occurs. If you have any question, please contact me directly at thedaviddias@gmail.com. Thank you
10 | for your contributions to that project!
11 | # Comment to post when closing a stale issue. Set to `false` to disable
12 | closeComment: false
13 |
--------------------------------------------------------------------------------
/data/jp/items/利用方法.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "Doctype",
4 | "priority": "High",
5 | "description": "The Doctype is HTML5 and is at the top of all your HTML pages.",
6 | "code": "https://gist.github.com/thedaviddias/bccee9f4dfa728830cf38bb83838d2d3.js",
7 | "documentation": [
8 | {
9 | "title": "Determining the character encoding - HTML5 W3C",
10 | "url": "https://www.w3.org/TR/html5/syntax.html#determining-the-character-encoding"
11 | }
12 | ],
13 | "tags": ["all", "Meta tag"]
14 | }
15 | ]
16 |
--------------------------------------------------------------------------------
/src/styles/components/_c-tags.scss:
--------------------------------------------------------------------------------
1 | .c-tags {
2 | &__list {
3 | padding: 0;
4 | list-style: none;
5 | position: relative;
6 | opacity: .7;
7 |
8 | [data-item-check='true'] & {
9 | opacity: .2;
10 | }
11 | }
12 |
13 | &__item {
14 | font-size: 1rem;
15 | display: inline;
16 | padding: 3px;
17 | white-space: nowrap;
18 | opacity: 1;
19 | overflow: hidden;
20 | border: .5px solid $border;
21 |
22 | @include mq('handheld-and-up') {
23 | font-size: 11px;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/views/components/svg/checked.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns="http://www.w3.org/2000/svg" width='30', height='30' viewBox="0 0 330 330" aria-hidden="true")&attributes(attributes)
2 | path(d="M315 0H15C6.716 0 0 6.716 0 15v300c0 8.284 6.716 15 15 15h300c8.284 0 15-6.716 15-15V15c0-8.284-6.716-15-15-15zm-49.394 107.796l-135.62 135.62c-2.813 2.814-6.63 4.394-10.606 4.394-3.98 0-7.794-1.58-10.607-4.393l-44.38-44.38c-5.858-5.86-5.858-15.356 0-21.214 5.858-5.857 15.354-5.857 21.214 0l33.772 33.774L244.393 86.583c5.857-5.858 15.355-5.858 21.213 0 5.858 5.857 5.858 15.355 0 21.213z")
3 |
--------------------------------------------------------------------------------
/src/views/components/s-section-top.pug:
--------------------------------------------------------------------------------
1 | //- List of all sections in the order the mixin +section is called in the article section.
2 | //- Array is populate by
3 | - listSections = []
4 |
5 | //- Ids of each section generated by the mixin +section when called.
6 | - listSectionId = []
7 |
8 | //- Section with Ad and search (TODO: to enable after first launch)
9 | .s-main__section.s-main__meta
10 |
11 | include c-sponsor
12 | //- include c-search
13 |
14 | //- Section with tag filter
15 | .s-main__section.s-main__filter
16 |
17 | include c-tag-filter
18 |
--------------------------------------------------------------------------------
/src/views/base/after-scripts.pug:
--------------------------------------------------------------------------------
1 | script(src="/scripts/app.bundle.js" async)
2 | script.
3 |
4 | if ('serviceWorker' in navigator) {
5 | //- console.log('CLIENT: service worker registration in progress.');
6 | navigator.serviceWorker.register('/service-worker.js').then(function() {
7 | //- console.log('CLIENT: service worker registration complete.');
8 | }, function() {
9 | //- console.log('CLIENT: service worker registration failure.');
10 | });
11 | }
12 | else {
13 | //- console.log('CLIENT: service worker is not supported.');
14 | }
15 |
--------------------------------------------------------------------------------
/src/img/flags/jp.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/src/styles/layout/_s-footer.scss:
--------------------------------------------------------------------------------
1 | .s-footer {
2 | display: grid;
3 | text-align: center;
4 | padding: 20px;
5 |
6 | @include mq(lap-and-up) {
7 | padding: 50px 0;
8 | }
9 |
10 | @include mq('print') {
11 | padding: 10px;
12 | }
13 |
14 | &__badges {
15 | @include mq('print') {
16 | display: none;
17 | }
18 | }
19 |
20 | &__grateful {
21 | @include mq('print') {
22 | display: none;
23 | }
24 | }
25 |
26 | &__made {
27 | font-size: 1.4rem;
28 |
29 | @include mq('print') {
30 | font-size: 7pt;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/img/flags/vn.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack');
2 | const path = require('path');
3 |
4 | const mainPath = path.resolve(__dirname, 'src/scripts', 'main.js');
5 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
6 |
7 | module.exports = {
8 | cache: true,
9 | mode: 'production',
10 | entry: {
11 | app: mainPath
12 | },
13 | output: {
14 | filename: '[name].bundle.js',
15 | },
16 | module: {
17 | rules: [
18 | {
19 | test: /\.js$/,
20 | exclude: /node_modules/,
21 | loader: 'babel-loader'
22 | }
23 | ]
24 | },
25 | optimization: {
26 | minimize: true
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/.stylelintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "stylelint-config-standard",
3 | "plugins": [
4 | "stylelint-scss"
5 | ],
6 | "rules": {
7 | "at-rule-no-unknown": null,
8 | "color-named": [
9 | "always-where-possible",
10 | ignore: ["inside-function"]
11 | ],
12 | "max-empty-lines": 4,
13 | "string-quotes": "single",
14 | "color-hex-length": "long",
15 | "declaration-colon-newline-after": null,
16 | "font-family-name-quotes": null,
17 | "number-leading-zero": "never",
18 | "value-list-comma-newline-after": null,
19 | "max-nesting-depth": 3,
20 | "unit-whitelist": ['%', 'px', 'rem', 's', 'deg', 'ms', 'fr', 'pt'],
21 | "no-descending-specificity": null
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/img/flags/tr.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/views/components/checklist/class.pug:
--------------------------------------------------------------------------------
1 | - allClass = ''
2 | - dataItemDropdown
3 | - priorityClass = item.priority.toLowerCase()
4 |
5 | //- Iteration over tags array
6 | each tag in item.tags
7 |
8 | //- Create an empty array to put all values from tags array
9 | - var tempClass = []
10 |
11 | //- Slip and add a dash if the tag is more than 1 word
12 | - tag = tag.toLowerCase().split(' ').join('-')
13 |
14 | //- Push array value into tempClass array
15 | - tempClass.push(tag)
16 |
17 | - for (var i = 0; i < tempClass.length; i++)
18 | - allClass += tempClass[i] + ' ';
19 |
20 | if item.tools || item.documentation || item.code || item.video
21 | - dataItemDropdown = "open"
22 | else
23 | - dataItemDropdown = "false"
24 |
--------------------------------------------------------------------------------
/src/_headers:
--------------------------------------------------------------------------------
1 | /*
2 | X-Frame-Options: DENY
3 | X-XSS-Protection: 1; mode=block
4 | # Prevent browsers from incorrectly detecting non-scripts as scripts
5 | X-Content-Type-Options: nosniff
6 | # Don't load any resource type not explicitly enabled
7 | # Disable plugins like Flash or Silverlight
8 | # Load images, scripts, stylesheets and fonts from self
9 | # Send reports to report-uri.io
10 | # Content-Security-Policy: default-src 'self' everywhere-8a59.kxcdn.com; object-src 'none'; img-src https: app.codesponsor.io www.google.com; script-src https: www.google-analytics.com ajax.googleapis.com platform.twitter.com buttons.github.io; style-src https: ; font-src https: ; report-uri https://frontendchecklist.report-uri.io/r/default/csp/enforce;
11 |
--------------------------------------------------------------------------------
/src/views/components/svg/eye.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns='http://www.w3.org/2000/svg', width='30', height='30' viewbox='-430 231.5 98.5 98.5' aria-hidden="true")&attributes(attributes)
2 | path(d='M-332.8 277.3c-.9-1-21.5-24.9-48-24.9-26.4 0-47.1 23.9-48 24.9-1.7 2-1.7 4.9 0 6.9.9 1 21.5 24.9 48 24.9 26.4 0 47.1-23.9 48-24.9 1.7-2 1.7-4.9 0-6.9zm-39.9-10.6c1.8-1 4.3.1 5.5 2.5 1.3 2.3.9 5-.9 6s-4.3-.1-5.5-2.5c-1.3-2.3-.9-5 .9-6zm-8.1 33.8c-18.5 0-34-14.2-39.4-19.7 3.6-3.8 11.9-11.4 22.6-16-2.1 3.2-3.3 6.9-3.3 11 0 11.1 9 20.1 20.1 20.1s20.1-9 20.1-20.1c0-4.1-1.2-7.9-3.3-11 10.7 4.6 18.9 12.3 22.6 16-5.4 5.5-20.9 19.7-39.4 19.7z')
3 | path(d='M-349.675 239.41l8.202 8.202-74.245 74.246-8.202-8.203z')
4 | path.st0(d='M-416.16 322.39l75.095-75.093 3.465 3.465-75.094 75.094z')
5 | title Eye
6 |
--------------------------------------------------------------------------------
/src/scripts/components/Analytics.js:
--------------------------------------------------------------------------------
1 | let instance = null;
2 | /**
3 | *
4 | *
5 | * @class Analytics
6 | */
7 | class Analytics {
8 | constructor() {
9 | if (!instance) {
10 | instance = this;
11 | }
12 |
13 | return instance;
14 | }
15 |
16 | addRef() {
17 | const details = document.querySelectorAll('.js-details');
18 |
19 | details.forEach(detail => {
20 | const links = detail.querySelectorAll('a');
21 | links.forEach(link => {
22 | link.setAttribute('href', link.href + '?ref=frontendchecklist');
23 | });
24 | });
25 | }
26 |
27 | enableAnalytics() {
28 | instance.addRef();
29 | }
30 | }
31 |
32 | const Instance = new Analytics();
33 | Object.freeze(Instance);
34 | export default Analytics;
35 |
--------------------------------------------------------------------------------
/src/views/components/s-section-bottom.pug:
--------------------------------------------------------------------------------
1 | .s-main__section.s-main__newsletter
2 |
3 | include c-newsletter
4 |
5 | //- Form and navigation anchors
6 | //- Navigation is at the bottom of the page because of the `listSections` generated by each +section present in the article.
7 | header.s-main__section.s-main__header
8 |
9 | .s-header__checklist
10 |
11 | h2.s-header__checklist__title Report and navigation
12 | //- Form to create new checklist
13 | .s-header__checklist__el
14 | include c-new-form
15 |
16 | //- Navigation with anchors based on the sections
17 | .s-header__checklist__el
18 | include c-nav
19 |
20 | //- Letter notation based on number of items checked
21 | .s-header__checklist__el
22 | include c-notation
23 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
3 |
4 | **Fixes**: #
5 |
6 | 🚨 Please review the [guidelines for contributing](CONTRIBUTING.md) and our [code of conduct](../CODE_OF_CONDUCT.md) to this repository. 🚨
7 | **Please complete these steps and check these boxes (by putting an x inside the brackets) before filing your PR:**
8 |
9 | - [ ] Check the commit's or even all commits' message styles matches our requested structure.
10 | - [ ] Check your code additions will fail neither code linting checks nor unit test.
11 |
12 | #### Short description of what this resolves:
13 |
14 |
15 | #### Proposed changes:
16 |
17 | -
18 | -
19 | -
20 |
21 | 👍 Thank you!
22 |
--------------------------------------------------------------------------------
/src/views/components/c-tools.pug:
--------------------------------------------------------------------------------
1 | .c-tools
2 |
3 | .c-button__group
4 | button.c-button-icon.js-check-all(title="Check all items")
5 | +svg-icon.icon.icon-check(data-icon-name='check')
6 |
7 | button.c-button-icon.js-uncheck-all(title="Uncheck all items")
8 | +svg-icon.icon.icon-uncheck(data-icon-name='check')
9 |
10 | .c-button__group
11 | button.c-button-icon.js-expand-all(title="Expand all items")
12 | +svg-icon.icon.icon-check(data-icon-name='expand')
13 |
14 | button.c-button-icon.js-collapse-all(title="Collapse all items")
15 | +svg-icon.icon.icon-uncheck(data-icon-name='collapse')
16 |
17 | .c-button__group
18 | button.c-button-icon.js-hide-section(title="Hide current section")
19 | +svg-icon.icon.icon-eye(data-icon-name='eye')
20 |
--------------------------------------------------------------------------------
/src/views/components/svg/code.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns='http://www.w3.org/2000/svg', width='30', height='30', viewbox='0 0 92.812 92.812' aria-hidden="true")&attributes(attributes)
2 | path.code-path-left(d='M92.226 44.992L60.97 13.736c-.78-.78-2.047-.78-2.827 0l-6.73 6.728c-.374.375-.585.884-.585 1.414 0 .53.21 1.04.586 1.414L74.53 46.406 51.415 69.52c-.375.376-.586.885-.586 1.415s.21 1.04.586 1.415l6.73 6.728c.39.39.902.585 1.414.585s1.024-.195 1.415-.586L92.227 47.82c.78-.78.78-2.047 0-2.828z')
3 | path.code-path-right(d='M18.283 46.406l23.114-23.114c.375-.375.586-.884.586-1.414 0-.53-.21-1.04-.586-1.414l-6.728-6.728c-.782-.78-2.05-.78-2.83 0L.587 44.992C.21 45.367 0 45.876 0 46.406s.21 1.04.586 1.414l31.26 31.256c.375.375.884.586 1.415.586.53 0 1.04-.21 1.415-.586l6.724-6.728c.78-.78.78-2.05 0-2.828L18.282 46.406z')
4 |
--------------------------------------------------------------------------------
/src/styles/config/_v-namespaces.scss:
--------------------------------------------------------------------------------
1 |
2 | //
3 | $use-top-alert: true !default;
4 | $use-button: true !default;
5 | $use-checklist: true !default;
6 | $use-dropdown: true !default;
7 | $use-list: true !default;
8 | $use-modal: true !default;
9 | $use-nav: true !default;
10 | $use-progress: true !default;
11 | $use-tooltip: true !default;
12 | $use-aside: true !default;
13 |
14 | // Components
15 | $namespace-top-alert: '.c-top-alert' !default;
16 | $namespace-button: '.c-button' !default;
17 | $namespace-checklist: '.c-checklist' !default;
18 | $namespace-dropdown: '.c-dropdown' !default;
19 | $namespace-list: '.c-list' !default;
20 | $namespace-modal: '.c-modal' !default;
21 | $namespace-nav: '.c-nav' !default;
22 | $namespace-progress: '.c-progress' !default;
23 | $namespace-tooltip: '.c-tooltip' !default;
24 | $namespace-aside: '.c-tag-filter' !default;
25 |
--------------------------------------------------------------------------------
/src/img/flags/cn.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/src/views/components/c-new-form.pug:
--------------------------------------------------------------------------------
1 | .s-form
2 | .form
3 |
4 | .form-group
5 | input(type="text", id="project-name" name="project-name", title=translation.form.TITLE_PROJECT_NAME required)
6 | label(for="project-name")= translation.form.LABEL_PROJECT_NAME
7 |
8 | .form-group
9 | input(type="text", id="page-title" name="page-title", title=translation.form.TITLE_PAGE_TITLE required)
10 | label(for="page-title")= translation.form.LABEL_PAGE_TITLE
11 |
12 | .form-group
13 | input(type="text", id="developer-name" name="developer-name", title=translation.form.TITLE_DEVELOPER_NAME required)
14 | label(for="developer-name")= translation.form.LABEL_DEVELOPER_NAME
15 |
16 | span#generated-date
17 |
18 | .s-meta
19 |
20 | button.button.btn--danger.js-reset-all
21 | +svg-icon.icon.icon-reset(data-icon-name='reset')
22 | | #[=translation.form.BUTTON_START_NEW]
23 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // https://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | env: {
7 | browser: true,
8 | es6: true,
9 | },
10 | // https://github.com/standard/standard/blob/master/docs/RULES-en.md
11 | extends: [
12 | 'airbnb-base/legacy',
13 | 'plugin:flowtype/recommended',
14 | 'prettier',
15 | 'prettier/flowtype'
16 | ],
17 | plugins: [
18 | 'flowtype',
19 | 'prettier'
20 | ],
21 | // add your custom rules here
22 | 'rules': {
23 | "class-methods-use-this": 0,
24 | // allow debugger during development
25 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
26 |
27 | 'prettier/prettier': ['error', {
28 | 'useTabs': false,
29 | 'printWidth': 80,
30 | 'tabWidth': 2,
31 | 'singleQuote': true,
32 | 'trailingComma': 'all',
33 | 'bracketSpacing': false
34 | }]
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/styles/base/_headings.scss:
--------------------------------------------------------------------------------
1 | .h1,
2 | .h2,
3 | .h3,
4 | .h4,
5 | .h5,
6 | .h6,
7 | h1,
8 | h2,
9 | h3,
10 | h4,
11 | h5,
12 | h6 {
13 | margin-bottom: .5rem;
14 | font-family: inherit;
15 | font-weight: 500;
16 | line-height: 1.2;
17 | color: inherit;
18 | }
19 |
20 | h1,
21 | .h1 {
22 | margin: 0;
23 | padding: 15px 0 0;
24 | font-weight: 700;
25 | font-size: 2.5rem;
26 |
27 | @include mq('handheld-and-up') {
28 | font-size: 3rem;
29 | }
30 |
31 | @include mq('print') {
32 | font-size: 18pt;
33 | padding: 0 0 5px;
34 | }
35 | }
36 |
37 | h2,
38 | .h2 {
39 | font-size: 2rem;
40 | }
41 |
42 | h3,
43 | .h3 {
44 | font-size: 1.2rem;
45 | font-weight: 700;
46 |
47 | @include mq('handheld-and-up') {
48 | font-size: 1.3rem;
49 | }
50 | }
51 |
52 | h4,
53 | .h4 {
54 | font-size: 1.2rem;
55 | font-weight: 700;
56 |
57 | @include mq('handheld-and-up') {
58 | font-size: 1.3rem;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/views/mixins/m-icon.pug:
--------------------------------------------------------------------------------
1 | mixin svg-icon
2 | -
3 | var icon = attributes['data-icon-name']
4 |
5 | case icon
6 | when 'checkbox'
7 | include ../components/svg/checkbox
8 |
9 | when 'checked'
10 | include ../components/svg/checked
11 |
12 | when 'arrow'
13 | include ../components/svg/arrow
14 |
15 | when 'bullet'
16 | include ../components/svg/bullet
17 |
18 | when 'reset'
19 | include ../components/svg/reset
20 |
21 | when 'eye'
22 | include ../components/svg/eye
23 |
24 | when 'check'
25 | include ../components/svg/check
26 |
27 | when 'collapse'
28 | include ../components/svg/collapse
29 |
30 | when 'expand'
31 | include ../components/svg/expand
32 |
33 | when 'print'
34 | include ../components/svg/print
35 |
36 | when 'code'
37 | include ../components/svg/code
38 |
39 | default
40 | include ../components/svg/checkbox
41 |
--------------------------------------------------------------------------------
/src/views/components/svg/print.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns='http://www.w3.org/2000/svg', width='30', height='30', viewbox='0 0 94.168 94.168' aria-hidden="true")&attributes(attributes)
2 | title Printer
3 | path(d='M93.135 27.803H79.167v6.447c0 1.104-.896 2-2 2H17c-1.103 0-2-.896-2-2v-6.447H1.034c-.57 0-1.033.462-1.033 1.033v36.497c0 .57.462 1.033 1.033 1.033H15V59.92c0-1.105.897-2 2-2h60.167c1.104 0 2 .895 2 2v6.446h13.968c.57 0 1.033-.463 1.033-1.033V28.836c0-.57-.463-1.033-1.033-1.033zM82.98 52.625c-2.425 0-4.392-1.965-4.392-4.39 0-2.424 1.967-4.39 4.39-4.39s4.39 1.966 4.39 4.39c0 2.426-1.968 4.39-4.39 4.39z')
4 | path(d='M75.617 22.522c0-.55-.22-1.073-.605-1.46L61.57 7.62c-.39-.388-.913-.606-1.46-.606H20.615c-1.14 0-2.065.925-2.065 2.066v23.754h57.067V22.522zm-17.333 2.952c-.278 0-.546-.11-.742-.306-.196-.197-.308-.463-.308-.742l.002-12.498 13.546 13.546H58.284z')
5 | path(d='M18.55 85.088c0 1.14.926 2.065 2.066 2.065h52.936c1.142 0 2.065-.925 2.065-2.065v-23.42H18.55v23.42z')
6 |
--------------------------------------------------------------------------------
/src/views/base/layout.pug:
--------------------------------------------------------------------------------
1 | block vars
2 | - listSections = []
3 |
4 | //- Inject all mixins to be able to call these
5 | include ../mixins/mixins
6 |
7 |
8 | doctype html
9 |
10 | html.no-js(lang=translation.SITE_LANGUAGE, dir=translation.SITE_DIRECTION)
11 | head
12 |
13 | //- Include the HEAD of the page
14 | include head
15 | body
16 |
17 | //- Scripts needed to be load just after the body
18 | include before-scripts
19 |
20 | //- Website wrapper
21 | .page-wrapper
22 |
23 | .page-header
24 | //- Top banners with informations for the user
25 | include ../components/c-top-alert
26 |
27 | include header
28 |
29 | .page-main
30 |
31 | //- The main tag is not include in the block main because repeted
32 | main.s-main#js-main
33 | block main
34 |
35 | .page-footer
36 | include footer
37 |
38 | //- Scripts loading
39 | include after-scripts
40 |
--------------------------------------------------------------------------------
/src/views/base/social.pug:
--------------------------------------------------------------------------------
1 | meta(property="og:site_name" content="Front-End Checklist")
2 | meta(property="og:url" content=translation.URL_WEBSITE)
3 | meta(property="og:type" content="website")
4 | meta(property="og:title" content=translation.INDEX_TITLE)
5 | meta(property="og:description" content=translation.SITE_DESCRIPTION)
6 | meta(property="og:image" content="https://everywhere-8a59.kxcdn.com/img/social/facebook-banner.jpg")
7 | meta(property="og:image:type" content="image/jpeg")
8 | meta(property="og:image:width" content="1200")
9 | meta(property="og:image:height" content="630")
10 | meta(property="og:image:alt" content="The NEW Front-End Checklist - Start, Check, Generate and enjoy!")
11 | meta(property="og:locale" content="en_US")
12 |
13 | meta(name="twitter:card" content="summary_large_image")
14 | meta(name="twitter:site" content="@thedaviddias")
15 | meta(name="twitter:creator" content="@thedaviddias")
16 | meta(name="twitter:image" content="https://everywhere-8a59.kxcdn.com/img/social/facebook-banner.jpg")
17 |
--------------------------------------------------------------------------------
/src/styles/utilities/mixins/_m-breakpoints.scss:
--------------------------------------------------------------------------------
1 | $av-breakpoints: (
2 | 'print': 'print', 'thumb': 'screen and (max-width: 499px)', 'handheld': 'screen and (min-width: 500px) and (max-width: 800px)', 'handheld-and-up': 'screen and (min-width: 500px)', 'pocket': 'screen and (max-width: 800px)', 'lap': 'screen and (min-width: 801px) and (max-width: 1024px)', 'lap-and-up': 'screen and (min-width: 801px)', 'portable': 'screen and (max-width: 1024px)', 'desk': 'screen and (min-width: 1025px)', 'widescreen': 'screen and (min-width: 1160px)', 'retina': 'screen and (-webkit-min-device-pixel-ratio: 2), screen and (min-resolution: 192dpi), screen and (min-resolution: 2dppx)') !default; // Responsive breakpoints.
3 |
4 | @mixin mq($alias) {
5 | // Search breakpoint map for alias
6 | $query: map-get($av-breakpoints, $alias);
7 | // If alias exists, print out media query
8 | @if $query {
9 | @media #{$query} {
10 | @content;
11 | }
12 | }
13 |
14 | @else {
15 | @error 'No breakpoint found for #{$alias}';
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/views/components/c-newsletter.pug:
--------------------------------------------------------------------------------
1 | #mc_embed_signup
2 | h2 Don't miss the Front-End Checklist news!
3 |
4 | p Time to time I'll send you an email with all new evolutions and projects related to the Front-End Checklist. No spam, no cheese!
5 |
6 | form#mc-embedded-subscribe-form.validate(action='https://frontendchecklist.us4.list-manage.com/subscribe/post?u=766ec606ec124252ef84eae4e&id=ef844c4ec4', method='post', name='mc-embedded-subscribe-form', target='_blank', novalidate='')
7 | #mc_embed_signup_scroll
8 | input#mce-EMAIL.email(type='email', value='', name='EMAIL', placeholder='Enter your Email address', required='', aria-label="Email for newsletter")
9 | //- real people should not fill this in and expect good things - do not remove this or risk form bot signups
10 | div(style='position: absolute; left: -5000px;', aria-hidden='true')
11 | input(type='text', name='b_766ec606ec124252ef84eae4e_ef844c4ec4', tabindex='-1', value='')
12 | .clear
13 | input#mc-embedded-subscribe.button(type='submit', value='Subscribe', name='subscribe')
14 |
--------------------------------------------------------------------------------
/src/views/components/c-corner.pug:
--------------------------------------------------------------------------------
1 | .c-github-corner
2 | a(href=translation.URL_GITHUB_ROOT class="github-corner" aria-label="View source on Github")
3 | svg(width="80" height="80" viewBox="0 0 250 250" aria-hidden="true")
4 | path(d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z")
5 | path(d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" class="octo-arm")
6 | path(d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body")
7 |
--------------------------------------------------------------------------------
/src/views/components/c-tag-filter.pug:
--------------------------------------------------------------------------------
1 | //- Array container for each filters
2 | - tagFilter = []
3 |
4 | //- Loop to save each tags present in JSON into tagFilter
5 | each item, i in _items
6 |
7 | each tagList in item
8 |
9 | each tag in tagList.tags
10 |
11 | //- Check if the filter tag already exist in the tagFilter array
12 | - if (tagFilter.indexOf(tag) === -1)
13 | - tagFilter.push(tag)
14 |
15 | //- Filter code implementation
16 | aside.c-tag-filter
17 | h2.c-tag-filter__title= translation.SECTION_TAG
18 |
19 | ul.c-tag-filter__list
20 |
21 | //- Loop to grab each title in the tagFilter array
22 | each title in tagFilter
23 |
24 | //- Add uppercase in the first letter
25 | - titleFilter = title.charAt(0).toUpperCase() + title.slice(1)
26 |
27 | //- Slip and add a dash if the tag is more than 1 word
28 | - dataFilter = title.split(' ').join('-')
29 |
30 | //- Check if title is not empty before printing it
31 | if title != ''
32 | li.c-tag-filter__item
33 | button.js-filter-tag(data-tag=`${dataFilter}`)= titleFilter
34 |
--------------------------------------------------------------------------------
/src/safari-pinned-tab.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
22 |
--------------------------------------------------------------------------------
/src/styles/config/_v-typography.scss:
--------------------------------------------------------------------------------
1 |
2 | $text: map-get($colors, grey-dark) !default;
3 | $text-light: map-get($colors, grey) !default;
4 | $text-strong: map-get($colors, grey-darker) !default;
5 |
6 | // Typography
7 | $family-sans-serif: BlinkMacSystemFont, -apple-system, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif !default;
8 | $family-monospace: monospace !default;
9 | $render-mode: optimizeLegibility !default;
10 | $family-primary: $family-sans-serif !default;
11 | $family-code: $family-monospace !default;
12 | $weight-light: 300 !default;
13 | $weight-normal: 400 !default;
14 | $weight-semibold: 500 !default;
15 | $weight-bold: 700 !default;
16 | $size-1: 3rem !default;
17 | $size-2: 2.5rem !default;
18 | $size-3: 2rem !default;
19 | $size-4: 1.5rem !default;
20 | $size-5: 1.25rem !default;
21 | $size-6: 1rem !default;
22 | $size-7: .75rem !default;
23 | $size-small: $size-7 !default;
24 | $size-normal: $size-6 !default;
25 | $size-medium: $size-5 !default;
26 | $size-large: $size-4 !default;
27 | $sizes: $size-1 $size-2 $size-3 $size-4 $size-5 $size-6 $size-7 !default;
28 |
--------------------------------------------------------------------------------
/src/views/components/svg/reset.pug:
--------------------------------------------------------------------------------
1 | svg(xmlns='http://www.w3.org/2000/svg', width='30', height='30', viewbox='0 0 94.073 94.072' aria-hidden="true")&attributes(attributes)
2 | title Two arrows turn around
3 | path(d='M91.465 5.49c-.748-.31-1.61-.138-2.18.435L80.97 14.24C72.045 5.058 60.124 0 47.4 0c-2.693 0-5.408.235-8.07.697C21.22 3.845 6.543 17.405 1.945 35.244c-.155.6-.023 1.235.355 1.724.378.49.96.775 1.58.775h12.738c.84 0 1.59-.524 1.878-1.313 3.73-10.193 12.992-17.97 23.598-19.814 1.747-.303 3.525-.456 5.288-.456 8.428 0 16.3 3.374 22.168 9.5l-8.445 8.444c-.57.572-.742 1.432-.434 2.18.312.747 1.04 1.234 1.85 1.234H90.7c1.104 0 2-.896 2-2V7.338c0-.808-.49-1.537-1.235-1.847z')
4 | path(d='M90.192 56.328H77.455c-.84 0-1.59.523-1.878 1.312-3.73 10.193-12.992 17.972-23.598 19.814-1.75.303-3.526.456-5.29.456-8.427 0-16.3-3.374-22.167-9.5l8.444-8.444c.572-.572.743-1.432.434-2.18-.31-.747-1.038-1.234-1.847-1.234H3.373c-1.103 0-2 .896-2 2v28.18c0 .81.488 1.54 1.236 1.85.745.31 1.606.137 2.178-.436l8.316-8.315c8.922 9.184 20.843 14.242 33.57 14.242 2.692 0 5.407-.235 8.068-.697 18.112-3.146 32.79-16.708 37.387-34.547.154-.6.022-1.234-.355-1.725-.38-.488-.964-.775-1.583-.775z')
5 |
--------------------------------------------------------------------------------
/src/views/mixins/m-checklist-section.pug:
--------------------------------------------------------------------------------
1 | mixin checklist-section(options)
2 |
3 | - sectionId = '0'; //- Start with 0 to have 1 as first section
4 | - sectionTitle = options.sectionTitle || '';
5 | - dataSection = options.dataSection || [];
6 | - filter = options.filter || 'all';
7 |
8 | //- Push each section title to build navigation bar
9 | - listSections.push(sectionTitle.toLowerCase())
10 |
11 | //- Add a 0 in the array everytime the mixin is called
12 | - listSectionId.push(sectionId++)
13 |
14 |
15 | //- Section
16 | section.s-checklist.js-section(class="s-checklist__" + sectionTitle.toLowerCase(), data-section=sectionTitle.toLowerCase(), data-section-id=`${listSectionId.length-1}`, id="section-" + sectionTitle.toLowerCase())
17 | .s-checklist__inner
18 | .s-checklist__header
19 |
20 | .s-checklist__title
21 |
22 | h2.s-checklist__header__title= sectionTitle
23 |
24 | include ../components/c-progress
25 |
26 | include ../components/c-tools
27 |
28 | .s-checklist__body.js-checklist-body(data-body-visibility="visible", aria-hidden="false")
29 |
30 | //- Include checklist component
31 | include ../components/c-checklist
32 |
--------------------------------------------------------------------------------
/src/service-worker.js:
--------------------------------------------------------------------------------
1 | // importScripts('/cache-polyfill.js');
2 | 'use strict';
3 |
4 | var version = 'v1::';
5 |
6 | self.addEventListener("install", function(event) {
7 | // console.log('WORKER: install event in progress.');
8 | event.waitUntil(
9 | /* The caches built-in is a promise-based API that helps you cache responses,
10 | as well as finding and deleting them.
11 | */
12 | caches
13 | /* You can open a cache by name, and this method returns a promise. We use
14 | a versioned cache name here so that we can remove old cache entries in
15 | one fell swoop later, when phasing out an older service worker.
16 | */
17 | .open(version + 'fundamentals')
18 | .then(function(cache) {
19 | /* After the cache is opened, we can fill it with the offline fundamentals.
20 | The method below will add all resources we've indicated to the cache,
21 | after making HTTP requests for each of them.
22 | */
23 | return cache.addAll([
24 | '/',
25 | '/index.html',
26 | '/styles/main.min.css',
27 | '/scripts/app.bundle.js'
28 | ]);
29 | })
30 | .then(function() {
31 | // console.log('WORKER: install completed');
32 | })
33 | );
34 | });
35 |
--------------------------------------------------------------------------------
/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @charset 'utf-8';
2 |
3 | // Config and utilities
4 | @import 'config/variables';
5 | @import 'config/v-namespaces';
6 | @import 'config/v-colors';
7 | @import 'config/v-typography';
8 | @import 'utilities/functions/functions';
9 | @import 'utilities/mixins/mixins';
10 | @import 'utilities/utilities';
11 |
12 | // General styling using DOM element selectors
13 | @import 'base/print';
14 | @import 'base/fonts';
15 | @import 'base/icons';
16 | @import 'base/generic';
17 | @import 'base/headings';
18 | @import 'base/form';
19 | @import 'base/media';
20 | @import 'base/links';
21 | @import 'base/typography';
22 |
23 | // Layout
24 | @import 'layout/page';
25 | @import 'layout/s-header';
26 | @import 'layout/s-aside';
27 | @import 'layout/s-main';
28 | @import 'layout/s-checklist';
29 | @import 'layout/s-footer';
30 |
31 | // Components
32 | @import 'components/c-top-alert';
33 | @import 'components/c-sponsor';
34 | @import 'components/c-button';
35 | @import 'components/c-checklist';
36 | @import 'components/c-dropdown';
37 | @import 'components/c-newsletter';
38 | @import 'components/c-github';
39 | @import 'components/c-tools';
40 | @import 'components/c-list';
41 | @import 'components/c-nav';
42 | @import 'components/c-progress';
43 | @import 'components/c-notation';
44 | @import 'components/c-tags';
45 |
--------------------------------------------------------------------------------
/src/styles/base/_form.scss:
--------------------------------------------------------------------------------
1 | fieldset {
2 | border: 0;
3 | margin: 0;
4 | }
5 |
6 | label:hover {
7 | cursor: pointer;
8 | }
9 |
10 | .s-form {
11 | margin: 10px 0 20px;
12 |
13 | @include mq('handheld-and-up') {
14 | margin-bottom: 20px;
15 | }
16 | }
17 |
18 | .form {
19 | input {
20 | font-size: 1.5rem;
21 | padding: 5px;
22 | display: block;
23 | border: 0;
24 | width: 100%;
25 | border-radius: 0;
26 | border-bottom: 1px solid #757575;
27 |
28 | @include mq('handheld-and-up') {
29 | width: 300px;
30 | }
31 |
32 | &:focus {
33 | outline: none;
34 | }
35 |
36 | &:focus ~ label,
37 | &:valid ~ label {
38 | top: -15px;
39 | font-size: 12px;
40 | color: map-get($colors, $primary);
41 | }
42 | }
43 |
44 | label {
45 | color: #999999;
46 | font-size: 14px;
47 | font-weight: normal;
48 | position: absolute;
49 | pointer-events: none;
50 | left: 5px;
51 | top: 0;
52 | transition: .2s ease all;
53 | }
54 | }
55 |
56 | .form-group {
57 | position: relative;
58 | margin: 20px 0;
59 |
60 | &:last-of-type {
61 | margin: 20px 0 0;
62 | }
63 | }
64 |
65 | .label__title {
66 | font-weight: bold;
67 | display: inline;
68 | }
69 |
70 | label,
71 | .nav li a,
72 | .nav li input {
73 | transition: background-color .08s ease-in-out;
74 | }
75 |
--------------------------------------------------------------------------------
/src/styles/base/_generic.scss:
--------------------------------------------------------------------------------
1 | $body-background-color: #ededed !default;
2 | $body-size: 62.5% !default;
3 | $body-rendering: optimizeLegibility !default;
4 | $body-family: $family-sans-serif !default;
5 | $body-color: $text !default;
6 | $body-weight: $weight-normal !default;
7 | $body-line-height: 1.5 !default;
8 |
9 | // $hr-background-color: $border !default;
10 | $hr-height: 1px !default;
11 | $hr-margin: 1.5rem 0 !default;
12 | $strong-color: $text-strong !default;
13 | $strong-weight: $weight-bold !default;
14 |
15 | // Set box-sizing globally to handle padding and border widths
16 | *,
17 | *::after,
18 | *::before {
19 | box-sizing: inherit;
20 | }
21 |
22 | // The base font-size is set at 62.5% for having the convenience
23 | // of sizing rems in a way that is similar to using px: 1.6rem = 16px
24 | html {
25 | background-color: $body-background-color;
26 | min-width: 100%;
27 | overflow-x: hidden;
28 | overflow-y: scroll;
29 | box-sizing: border-box;
30 | font-size: $body-size;
31 | text-rendering: $body-rendering;
32 | -moz-osx-font-smoothing: grayscale;
33 | -webkit-font-smoothing: antialiased;
34 | scroll-behavior: smooth;
35 | }
36 |
37 | // Default body styles
38 | body {
39 | color: $body-color;
40 | font-size: 1rem;
41 | font-weight: $body-weight;
42 | line-height: $body-line-height;
43 | font-family: $family-sans-serif;
44 | margin: 0;
45 | }
46 |
--------------------------------------------------------------------------------
/src/views/base/footer.pug:
--------------------------------------------------------------------------------
1 | footer.page-footer
2 | .s-footer
3 |
4 | .s-footer__badges
5 |
6 | p
7 | a(href="https://github.com/thedaviddias/Front-End-Checklist/")
8 | img(src="https://camo.githubusercontent.com/05034eed0515ee94cb8c8829dad9ace1f4e7d79e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f46726f6e74254532253830253931456e645f436865636b6c6973742d666f6c6c6f7765642d627269676874677265656e2e737667" alt="Front‑End_Checklist followed" data-canonical-src="https://img.shields.io/badge/Front%E2%80%91End_Checklist-followed-brightgreen.svg")
9 |
10 | .s-footer__grateful
11 |
12 | p Accelerated by #[a(href="https://www.keycdn.com/" target='_blank', rel="noopener noreferrer") KeyCDN]
13 |
14 | p Icons made by #[a(href='http://www.freepik.com' target='_blank', rel="nofollow noopener noreferrer") Freepik] from #[a(href='https://www.flaticon.com/', title='Flaticon' rel="nofollow noopener noreferrer") www.flaticon.com] is licensed by #[a(href='http://creativecommons.org/licenses/by/3.0/', title='Creative Commons BY 3.0', target='_blank', rel="noopener noreferrer") CC 3.0 BY]
15 |
16 | .s-footer__made
17 | p Made with ❤️ by #[a(href="https://thedaviddias.me") David Dias ("The")] #[a.twitter-follow-button(href="https://twitter.com/TwitterDev" data-show-count="false" data-show-screen-name="false") Follow @thedaviddias] for the Open-Source Community.
18 |
--------------------------------------------------------------------------------
/data/en/items/webfonts.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "Webfont format",
4 | "priority": "High",
5 | "description": "WOFF, WOFF2 and TTF are supported by all modern browsers.",
6 | "documentation": [
7 | {
8 | "title": "WOFF - Web Open Font Format - Caniuse",
9 | "url": "https://caniuse.com/#feat=woff"
10 | },
11 | {
12 | "title": "WOFF 2.0 - Web Open Font Format - Caniuse",
13 | "url": "https://caniuse.com/#feat=woff2"
14 | },
15 | {
16 | "title": "TTF/OTF - TrueType and OpenType font support",
17 | "url": "https://caniuse.com/#feat=ttf"
18 | },
19 | {
20 | "title": "Using @font-face - CSS-Tricks",
21 | "url": "https://css-tricks.com/snippets/css/using-font-face/"
22 | }
23 | ],
24 | "tags": ["all", "webfont"]
25 | },
26 | {
27 | "title": "Webfont size",
28 | "priority": "High",
29 | "description": "Webfont sizes don't exceed 2 MB (all variants included).",
30 | "tags": ["all", "webfont"]
31 | },
32 | {
33 | "title": "Webfont loader",
34 | "priority": "Low",
35 | "description": "Control loading behavior with a webfont loader.",
36 | "documentation": [
37 | {
38 | "title": "Typekit Web Font Loader",
39 | "url": "https://github.com/typekit/webfontloader"
40 | }
41 | ],
42 | "tags": ["all", "webfont"]
43 | }
44 | ]
45 |
--------------------------------------------------------------------------------
/src/styles/layout/_page.scss:
--------------------------------------------------------------------------------
1 | $layout-width: '1140px' !default;
2 | $av-element-class-chain: '__' !default; // Chain characters between block and element
3 | $av-modifier-class-chain: '--' !default; // Chain characters between block and modifier
4 | $av-breakpoint-class-chain: '--' !default; // Chain characters between width and breakpoint
5 | $logo-width: 150px;
6 |
7 | .page-wrapper {
8 | display: grid;
9 | grid-template-columns: auto;
10 | grid-template-areas:
11 | 'header'
12 | 'main'
13 | 'footer';
14 |
15 | @include mq('lap-and-up') {
16 | grid-template-areas: 'header header header' 'main main main' 'footer footer footer';
17 | }
18 |
19 | .page-header {
20 | grid-area: header;
21 | }
22 |
23 | .page-main {
24 | grid-area: main;
25 |
26 | @include mq('lap-and-up') {
27 | display: grid;
28 | grid-template-columns: auto 150px 960px 150px auto;
29 | }
30 | }
31 |
32 | .page-footer {
33 | grid-area: footer;
34 | }
35 | }
36 |
37 |
38 | .page-header {
39 | &__logo {
40 | grid-area: header-left;
41 | align-self: center;
42 |
43 | .page-header__inner--centered & {
44 | grid-area: header-center;
45 | justify-self: center;
46 | }
47 | }
48 |
49 | &__nav {
50 | grid-area: header-right;
51 | align-self: center;
52 | display: flex;
53 |
54 | & .version-01 {
55 | grid-column-start: 3;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/styles/layout/_s-main.scss:
--------------------------------------------------------------------------------
1 | .s-main {
2 | display: grid;
3 | grid-column-start: 1;
4 | position: relative;
5 | background-color: map-get($colors, white);
6 | text-align: left;
7 | padding: 0 10px;
8 |
9 | &__section {
10 | margin: 0 0 10px;
11 | }
12 |
13 | @include mq('handheld-and-up') {
14 | display: grid;
15 | grid-column-start: 3;
16 | margin-top: -50px;
17 | width: 100%;
18 | padding: 10px;
19 | border-radius: 5px;
20 | border-color: rgba(0, 0, 0, .1);
21 | border-style: solid;
22 | border-width: 1px;
23 | }
24 |
25 | &__section:nth-child(1) {
26 | order: 2;
27 |
28 | @include mq('handheld-and-up') {
29 | padding: 0 20px;
30 | }
31 | }
32 |
33 | &__section:nth-child(2) {
34 | order: 4;
35 |
36 | @include mq('handheld-and-up') {
37 | padding: 0 20px;
38 | }
39 | }
40 |
41 | &__section:nth-child(3) {
42 | order: 4;
43 | }
44 |
45 | &__section:nth-child(4) {
46 | text-align: center;
47 | order: 5;
48 | }
49 |
50 | &__section:nth-child(5) {
51 | order: 1;
52 | }
53 |
54 | &__item {
55 | background: #ff6600;
56 | }
57 |
58 | &__header {
59 | text-align: center;
60 | z-index: 99999;
61 | }
62 |
63 | &__meta {
64 | display: none;
65 |
66 | @include mq('handheld-and-up') {
67 | display: flex;
68 | justify-content: flex-end;
69 | }
70 | }
71 | }
72 |
73 |
74 | .s-meta {
75 | text-align: left;
76 | }
77 |
--------------------------------------------------------------------------------
/src/styles/base/_fonts.scss:
--------------------------------------------------------------------------------
1 | // =============================================================================
2 | // String Replace
3 | // =============================================================================
4 |
5 | @function str-replace($string, $search, $replace: '') {
6 | $index: str-index($string, $search);
7 |
8 | @if $index {
9 | @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
10 | }
11 |
12 | @return $string;
13 | }
14 | // =============================================================================
15 | // Font Face
16 | // =============================================================================
17 | @mixin font-face($name, $path, $weight: null, $style: null, $exts: eot woff2 woff ttf svg) {
18 | $src: null;
19 | $extmods: (eot: '?', svg: '#' + str-replace($name, ' ', '_'));
20 | $formats: (otf: 'opentype', ttf: 'truetype');
21 |
22 | @each $ext in $exts {
23 | $extmod: if(map-has-key($extmods, $ext), $ext + map-get($extmods, $ext), $ext);
24 | $format: if(map-has-key($formats, $ext), map-get($formats, $ext), $ext);
25 | $src: append($src, url(quote($path + '.' + $extmod)) format(quote($format)), comma);
26 | }
27 |
28 | @font-face {
29 | font-family: quote($name);
30 | font-style: $style;
31 | font-weight: $weight;
32 | src: $src;
33 | }
34 | }
35 |
36 | // @include font-face(Samplinal, fonts/Samplinal, 500, normal, eot woff2 woff);
37 |
--------------------------------------------------------------------------------
/src/views/index-en.pug:
--------------------------------------------------------------------------------
1 | extends base/layout
2 |
3 | //- Block main
4 | block main
5 |
6 | include components/s-section-top
7 |
8 | //- List each section (the order is linked to the order of the c-nav)
9 | //- _items is in the JSON injected in the view with gulp-data (called _project.json)
10 | .s-main__section.s-main__checklist
11 |
12 | if _items !== undefined
13 |
14 | +checklist-section({
15 | dataSection: _items.head,
16 | sectionTitle: "Head"
17 | })
18 |
19 | +checklist-section({
20 | dataSection: _items.html,
21 | sectionTitle: "HTML"
22 | })
23 |
24 | +checklist-section({
25 | dataSection: _items.webfonts,
26 | sectionTitle: "Webfonts"
27 | })
28 |
29 | +checklist-section({
30 | dataSection: _items.css,
31 | sectionTitle: "CSS"
32 | })
33 |
34 | +checklist-section({
35 | dataSection: _items.javascript,
36 | sectionTitle: "JavaScript"
37 | })
38 |
39 | +checklist-section({
40 | dataSection: _items.images,
41 | sectionTitle: "Images"
42 | })
43 |
44 | +checklist-section({
45 | dataSection: _items.accessibility,
46 | sectionTitle: "Accessibility"
47 | })
48 |
49 | +checklist-section({
50 | dataSection: _items.performance,
51 | sectionTitle: "Performance"
52 | })
53 |
54 | +checklist-section({
55 | dataSection: _items.seo,
56 | sectionTitle: "SEO"
57 | })
58 |
59 | include components/s-section-bottom
60 |
--------------------------------------------------------------------------------
/src/views/components/c-checklist.pug:
--------------------------------------------------------------------------------
1 | .c-checklist
2 |
3 | //- Grab introduction based on the name of the section
4 | if introductions[0][sectionTitle.toLowerCase()]
5 |
6 | each el in introductions[0][sectionTitle.toLowerCase()]
7 |
8 | p.c-checklist__intro= el
9 |
10 | //- List of all items elements based on the dataSection variable
11 | ul.c-checklist__list
12 |
13 | each item, i in dataSection
14 |
15 | include ../components/checklist/class
16 |
17 | //- data-item-check (false or true) => Element is checked or not
18 | //- data-item-priority (high, medium or low) => The priority of the task
19 | //- data-item-id (number) => the ID of the elements based on dataSection array
20 | //- data-item-dropdown (open close or false) => State of the dropdown
21 | //- data-item-visible (true or false) => Visibility of the item used by the tag filter
22 | li.c-checklist__item.js-item(class=` ${allClass}`, data-item-priority=priorityClass ,data-item-id=i, data-item-check="false", data-item-dropdown=dataItemDropdown, data-item-visible="true" aria-hidden="false")
23 |
24 | .c-checklist__item__inner
25 |
26 | .c-checklist__body
27 |
28 | //- Columns of the item
29 |
30 | //- Priority column
31 | include ../components/checklist/priority
32 |
33 | //- Checkbox column
34 | include ../components/checklist/checkbox
35 |
36 | //- Label column
37 | include ../components/checklist/label
38 |
39 | //- Dropdown column
40 | include ../components/checklist/dropdown
41 |
--------------------------------------------------------------------------------
/src/styles/components/_c-github.scss:
--------------------------------------------------------------------------------
1 | .github-corner:hover .octo-arm {
2 | animation: octocat-wave 560ms ease-in-out;
3 | }
4 |
5 | .github-corner {
6 | svg {
7 | fill: white;
8 | color: #151513;
9 | position: absolute;
10 | top: 0;
11 | border: 0;
12 | right: 0;
13 | }
14 |
15 | .octo-arm {
16 | transform-origin: 130px 106px;
17 | }
18 | }
19 |
20 | @keyframes octocat-wave {
21 | 0%,
22 | 100% {
23 | transform: rotate(0);
24 | }
25 |
26 | 20%,
27 | 60% {
28 | transform: rotate(-25deg);
29 | }
30 |
31 | 40%,
32 | 80% {
33 | transform: rotate(10deg);
34 | }
35 | }
36 |
37 | @media (max-width: 500px) {
38 | .github-corner:hover .octo-arm {
39 | animation: none;
40 | }
41 |
42 | .github-corner .octo-arm {
43 | animation: octocat-wave 560ms ease-in-out;
44 | }
45 | }
46 |
47 |
48 | .gist {
49 | display: block !important;
50 | position: relative !important;
51 | margin: 0 !important;
52 | width: calc(100%) !important; /* Fill 100% of the parent container with an extra 30px on each side */
53 | overflow: hidden !important;
54 | }
55 |
56 | .gist-file {
57 | margin: 0 !important;
58 | border: none !important;
59 | }
60 |
61 | .gist-data {
62 | padding: 5px !important;
63 | border: 0 !important;
64 | border-bottom: none !important;
65 | border-radius: 0;
66 | }
67 |
68 | .gist .gist-meta {
69 | color: map-get($colors, black) !important;
70 | border: 0 !important;
71 | border-radius: 0;
72 | padding: 3px !important;
73 | font-size: 8px !important;
74 |
75 | @include mq('handheld-and-up') {
76 | font-size: 10px !important;
77 | padding: 5px !important;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/views/index-jp.pug:
--------------------------------------------------------------------------------
1 | extends base/layout
2 |
3 | //- Block main
4 | block main
5 |
6 | include components/s-section-top
7 |
8 | //- List each section (the order is linked to the order of the c-nav)
9 | //- _items is in the JSON injected in the view with gulp-data (called _project.json)
10 | .s-main__section.s-main__checklist
11 |
12 | if _items !== undefined
13 |
14 | +checklist-section({
15 | dataSection: _items.利用方法,
16 | sectionTitle: "利用方法"
17 | })
18 |
19 | //- +checklist-section({
20 | //- dataSection: _items.html,
21 | //- sectionTitle: "HTML"
22 | //- })
23 |
24 | //- +checklist-section({
25 | //- dataSection: _items.webfonts,
26 | //- sectionTitle: "Webfonts"
27 | //- })
28 |
29 | //- +checklist-section({
30 | //- dataSection: _items.css,
31 | //- sectionTitle: "CSS"
32 | //- })
33 |
34 | //- +checklist-section({
35 | //- dataSection: _items.javascript,
36 | //- sectionTitle: "JavaScript"
37 | //- })
38 |
39 | //- +checklist-section({
40 | //- dataSection: _items.images,
41 | //- sectionTitle: "Images"
42 | //- })
43 |
44 | //- +checklist-section({
45 | //- dataSection: _items.accessibility,
46 | //- sectionTitle: "Accessibility"
47 | //- })
48 |
49 | //- +checklist-section({
50 | //- dataSection: _items.performance,
51 | //- sectionTitle: "Performance"
52 | //- })
53 |
54 | //- +checklist-section({
55 | //- dataSection: _items.seo,
56 | //- sectionTitle: "SEO"
57 | //- })
58 |
59 | include components/s-section-bottom
60 |
--------------------------------------------------------------------------------
/src/views/base/header.pug:
--------------------------------------------------------------------------------
1 | header.s-header
2 |
3 | include ../components/c-corner
4 |
5 | .s-header__banner
6 | .text-center
7 | picture
8 | source(srcset="/img/logos/logo-front-end-checklist.webp" type="image/webp")
9 | source(srcset="/img/logos/logo-front-end-checklist.jpg" type="image/jpeg")
10 | img.img-logo(src="/img/logos/logo-front-end-checklist.jpg" alt="Front-End Checklist Logo" width="100" height="100")
11 | h1.font-weight-bold= translation.SITE_NAME
12 | p.sub-heading= translation.SITE_TAGLINE
13 |
14 | .s-header__media
15 | ul.s-header__media__list
16 | li.s-header__media__item
17 | .fb-like(data-href=translation.URL_WEBSITE data-layout="button_count" data-action="like" data-size="small" data-show-faces="true" data-share="true")
18 | li.s-header__media__item
19 | a(href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-text=translation.social.TWITTER_MSG data-via=translation.social.TWITTER_VIA data-hashtags=translation.social.TWITTER_HASHTAGS data-show-count="false")= translation.social.TWEET
20 | li.s-header__media__item
21 | a.github-button(href=translation.URL_GITHUB_ROOT data-icon="octicon-star" data-show-count="true" aria-label=translation.social.GITHUB_STAR_MSG)= translation.social.STAR
22 |
23 | //- Add new language manually
24 | .s-header__lang
25 | ul.s-header__lang__list
26 | li.s-header__lang__item
27 | a(href="/")
28 | img(src="/img/flags/en.svg" width="20" height="15" alt="English language")
29 | li.s-header__lang__item
30 | a(href="/jp")
31 | img(src="/img/flags/jp.svg" width="20" height="15" alt="Japanese language")
32 |
--------------------------------------------------------------------------------
/src/views/components/c-notation.pug:
--------------------------------------------------------------------------------
1 | .c-notation
2 |
3 | - priority = []
4 | - totalHigh = []
5 | - totalMedium = []
6 | - totalLow = []
7 |
8 | each item, i in locals._items
9 |
10 | each item2 in item
11 |
12 | - priority.push(item2.priority)
13 |
14 | each el, i in priority
15 |
16 | if (el == 'High')
17 | - totalHigh.push('1')
18 |
19 | else if (el == 'Medium')
20 | - totalMedium.push('1')
21 |
22 | else
23 | - totalLow.push('1')
24 |
25 | .c-notation__details
26 | ul.c-notation__details__list
27 | li.c-notation__details__item.js-detail-high
28 | +svg-icon.icon.icon--small.icon-priority--high(data-icon-name='bullet')
29 | span.js-notation-checked 0
30 | |/
31 | span.js-notation-total= totalHigh.length
32 | | #[=translation.HIGH_CHECKED]
33 | li.c-notation__details__item.js-detail-medium
34 | +svg-icon.icon.icon--small.icon-priority--medium(data-icon-name='bullet')
35 | span.js-notation-checked 0
36 | |/
37 | span.js-notation-total= totalMedium.length
38 | | #[=translation.MEDIUM_CHECKED]
39 | li.c-notation__details__item.js-detail-low
40 | +svg-icon.icon.icon--small.icon-priority--low(data-icon-name='bullet')
41 | span.js-notation-checked 0
42 | |/
43 | span.js-notation-total= totalLow.length
44 | | #[=translation.LOW_CHECKED]
45 |
46 | .c-notation__box
47 | #js-notation.c-notation__item(data-notation="0")
48 | span.c-notation__letter X
49 |
50 |
51 | .c-notation__generate
52 | button.button.--fill.--large.js-print
53 | +svg-icon.icon.icon-print(data-icon-name='print')
54 | | #[=translation.form.BUTTON_GENERATE_PRINT]
55 |
--------------------------------------------------------------------------------
/src/styles/layout/_s-checklist.scss:
--------------------------------------------------------------------------------
1 | .s-checklist {
2 | position: relative;
3 | min-height: 1px;
4 |
5 | @include mq('handheld-and-up') {
6 | padding: 0 10px;
7 | }
8 |
9 | @include mq('print') {
10 | padding: 15px 0;
11 |
12 | &:first-child {
13 | padding: 0 0 15px;
14 | }
15 | }
16 |
17 | &::after {
18 | content: '';
19 | position: absolute;
20 | height: 2px;
21 | border-top: 1px solid #e4ebf0;
22 | bottom: 0;
23 | width: 98%;
24 | }
25 |
26 | &__inner {
27 | display: grid;
28 | }
29 |
30 | &__body {
31 | padding: 0;
32 |
33 | .introduction {
34 | text-align: center;
35 | }
36 |
37 | .slide {
38 | display: grid;
39 | }
40 | }
41 |
42 | &__header {
43 | padding: 15px 0;
44 | z-index: 58;
45 |
46 | @include mq('print') {
47 | padding: 0;
48 | }
49 |
50 | @include mq('handheld-and-up') {
51 | display: flex;
52 | align-items: center;
53 | justify-content: space-between;
54 | }
55 | }
56 |
57 | &__title {
58 | @include mq('print') {
59 | display: flex;
60 | }
61 |
62 | @include mq('handheld-and-up') {
63 | display: flex;
64 | align-items: center;
65 | justify-content: center;
66 | }
67 | }
68 |
69 | &__header__title {
70 | margin: 0;
71 | text-align: left;
72 | color: rgb(65, 82, 87);
73 | font-weight: bold;
74 | text-transform: uppercase;
75 | line-height: 1.2;
76 | font-size: 2.5rem;
77 |
78 | @include mq('handheld-and-up') {
79 | font-size: 4rem;
80 | margin: 0;
81 | }
82 | }
83 |
84 | &__progress {
85 | display: flex;
86 | }
87 |
88 | &__footer {
89 | text-align: center;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/styles/components/_c-progress.scss:
--------------------------------------------------------------------------------
1 | @if $use-progress == true {
2 |
3 | $i: 0;
4 |
5 | #{$namespace-progress} {
6 | position: relative;
7 | display: flex;
8 | padding: 10px 0;
9 |
10 | @include mq('handheld-and-up') {
11 | padding: 0;
12 | display: block;
13 | }
14 |
15 | &__counter {
16 | text-align: center;
17 | margin-left: 20px;
18 |
19 | @include mq('handheld-and-up') {
20 | margin: 0;
21 | }
22 | }
23 |
24 | &__label {
25 | font-size: 1.3rem;
26 | font-weight: 600;
27 |
28 | @include mq('handheld-and-up') {
29 | position: absolute;
30 | top: 28%;
31 | left: 50%;
32 | transform: translate(-50%, -50%);
33 | }
34 | }
35 |
36 | &__text {
37 | font-size: 1.3rem;
38 |
39 | @include mq('handheld-and-up') {
40 | font-size: 1.1rem;
41 | padding: 0 5px;
42 | }
43 | }
44 | }
45 |
46 | .c-progress__bar {
47 | background-color: map-get($shades, white-ter);
48 | border: 0;
49 | height: 19px;
50 | border-radius: 3px;
51 | width: 120px;
52 |
53 | @include mq('handheld-and-up') {
54 | height: 20px;
55 | margin: 0 20px;
56 | }
57 |
58 | .c-progress--big & {
59 | height: 30px;
60 | width: 150px;
61 | }
62 |
63 | &::-webkit-progress-value {
64 | border-radius: 2px;
65 | }
66 |
67 | @while $i < 100 {
68 | $i: $i + 1;
69 | $hue: round((65 / 100) * $i);
70 |
71 | &[value='#{$i}'] {
72 | &::-webkit-progress-value {
73 | background-color: adjust-hue($progress-20, $hue);
74 | }
75 | }
76 | }
77 |
78 | &::-webkit-progress-bar {
79 | background-color: map-get($shades, white-ter);
80 | transition: all 300ms ease-in 0s;
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/styles/components/_c-notation.scss:
--------------------------------------------------------------------------------
1 | .c-notation__details__list {
2 | margin: 0;
3 | padding: 5px 0;
4 | text-align: left;
5 | }
6 |
7 | .c-notation__details__item {
8 | font-size: 1.3rem;
9 |
10 | .icon {
11 | display: inline-block;
12 | margin-right: 5px;
13 | }
14 | }
15 |
16 | // Declarations
17 | // =============================================================================
18 | .c-notation {
19 | display: flex;
20 | align-content: space-between;
21 | justify-content: space-between;
22 | margin: 15px 0 0;
23 |
24 | &__box {
25 | position: relative;
26 | }
27 |
28 | &__letter {
29 | position: absolute;
30 | top: 50%;
31 | left: 50%;
32 | transform: translate(-50%, -50%);
33 | text-align: center;
34 | font-size: 45px;
35 | color: white;
36 | line-height: 1;
37 | }
38 |
39 | &__item {
40 | width: 75px;
41 | height: 75px;
42 | background: #f3f3f3;
43 | position: relative;
44 | }
45 |
46 | &__generate {
47 | text-align: right;
48 | margin-top: 15px;
49 | }
50 |
51 | &__details {
52 | font-size: 1.2rem;
53 | }
54 | }
55 | $notation: -1;
56 |
57 | @while $notation <= 100 {
58 | $notation: $notation + 1;
59 |
60 | [data-notation='#{$notation}'] {
61 | @if $notation <= 20 {
62 | background-color: $progress-0;
63 | }
64 |
65 | @else if $notation <= 40 {
66 | background-color: $progress-20;
67 | }
68 |
69 | @else if $notation <= 60 {
70 | background-color: $progress-40;
71 | }
72 |
73 | @else if $notation <= 80 {
74 | background-color: $progress-60;
75 | }
76 |
77 | @else if $notation < 100 {
78 | background-color: $progress-80;
79 | }
80 |
81 | @else if $notation == 100 {
82 | background-color: $progress-100;
83 | }
84 |
85 | @else {
86 | background-color: $progress-0;
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/styles/components/_c-newsletter.scss:
--------------------------------------------------------------------------------
1 | /* MailChimp Form Embed Code - Horizontal Super Slim - 12/16/2015 v10.7
2 | Adapted from: http://blog.heyimcat.com/universal-signup-form/ */
3 |
4 | .mc-field-group {
5 | display: inline-block;
6 | }
7 |
8 | #mc_embed_signup {
9 | @include mq('print') {
10 | display: none;
11 | }
12 |
13 |
14 | form {
15 | text-align: center;
16 | padding: 10px 0;
17 | }
18 |
19 | input.email {
20 | font-size: 15px;
21 | border: 1px solid #abb0b2;
22 | -webkit-border-radius: 3px;
23 | -moz-border-radius: 3px;
24 | border-radius: 3px;
25 | color: #343434;
26 | background-color: white;
27 | box-sizing: border-box;
28 | height: 32px;
29 | padding: 0 5px;
30 | display: inline-block;
31 | margin: 0;
32 | width: 350px;
33 | vertical-align: top;
34 | }
35 |
36 | label {
37 | display: block;
38 | font-size: 16px;
39 | padding-bottom: 10px;
40 | font-weight: bold;
41 | }
42 |
43 | .clear {
44 | display: inline-block;
45 | }
46 |
47 | /* positions button horizontally in line with input */
48 | .button {
49 | font-size: 13px;
50 | border: none;
51 | border-radius: 3px;
52 | letter-spacing: 1px;
53 | color: white;
54 | background-color: #aaaaaa;
55 | box-sizing: border-box;
56 | height: 32px;
57 | line-height: 32px;
58 | padding: 0 18px;
59 | display: inline-block;
60 | margin: 0;
61 | transition: all .23s ease-in-out 0s;
62 | }
63 |
64 | .button:hover {
65 | background-color: #777777;
66 | cursor: pointer;
67 | }
68 | }
69 |
70 | @media (max-width: 768px) {
71 | #mc_embed_signup {
72 | input.email {
73 | width: 100%;
74 | margin-bottom: 5px;
75 | }
76 |
77 | .clear {
78 | display: block;
79 | width: 100%;
80 | }
81 |
82 | .button {
83 | width: 100%;
84 | margin: 0;
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/styles/base/_links.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Links
3 | //
4 |
5 | // Link colors
6 | $link: map-get($colors, primary) !default;
7 | $link-invert: map-get($colors, primary-invert) !default;
8 | $link-visited: map-get($colors, purple) !default;
9 | $link-hover: map-get($colors, grey-darker) !default;
10 | $link-hover-border: map-get($colors, grey-light) !default;
11 | $link-focus: map-get($colors, grey-darker) !default;
12 | $link-focus-border: map-get($colors, primary) !default;
13 | $link-active: map-get($colors, grey-darker) !default;
14 | $link-active-border: map-get($colors, grey-dark) !default;
15 | $link-color: $primary !default;
16 | $link-brand-color: #f40057 !default;
17 | $link-info-color: $info !default;
18 | $link-warning-color: $warning !default;
19 | $link-success-color: $success !default;
20 | $link-error-color: $danger !default;
21 | $link-text-decoration: none !default;
22 | $link-hover-text-decoration: underline !default;
23 |
24 | @mixin link--color($color: $link-color) {
25 | &:not(:disabled) {
26 | background-color: transparent;
27 | color: $link-color;
28 | // &:visited {
29 | // color: darken($color, $color-tint);
30 | // }
31 |
32 | &:hover {
33 | background-color: transparent;
34 | color: lighten($color, $color-tint);
35 | }
36 |
37 | &:active {
38 | background-color: transparent;
39 | color: lighten($color, $color-tint);
40 | }
41 | }
42 | }
43 |
44 | a,
45 | .c-link {
46 | @include link--color;
47 |
48 | text-decoration: $link-text-decoration;
49 | cursor: pointer;
50 |
51 | &:hover {
52 | text-decoration: $link-hover-text-decoration;
53 | }
54 | }
55 |
56 | .a-link--info {
57 | @include link--color($link-info-color);
58 | }
59 |
60 | .c-link--warning {
61 | @include link--color($link-warning-color);
62 | }
63 |
64 | .c-link--success {
65 | @include link--color($link-success-color);
66 | }
67 |
68 | .c-link--error {
69 | @include link--color($link-error-color);
70 | }
71 |
72 | // a:not( [href*='localhost:3000'] ):not( [href^='#'] ):not( [href^='/'] ):after {
73 | // content: " (external)";
74 | // }
75 |
--------------------------------------------------------------------------------
/src/precache-config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | staticFileGlobs: [
3 | 'index.html',
4 | 'manifest.json',
5 | 'favicon-32x32.png',
6 | 'android-chrome-192x192.png',
7 | 'favicon-16x16.png',
8 | 'safari-pinned-tab.svg',
9 | 'mstile-144x144.png',
10 | 'browserconfig.xml',
11 | 'apple-touch-icon.png'
12 | ],
13 | navigateFallback: '/index.html',
14 | navigateFallbackWhitelist: [/^\/user\//],
15 | skipWaiting: true,
16 | runtimeCaching: [
17 | {
18 | urlPattern: '/',
19 | handler: 'networkFirst',
20 | options: {
21 | cache: {
22 | name: 'src'
23 | }
24 | }
25 | },
26 | {
27 | urlPattern: /src/,
28 | handler: 'networkFirst',
29 | options: {
30 | cache: {
31 | name: 'src'
32 | }
33 | }
34 | },
35 | {
36 | urlPattern: /^https:\/\/api\.github\.com\/users\/[^\/]*\?/,
37 | handler: 'cacheFirst',
38 | options: {
39 | cache: {
40 | maxAgeSeconds: 60 * 60 * 4,
41 | name: 'users'
42 | }
43 | }
44 | },
45 | {
46 | urlPattern: /^https:\/\/api\.github\.com\/users\/[^\/]*\/repos\?.*$/,
47 | handler: 'cacheFirst',
48 | options: {
49 | cache: {
50 | maxAgeSeconds: 60 * 60 * 4,
51 | name: 'repos'
52 | }
53 | }
54 | },
55 | {
56 | urlPattern: /^https:\/\/api\.github\.com\/repos/,
57 | handler: 'cacheFirst',
58 | options: {
59 | cache: {
60 | maxAgeSeconds: 60 * 60 * 4,
61 | name: 'contributors'
62 | }
63 | }
64 | },
65 | {
66 | urlPattern: /^https:\/\/.*\.githubusercontent\.com\//,
67 | handler: 'cacheFirst',
68 | options: {
69 | cache: {
70 | maxAgeSeconds: 60 * 60 * 24,
71 | name: 'user-images'
72 | }
73 | }
74 | }
75 | ]
76 | };
77 |
--------------------------------------------------------------------------------
/data/en/project/translation.json:
--------------------------------------------------------------------------------
1 | {
2 | "SITE_NAME": "The Front-End Checklist",
3 | "INDEX_TITLE": "✨ Your best Front-End Tool ✨",
4 | "URL_WEBSITE": "https://frontendchecklist.io",
5 | "SITE_TAGLINE": "🗂 The Front-End Checklist Application is perfect for modern websites and meticulous developers!",
6 | "SITE_DESCRIPTION": "🗂 The Front-End Checklist Application is perfect for modern websites and meticulous developers! Follow the rules and deliver the best of your work in a generated report!",
7 | "SITE_LANGUAGE": "en",
8 | "SITE_DIRECTION": "ltr",
9 | "URL_GITHUB_ROOT": "https://github.com/thedaviddias/Front-End-Checklist",
10 | "URL_GITHUB_REPO": "https://github.com/thedaviddias/Front-End-Checklist/tree/gh-pages",
11 | "HIGH_CHECKED": "✓ high priority",
12 | "MEDIUM_CHECKED": "✓ medium priority",
13 | "LOW_CHECKED": "✓ low priority",
14 | "PERCENTAGE_CHECKED": "items are ✓",
15 | "SECTION_DOCUMENTATION": "Documentation",
16 | "SECTION_TOOL": "Tools",
17 | "SECTION_VIDEO": "Videos",
18 | "SECTION_TAG": "Filter by tags",
19 | "alert": {
20 | "JAVASCRIPT_DESACTIVATE": "Your JavaScript seems to be desactivated. Please enable your JavaScript to use all functionnalities of the Front-End Checklist."
21 | },
22 | "form": {
23 | "LABEL_PROJECT_NAME": "Project Name",
24 | "TITLE_PROJECT_NAME": "Type the name of your project",
25 | "LABEL_PAGE_TITLE": "Page title or URL",
26 | "TITLE_PAGE_TITLE": "Type the name of your page or URL",
27 | "LABEL_DEVELOPER_NAME": "Developer's name or team",
28 | "TITLE_DEVELOPER_NAME": "Type your name or the name of your team",
29 | "LABEL_SEARCH": "Search",
30 | "BUTTON_START_NEW": "Start new checklist",
31 | "BUTTON_GENERATE_PRINT": "Generate report"
32 | },
33 | "social": {
34 | "TWEET": "Tweet",
35 | "TWITTER_MSG": "Check the ✨ Front-End Checklist Application ✨ for modern websites and meticulous developers! With more than 28 000 🌟 on #Github, now you can use it on your daily workflow and generate reports 📑!",
36 | "TWITTER_VIA": "thedaviddias",
37 | "TWITTER_HASHTAGS": "FrontEndChecklist #FrontEnd #Tool #Web",
38 | "STAR": "Star",
39 | "GITHUB_STAR_MSG": "Star thedaviddias/Front-End-Checklist on GitHub"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/data/jp/project/translation.json:
--------------------------------------------------------------------------------
1 | {
2 | "SITE_NAME": "フロントエンドチェックリスト日本語訳 ",
3 | "INDEX_TITLE": "🔥 Your NEW Front-End Tool 🔥",
4 | "URL_WEBSITE": "https://frontendchecklist.io",
5 | "URL_PAGE": "https://frontendchecklist.io/jp/",
6 | "SITE_TAGLINE": "🗂 The Front-End Checklist Application is perfect for modern websites and meticulous developers!",
7 | "SITE_DESCRIPTION": "🗂 The Front-End Checklist Application is perfect for modern websites and meticulous developers! Follow the rules and deliver the best of your work in a generated report!",
8 | "SITE_LANGUAGE": "jp",
9 | "SITE_DIRECTION": "ltr",
10 | "URL_GITHUB_ROOT": "https://github.com/thedaviddias/Front-End-Checklist",
11 | "URL_GITHUB_REPO": "https://github.com/thedaviddias/Front-End-Checklist/tree/gh-pages",
12 | "HIGH_CHECKED": "✓ high priority",
13 | "MEDIUM_CHECKED": "✓ medium priority",
14 | "LOW_CHECKED": "✓ low priority",
15 | "PERCENTAGE_CHECKED": "items are ✓",
16 | "SECTION_DOCUMENTATION": "Documentation",
17 | "SECTION_TOOL": "Tools",
18 | "SECTION_VIDEO": "Videos",
19 | "SECTION_TAG": "Filter by tags",
20 | "alert": {
21 | "JAVASCRIPT_DESACTIVATE": "Your JavaScript seems to be desactivate. Please enable your JavaScript to use all functionnalities of the Front-End Checklist."
22 | },
23 | "form": {
24 | "LABEL_PROJECT_NAME": "Project Name",
25 | "TITLE_PROJECT_NAME": "Type the name of your project",
26 | "LABEL_PAGE_TITLE": "Page title or URL",
27 | "TITLE_PAGE_TITLE": "Type the name of your page or URL",
28 | "LABEL_DEVELOPER_NAME": "Developer's name or team",
29 | "TITLE_DEVELOPER_NAME": "Type your name or the name of your team",
30 | "LABEL_SEARCH": "Search",
31 | "BUTTON_START_NEW": "Start new checklist",
32 | "BUTTON_GENERATE_PRINT": "Generate report"
33 | },
34 | "social": {
35 | "TWEET": "Tweet",
36 | "TWITTER_MSG": "Check the 🔥 NEW Front-End Checklist Application 🔥 for modern websites and meticulous developers! With more than 15 000 🌟 on Github, now you can use it on your daily workflow and generate reports 📑!",
37 | "TWITTER_VIA": "thedaviddias",
38 | "TWITTER_HASHTAGS": "FrontEndChecklist #FrontEnd #Tool",
39 | "STAR": "Star",
40 | "GITHUB_STAR_MSG": "Star thedaviddias/Front-End-Checklist on GitHub"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/views/components/checklist/label.pug:
--------------------------------------------------------------------------------
1 | .c-checklist__column.c-checklist__label
2 | label(for=`c-checklist__item-${sectionTitle.toLowerCase()}-${i}`)
3 |
4 | span.label__title= item.title + ': '
5 | span.label__description #{item.description}
6 |
7 | if item.tools || item.documentation || item.code || item.video
8 | .c-checklist__details.js-details
9 |
10 | if item.detail
11 | p.c-checklist__text= item.detail
12 |
13 | if item.code
14 | .c-checklist__code
15 | .c-checklist__code__loader.js-loader
16 | .code-icons
17 | .c-checklist__code__github.js-code(data-code-url=`${item.code}`)
18 |
19 | if item.documentation
20 | .c-checklist__documentation
21 | h4= translation.SECTION_DOCUMENTATION
22 | ul.documentation__list
23 | each documentation, i in item.documentation
24 | li
25 | if documentation.url && documentation.title
26 | img.c-checklist__favicon(src="/img/icons/1x1.png" data-src=`https://www.google.com/s2/favicons?domain_url=${documentation.url}`, alt="")
27 | a(href=`${documentation.url}`, target="_blank", rel="noopener noreferrer")= documentation.title
28 |
29 | if item.tools
30 | .c-checklist__tools
31 | h4= translation.SECTION_TOOL
32 | ul.documentation__list
33 | each tool, i in item.tools
34 | li
35 | img.c-checklist__favicon(src="/img/icons/1x1.png" data-src=`https://www.google.com/s2/favicons?domain_url=${tool.url}`, alt="")
36 | a(href=`${tool.url}`, target="_blank", rel="noopener noreferrer")= tool.title
37 |
38 | if item.video
39 | .c-checklist__video
40 | h4= translation.SECTION_VIDEO
41 | ul.video__list
42 | each video, i in item.video
43 | li
44 | img.c-checklist__favicon(src="/img/icons/1x1.png" data-src=`https://www.google.com/s2/favicons?domain_url=${video.url}`, alt="")
45 | a(href=`${video.url}`, target="_blank", rel="noopener noreferrer")= video.title
46 |
47 | .c-tags
48 | ul.c-tags__list
49 | each tag in item.tags
50 | if tag == 'all'
51 | else
52 | li.c-tags__item= tag.toUpperCase()
53 |
--------------------------------------------------------------------------------
/data/jp/_project.json:
--------------------------------------------------------------------------------
1 | {"_items":{"利用方法":[{"title":"Doctype","priority":"High","description":"The Doctype is HTML5 and is at the top of all your HTML pages.","code":"https://gist.github.com/thedaviddias/bccee9f4dfa728830cf38bb83838d2d3.js","documentation":[{"title":"Determining the character encoding - HTML5 W3C","url":"https://www.w3.org/TR/html5/syntax.html#determining-the-character-encoding"}],"tags":["all","Meta tag"]}]},"introductions":[{"head":{"introduction":""}}],"translation":{"SITE_NAME":"フロントエンドチェックリスト日本語訳 ","INDEX_TITLE":"🔥 Your NEW Front-End Tool 🔥","URL_WEBSITE":"https://frontendchecklist.io","URL_PAGE":"https://frontendchecklist.io/jp/","SITE_TAGLINE":"🗂 The Front-End Checklist Application is perfect for modern websites and meticulous developers!","SITE_DESCRIPTION":"🗂 The Front-End Checklist Application is perfect for modern websites and meticulous developers! Follow the rules and deliver the best of your work in a generated report!","SITE_LANGUAGE":"jp","SITE_DIRECTION":"ltr","URL_GITHUB_ROOT":"https://github.com/thedaviddias/Front-End-Checklist","URL_GITHUB_REPO":"https://github.com/thedaviddias/Front-End-Checklist/tree/gh-pages","HIGH_CHECKED":"✓ high priority","MEDIUM_CHECKED":"✓ medium priority","LOW_CHECKED":"✓ low priority","PERCENTAGE_CHECKED":"items are ✓","SECTION_DOCUMENTATION":"Documentation","SECTION_TOOL":"Tools","SECTION_VIDEO":"Videos","SECTION_TAG":"Filter by tags","alert":{"JAVASCRIPT_DESACTIVATE":"Your JavaScript seems to be desactivate. Please enable your JavaScript to use all functionnalities of the Front-End Checklist."},"form":{"LABEL_PROJECT_NAME":"Project Name","TITLE_PROJECT_NAME":"Type the name of your project","LABEL_PAGE_TITLE":"Page title or URL","TITLE_PAGE_TITLE":"Type the name of your page or URL","LABEL_DEVELOPER_NAME":"Developer's name or team","TITLE_DEVELOPER_NAME":"Type your name or the name of your team","LABEL_SEARCH":"Search","BUTTON_START_NEW":"Start new checklist","BUTTON_GENERATE_PRINT":"Generate report"},"social":{"TWEET":"Tweet","TWITTER_MSG":"Check the 🔥 NEW Front-End Checklist Application 🔥 for modern websites and meticulous developers! With more than 15 000 🌟 on Github, now you can use it on your daily workflow and generate reports 📑!","TWITTER_VIA":"thedaviddias","TWITTER_HASHTAGS":"FrontEndChecklist #FrontEnd #Tool","STAR":"Star","GITHUB_STAR_MSG":"Star thedaviddias/Front-End-Checklist on GitHub"}}}
--------------------------------------------------------------------------------
/src/styles/components/_c-list.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Lists
3 | //
4 |
5 |
6 | // Variables
7 | // =============================================================================
8 | $list-margin: 0 !default;
9 | $list-padding: 0 0 0 $spacing-medium !default;
10 | $list-unstyled-padding: 0 !default;
11 | $list-unstyled-list-style: none !default;
12 | $list-nested-padding: $list-padding !default;
13 | $list-item-padding: 0 !default;
14 | $list-item-unstyled-list-style: none !default;
15 | $list-ordered-item-padding: 0 $spacing-small 0 0 !default;
16 | $list-inline-padding: 0 !default;
17 | $list-inline-item-padding-right: $spacing-medium !default;
18 | $list-inline-item-bullet-content: '\2022' !default;
19 | $list-inline-item-bullet-padding: 0 $spacing-small 0 0 !default;
20 |
21 | @mixin list--unstyled {
22 | padding: $list-unstyled-padding;
23 | list-style: $list-unstyled-list-style;
24 | }
25 |
26 | @mixin list--inline {
27 | padding: $list-inline-padding;
28 | }
29 |
30 | // Declarations
31 | // =============================================================================
32 | #{$namespace-list} {
33 | display: block;
34 | margin: $list-margin;
35 | padding: $list-padding;
36 | list-style-position: outside;
37 |
38 | & .c-list {
39 | padding: $list-nested-padding;
40 | }
41 |
42 | &__item {
43 | padding: $list-item-padding;
44 | }
45 |
46 | &__item--unstyled {
47 | list-style: $list-item-unstyled-list-style;
48 | }
49 |
50 | &--unstyled {
51 | @include list--unstyled;
52 | }
53 |
54 | &--ordered {
55 | @include list--unstyled;
56 |
57 | counter-reset: ordered;
58 |
59 | .c-list__item {
60 | &::before {
61 | padding: $list-ordered-item-padding;
62 | content: counters(ordered, '.') ' ';
63 | counter-increment: ordered;
64 | }
65 | }
66 | }
67 |
68 | // &--inline {
69 | // @include list--inline;
70 |
71 | // .c-list--inline {
72 | // @include list--inline;
73 | // }
74 |
75 | // .c-list__item {
76 | // display: inline-block;
77 | // width: auto;
78 | // padding-right: $list-inline-item-padding-right;
79 | // }
80 |
81 | // &:not(.c-list--unstyled) {
82 | // .c-list__item {
83 | // &::before {
84 | // padding: $list-inline-item-bullet-padding;
85 | // content: $list-inline-item-bullet-content;
86 | // }
87 | // }
88 | // }
89 | // }
90 | }
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/src/styles/config/_v-colors.scss:
--------------------------------------------------------------------------------
1 | // Colors
2 | $colors: (
3 | black: hsl(0, 0%, 4%),
4 | black-bis: hsl(0, 0%, 7%),
5 | black-ter: hsl(0, 0%, 14%),
6 | grey-darker: hsl(0, 0%, 21%),
7 | grey-dark: #212529,
8 | grey: hsl(0, 0%, 48%),
9 | grey-light: hsl(0, 0%, 71%),
10 | grey-lighter: hsl(0, 0%, 86%),
11 | white-ter: hsl(0, 0%, 96%),
12 | white-bis: hsl(0, 0%, 98%),
13 | white: hsl(0, 0%, 100%),
14 | orange: #d75637,
15 | yellow: hsl(48, 100%, 67%),
16 | green: hsl(141, 71%, 48%),
17 | blue: #415257,
18 | red: red
19 | );
20 |
21 | // :root {
22 | // // each item in color map
23 | // @each $name, $color in $colors {
24 | // --color-#{$name}: $color;
25 | // }
26 | // }
27 |
28 | // Lists and maps
29 | $colors: ('white': ($white, $black), 'black': ($black, $white), 'light': ($light, $light-invert), 'dark': ($dark, $dark-invert), 'primary': ($primary, $primary-invert), 'info': ($info, $info-invert), 'success': ($success, $success-invert), 'warning': ($warning, $warning-invert), 'danger': ($danger, $danger-invert)) !default;
30 |
31 | $shades: ('black-bis': map-get($colors, black-bis), 'black-ter': map-get($colors, black-ter), 'grey-darker': map-get($colors, grey-darker), 'grey-dark': map-get($colors, grey-dark), 'grey': map-get($colors, grey), 'grey-light': map-get($colors, grey-light), 'grey-lighter': map-get($colors, grey-lighter), 'white-ter': map-get($colors, white-ter), 'white-bis': map-get($colors, white-bis)) !default;
32 |
33 | $primary: map-get($colors, orange) !default;
34 | $secondary: map-get($colors, blue) !default;
35 |
36 | $info: map-get($colors, blue) !default;
37 | $success: map-get($colors, green) !default;
38 | $warning: map-get($colors, yellow) !default;
39 | $danger: map-get($colors, red) !default;
40 | $light: map-get($colors, white-ter) !default;
41 | $dark: map-get($colors, grey-darker) !default;
42 | $background: map-get($colors, white-ter) !default;
43 | $border: map-get($colors, grey-lighter) !default;
44 | $border-hover: map-get($colors, grey-light) !default;
45 |
46 | $color-tint: 9 !default;
47 | $color-tint-dark: $color-tint !default;
48 | $color-tint-darker: $color-tint * 2 !default;
49 | $color-tint-light: $color-tint !default;
50 | $color-tint-lighter: $color-tint * 2 !default;
51 |
52 |
53 | $progress-0: #6f2110;
54 | $progress-20: #f63a0f;
55 | $progress-40: #f27011;
56 | $progress-60: #f2b01e;
57 | $progress-80: #f2d31b;
58 | $progress-100: #86e01e;
59 |
--------------------------------------------------------------------------------
/src/img/flags/kr.svg:
--------------------------------------------------------------------------------
1 |
25 |
--------------------------------------------------------------------------------
/data/en/items/images.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "Optimization",
4 | "priority": "High",
5 | "description": "All images are optimized to be rendered in the browser. WebP format could be used for critical pages (like Homepage)",
6 | "tools": [
7 | {
8 | "title": "Imagemin",
9 | "url": "https://github.com/imagemin/imagemin"
10 | },
11 | {
12 | "title": "Use ImageOptim to optimise your images for free.",
13 | "url": "https://imageoptim.com/"
14 | },
15 | {
16 | "title": "Use Kraken.io awesome alternative for both png and jpg optimization. Up to 1mb per files on free plan.",
17 | "url": "https://kraken.io/web-interface"
18 | }
19 | ],
20 | "tags": ["all", "images", "best practices"]
21 | },
22 | {
23 | "title": "Picture/Srcset",
24 | "priority": "Medium",
25 | "description": "You use picture/srcset to provide the most appropriate image for the current viewport of the user.",
26 | "documentation": [
27 | {
28 | "title": "How to Build Responsive Images with srcset",
29 | "url": "https://www.sitepoint.com/how-to-build-responsive-images-with-srcset/"
30 | }
31 | ],
32 | "tags": ["all", "images"]
33 | },
34 | {
35 | "title": "Retina",
36 | "priority": "Low",
37 | "description": "You provide layout images 2x or 3x, support retina display.",
38 | "tags": ["all", "images"]
39 | },
40 | {
41 | "title": "Sprite",
42 | "priority": "Medium",
43 | "description": "Small images are in a sprite file (in the case of icons, they can be in an SVG sprite image).",
44 | "tags": ["all", "images"]
45 | },
46 | {
47 | "title": "Width and Height",
48 | "priority": "High",
49 | "description": "Set width and height attributes on
if the final rendered image size is known (can be omitted for CSS sizing).",
50 | "tags": ["all", "images"]
51 | },
52 | {
53 | "title": "Alternative text",
54 | "priority": "High",
55 | "description": "All
have an alternative text which describe the image visually.",
56 | "documentation": [
57 | {
58 | "title": "Alt-texts: The Ultimate Guide",
59 | "url": "https://axesslab.com/alt-texts/"
60 | }
61 | ],
62 | "tags": ["all", "images"]
63 | },
64 | {
65 | "title": "Lazy loading",
66 | "priority": "Medium",
67 | "description": "Images are lazyloaded (A noscript fallback is always provided).",
68 | "tags": ["all", "images", "performance"]
69 | }
70 | ]
71 |
--------------------------------------------------------------------------------
/src/styles/layout/_s-aside.scss:
--------------------------------------------------------------------------------
1 | .s-aside {
2 | position: fixed;
3 | transform: translateX(960px);
4 | text-align: left;
5 | margin-top: 55px;
6 | font-size: 1.5rem;
7 | top: 300px;
8 |
9 | ul {
10 | margin: 0;
11 | padding: 0;
12 | }
13 | }
14 |
15 | @if $use-aside == true {
16 |
17 | // Variables
18 | // =============================================================================
19 | $aside-height: 64px;
20 | $aside-background: #f8f7f6;
21 | $aside-border: #dddddd;
22 | $aside-collapse-breakpoint: 768px;
23 | $aside-item-font-size: 14px;
24 | $aside-item-border-width: 4px;
25 | $aside-item-color: #555555;
26 | $aside-item-active-color: #333333;
27 | $aside-item-border: transparent;
28 | $aside-item-active-border: #673ab7;
29 |
30 | // Declarations
31 | // =============================================================================
32 | #{$namespace-aside} {
33 | display: flex;
34 | align-items: center;
35 | justify-content: space-between;
36 | align-self: center;
37 | flex-flow: wrap row;
38 |
39 | @include mq('print') {
40 | display: none;
41 | }
42 |
43 | @include mq(lap-and-up) {
44 | display: flex;
45 | flex-direction: row;
46 | }
47 |
48 | &__title {
49 | font-size: 1.2rem;
50 | font-weight: 700;
51 |
52 | @include mq('handheld-and-up') {
53 | font-size: 1.3rem;
54 | }
55 | }
56 |
57 | &__inner {
58 | display: flex;
59 | align-content: center;
60 | justify-content: center;
61 | flex-direction: column;
62 | }
63 |
64 | &__list {
65 | flex-direction: row;
66 | width: 100%;
67 | margin: 0;
68 | padding: 10px;
69 | background-color: $aside-background;
70 |
71 | @include mq(lap-and-up) {
72 | display: flex;
73 | flex-wrap: wrap;
74 | }
75 | }
76 |
77 | &__item {
78 | display: inline-block;
79 | }
80 |
81 | &__item a,
82 | &__item button {
83 | display: block;
84 | text-transform: uppercase;
85 | font-size: 1.3rem;
86 | line-height: 1;
87 | color: map-get($colors, black-bis);
88 | padding: 5px 10px;
89 | border: 2px solid transparent;
90 | background-color: transparent;
91 |
92 | &:hover {
93 | text-decoration: none;
94 | font-weight: $weight-normal;
95 | border: 2px solid #dbdbdb;
96 | }
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/scripts/Utils.js:
--------------------------------------------------------------------------------
1 | let instance = null;
2 |
3 | class Utils {
4 | constructor() {
5 | if (!instance) {
6 | instance = this;
7 | }
8 |
9 | return instance;
10 | }
11 |
12 | variableList(el) {
13 | const section = instance.getClosest(el, '.js-section');
14 | const sectionName = section.getAttribute('data-section');
15 | const sectionId = section.getAttribute('data-section-id');
16 |
17 | const item = instance.getClosest(el, '.js-item ');
18 |
19 | let itemId;
20 | let itemCheck;
21 | let itemDropdown;
22 |
23 | if (item !== null) {
24 | itemId = item.getAttribute('data-item-id');
25 | itemCheck = item.getAttribute('data-item-check');
26 | itemDropdown = item.getAttribute('data-item-dropdown');
27 | }
28 |
29 | return {
30 | sectionId,
31 | section,
32 | sectionName,
33 | item,
34 | itemId,
35 | itemCheck,
36 | itemDropdown,
37 | };
38 | }
39 |
40 | visibityEl(container, el, status) {
41 | const tags = container.querySelectorAll(el)[0];
42 |
43 | if (tags !== undefined) {
44 | if (status === 'hide') {
45 | tags.style.display = 'none';
46 | } else {
47 | tags.style.display = 'flex';
48 | }
49 | }
50 | }
51 |
52 | detailsContainer(section) {
53 | const sectionClass = section.classList[1];
54 | const sectionObj = document.querySelectorAll('.' + sectionClass);
55 | const detailsContainer = sectionObj[0].querySelectorAll('.js-details');
56 |
57 | return detailsContainer;
58 | }
59 |
60 | /* eslint-disable */
61 | getClosest(elem, selector) {
62 | if (!Element.prototype.matches) {
63 | Element.prototype.matches =
64 | Element.prototype.matchesSelector ||
65 | Element.prototype.mozMatchesSelector ||
66 | Element.prototype.msMatchesSelector ||
67 | Element.prototype.oMatchesSelector ||
68 | Element.prototype.webkitMatchesSelector ||
69 | function parse(s) {
70 | let matches = (this.document || this.ownerDocument).querySelectorAll(
71 | s);
72 | let i = matches.length;
73 | while ((--i >= 0 && matches.item(i) !== this)) {}
74 | return i > -1;
75 | };
76 | }
77 |
78 | // Get closest match
79 | for (; elem && elem !== document; elem = elem.parentNode) {
80 | if (elem.matches(selector)) return elem;
81 | }
82 |
83 | return null;
84 | }
85 | /* eslint-enable */
86 | }
87 |
88 | const Instance = new Utils();
89 | Object.freeze(Instance);
90 |
91 | export default Utils;
92 |
--------------------------------------------------------------------------------
/src/scripts/components/ProgressBar.js:
--------------------------------------------------------------------------------
1 | let instance = null;
2 | /**
3 | *
4 | *
5 | * @class ProgressBar
6 | */
7 | class ProgressBar {
8 | constructor() {
9 | if (!instance) {
10 | instance = this;
11 | }
12 |
13 | this.main = document.getElementById('js-main');
14 |
15 | return instance;
16 | }
17 |
18 | /**
19 | * Count all items based on a section
20 | *
21 | * @param {any} el
22 | * @returns the number of items
23 | * @memberof ProgressBar
24 | */
25 | allItemsCounter(el) {
26 | const nbrItems = el.querySelectorAll('.js-item').length;
27 |
28 | return nbrItems;
29 | }
30 |
31 | /**
32 | * Update the main progress bar in the top of the page
33 | *
34 | * @depends updateProgressBar
35 | * @memberof ProgressBar
36 | */
37 | updateMainProgressBar() {
38 | const mainCount = this.main.querySelectorAll('[data-item-check="true"]').length;
39 | new ProgressBar().updateProgressBar(this.main, mainCount, 'main');
40 | }
41 |
42 | /**
43 | *
44 | *
45 | * @param {any} section
46 | * @param {any} checkedItems
47 | * @param {any} type
48 | * @memberof ProgressBar
49 | */
50 | updateProgressBar(section, checkedItems, type) {
51 | const currentSection = section;
52 | // Total items in the list
53 | // const checklistItem = section.querySelectorAll('.js-item');
54 | const totalItems = instance.allItemsCounter(section);
55 |
56 | let progressBar;
57 |
58 | switch (type) {
59 | // Main progress bar
60 | case 'main':
61 | progressBar = section.querySelector('.js-all-progress');
62 | break;
63 |
64 | default:
65 | progressBar = section.querySelector('.js-progress');
66 | break;
67 | }
68 |
69 | const getPercent = parseInt(checkedItems / totalItems * 100, 10);
70 |
71 | progressBar.setAttribute('value', getPercent);
72 |
73 | currentSection.querySelector('.c-progress__label',
74 | ).innerHTML = `${getPercent} %`;
75 |
76 | // section.getAttribute('data-section')
77 | document.querySelectorAll(
78 | '#js-nav-' + section.getAttribute('data-section'),
79 | )[0].setAttribute('data-notation', getPercent);
80 | }
81 |
82 | /**
83 | * Update all progress bar, the main and on each section
84 | *
85 | * @param {any} section
86 | * @param {number} items
87 | * @memberof ProgressBar
88 | */
89 | updateAllProgressBars(section, items) {
90 | new ProgressBar().updateProgressBar(section, items);
91 | // new ProgressBar().updateMainProgressBar();
92 | }
93 | }
94 |
95 | const Instance = new ProgressBar();
96 | Object.freeze(Instance);
97 |
98 | export default ProgressBar;
99 |
--------------------------------------------------------------------------------
/src/scripts/components/Notation.js:
--------------------------------------------------------------------------------
1 | let instance = null;
2 | /**
3 | *
4 | *
5 | * @class Notation
6 | */
7 | class Notation {
8 | constructor() {
9 | if (!instance) {
10 | instance = this;
11 | }
12 |
13 | this.main = document.getElementById('js-main');
14 | this.notationDetails = document.querySelector('.c-notation__details');
15 | this.items = document.querySelectorAll('.js-item');
16 | this.priority = [];
17 |
18 | return instance;
19 | }
20 |
21 | updatePriority() {
22 | this.priority.forEach((el, i) => {
23 | const checkedCounter = document.querySelectorAll(`[data-item-priority=${el}][data-item-check='true']`).length
24 | const number = document.querySelectorAll(`.js-detail-${el}`);
25 | number[0].querySelectorAll('.js-notation-checked')[0].innerHTML = checkedCounter
26 | });
27 | }
28 |
29 | /**
30 | * Read the localStorage about the number of items by priority
31 | *
32 | * @param {any} priorityId
33 | * @memberof Notation
34 | */
35 | readPriority(priorityId) {
36 | this.items.forEach((el, i) => {
37 | const currentPriority = el.getAttribute('data-item-priority');
38 | if (this.priority.indexOf(currentPriority) === -1) {
39 | this.priority.push(currentPriority);
40 | }
41 | })
42 | instance.updatePriority();
43 | }
44 |
45 | /**
46 | * Update the letter for the global notation
47 | *
48 | * @memberof Notation
49 | */
50 | updateNotation() {
51 | const items = this.main.querySelectorAll('.js-item').length;
52 | const mainCount = this.main.querySelectorAll('[data-item-check="true"]').length;
53 |
54 | const getPercent = parseInt(mainCount / items * 100, 10);
55 |
56 | const notation = document.getElementById('js-notation');
57 | const notationLetter = notation.getElementsByClassName('c-notation__letter')[0];
58 |
59 | notation.setAttribute('data-notation', getPercent);
60 |
61 | switch (true) {
62 | case getPercent <= 20:
63 | notationLetter.innerHTML = 'F';
64 | break;
65 |
66 | case getPercent <= 40:
67 | notationLetter.innerHTML = 'E';
68 | break;
69 |
70 | case getPercent <= 60:
71 | notationLetter.innerHTML = 'D';
72 | break;
73 |
74 | case getPercent <= 80:
75 | notationLetter.innerHTML = 'C';
76 | break;
77 |
78 | case getPercent < 100:
79 | notationLetter.innerHTML = 'B';
80 | break;
81 | case getPercent === 100:
82 | notationLetter.innerHTML = 'A';
83 | break;
84 | default:
85 | }
86 | }
87 |
88 | }
89 |
90 | const Instance = new Notation();
91 | Object.freeze(Instance);
92 |
93 | export default Notation;
94 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "front-end-checklist",
3 | "version": "0.0.1",
4 | "description": "The perfect Front-End Checklist for modern websites and meticulous developers",
5 | "scripts": {
6 | "start": "gulp dev",
7 | "build": "gulp build",
8 | "test": "gulp test",
9 | "eslint-check": "eslint --print-config .eslintrc.js | eslint-config-prettier-check"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://thedaviddias@github.com/thedaviddias/Front-End-Checklist-App.git"
14 | },
15 | "author": "David Dias (thedaviddias@gmail.com)",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/thedaviddias/Front-End-Checklist-App/issues"
19 | },
20 | "homepage": "https://github.com/thedaviddias/Front-End-Checklist-App#readme",
21 | "devDependencies": {
22 | "babel-cli": "^6.26.0",
23 | "babel-eslint": "^9.0.0",
24 | "babel-loader": "^7.1.4",
25 | "babel-polyfill": "^6.26.0",
26 | "babel-preset-env": "^1.6.1",
27 | "babel-register": "^6.26.0",
28 | "browser-sync": "^2.23.6",
29 | "chai": "^4.1.2",
30 | "critical": "^1.1.0",
31 | "eslint-config-airbnb-base": "^13.0.0",
32 | "eslint-config-prettier": "^3.0.0",
33 | "eslint-plugin-flowtype": "^2.46.1",
34 | "eslint-plugin-import": "^2.9.0",
35 | "eslint-plugin-prettier": "^2.6.0",
36 | "flow-bin": "^0.76.0",
37 | "gulp": "^3.9.1",
38 | "gulp-autoprefixer": "^6.0.0",
39 | "gulp-cached": "^1.1.1",
40 | "gulp-cdnizer": "^2.0.0",
41 | "gulp-changed": "^3.2.0",
42 | "gulp-cssnano": "^2.1.2",
43 | "gulp-data": "^1.3.1",
44 | "gulp-eslint": "^5.0.0",
45 | "gulp-group-css-media-queries": "^1.2.2",
46 | "gulp-html-replace": "^1.6.2",
47 | "gulp-htmlmin": "^5.0.0",
48 | "gulp-if": "^2.0.2",
49 | "gulp-imagemin": "^4.1.0",
50 | "gulp-istanbul": "^1.1.3",
51 | "gulp-json-concat": "^0.1.1",
52 | "gulp-mocha": "^6.0.0",
53 | "gulp-newer": "^1.4.0",
54 | "gulp-plumber": "^1.2.0",
55 | "gulp-pug": "^4.0.1",
56 | "gulp-rename": "^1.2.2",
57 | "gulp-sass": "^4.0.1",
58 | "gulp-sourcemaps": "^2.6.4",
59 | "gulp-stylelint": "^7.0.0",
60 | "gulp-util": "^3.0.8",
61 | "gulp-webpack": "^1.5.0",
62 | "html-webpack-plugin": "^3.0.0",
63 | "imagemin-webp": "^4.1.0",
64 | "jsdom": "^12.0.0",
65 | "jsdom-global": "3.0.2",
66 | "modernizr": "^3.6.0",
67 | "postscribe": "^2.0.8",
68 | "prettier": "^1.11.1",
69 | "run-sequence": "^2.2.1",
70 | "sinon": "^6.1.3",
71 | "stylelint": "^9.1.1",
72 | "stylelint-config-standard": "^18.2.0",
73 | "stylelint-scss": "^3.1.3",
74 | "uglifyjs-webpack-plugin": "^1.2.3",
75 | "url-loader": "^1.0.1",
76 | "webpack": "^4.16.1",
77 | "webpack-stream": "^5.0.0",
78 | "yargs": "^12.0.1"
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/scripts/components/Filter.js:
--------------------------------------------------------------------------------
1 | let instance = null;
2 | /**
3 | *
4 | *
5 | * @class Filter
6 | */
7 | class Filter {
8 | constructor() {
9 | if (!instance) {
10 | instance = this;
11 | }
12 |
13 | return instance;
14 | }
15 |
16 | highlightButton(nameFilter, type) {
17 |
18 | const button = document.querySelector(
19 | '[data-' + type + '="' + nameFilter + '"]',
20 | );
21 | const buttons = document.querySelectorAll('[data-' + type + ']');
22 |
23 | // Remove all filter-active class on all buttons
24 | buttons.forEach(el => {
25 | el.classList.remove('filter-active');
26 | })
27 |
28 | // Add class to highlight button
29 | button.classList.add('filter-active');
30 | }
31 |
32 | addFilter(el, storageName) {
33 | let storage = [];
34 | const name = storageName;
35 |
36 | if (localStorage.getItem(name) === null) {
37 | storage = [{'filter': 'all'}];
38 | } else {
39 | let item = {'filter': el};
40 | storage.push(item);
41 |
42 | instance.highlightButton(item.filter, storageName);
43 | }
44 |
45 | localStorage.setItem(name, JSON.stringify(storage));
46 | }
47 |
48 | selectBy(dataName) {
49 | let items = document.querySelectorAll('.js-item');
50 |
51 | items.forEach((el, i) => {
52 | if ((' ' + items[i].className + ' ').indexOf(' ' + dataName + ' ') < 0) {
53 | items[i].setAttribute('data-item-visible', false);
54 | items[i].setAttribute('aria-hidden', true);
55 | } else {
56 | items[i].setAttribute('data-item-visible', true);
57 | items[i].setAttribute('aria-hidden', false);
58 | }
59 | });
60 | }
61 |
62 | readFilterStorage(name) {
63 |
64 | let storage2 = [{'filter': 'all'}];
65 |
66 | if (localStorage.getItem(name) !== null) {
67 | const storage = JSON.parse(localStorage.getItem(name));
68 |
69 | storage.forEach(el => {
70 | instance.selectBy(el.filter);
71 | instance.highlightButton(el.filter, name);
72 | })
73 | }
74 | else {
75 | localStorage.setItem(name, JSON.stringify(storage2));
76 | instance.selectBy('all');
77 | instance.highlightButton('all', 'tag');
78 | }
79 | }
80 |
81 | enableFilter(name, dataName, filterClass) {
82 | const filterNames = document.querySelectorAll(filterClass);
83 |
84 | filterNames.forEach(el => {
85 | el.addEventListener(
86 | 'click',
87 | e => {
88 | e.preventDefault();
89 |
90 | instance.selectBy(e.target.getAttribute(dataName));
91 | instance.addFilter(e.target.getAttribute(dataName), name);
92 | },
93 | false,
94 | );
95 | });
96 | }
97 | }
98 |
99 | const Instance = new Filter();
100 | Object.freeze(Instance);
101 |
102 | export default Filter;
103 |
--------------------------------------------------------------------------------
/src/styles/components/_c-nav.scss:
--------------------------------------------------------------------------------
1 | @if $use-nav == true {
2 |
3 | // Variables
4 | // =============================================================================
5 | $nav-height: 64px;
6 | $nav-background: map-get($colors, white);
7 | $nav-border: #dddddd;
8 | $nav-collapse-breakpoint: 768px;
9 | $nav-item-font-size: 14px;
10 | $nav-item-border-width: 4px;
11 | $nav-item-color: #555555;
12 | $nav-item-active-color: #333333;
13 | $nav-item-border: transparent;
14 | $nav-item-active-border: $primary;
15 |
16 | // Declarations
17 | // =============================================================================
18 | #{$namespace-nav} {
19 | display: flex;
20 | align-items: flex-start;
21 | justify-content: space-between;
22 | margin-top: 15px;
23 |
24 | @include mq(lap-and-up) {
25 | display: flex;
26 | margin: 15px 0;
27 | }
28 |
29 | &--inline {
30 | flex-direction: row;
31 | }
32 |
33 | &__inner {
34 | display: flex;
35 | align-content: center;
36 | justify-content: center;
37 | flex-direction: column;
38 | }
39 |
40 | &__list {
41 | width: 100%;
42 | margin: 0;
43 | padding: 0;
44 | flex-wrap: wrap;
45 | display: flex;
46 |
47 | @include mq(lap-and-up) {
48 | display: flex;
49 | flex-wrap: wrap;
50 | }
51 | }
52 |
53 | &__item {
54 | margin: 0 10px 10px 0;
55 |
56 | @include mq(lap-and-up) {
57 | margin: 0 5px 5px 0;
58 | }
59 | }
60 |
61 | &__status {
62 | padding-left: 3px;
63 | margin-right: 7px;
64 | }
65 |
66 | &__sidebar {
67 | position: absolute;
68 | right: -10px;
69 | // animation: navShow 1s normal;
70 | // z-index: -1;
71 |
72 | .c-nav__list {
73 | position: fixed;
74 | top: 50px;
75 | flex-direction: column;
76 | width: auto;
77 | will-change: transform;
78 | }
79 |
80 | .c-button {
81 | text-align: left;
82 | }
83 | }
84 |
85 | &__item a,
86 | &__item button {
87 | display: block;
88 | text-transform: uppercase;
89 | color: map-get($colors, black);
90 | padding: 5px 10px;
91 | font-size: 1.3rem;
92 | border: 1px solid #cccccc;
93 |
94 | @include mq('handheld-and-up') {
95 | font-size: 14px;
96 | }
97 |
98 | &:hover {
99 | text-decoration: none;
100 | font-weight: $weight-normal;
101 | border: 1px solid $nav-item-active-border;
102 | }
103 | }
104 | }
105 | }
106 |
107 |
108 | @keyframes navShow {
109 | 0% {
110 | right: 150px;
111 | opacity: 0;
112 | }
113 |
114 | 80% {
115 | opacity: .2;
116 | }
117 |
118 | 100% {
119 | right: -10px;
120 | z-index: 9;
121 | opacity: 1;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/data/en/items/html.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "HTML5 Semantic Elements",
4 | "priority": "High",
5 | "description": "HTML5 Semantic Elements are used appropriately (header, section, footer, main...).",
6 | "tools": [
7 | {
8 | "title": "HTML Reference",
9 | "url": "http://htmlreference.io/"
10 | }
11 | ],
12 | "tags": ["all", "html", "best practices"]
13 | },
14 | {
15 | "title": "Error pages",
16 | "priority": "High",
17 | "description": "Error 404 page and 5xx exist",
18 | "detail": "Remember that the 5xx error pages need to have their CSS integrated (no external call on the current server).",
19 | "tags": ["all", "html", "best practices"]
20 | },
21 | {
22 | "title": "Noopener",
23 | "priority": "Medium",
24 | "description": "In case you are using external links with target=\"_blank\", your link should have a rel=\"noopener\" attribute to prevent tab nabbing. If you need to support older versions of Firefox, use rel=\"noopener noreferrer\"",
25 | "documentation": [
26 | {
27 | "title": "About rel=noopener",
28 | "url": "https://mathiasbynens.github.io/rel-noopener/"
29 | }
30 | ],
31 | "tags": ["all", "html", "best practices", "security"]
32 | },
33 | {
34 | "title": "Clean up comments",
35 | "priority": "Low",
36 | "description": "Unnecessary code needs to be removed before sending the page to production.",
37 | "tags": ["all", "html", "best practices"]
38 | },
39 | {
40 | "title": "W3C compliant",
41 | "priority": "High",
42 | "description": "All pages need to be tested with the W3C validator to identify possible issues in the HTML code.",
43 | "tools": [
44 | {
45 | "title": "W3C validator",
46 | "url": "https://validator.w3.org/"
47 | }
48 | ],
49 | "tags": ["all", "html", "testing"]
50 | },
51 | {
52 | "title": "HTML Lint",
53 | "priority": "High",
54 | "description": "I use tools to help me analyze any issues I could have on my HTML code.",
55 | "tools": [
56 | {
57 | "title": "Dirty markup",
58 | "url": "https://dirtymarkup.com/"
59 | },
60 | {
61 | "title": "webhint",
62 | "url": "https://webhint.io/"
63 | }
64 | ],
65 | "tags": ["all", "html", "testing"]
66 | },
67 | {
68 | "title": "Link checker",
69 | "priority": "High",
70 | "description": "There are no broken links in my page, verify that you don't have any 404 error.",
71 | "tools": [
72 | {
73 | "title": "W3C Link Checker",
74 | "url": "https://validator.w3.org/checklink"
75 | }
76 | ],
77 | "tags": ["all", "html", "testing"]
78 | },
79 | {
80 | "title": "Adblockers test",
81 | "priority": "Medium",
82 | "description": "Your website shows your content correctly with adblockers enabled",
83 | "detail": "(You can provide a message encouraging people to disable their adblocker)",
84 | "tags": ["all", "html", "testing"]
85 | }
86 |
87 |
88 | ]
89 |
--------------------------------------------------------------------------------
/src/scripts/components/Report.js:
--------------------------------------------------------------------------------
1 | let instance = null;
2 | /**
3 | *
4 | *
5 | * @class Report
6 | */
7 | class Report {
8 | constructor() {
9 | if (!instance) {
10 | instance = this;
11 | }
12 |
13 | this.form = document.querySelector('.s-form');
14 | this.inputs = this.form.querySelectorAll('input');
15 |
16 | }
17 |
18 | readInputs() {
19 | this.inputs.forEach(el => {
20 | if (localStorage.getItem(el.name) !== null) {
21 | const storage = JSON.parse(localStorage.getItem(el.name));
22 | el.value = storage[0]
23 | }
24 | else {
25 | localStorage.getItem(el.name);
26 | }
27 | });
28 | }
29 |
30 | inputSave() {
31 |
32 |
33 | this.inputs.forEach(el => {
34 |
35 | // Save input value when the user reload the page
36 | window.addEventListener("beforeunload", e => {
37 |
38 | // let storage = [];
39 | // const valueInput = el.target.value;
40 | // const inputName = el.target.name;
41 | // // Push the input value to the storage array
42 | // storage.push(valueInput);
43 | // // Inject the new value typed in the localStorage
44 | // localStorage.setItem(inputName, JSON.stringify(storage));
45 | }, false);
46 |
47 | // Save input value when change focus
48 | el.addEventListener('blur', e => {
49 | let storage = [];
50 | const valueInput = e.target.value;
51 | const inputName = e.target.name;
52 | // Push the input value to the storage array
53 | storage.push(valueInput);
54 | // Inject the new value typed in the localStorage
55 | localStorage.setItem(inputName, JSON.stringify(storage));
56 | });
57 |
58 | });
59 | }
60 |
61 | resetAll() {
62 | document.querySelector('.js-reset-all').addEventListener('click', () => {
63 | const developerName = localStorage.getItem('developer-name');
64 | const projectName = localStorage.getItem('project-name');
65 | const pageTitle = localStorage.getItem('page-title');
66 | localStorage.clear();
67 | localStorage.setItem('developer-name', developerName);
68 | localStorage.setItem('project-name', projectName);
69 | localStorage.setItem('page-title', pageTitle);
70 | gtag('event', 'reset-all', {
71 | 'event_category': 'Click',
72 | 'event_label': 'Star new checklist'
73 | });
74 | window.location.reload(false);
75 | });
76 | }
77 |
78 | print() {
79 | document.querySelector('.js-print').addEventListener('click', () => {
80 | window.print();
81 | gtag('event', 'generate-reports', {
82 | 'event_category': 'Click',
83 | 'event_label': 'Generate reports'
84 | });
85 | });
86 | }
87 |
88 | enableReport() {
89 | instance.print();
90 | instance.resetAll();
91 | instance.inputSave();
92 | instance.readInputs(this.inputs);
93 |
94 | }
95 | }
96 | const Instance = new Report();
97 | Object.freeze(Instance);
98 |
99 | export default Report;
100 |
--------------------------------------------------------------------------------
/data/en/items/javascript.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "title": "JavaScript Inline",
4 | "priority": "High",
5 | "description": "You don't have any JavaScript code inline (mixed with your HTML code).",
6 | "tags": ["all", "javascript"]
7 | },
8 | {
9 | "title": "Concatenation",
10 | "priority": "High",
11 | "description": "JavaScript files are concatenated.",
12 | "tags": ["all", "javascript"]
13 | },
14 | {
15 | "title": "Minification",
16 | "priority": "High",
17 | "description": "JavaScript files are minified (you can add the .min suffix).",
18 | "documentation": [
19 | {
20 | "title": "Minify Resources (HTML, CSS, and JavaScript)",
21 | "url": "https://developers.google.com/speed/docs/insights/MinifyResources"
22 | }
23 | ],
24 | "tags": ["all", "javascript"]
25 | },
26 | {
27 | "title": "JavaScript security",
28 | "priority": "High",
29 | "description": "",
30 | "documentation": [
31 | {
32 | "title": "Guidelines for Developing Secure Applications Utilizing JavaScript",
33 | "url": "https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet#Guidelines_for_Developing_Secure_Applications_Utilizing_JavaScript"
34 | }
35 | ],
36 | "tags": ["all", "javascript", "security"]
37 | },
38 | {
39 | "title": "noscript tag",
40 | "priority": "Medium",
41 | "description": "Use `