Merge pull request #1464 from rstacruz/feature-parcel

This commit is contained in:
Rico Sta. Cruz 2020-06-22 20:44:30 +10:00 committed by GitHub
commit 048697b3d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 6712 additions and 5602 deletions

View File

@ -1,9 +1,10 @@
{ {
"presets": [ "presets": [
[ [
"env", "@babel/preset-env",
{ {
"forceAllTransforms": true "useBuiltIns": "entry",
"targets": "> 2%"
} }
] ]
] ]

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
yarn.lock binary

6
.gitignore vendored
View File

@ -3,4 +3,8 @@ _site
.jekyll-metadata .jekyll-metadata
/node_modules /node_modules
/vendor /vendor
.idea/ .idea/
# Generated by 'yarn dev'
/_includes/2017/critical/critical-home.js
/_includes/2017/critical/critical-sheet.js

View File

@ -1,5 +1,6 @@
{ {
"semi": false, "semi": false,
"singleQuote": true, "singleQuote": true,
"jsxSingleQuote": true "jsxSingleQuote": true,
"trailingComma": "none"
} }

View File

@ -1,10 +1,25 @@
language: ruby language: ruby
rvm: rvm: [2.7.1]
- 2.5
before_install:
- nvm install 12
- nvm use 12
- node --version
- ruby --version
install:
- yarn --frozen-lockfile
- bundle --jobs=3 --retry=3 --deployment --path=${BUNDLE_PATH:-vendor/bundle}
script: script:
- make -B _site - yarn build
- if ! make test; then make test-warning; exit 16; fi - yarn test
cache: bundler - if ! make test; then make test-warning; exit 16; fi
cache:
bundler: true
yarn: true
notifications: notifications:
slack: slack:
if: branch = master OR branch =~ ^.*slack.*$ if: branch = master OR branch =~ ^.*slack.*$

View File

@ -1,6 +1,7 @@
# Developer notes # Developer notes
## Gitpod ## Gitpod
This repository supports contribution using [gitpod](https://gitpod.io) which is online IDE using [Theia](https://github.com/eclipse-theia/theia). This repository supports contribution using [gitpod](https://gitpod.io) which is online IDE using [Theia](https://github.com/eclipse-theia/theia).
To open-up the environment simple natigate on https://gitpod.io/#https://github.com/rstacruz/cheatsheets To open-up the environment simple natigate on https://gitpod.io/#https://github.com/rstacruz/cheatsheets
@ -9,14 +10,14 @@ Or using a button:<br>
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/rstacruz/cheatsheets) [![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/rstacruz/cheatsheets)
### Preview built website ### Preview built website
To preview the website you need to first build it then you can navigate to file that you are trying to contribute and preview directly. To preview the website you need to first build it then you can navigate to file that you are trying to contribute and preview directly.
<img src='_docs/images/gitpod_preview_tut.png' width=828 height=459/> <img src='_docs/images/gitpod_preview_tut.png' width=828 height=459/>
## Starting a local instance ## Starting a local instance
This starts Jekyll and Webpack. This requires recent versions of [Node.js], [Yarn], [Ruby] and [Bundler] installed. This starts Jekyll and Parcel. This requires recent versions of [Node.js], [Yarn], [Ruby] and [Bundler] installed.
```bash ```bash
yarn install yarn install
@ -56,9 +57,11 @@ See <https://devhints.io/cheatsheet-styles> for a reference on styling.
## JavaScript ## JavaScript
When updating JavaScript, be sure webpack is running (`yarn run dev` takes care of this). When updating JavaScript, be sure Parcel is running (`yarn dev` takes care of this).
This auto-updates `/assets/packed/` with sources in `_js/`. This auto-updates `/assets/packed/` and `_includes/2017/critical/` with sources in `_parcel/`.
Before committing, run `yarn parcel:build` first.
## JavaScript tests ## JavaScript tests
@ -75,16 +78,16 @@ Each sheet supports these metadata:
```yml ```yml
--- ---
title: React.js title: React.js
layout: 2017/sheet # 'default' | '2017/sheet' layout: 2017/sheet # 'default' | '2017/sheet'
# Optional: # Optional:
category: React category: React
updated: 2017-08-30 # To show in the updated list updated: 2017-08-30 # To show in the updated list
ads: false # Add this to disable ads ads: false # Add this to disable ads
weight: -5 # lower number = higher in related posts list weight: -5 # lower number = higher in related posts list
deprecated: true # Don't show in related posts deprecated: true # Don't show in related posts
deprecated_by: /enzyme # Point to latest version deprecated_by: /enzyme # Point to latest version
prism_languages: [vim] # Extra syntax highlighting prism_languages: [vim] # Extra syntax highlighting
intro: | intro: |
This is some *Markdown* at the beginning of the article. This is some *Markdown* at the beginning of the article.
tags: tags:
@ -93,9 +96,10 @@ tags:
# Special pages: # Special pages:
# (don't set these for cheatsheets) # (don't set these for cheatsheets)
type: home # home | article | error type: home # home | article | error
og_type: website # opengraph type og_type: website # opengraph type
--- ---
``` ```
## Prism languages ## Prism languages
@ -115,6 +119,7 @@ title: ES2015
category: Hidden category: Hidden
redirect_to: /es6 redirect_to: /es6
--- ---
``` ```
## Localizations ## Localizations
@ -170,26 +175,3 @@ building web user interfaces...
### intro only ### intro only
If you left out `description` or `keywords`, a default description will be added. If you left out `description` or `keywords`, a default description will be added.
## Critical path CSS
The critical path CSS is stored in:
- `_includes/2017/critical/home.html`
- `_includes/2017/critical/sheet.html`
You'll need to update these every now and then when you change something in the CSS. Use this to update these snippets:
```
yarn run critical
```
You can temporarily disable critical path optimizations by loading it with `?nocrit=1`, eg, `https://devhints.io/?nocrit=1`.
## Critical path JS
There's JavaScript that's included inline in every page. It's entrypoint is:
- `_js/critical.js`
This is automatically compiled into the partial `_includes/2017/critical/critical.js`. Keep this bundle as small as possible.

View File

@ -1,5 +1,5 @@
FROM ruby:2.5.1 FROM ruby:2.7.1
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
RUN apt-get update -qq && apt-get install -qq --no-install-recommends \ RUN apt-get update -qq && apt-get install -qq --no-install-recommends \

View File

@ -9,43 +9,14 @@ help:
@echo @echo
# Builds intermediate files. Needs a _site built first though # Builds intermediate files. Needs a _site built first though
update: _site critical update: _site
# Builds _site # Builds _site
_site: _site:
bundle exec jekyll build --incremental yarn build
critical: _site ## Builds critical path CSS/JS dev:
node _support/critical.js yarn dev
# Ensure that bins are available.
ensure-bin:
@if [ ! -d $(npmbin) ]; then \
echo "---"; \
echo "Error: $(npmbin) not found, you may need to run '[docker-compose run --rm web] yarn install'."; \
echo "---"; \
exit 1; \
fi
@if ! which jekyll &>/dev/null; then \
echo "---"; \
echo "Warning: Jekyll not found, you may need to run '[docker-compose run --rm web] bundle install'."; \
echo "---"; \
fi
dev: ensure-bin ## Starts development server
$(npmbin)/concurrently -k -p command -c "blue,green" \
"make dev-webpack" \
"make dev-jekyll"
dev-webpack: ensure-bin
$(npmbin)/webpack --watch --colors -p
dev-jekyll: ensure-bin
if [ -f _site ]; then \
bundle exec jekyll serve --safe --trace --drafts --watch --incremental --host $(HOST) --port $(PORT); \
else \
bundle exec jekyll serve --safe --trace --drafts --watch --host $(HOST) --port $(PORT); \
fi
test: _site ## Runs rudimentary tests test: _site ## Runs rudimentary tests
@test -f _site/vim.html @test -f _site/vim.html

View File

@ -9,21 +9,23 @@ plugins:
- jekyll-github-metadata - jekyll-github-metadata
exclude: exclude:
- Makefile - .babelrc
- README.md - .cache
- CNAME
- CONTRIBUTING.md - CONTRIBUTING.md
- docker_compose.yml
- Dockerfile
- Gemfile - Gemfile
- Gemfile.lock - Gemfile.lock
- CNAME - Makefile
- vendor
- package.json
- .babelrc
- yarn.lock
- package-lock.json
- webpack.config.js
- node_modules - node_modules
- Dockerfile - package.json
- docker_compose.yml - package-lock.json
- README.md
- vendor
- webpack.config.js
- yarn-error.log
- yarn.lock
# Markdown # Markdown

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1,15 @@
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}var t={};n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},n.p="",n(n.s=2)}([function(e,n){function t(e,n){var t=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;if(t)return t.call(e,n);if(e.parentNode){for(var r=e.parentNode.querySelectorAll(n),o=r.length;o--;0)if(r[o]===e)return!0;return!1}}e.exports=t},function(e,n,t){function r(e,n){if(n){if(Array.isArray(n))return void o(n,function(n){r(e,n)});if(e.classList){var t=n.split(" ").filter(Boolean);o(t,function(n){e.classList.add(n)})}else e.className+=" "+n}}var o=t(4);e.exports=r},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(){d||((0,c.default)(document.documentElement,"LoadDone"),d=!0)}var i=t(3),u=r(i),a=t(1),c=r(a),f=t(6),l=r(f),s=document.querySelector("[data-js-main-body]");s&&((0,u.default)(s),(0,c.default)(s,"-wrapified")),(0,l.default)(window,"load",o),setTimeout(o,5e3);var d=void 0},function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(e){if(Array.isArray(e)){for(var n=0,t=Array(e.length);n<e.length;n++)t[n]=e[n];return t}return Array.from(e)}function i(e){u(e).forEach(function(e){(0,p.findChildren)(e,"[data-js-h3-section-list]").forEach(function(e){a(e)})})}function u(e){return c(e,{tag:"h2",wrapperFn:function(){return(0,p.createDiv)({class:"h2-section"})},bodyFn:function(){return(0,p.createDiv)({class:"body h3-section-list","data-js-h3-section-list":""})}})}function a(e){return c(e,{tag:"h3",wrapperFn:function(){return(0,p.createDiv)({class:"h3-section"})},bodyFn:function(){return(0,p.createDiv)({class:"body"})}})}function c(e,n){function t(e,n,t){var r=i(),o=e.className;o&&(0,d.default)(r,o),(0,p.before)(e,r);var a=u();return o&&(0,d.default)(a,o),(0,p.appendMany)(a,t),n&&r.appendChild(n),r.appendChild(a),r}var r=n.tag,i=n.wrapperFn,u=n.bodyFn,a=e.children[0],c=[];if(a&&!(0,l.default)(a,r)){var f=(0,p.nextUntil)(a,r);c.push(t(a,null,[a].concat(o(f))))}return(0,p.findChildren)(e,r).forEach(function(e){var n=(0,p.nextUntil)(e,r);c.push(t(e,e,n))}),c}Object.defineProperty(n,"__esModule",{value:!0}),n.default=i,n.groupify=c;var f=t(0),l=r(f),s=t(1),d=r(s),p=t(5)},function(e,n){function t(e,n){var t,r,o=e.length;if("number"==typeof o)for(t=0;t<o;t++)n(e[t],t);else{r=0;for(t in e)e.hasOwnProperty(t)&&n(e[t],t,r++)}return e}e.exports=t},function(e,n,t){"use strict";function r(e){if(Array.isArray(e)){for(var n=0,t=Array(e.length);n<e.length;n++)t[n]=e[n];return t}return Array.from(e)}function o(e,n){n.forEach(function(n){e.appendChild(n)})}function i(e,n){return u(e.nextSibling,n,[])}function u(e,n,t){return e?(0,s.default)(e,n)?t:u(e.nextSibling,n,[].concat(r(t),[e])):t}function a(e,n){e.parentNode.insertBefore(n,e)}function c(e,n){return[].slice.call(e.children).filter(function(e){return(0,s.default)(e,n)})}function f(e){var n=document.createElement("div");return Object.keys(e).forEach(function(t){n.setAttribute(t,e[t])}),n}Object.defineProperty(n,"__esModule",{value:!0}),n.appendMany=o,n.nextUntil=i,n.before=a,n.findChildren=c,n.createDiv=f;var l=t(0),s=function(e){return e&&e.__esModule?e:{default:e}}(l)},function(e,n){function t(e,n,t){e.addEventListener?e.addEventListener(n,t):e.attachEvent("on"+n,function(){t.call(e)})}e.exports=t}]); parcelRequire=function(e,r,t,n){var i,o="function"==typeof parcelRequire&&parcelRequire,u="function"==typeof require&&require;function f(t,n){if(!r[t]){if(!e[t]){var i="function"==typeof parcelRequire&&parcelRequire;if(!n&&i)return i(t,!0);if(o)return o(t,!0);if(u&&"string"==typeof t)return u(t);var c=new Error("Cannot find module '"+t+"'");throw c.code="MODULE_NOT_FOUND",c}p.resolve=function(r){return e[t][1][r]||r},p.cache={};var l=r[t]=new f.Module(t);e[t][0].call(l.exports,p,l,l.exports,this)}return r[t].exports;function p(e){return f(p.resolve(e))}}f.isParcelRequire=!0,f.Module=function(e){this.id=e,this.bundle=f,this.exports={}},f.modules=e,f.cache=r,f.parent=o,f.register=function(r,t){e[r]=[function(e,r){r.exports=t},{}]};for(var c=0;c<t.length;c++)try{f(t[c])}catch(e){i||(i=e)}if(t.length){var l=f(t[t.length-1]);"object"==typeof exports&&"undefined"!=typeof module?module.exports=l:"function"==typeof define&&define.amd?define(function(){return l}):n&&(this[n]=l)}if(parcelRequire=f,i)throw i;return f}({"r6WJ":[function(require,module,exports) {
function e(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;if(r)return r.call(e,t);if(e.parentNode){for(var c=e.parentNode.querySelectorAll(t),o=c.length;o--;0)if(c[o]===e)return!0;return!1}}module.exports=e;
},{}],"cDuO":[function(require,module,exports) {
function e(e,r){var n,o,t=e.length;if("number"==typeof t)for(n=0;n<t;n++)r(e[n],n);else for(n in o=0,e)e.hasOwnProperty(n)&&r(e[n],n,o++);return e}module.exports=e;
},{}],"G20n":[function(require,module,exports) {
var s=require("./each");function e(i,a){if(a)if(Array.isArray(a))s(a,function(s){e(i,s)});else if(i.classList){var r=a.split(" ").filter(Boolean);s(r,function(s){i.classList.add(s)})}else i.className+=" "+a}module.exports=e;
},{"./each":"cDuO"}],"THIL":[function(require,module,exports) {
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.appendMany=c,exports.nextUntil=f,exports.before=s,exports.findChildren=d,exports.createDiv=p;var t=e(require("dom101/matches"));function e(t){return t&&t.__esModule?t:{default:t}}function r(t){return u(t)||i(t)||o(t)||n()}function n(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function o(t,e){if(t){if("string"==typeof t)return a(t,e);var r=Object.prototype.toString.call(t).slice(8,-1);return"Object"===r&&t.constructor&&(r=t.constructor.name),"Map"===r||"Set"===r?Array.from(t):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?a(t,e):void 0}}function i(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}function u(t){if(Array.isArray(t))return a(t)}function a(t,e){(null==e||e>t.length)&&(e=t.length);for(var r=0,n=new Array(e);r<e;r++)n[r]=t[r];return n}function c(t,e){e.forEach(function(e){t.appendChild(e)})}function f(t,e){return l(t.nextSibling,e,[])}function l(e,n,o){return e?(0,t.default)(e,n)?o:l(e.nextSibling,n,[].concat(r(o),[e])):o}function s(t,e){t.parentNode.insertBefore(e,t)}function d(e,r){return[].slice.call(e.children).filter(function(e){return(0,t.default)(e,r)})}function p(t){var e=document.createElement("div");return Object.keys(t).forEach(function(r){e.setAttribute(r,t[r])}),e}
},{"dom101/matches":"r6WJ"}],"hE9p":[function(require,module,exports) {
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=f,exports.groupify=p;var r=e(require("dom101/matches")),t=e(require("dom101/add-class")),n=require("../helpers/dom");function e(r){return r&&r.__esModule?r:{default:r}}function o(r){return c(r)||u(r)||i(r)||a()}function a(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function i(r,t){if(r){if("string"==typeof r)return s(r,t);var n=Object.prototype.toString.call(r).slice(8,-1);return"Object"===n&&r.constructor&&(n=r.constructor.name),"Map"===n||"Set"===n?Array.from(r):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(r,t):void 0}}function u(r){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(r))return Array.from(r)}function c(r){if(Array.isArray(r))return s(r)}function s(r,t){(null==t||t>r.length)&&(t=r.length);for(var n=0,e=new Array(t);n<t;n++)e[n]=r[n];return e}function f(r){l(r).forEach(function(r){(0,n.findChildren)(r,"[data-js-h3-section-list]").forEach(function(r){d(r)})})}function l(r){return p(r,{tag:"h2",wrapperFn:function(){return(0,n.createDiv)({class:"h2-section"})},bodyFn:function(){return(0,n.createDiv)({class:"body h3-section-list","data-js-h3-section-list":""})}})}function d(r){return p(r,{tag:"h3",wrapperFn:function(){return(0,n.createDiv)({class:"h3-section"})},bodyFn:function(){return(0,n.createDiv)({class:"body"})}})}function p(e,a){var i=a.tag,u=a.wrapperFn,c=a.bodyFn,s=e.children[0],f=[];if(s&&!(0,r.default)(s,i)){var l=(0,n.nextUntil)(s,i);f.push(d(s,null,[s].concat(o(l))))}return(0,n.findChildren)(e,i).forEach(function(r){var t=(0,n.nextUntil)(r,i);f.push(d(r,r,t))}),f;function d(r,e,o){var a=u(),i=r.className;i&&(0,t.default)(a,i),(0,n.before)(r,a);var s=c();return i&&(0,t.default)(s,i),(0,n.appendMany)(s,o),e&&a.appendChild(e),a.appendChild(s),a}}
},{"dom101/matches":"r6WJ","dom101/add-class":"G20n","../helpers/dom":"THIL"}],"DJ2P":[function(require,module,exports) {
function n(n,t,e){n.addEventListener?n.addEventListener(t,e):n.attachEvent("on"+t,function(){e.call(n)})}module.exports=n;
},{}],"eoMl":[function(require,module,exports) {
"use strict";var e=u(require("./wrapify")),d=u(require("dom101/add-class")),t=u(require("dom101/on"));function u(e){return e&&e.__esModule?e:{default:e}}var a,o=document.querySelector("[data-js-main-body]");function r(){a||((0,d.default)(document.documentElement,"LoadDone"),a=!0)}o&&((0,e.default)(o),(0,d.default)(o,"-wrapified")),(0,t.default)(window,"load",r),setTimeout(r,5e3);
},{"./wrapify":"hE9p","dom101/add-class":"G20n","dom101/on":"DJ2P"}]},{},["eoMl"], null)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,3 @@
<!-- critical js -->
<script>{% include 2017/critical/critical.js %}</script> <script>{% include 2017/critical/critical.js %}</script>
<script src='{{base}}/assets/packed/vendor.js?t={{ timestamp }}'></script>
<script src='{{base}}/assets/packed/app.js?t={{ timestamp }}'></script> <script src='{{base}}/assets/packed/app.js?t={{ timestamp }}'></script>
{% for lang in page.prism_languages %}<script src='https://cdn.jsdelivr.net/npm/prismjs@1.6.0/components/prism-{{lang}}.min.js'></script>{% endfor %} {% for lang in page.prism_languages %}<script src='https://cdn.jsdelivr.net/npm/prismjs@1.6.0/components/prism-{{lang}}.min.js'></script>{% endfor %}

View File

@ -3,11 +3,11 @@
<!-- critical css --> <!-- critical css -->
{% if include.critical == 'home' {% if include.critical == 'home'
%}<style id='critical-css'>{% include 2017/critical/home.css %}</style>{% %}<style id='critical-css'>{% include 2017/critical/critical-home.css %}</style>{%
endif endif
%}{% %}{%
if include.critical == 'sheet' if include.critical == 'sheet'
%}<style id='critical-css'>{% include 2017/critical/sheet.css %}</style>{% %}<style id='critical-css'>{% include 2017/critical/critical-sheet.css %}</style>{%
endif %} endif %}
<!-- allow disabling critical CSS optimization by passing ?nocrit=1 --> <!-- allow disabling critical CSS optimization by passing ?nocrit=1 -->

View File

@ -1,7 +0,0 @@
// 3rd party libs
window.Prism = require('prismjs')
// All the others
function requireAll (r) { r.keys().forEach(r) }
requireAll(require.context('./initializers/', true, /\.js$/))
requireAll(require.context('./behaviors/', true, /\.js$/))

View File

@ -1,21 +0,0 @@
/* eslint-env jest */
import qs from '../qs'
describe('qs()', () => {
test('basic', run({
input: '?preview=1',
output: { preview: '1' }
}))
test('two fragments', run({
input: '?a=1&b=2',
output: { a: '1', b: '2' }
}))
function run ({ input, output }) {
return function () {
const result = qs(input)
expect(result).toEqual(output)
}
}
})

View File

@ -1,63 +0,0 @@
/* eslint-env jest */
import wrapify from '../index'
import $ from 'jquery'
it('simple usage', run(`
<div>
<h2>simple usage<h2>
<h3>install</h3>
<p>(install)</p>
<h3>usage</h3>
<p>(usage)</p>
</div>
`, $div => {
expect($div.find('.h2-section .h3-section-list .h3-section').length).toEqual(2)
}))
it('h3 with class', run(`
<div>
<h3 class='-hello'>install</h3>
<p>(install)</p>
</div>
`, $div => {
expect($div.find('div.h3-section.-hello').length).toEqual(1)
expect($div.find('div.h3-section-list.-hello').length).toEqual(1)
}))
it('multiple h2s', run(`
<div>
<h2>multiple h2<h2>
<h3>install</h3>
<p>(install)</p>
<h3>usage</h3>
<p>(usage)</p>
<h2>getting started<h2>
<h3>first</h3>
<p>(first)</p>
<h3>second</h3>
<p>(second)</p>
</div>
`))
function run (input, fn) {
return function () {
const $div = $(input)
wrapify($div[0])
expect($div[0]).toMatchSnapshot()
if (fn) fn($div)
}
}
it('h2 + pre', run(`
<div>
<h2>heading</h2>
<pre class='language-markdown'>(code)</pre>
</div>
`))

32
_parcel/_base.scss Normal file
View File

@ -0,0 +1,32 @@
// Vendor and variables
@import 'sanitize.css/sanitize.css';
@import '../_sass/2017/variables.scss';
@import '../node_modules/modularscale-sass/stylesheets/_modularscale.scss';
@import '../_sass/vendor/ionicons-inline/ionicons.scss';
// Utilities
@import '../_sass/2017/utils/carbon-style.scss';
@import '../_sass/2017/utils/_font-size.scss';
@import '../_sass/2017/utils/gutter.scss';
@import '../_sass/2017/utils/heading-style.scss';
@import '../_sass/2017/utils/section-gutter.scss';
@import '../_sass/2017/utils/section-with-container.scss';
// Base
@import 'sanitize.css/sanitize.css';
@import '../_sass/2017/base/base.scss';
@import '../_sass/2017/base/fade.scss';
// Components
@import '../_sass/2017/components/attribute-peg.scss';
@import '../_sass/2017/components/announcements-item.scss';
@import '../_sass/2017/components/announcements-list.scss';
@import '../_sass/2017/components/back-button.scss';
@import '../_sass/2017/components/body-area.scss';
@import '../_sass/2017/components/codefund-sponsor.scss';
@import '../_sass/2017/components/page-actions.scss';
@import '../_sass/2017/components/pages-list.scss';
@import '../_sass/2017/components/search-box.scss';
@import '../_sass/2017/components/site-header.scss';
@import '../_sass/2017/components/top-nav.scss';
@import '../_sass/2017/components/top-sheet.scss';

12
_parcel/_utils.scss Normal file
View File

@ -0,0 +1,12 @@
// Vendor
@import '../_sass/2017/variables.scss';
@import '../node_modules/modularscale-sass/stylesheets/_modularscale.scss';
@import '../_sass/vendor/ionicons-inline/ionicons.scss';
// Utilities
@import '../_sass/2017/utils/carbon-style.scss';
@import '../_sass/2017/utils/_font-size.scss';
@import '../_sass/2017/utils/gutter.scss';
@import '../_sass/2017/utils/heading-style.scss';
@import '../_sass/2017/utils/section-gutter.scss';
@import '../_sass/2017/utils/section-with-container.scss';

30
_parcel/app.js Normal file
View File

@ -0,0 +1,30 @@
// Prismjs
import 'prismjs'
import 'prismjs/plugins/line-highlight/prism-line-highlight.min.js'
import 'prismjs/components/prism-jsx.min.js'
import 'prismjs/components/prism-bash.min.js'
import 'prismjs/components/prism-scss.min.js'
import 'prismjs/components/prism-css.min.js'
import 'prismjs/components/prism-elixir.min.js'
import 'prismjs/components/prism-ruby.min.js'
// Initializers
import './initializers/prism'
import './initializers/onmount'
// Behaviors
import './behaviors/anchors'
import './behaviors/dismissable'
import './behaviors/dismiss'
import './behaviors/disqus'
import './behaviors/h3-section-list'
import './behaviors/main-body'
import './behaviors/no-preview'
import './behaviors/searchable-header'
import './behaviors/searchable-item'
import './behaviors/search-form'
import './behaviors/search-input'
// CSS
import 'prismjs/plugins/line-highlight/prism-line-highlight.css'
import 'hint.css/hint.min.css'

View File

@ -9,7 +9,7 @@ const DEFAULTS = {
// text of anchor // text of anchor
text: '#', text: '#',
// append before or after innerText? // append before or after innerText?
shouldAppend: false, shouldAppend: false
} }
/* /*
@ -19,7 +19,9 @@ const DEFAULTS = {
onmount('[data-js-anchors]', function () { onmount('[data-js-anchors]', function () {
const data = JSON.parse(this.getAttribute('data-js-anchors') || '{}') const data = JSON.parse(this.getAttribute('data-js-anchors') || '{}')
const rules = Array.isArray(data) const rules = Array.isArray(data)
? (data.length ? data : [DEFAULTS]) ? data.length
? data
: [DEFAULTS]
: [Object.assign({}, DEFAULTS, data)] : [Object.assign({}, DEFAULTS, data)]
for (const { rule, className, text, shouldAppend } of rules) { for (const { rule, className, text, shouldAppend } of rules) {

View File

@ -14,7 +14,7 @@ onmount('[data-js-dismiss]', function () {
const dismissable = getData(parent, 'js-dismissable') const dismissable = getData(parent, 'js-dismissable')
const id = (dismissable && dismissable.id) || '' const id = (dismissable && dismissable.id) || ''
on(this, 'click', e => { on(this, 'click', (e) => {
Dismiss.setDismissed(id) Dismiss.setDismissed(id)
e.preventDefault() e.preventDefault()
if (parent) remove(parent) if (parent) remove(parent)

View File

@ -1,6 +1,6 @@
/* eslint-disable no-new */ /* eslint-disable no-new */
import Isotope from 'isotope-layout/dist/isotope.pkgd.js' import Isotope from 'isotope-layout'
import onmount from 'onmount' import onmount from 'onmount'
import on from 'dom101/on' import on from 'dom101/on'
import qsa from 'dom101/query-selector-all' import qsa from 'dom101/query-selector-all'
@ -17,7 +17,7 @@ onmount('[data-js-h3-section-list]', function () {
const images = qsa('img', this) const images = qsa('img', this)
images.forEach(image => { images.forEach((image) => {
on(image, 'load', () => { on(image, 'load', () => {
iso.layout() iso.layout()
}) })

View File

@ -6,7 +6,7 @@ import on from 'dom101/on'
*/ */
onmount('[data-js-search-form]', function () { onmount('[data-js-search-form]', function () {
on(this, 'submit', e => { on(this, 'submit', (e) => {
e.preventDefault() e.preventDefault()
const link = document.querySelector('a[data-search-index]:visible') const link = document.querySelector('a[data-search-index]:visible')

View File

@ -17,6 +17,8 @@ onmount('[data-js-search-input]', function () {
const query = (qs(window.location.search) || {}).q const query = (qs(window.location.search) || {}).q
if (query && query.length) { if (query && query.length) {
this.value = query this.value = query
setTimeout(() => { Search.show(query) }) setTimeout(() => {
Search.show(query)
})
} }
}) })

View File

@ -10,11 +10,12 @@ import './searchable-item'
*/ */
onmount('[data-js-searchable-header]', function () { onmount('[data-js-searchable-header]', function () {
const els = nextUntil(this, '[data-js-searchable-header]') const els = nextUntil(this, '[data-js-searchable-header]').filter((el) =>
.filter(el => matches(el, '[data-search-index]')) matches(el, '[data-search-index]')
)
const keywords = els const keywords = els
.map(n => n.getAttribute('data-search-index')) .map((n) => n.getAttribute('data-search-index'))
.join(' ') .join(' ')
.split(' ') .split(' ')

View File

@ -0,0 +1,16 @@
@import './_utils.scss';
@import './_base.scss';
// Components
@import '../_sass/2017/components/attribute-peg.scss';
@import '../_sass/2017/components/announcements-item.scss';
@import '../_sass/2017/components/announcements-list.scss';
@import '../_sass/2017/components/back-button.scss';
@import '../_sass/2017/components/body-area.scss';
@import '../_sass/2017/components/codefund-sponsor.scss';
@import '../_sass/2017/components/page-actions.scss';
@import '../_sass/2017/components/pages-list.scss';
@import '../_sass/2017/components/search-box.scss';
@import '../_sass/2017/components/site-header.scss';
@import '../_sass/2017/components/top-nav.scss';
@import '../_sass/2017/components/top-sheet.scss';

View File

@ -0,0 +1,21 @@
@import './_utils.scss';
@import './_base.scss';
// Markdown
@import '../_sass/2017/markdown/a-em.scss';
@import '../_sass/2017/markdown/code.scss';
@import '../_sass/2017/markdown/headings.scss';
@import '../_sass/2017/markdown/local-anchor.scss';
@import '../_sass/2017/markdown/p.scss';
@import '../_sass/2017/markdown/table.scss';
@import '../_sass/2017/markdown/ul.scss';
// Components
@import '../_sass/2017/components/back-button.scss';
@import '../_sass/2017/components/body-area.scss';
@import '../_sass/2017/components/codefund-sponsor.scss';
@import '../_sass/2017/components/h3-section.scss';
@import '../_sass/2017/components/h3-section-list.scss';
@import '../_sass/2017/components/main-heading.scss';
@import '../_sass/2017/components/page-actions.scss';
@import '../_sass/2017/components/top-nav.scss';

View File

@ -20,7 +20,7 @@ on(window, 'load', done)
setTimeout(done, 5000) setTimeout(done, 5000)
let isDone let isDone
function done () { function done() {
if (isDone) return if (isDone) return
addClass(document.documentElement, 'LoadDone') addClass(document.documentElement, 'LoadDone')
isDone = true isDone = true

View File

@ -2,7 +2,7 @@
* Stores and retrieves data from an element. Works like jQuery.data(). * Stores and retrieves data from an element. Works like jQuery.data().
*/ */
export function data (el, key, val) { export function data(el, key, val) {
if (typeof val !== 'undefined') { if (typeof val !== 'undefined') {
return getData(el, key) return getData(el, key)
} else { } else {
@ -10,11 +10,11 @@ export function data (el, key, val) {
} }
} }
export function getData (el, key) { export function getData(el, key) {
const str = el.getAttribute('data-' + key) const str = el.getAttribute('data-' + key)
return JSON.parse(str || '{}') return JSON.parse(str || '{}')
} }
export function setData (el, key, val) { export function setData(el, key, val) {
el.setAttribute('data-' + key, JSON.stringify(val)) el.setAttribute('data-' + key, JSON.stringify(val))
} }

View File

@ -7,7 +7,7 @@ import * as Store from './store'
* setDismissed('2017-09-02-happy-birthday') * setDismissed('2017-09-02-happy-birthday')
*/ */
export function setDismissed (id) { export function setDismissed(id) {
Store.update('dismissed', function (data) { Store.update('dismissed', function (data) {
data[id] = true data[id] = true
return data return data
@ -22,7 +22,7 @@ export function setDismissed (id) {
* isDismissed('2017-09-02-happy-birthday') => true * isDismissed('2017-09-02-happy-birthday') => true
*/ */
export function isDismissed (id) { export function isDismissed(id) {
const data = Store.fetch('dismissed') const data = Store.fetch('dismissed')
return data && data[id] return data && data[id]
} }

View File

@ -4,33 +4,35 @@ import matches from 'dom101/matches'
* Just like jQuery.append * Just like jQuery.append
*/ */
export function appendMany (el, children) { export function appendMany(el, children) {
children.forEach(child => { el.appendChild(child) }) children.forEach((child) => {
el.appendChild(child)
})
} }
/* /*
* Just like jQuery.nextUntil * Just like jQuery.nextUntil
*/ */
export function nextUntil (el, selector) { export function nextUntil(el, selector) {
const nextEl = el.nextSibling const nextEl = el.nextSibling
return nextUntilTick(nextEl, selector, []) return nextUntilTick(nextEl, selector, [])
} }
function nextUntilTick (el, selector, acc) { function nextUntilTick(el, selector, acc) {
if (!el) return acc if (!el) return acc
const isMatch = matches(el, selector) const isMatch = matches(el, selector)
if (isMatch) return acc if (isMatch) return acc
return nextUntilTick(el.nextSibling, selector, [ ...acc, el ]) return nextUntilTick(el.nextSibling, selector, [...acc, el])
} }
/* /*
* Just like jQuery.before * Just like jQuery.before
*/ */
export function before (reference, newNode) { export function before(reference, newNode) {
reference.parentNode.insertBefore(newNode, reference) reference.parentNode.insertBefore(newNode, reference)
} }
@ -38,9 +40,8 @@ export function before (reference, newNode) {
* Like jQuery.children('selector') * Like jQuery.children('selector')
*/ */
export function findChildren (el, selector) { export function findChildren(el, selector) {
return [].slice.call(el.children) return [].slice.call(el.children).filter((child) => matches(child, selector))
.filter(child => matches(child, selector))
} }
/** /**
@ -52,9 +53,9 @@ export function findChildren (el, selector) {
* createDiv({ class: 'foo' }) * createDiv({ class: 'foo' })
*/ */
export function createDiv (props) { export function createDiv(props) {
const d = document.createElement('div') const d = document.createElement('div')
Object.keys(props).forEach(key => { Object.keys(props).forEach((key) => {
d.setAttribute(key, props[key]) d.setAttribute(key, props[key])
}) })
return d return d

View File

@ -5,12 +5,12 @@
* inject('devhints.disqus.com') * inject('devhints.disqus.com')
*/ */
export default function inject (host) { export default function inject(host) {
injectEmbed(host) injectEmbed(host)
injectCount(host) injectCount(host)
} }
export function injectEmbed (host) { export function injectEmbed(host) {
const d = document const d = document
const s = d.createElement('script') const s = d.createElement('script')
s.src = `https://${host}/embed.js` s.src = `https://${host}/embed.js`
@ -18,7 +18,7 @@ export function injectEmbed (host) {
;(d.head || d.body).appendChild(s) ;(d.head || d.body).appendChild(s)
} }
export function injectCount (host) { export function injectCount(host) {
const d = document const d = document
const s = d.createElement('script') const s = d.createElement('script')
s.src = `https://${host}/count.js` s.src = `https://${host}/count.js`

View File

@ -7,7 +7,7 @@
* }) * })
*/ */
export default function permutate (data) { export default function permutate(data) {
let words = [] let words = []
if (data.slug) { if (data.slug) {
words = words.concat(permutateString(data.slug)) words = words.concat(permutateString(data.slug))
@ -26,11 +26,11 @@ export default function permutate (data) {
* => ['h', 'hi', 'j', 'jo', 'joe'] * => ['h', 'hi', 'j', 'jo', 'joe']
*/ */
export function permutateString (str) { export function permutateString(str) {
let words = [] let words = []
let inputs = splitwords(str) let inputs = splitwords(str)
inputs.forEach(word => { inputs.forEach((word) => {
words = words.concat(permutateWord(word)) words = words.concat(permutateWord(word))
}) })
@ -45,7 +45,7 @@ export function permutateString (str) {
* => ['h', 'he', 'hel', 'hell', 'hello'] * => ['h', 'he', 'hel', 'hell', 'hello']
*/ */
export function permutateWord (str) { export function permutateWord(str) {
let words = [] let words = []
const len = str.length const len = str.length
for (var i = 1; i <= len; ++i) { for (var i = 1; i <= len; ++i) {
@ -62,10 +62,11 @@ export function permutateWord (str) {
* => ['hello', 'world'] * => ['hello', 'world']
*/ */
export function splitwords (str) { export function splitwords(str) {
const words = str.toLowerCase() const words = str
.toLowerCase()
.split(/[ /\-_]/) .split(/[ /\-_]/)
.filter(k => k && k.length !== 0) .filter((k) => k && k.length !== 0)
return words return words
} }

View File

@ -2,6 +2,6 @@
* Checks if we're in preview mode (?preview=1). * Checks if we're in preview mode (?preview=1).
*/ */
export function isPreview () { export function isPreview() {
return window.location.search.indexOf('preview=1') !== -1 return window.location.search.indexOf('preview=1') !== -1
} }

View File

@ -2,16 +2,16 @@
* Helper: minimal qs implementation * Helper: minimal qs implementation
*/ */
export default function qs (search) { export default function qs(search) {
search = search.substr(1) search = search.substr(1)
const parts = search.split('&').map(p => p.split('=')) const parts = search.split('&').map((p) => p.split('='))
return parts.reduce((result, part) => { return parts.reduce((result, part) => {
result[part[0]] = qsdecode(part[1]) result[part[0]] = qsdecode(part[1])
return result return result
}, {}) }, {})
} }
export function qsdecode (string) { export function qsdecode(string) {
if (!string) string = '' if (!string) string = ''
string = string.replace(/\+/g, ' ') string = string.replace(/\+/g, ' ')
return string return string

View File

@ -8,8 +8,8 @@ import qsa from 'dom101/query-selector-all'
* Search.showAll() * Search.showAll()
*/ */
export function showAll () { export function showAll() {
qsa('[data-search-index]').forEach(el => { qsa('[data-search-index]').forEach((el) => {
el.removeAttribute('aria-hidden') el.removeAttribute('aria-hidden')
}) })
} }
@ -21,20 +21,20 @@ export function showAll () {
* Search.show('hello') * Search.show('hello')
*/ */
export function show (val) { export function show(val) {
const keywords = splitwords(val) const keywords = splitwords(val)
if (!keywords.length) return showAll() if (!keywords.length) return showAll()
const selectors = keywords const selectors = keywords
.map(k => `[data-search-index~=${JSON.stringify(k)}]`) .map((k) => `[data-search-index~=${JSON.stringify(k)}]`)
.join('') .join('')
qsa('[data-search-index]').forEach(el => { qsa('[data-search-index]').forEach((el) => {
el.setAttribute('aria-hidden', true) el.setAttribute('aria-hidden', true)
}) })
qsa(selectors).forEach(el => { qsa(selectors).forEach((el) => {
el.removeAttribute('aria-hidden') el.removeAttribute('aria-hidden')
}) })
} }

View File

@ -9,7 +9,7 @@
* }) * })
*/ */
export function update (key, fn) { export function update(key, fn) {
if (!window.localStorage) return if (!window.localStorage) return
let data = JSON.parse(window.localStorage[key] || '{}') let data = JSON.parse(window.localStorage[key] || '{}')
data = fn(data) data = fn(data)
@ -23,7 +23,7 @@ export function update (key, fn) {
* const data = fetch('dismissed') * const data = fetch('dismissed')
*/ */
export function fetch (key) { export function fetch(key) {
if (!window.localStorage) return if (!window.localStorage) return
return JSON.parse(window.localStorage[key] || '{}') return JSON.parse(window.localStorage[key] || '{}')
} }

View File

@ -6,5 +6,7 @@ import onmount from 'onmount'
*/ */
ready(() => { ready(() => {
setTimeout(() => { onmount() }) setTimeout(() => {
onmount()
})
}) })

View File

@ -0,0 +1 @@
window.Prism = require('prismjs')

View File

@ -0,0 +1,88 @@
/* eslint-env jest */
import wrapify from '../index'
it(
'simple usage',
run(
`
<div>
<h2>simple usage<h2>
<h3>install</h3>
<p>(install)</p>
<h3>usage</h3>
<p>(usage)</p>
</div>
`,
(root) => {
expect(
root.querySelectorAll('.h2-section .h3-section-list .h3-section').length
).toEqual(2)
}
)
)
it(
'h3 with class',
run(
`
<div>
<h3 class='-hello'>install</h3>
<p>(install)</p>
</div>
`,
(root) => {
expect(root.querySelectorAll('div.h3-section.-hello').length).toEqual(1)
expect(
root.querySelectorAll('div.h3-section-list.-hello').length
).toEqual(1)
}
)
)
it(
'multiple h2s',
run(`
<div>
<h2>multiple h2<h2>
<h3>install</h3>
<p>(install)</p>
<h3>usage</h3>
<p>(usage)</p>
<h2>getting started<h2>
<h3>first</h3>
<p>(first)</p>
<h3>second</h3>
<p>(second)</p>
</div>
`)
)
function run(input, fn) {
return function () {
const div = document.createElement('div')
div.innerHTML = input
const root = div.children[0]
wrapify(root)
expect(root).toMatchSnapshot()
if (fn) fn(root)
}
}
it(
'h2 + pre',
run(`
<div>
<h2>heading</h2>
<pre class='language-markdown'>(code)</pre>
</div>
`)
)

View File

@ -1,6 +1,12 @@
import matches from 'dom101/matches' import matches from 'dom101/matches'
import addClass from 'dom101/add-class' import addClass from 'dom101/add-class'
import { appendMany, nextUntil, before, findChildren, createDiv } from '../helpers/dom' import {
appendMany,
nextUntil,
before,
findChildren,
createDiv
} from '../helpers/dom'
/** /**
* Wraps h2 sections into h2-section. * Wraps h2 sections into h2-section.
@ -9,14 +15,16 @@ import { appendMany, nextUntil, before, findChildren, createDiv } from '../helpe
* @private * @private
*/ */
export default function wrapify (root) { export default function wrapify(root) {
// These are your H2 sections. Returns a list of .h2-section nodes. // These are your H2 sections. Returns a list of .h2-section nodes.
const sections = wrapifyH2(root) const sections = wrapifyH2(root)
// For each h2 section, wrap the H3's in them // For each h2 section, wrap the H3's in them
sections.forEach(section => { sections.forEach((section) => {
const bodies = findChildren(section, '[data-js-h3-section-list]') const bodies = findChildren(section, '[data-js-h3-section-list]')
bodies.forEach(body => { wrapifyH3(body) }) bodies.forEach((body) => {
wrapifyH3(body)
})
}) })
} }
@ -33,14 +41,15 @@ export default function wrapify (root) {
* @private * @private
*/ */
function wrapifyH2 (root) { function wrapifyH2(root) {
return groupify(root, { return groupify(root, {
tag: 'h2', tag: 'h2',
wrapperFn: () => createDiv({ class: 'h2-section' }), wrapperFn: () => createDiv({ class: 'h2-section' }),
bodyFn: () => createDiv({ bodyFn: () =>
class: 'body h3-section-list', createDiv({
'data-js-h3-section-list': '' class: 'body h3-section-list',
}) 'data-js-h3-section-list': ''
})
}) })
} }
@ -57,7 +66,7 @@ function wrapifyH2 (root) {
* @private * @private
*/ */
function wrapifyH3 (root) { function wrapifyH3(root) {
return groupify(root, { return groupify(root, {
tag: 'h3', tag: 'h3',
wrapperFn: () => createDiv({ class: 'h3-section' }), wrapperFn: () => createDiv({ class: 'h3-section' }),
@ -71,27 +80,27 @@ function wrapifyH3 (root) {
* @private * @private
*/ */
export function groupify (el, { tag, wrapperFn, bodyFn }) { export function groupify(el, { tag, wrapperFn, bodyFn }) {
const first = el.children[0] const first = el.children[0]
let result = [] let result = []
// Handle the markup before the first h2 // Handle the markup before the first h2
if (first && !matches(first, tag)) { if (first && !matches(first, tag)) {
const sibs = nextUntil(first, tag) const sibs = nextUntil(first, tag)
result.push(wrap(first, null, [ first, ...sibs ])) result.push(wrap(first, null, [first, ...sibs]))
} }
// Find all h3's inside it // Find all h3's inside it
const children = findChildren(el, tag) const children = findChildren(el, tag)
children.forEach(child => { children.forEach((child) => {
const sibs = nextUntil(child, tag) const sibs = nextUntil(child, tag)
result.push(wrap(child, child, sibs)) result.push(wrap(child, child, sibs))
}) })
return result return result
function wrap (pivot, first, sibs) { function wrap(pivot, first, sibs) {
const wrap = wrapperFn() const wrap = wrapperFn()
const pivotClass = pivot.className const pivotClass = pivot.className

View File

@ -43,6 +43,7 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
cursor: pointer; cursor: pointer;
background: transparent;
&:hover, &:hover,
&:focus { &:focus {

View File

@ -1,4 +1,6 @@
@import '../vendor/sanitize.css/sanitize'; // Generated by parcel
@import '../../assets/packed/app.css';
@import './variables'; @import './variables';
@import '../vendor/modularscale/modularscale'; @import '../vendor/modularscale/modularscale';
@import '../vendor/ionicons-inline/ionicons'; @import '../vendor/ionicons-inline/ionicons';

View File

@ -80,14 +80,14 @@ $modularscale : () !default;// Parse settings starting with defaults.
// This does not support non-integer exponents, // This does not support non-integer exponents,
// Check and return an error if a non-integer exponent is passed. // Check and return an error if a non-integer exponent is passed.
@if (floor($e) != $e) { @if (floor($e) != $e) {
@error ' // @error '
====================================================================== // ======================================================================
Non-integer values are not supported in modularscale by default. // Non-integer values are not supported in modularscale by default.
Try using mathsass in your project to add non-integer scale support. // Try using mathsass in your project to add non-integer scale support.
https://github.com/terkel/mathsass // https://github.com/terkel/mathsass
====================================================================== // ======================================================================
' // '
} }
// Seed the return. // Seed the return.

View File

@ -1,45 +0,0 @@
const critical = require('critical')
console.warn('Generating critical path styles into _includes/2017/critical/...')
const OPTIONS = {
base: '_site',
width: 1400,
height: 900,
minify: true,
extract: true,
ignore: [
'@font-face'
],
include: [
// fade-in magic (base/fade)
/html\.WithJs/
]
}
critical.generate({
...OPTIONS,
src: 'index.html',
dest: '../_includes/2017/critical/home.css',
include: [
...OPTIONS.include,
// searchbox with placeholder
/\.search-box/
]
})
critical.generate({
...OPTIONS,
src: 'react.html',
dest: '../_includes/2017/critical/sheet.css',
include: [
...OPTIONS.include,
// sections (and h3 section list), just to be sure
/\.h3-section/,
// eg, -six-column in devhints.io/layout-thrashing
/-column/
]
})

View File

@ -1,73 +0,0 @@
const join = require('path').resolve
const webpack = require('webpack')
module.exports = {
context: join(__dirname, '..'),
entry: {
app: './_js/app.js',
vendor: [
// Large 3rd-party libs
'prismjs',
// Prism plugins
'prismjs/plugins/line-highlight/prism-line-highlight.min.js',
'prismjs/components/prism-jsx.min.js',
'prismjs/components/prism-bash.min.js',
'prismjs/components/prism-scss.min.js',
'prismjs/components/prism-css.min.js',
'prismjs/components/prism-elixir.min.js',
'prismjs/components/prism-ruby.min.js',
// CSS
'prismjs/plugins/line-highlight/prism-line-highlight.css',
'hint.css/hint.min.css'
]
},
output: {
path: join(__dirname, '..', 'assets', 'packed'),
filename: '[name].js',
devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' }
]
},
{
test: /\.css$/,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' }
]
}
]
},
resolve: {
alias: {
// Never bundle jQuery
'jquery': join(__dirname, '..', '_js/helpers/noop.js')
}
},
stats: 'minimal',
plugins: [
// Optimize module ID's for vendor chunks
new webpack.HashedModuleIdsPlugin({
hashFunction: 'sha256',
hashDigest: 'base64',
hashDigestLength: 20
}),
// Optimize vendor
new webpack.optimize.CommonsChunkPlugin('vendor'),
// Don't include debug symbols ever
new webpack.EnvironmentPlugin({
NODE_ENV: 'production'
})
],
devtool: 'source-map'
}

View File

@ -1,28 +0,0 @@
const join = require('path').resolve
const webpack = require('webpack')
module.exports = {
context: join(__dirname, '..'),
entry: './_js/critical.js',
output: {
path: join(__dirname, '..', '_includes', '2017', 'critical'),
filename: 'critical.js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{ loader: 'babel-loader' }
]
}
]
},
stats: 'minimal',
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'production'
})
]
}

3
assets/packed/app.css Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,11 +6,14 @@ services:
- .:/app - .:/app
- rubygems:/usr/local/bundle - rubygems:/usr/local/bundle
- ./node_modules:/app/node_modules - ./node_modules:/app/node_modules
- yarn_cache:/root/.cache/yarn
ports: ports:
- '4001:4001' - '4001:4001'
- '35729:35729' - '35729:35729'
command: 'env PORT=4001 HOST=0.0.0.0 yarn run dev' command: >
bash -c 'yarn; bundle; env PORT=4001 HOST=0.0.0.0 yarn run dev'
volumes: volumes:
rubygems: rubygems:
node_modules: node_modules:
yarn_cache:

16
netlify.toml Normal file
View File

@ -0,0 +1,16 @@
[build]
command = "yarn build"
publish = "_site/"
[[plugins]]
# https://www.npmjs.com/package/netlify-plugin-minify-html
package = "netlify-plugin-minify-html"
[plugins.inputs]
contexts = [ 'production', 'branch-deploy', 'deploy-preview' ]
# https://github.com/kangax/html-minifier#options-quick-reference
[plugins.inputs.minifierOptions]
removeComments = true
minifyCSS = true
minifyJS = true

View File

@ -1,59 +1,54 @@
{ {
"name": "cheatsheets", "name": "cheatsheets",
"description": "Devhints.io",
"version": "1.0.0", "version": "1.0.0",
"main": "index.js",
"repository": "https://github.com/rstacruz/cheatsheets.git",
"author": "Rico Sta. Cruz <rstacruz@users.noreply.github.com>", "author": "Rico Sta. Cruz <rstacruz@users.noreply.github.com>",
"license": "MIT",
"devDependencies": {
"babel-core": "6.26.0",
"babel-eslint": "8.0.1",
"babel-jest": "21.2.0",
"babel-loader": "7.1.2",
"babel-preset-env": "1.6.0",
"concurrently": "3.5.0",
"css-loader": "0.28.7",
"eslint-plugin-flowtype": "2.37.0",
"jest": "21.2.1",
"jest-html": "1.3.5",
"npm-run-all": "4.1.1",
"standard": "10.0.3",
"style-loader": "0.18.2",
"uglifyjs-webpack-plugin": "0.4.6",
"webpack": "3.6.0"
},
"scripts": {
"critical": "make critical",
"dev": "make dev",
"test": "jest",
"test:all": "run-s test lint",
"lint": "standard -v",
"jest-html": "jest-html"
},
"dependencies": { "dependencies": {
"babel-polyfill": "6.26.0", "autoprefixer": "^9.8.0",
"critical": "0.9.1", "dom101": "^2.2.1",
"dom101": "2.2.1", "hint.css": "^2.6.0",
"hint.css": "2.5.0", "isotope-layout": "^3.0.6",
"isotope-layout": "3.0.4", "lodash.noop": "^3.0.1",
"jquery": "3.2.1", "modularscale-sass": "^3.0.10",
"onmount": "1.3.0", "onmount": "^1.3.0",
"prettier": "1.11.1", "postcss-modules": "^2.0.0",
"prismjs": "1.8.1", "prismjs": "^1.20.0",
"sanitize.css": "5.0.0" "sanitize.css": "^11.0.1",
"sass": "^1.26.8"
}, },
"standard": { "devDependencies": {
"parser": "babel-eslint", "@babel/core": "^7.10.2",
"ignore": [ "@babel/preset-env": "^7.10.2",
"assets/script.js" "jest": "26.0.1",
], "jest-html": "1.5.0",
"plugins": [ "netlify-plugin-minify-html": "^0.2.3",
"flowtype" "npm-run-all": "^4.1.5",
] "parcel-bundler": "^1.12.4",
"prettier": "^2.0.5",
"wait-on": "^5.0.1"
}, },
"homepage": "https://devhints.io/",
"jest": { "jest": {
"snapshotSerializers": [ "snapshotSerializers": [
" <rootDir>/node_modules/jest-html" "<rootDir>/node_modules/jest-html"
] ]
},
"license": "MIT",
"main": "index.js",
"private": true,
"repository": "https://github.com/rstacruz/cheatsheets.git",
"scripts": {
"build": "run-s -s 'parcel:*:build' jekyll:build",
"dev": "run-p -sl jekyll:watch 'parcel:*:watch'",
"jekyll:build": "bundle exec jekyll build",
"jekyll:watch": "wait-on assets/packed/app.js && bundle exec jekyll serve --safe --trace --drafts --watch --incremental --host ${HOST:-0.0.0.0} --port ${PORT:-3000}",
"jest-html": "jest-html",
"parcel:app:build": "parcel build '_parcel/app.js' -d assets/packed --no-source-maps --no-autoinstall",
"parcel:app:watch": "parcel watch '_parcel/app.js' -d assets/packed --no-source-maps --no-autoinstall",
"parcel:build": "run-s -s 'parcel:*:build'",
"parcel:critical:build": "parcel build '_parcel/critical*.{js,scss}' -d _includes/2017/critical --no-source-maps --no-autoinstall",
"parcel:critical:watch": "parcel watch '_parcel/critical*.{js,scss}' -d _includes/2017/critical --no-source-maps --no-autoinstall",
"prettier:format": "prettier --write '_parcel/**/*.{js,scss}'",
"test": "jest"
} }
} }

View File

@ -1,4 +0,0 @@
module.exports = [
require('./_support/webpack.config.js'),
require('./_support/webpack.critical.js')
]

11231
yarn.lock

File diff suppressed because it is too large Load Diff