├── docs ├── 404.md ├── images │ ├── tide-wp.png │ ├── Tide-Team.png │ ├── api-php-auth.png │ ├── kinsta-logo.png │ ├── api-php-start.png │ ├── Tide-Contributor.png │ ├── api-php-payload.png │ ├── architecture-diagram.png │ ├── lighthouse-server-auth.png │ ├── lighthouse-server-poll.png │ ├── lighthouse-server-audit.png │ ├── lighthouse-server-header.png │ ├── lighthouse-server-queue.png │ ├── lighthouse-server-checksum.png │ ├── lighthouse-server-code-info.png │ ├── lighthouse-server-payload.png │ ├── lighthouse-server-raw-report.png │ ├── lighthouse-server-audit-complete.png │ └── lighthouse-server-summary-report.png ├── installation │ ├── index.md │ ├── cloning.md │ └── prerequisites.md ├── gcp │ ├── google-cloud-storage.md │ ├── google-cloud-memorystore.md │ ├── google-cloud-firestore.md │ ├── google-cloud-sql.md │ ├── index.md │ ├── google-app-engine.md │ └── google-kubernetes-engine.md ├── aws │ └── index.md ├── license.md ├── roadmap.md ├── README.md ├── services │ ├── index.md │ ├── phpcs-server.md │ ├── sync-server.md │ └── lighthouse-server.md ├── search.md ├── help.md ├── code-of-conduct.md ├── contributing.md └── local-development.md ├── src ├── css │ ├── base │ │ ├── ionicons.styl │ │ ├── 0-normalize.styl │ │ └── base.styl │ ├── docpress.styl │ ├── components │ │ ├── 404.styl │ │ ├── nprogress.styl │ │ ├── toc-menu-scrollbar.styl │ │ ├── sponsors.styl │ │ ├── heading-list.styl │ │ ├── hero.styl │ │ ├── link-index.styl │ │ ├── menu-toggle.styl │ │ ├── doc-layout.styl │ │ ├── api-check.styl │ │ ├── markdown-body.styl │ │ ├── toc-menu.styl │ │ ├── footer-nav.styl │ │ └── header-nav.styl │ └── variables.styl ├── js │ ├── polyfills │ │ └── index.js │ ├── script.js │ ├── waves │ │ └── index.js │ ├── apicheck │ │ └── index.js │ ├── scrollclass │ │ └── index.js │ └── scrolltrack │ │ └── index.js └── layout.pug ├── docpress ├── docpress-core │ ├── fixture │ │ ├── onmount │ │ │ ├── docs │ │ │ │ ├── image.png │ │ │ │ ├── assets │ │ │ │ │ └── style.css │ │ │ │ ├── turbolinks.md │ │ │ │ ├── cancelling.md │ │ │ │ ├── role.md │ │ │ │ ├── debugging.md │ │ │ │ ├── testing.md │ │ │ │ ├── unique-ids.md │ │ │ │ ├── README.md │ │ │ │ ├── rails.md │ │ │ │ ├── automatic-observation.md │ │ │ │ ├── cleanup.md │ │ │ │ ├── idempotency.md │ │ │ │ └── premise.md │ │ │ ├── metalsmith.js │ │ │ └── README.md │ │ ├── custom-docs │ │ │ ├── README.md │ │ │ ├── documents │ │ │ │ ├── intro.md │ │ │ │ └── README.md │ │ │ ├── docpress.json │ │ │ └── metalsmith.js │ │ ├── root-config │ │ │ ├── README.md │ │ │ ├── docpress.json │ │ │ └── metalsmith.js │ │ ├── package-config-2 │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ ├── docpress.json │ │ │ └── metalsmith.js │ │ ├── package-config-3 │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ └── metalsmith.js │ │ ├── package-config │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ └── metalsmith.js │ │ ├── tocless │ │ │ ├── README.md │ │ │ └── metalsmith.js │ │ ├── markdown-plugin-invalid │ │ │ ├── README.md │ │ │ ├── docpress.json │ │ │ └── metalsmith.js │ │ ├── with-anchors │ │ │ ├── README.md │ │ │ ├── docs │ │ │ │ └── README.md │ │ │ └── metalsmith.js │ │ ├── markdown-plugin │ │ │ ├── README.md │ │ │ ├── docpress.json │ │ │ └── metalsmith.js │ │ └── with-config │ │ │ └── docs │ │ │ └── docpress.json │ ├── index.js │ ├── ms.js │ ├── .gitignore │ ├── lib │ │ ├── external_source.js │ │ ├── log.js │ │ ├── slugify.js │ │ ├── memoize.js │ │ ├── syntax_highlight.js │ │ ├── indexify.js │ │ ├── helpers │ │ │ ├── strip_markdown.js │ │ │ └── markdown.js │ │ ├── tocify_page.js │ │ ├── ms.js │ │ └── fix_html.js │ └── package.json ├── docpress │ ├── fixture │ │ └── basic │ │ │ ├── README.md │ │ │ └── docs │ │ │ └── README.md │ ├── .gitignore │ ├── lib │ │ └── delegate_bin.js │ ├── package.json │ └── bin │ │ └── docpress └── docpress-base │ ├── fixture │ ├── css-file │ │ ├── README.md │ │ ├── docs │ │ │ └── extra.css │ │ ├── docpress.json │ │ └── metalsmith.js │ ├── external-css │ │ ├── README.md │ │ ├── docpress.json │ │ └── metalsmith.js │ ├── google-analytics │ │ ├── README.md │ │ ├── docpress.json │ │ └── metalsmith.js │ ├── stylus-imports │ │ ├── README.md │ │ ├── docpress.json │ │ ├── stylus │ │ │ └── extra.styl │ │ └── metalsmith.js │ ├── onmount │ │ ├── docs │ │ │ ├── assets │ │ │ │ └── script.js │ │ │ ├── docpress.json │ │ │ ├── turbolinks.md │ │ │ ├── cancelling.md │ │ │ ├── role.md │ │ │ ├── debugging.md │ │ │ ├── testing.md │ │ │ ├── unique-ids.md │ │ │ ├── README.md │ │ │ ├── rails.md │ │ │ ├── automatic-observation.md │ │ │ ├── cleanup.md │ │ │ ├── idempotency.md │ │ │ └── premise.md │ │ ├── metalsmith.js │ │ └── README.md │ └── with-anchors │ │ ├── README.md │ │ ├── docs │ │ └── README.md │ │ └── metalsmith.js │ ├── .npmignore │ ├── example │ ├── docs │ │ ├── usage.md │ │ ├── install.md │ │ ├── README.md │ │ └── hello.md │ ├── metalsmith.js │ └── README.md │ ├── lib │ ├── helpers │ │ ├── noop.js │ │ ├── to_array.js │ │ ├── use_cache.js │ │ └── each_cons.js │ ├── hash.js │ ├── build_js.js │ ├── memoize.js │ └── build_css.js │ ├── .gitignore │ ├── bin │ └── build │ └── package.json ├── .gitignore ├── footer.php ├── screenshot.png ├── _docpress ├── images │ ├── tide-wp.png │ ├── Tide-Team.png │ ├── api-php-auth.png │ ├── kinsta-logo.png │ ├── api-php-start.png │ ├── Tide-Contributor.png │ ├── api-php-payload.png │ ├── architecture-diagram.png │ ├── lighthouse-server-auth.png │ ├── lighthouse-server-poll.png │ ├── lighthouse-server-audit.png │ ├── lighthouse-server-header.png │ ├── lighthouse-server-queue.png │ ├── lighthouse-server-checksum.png │ ├── lighthouse-server-code-info.png │ ├── lighthouse-server-payload.png │ ├── lighthouse-server-raw-report.png │ ├── lighthouse-server-audit-complete.png │ └── lighthouse-server-summary-report.png └── 404.html ├── functions ├── enqueue-scripts.php ├── enqueue-styles.php ├── docpress-get-file-path.php ├── docpress-get-dirs.php ├── get-current-url.php └── docpress-make-absolute-urls.php ├── style.css ├── index.php ├── bin └── link ├── package.json ├── header.php ├── LICENSE ├── README.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md └── functions.php /docs/404.md: -------------------------------------------------------------------------------- 1 | # 404 -------------------------------------------------------------------------------- /src/css/base/ionicons.styl: -------------------------------------------------------------------------------- 1 | ion-font() 2 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/image.png: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docpress/docpress/fixture/basic/README.md: -------------------------------------------------------------------------------- 1 | # Oh hi 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/css-file/README.md: -------------------------------------------------------------------------------- 1 | # Hello 2 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/custom-docs/README.md: -------------------------------------------------------------------------------- 1 | # Hi 2 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/assets/style.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/root-config/README.md: -------------------------------------------------------------------------------- 1 | # Hi 2 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/external-css/README.md: -------------------------------------------------------------------------------- 1 | # Hello 2 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/google-analytics/README.md: -------------------------------------------------------------------------------- 1 | Hello. 2 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/stylus-imports/README.md: -------------------------------------------------------------------------------- 1 | # Hello 2 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config-2/README.md: -------------------------------------------------------------------------------- 1 | # Hi 2 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config-3/README.md: -------------------------------------------------------------------------------- 1 | # Hi 2 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config/README.md: -------------------------------------------------------------------------------- 1 | # Hi 2 | -------------------------------------------------------------------------------- /docpress/docpress-base/.npmignore: -------------------------------------------------------------------------------- 1 | example/ 2 | fixture/ 3 | test/ 4 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | } 3 | -------------------------------------------------------------------------------- /docpress/docpress-core/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib') 2 | -------------------------------------------------------------------------------- /docpress/docpress-core/ms.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/ms') 2 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/assets/script.js: -------------------------------------------------------------------------------- 1 | /* custom */ 2 | -------------------------------------------------------------------------------- /docpress/docpress/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | _docpress 3 | .nyc_output 4 | -------------------------------------------------------------------------------- /docpress/docpress/fixture/basic/docs/README.md: -------------------------------------------------------------------------------- 1 | * [Hello](../README.md) 2 | -------------------------------------------------------------------------------- /footer.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/screenshot.png -------------------------------------------------------------------------------- /src/css/base/0-normalize.styl: -------------------------------------------------------------------------------- 1 | @require './normalize.css/normalize.css' 2 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/tocless/README.md: -------------------------------------------------------------------------------- 1 | # My project 2 | 3 | Hello. 4 | -------------------------------------------------------------------------------- /docpress/docpress-base/example/docs/usage.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | Apply to forehead. 4 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/css-file/docs/extra.css: -------------------------------------------------------------------------------- 1 | #custom { font-family: fira } 2 | -------------------------------------------------------------------------------- /docpress/docpress-base/example/docs/install.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Use npm install. 4 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/custom-docs/documents/intro.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Hi. 4 | -------------------------------------------------------------------------------- /docs/images/tide-wp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/tide-wp.png -------------------------------------------------------------------------------- /docpress/docpress-core/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | _docpress 3 | /coverage 4 | .nyc_output 5 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/custom-docs/docpress.json: -------------------------------------------------------------------------------- 1 | { 2 | "docs": "documents" 3 | } 4 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/markdown-plugin-invalid/README.md: -------------------------------------------------------------------------------- 1 | # My project 2 | 3 | Hello. 4 | -------------------------------------------------------------------------------- /docs/images/Tide-Team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/Tide-Team.png -------------------------------------------------------------------------------- /_docpress/images/tide-wp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/tide-wp.png -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/css-file/docpress.json: -------------------------------------------------------------------------------- 1 | { 2 | "css": [ "docs/extra.css" ] 3 | } 4 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/with-anchors/README.md: -------------------------------------------------------------------------------- 1 | # Readme 2 | 3 | ## Two 4 | 5 | ## Three 6 | -------------------------------------------------------------------------------- /docpress/docpress-base/lib/helpers/noop.js: -------------------------------------------------------------------------------- 1 | function noop () { 2 | } 3 | 4 | module.exports = noop 5 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/with-anchors/README.md: -------------------------------------------------------------------------------- 1 | # Readme 2 | 3 | ## Two 4 | 5 | ## Three 6 | -------------------------------------------------------------------------------- /docs/images/api-php-auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/api-php-auth.png -------------------------------------------------------------------------------- /docs/images/kinsta-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/kinsta-logo.png -------------------------------------------------------------------------------- /src/css/docpress.styl: -------------------------------------------------------------------------------- 1 | @require './variables' 2 | @require './base/*' 3 | @require './components/*' 4 | -------------------------------------------------------------------------------- /_docpress/images/Tide-Team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/Tide-Team.png -------------------------------------------------------------------------------- /docpress/docpress-base/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | _docpress 3 | /cache 4 | /coverage 5 | .nyc_output 6 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/docpress.json: -------------------------------------------------------------------------------- 1 | { 2 | "github": "rstacruz/onmount" 3 | } 4 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/stylus-imports/docpress.json: -------------------------------------------------------------------------------- 1 | { 2 | "css": [ "stylus/extra.styl" ] 3 | } 4 | -------------------------------------------------------------------------------- /docs/images/api-php-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/api-php-start.png -------------------------------------------------------------------------------- /_docpress/images/api-php-auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/api-php-auth.png -------------------------------------------------------------------------------- /_docpress/images/kinsta-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/kinsta-logo.png -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/markdown-plugin/README.md: -------------------------------------------------------------------------------- 1 | # My project 2 | 3 | 4 | Hello. 5 | -------------------------------------------------------------------------------- /docs/images/Tide-Contributor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/Tide-Contributor.png -------------------------------------------------------------------------------- /docs/images/api-php-payload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/api-php-payload.png -------------------------------------------------------------------------------- /_docpress/images/api-php-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/api-php-start.png -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/external-css/docpress.json: -------------------------------------------------------------------------------- 1 | { 2 | "css": [ "http://site.com/external.css" ] 3 | } 4 | -------------------------------------------------------------------------------- /_docpress/images/Tide-Contributor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/Tide-Contributor.png -------------------------------------------------------------------------------- /_docpress/images/api-php-payload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/api-php-payload.png -------------------------------------------------------------------------------- /docs/images/architecture-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/architecture-diagram.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-auth.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-poll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-poll.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-audit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-audit.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-header.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-queue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-queue.png -------------------------------------------------------------------------------- /_docpress/images/architecture-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/architecture-diagram.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-auth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-auth.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-poll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-poll.png -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/stylus-imports/stylus/extra.styl: -------------------------------------------------------------------------------- 1 | $accent = #bada55 2 | 3 | #custom 4 | font-family: fira sans 5 | -------------------------------------------------------------------------------- /docs/images/lighthouse-server-checksum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-checksum.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-code-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-code-info.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-payload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-payload.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-audit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-audit.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-header.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-queue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-queue.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-raw-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-raw-report.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-checksum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-checksum.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-code-info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-code-info.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-payload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-payload.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-audit-complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-audit-complete.png -------------------------------------------------------------------------------- /docs/images/lighthouse-server-summary-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/docs/images/lighthouse-server-summary-report.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-raw-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-raw-report.png -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/custom-docs/documents/README.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Index](../README.md) 4 | * [Intro](intro.md) 5 | 6 | -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-audit-complete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-audit-complete.png -------------------------------------------------------------------------------- /_docpress/images/lighthouse-server-summary-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wptide/docs/HEAD/_docpress/images/lighthouse-server-summary-report.png -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/with-anchors/docs/README.md: -------------------------------------------------------------------------------- 1 | * [Intro 1](../README.md) 2 | * [Intro 2](../README.md#two) 3 | * [Intro 3](../README.md#three) 4 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/markdown-plugin/docpress.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdown": { 3 | "plugins": { 4 | "decorate": {} 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/with-anchors/docs/README.md: -------------------------------------------------------------------------------- 1 | * [Intro 1](../README.md) 2 | * [Intro 2](../README.md#two) 3 | * [Intro 3](../README.md#three) 4 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/markdown-plugin-invalid/docpress.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdown": { 3 | "plugins": { 4 | "lalalala": {} 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/google-analytics/docpress.json: -------------------------------------------------------------------------------- 1 | { 2 | "googleAnalytics": { 3 | "id": "UA-12345678-1", 4 | "domain": "docpress.github.io" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /functions/enqueue-scripts.php: -------------------------------------------------------------------------------- 1 | /^https?:\/\//.test(source) 9 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "docpress": { 3 | "custom": true, 4 | "plugins": { 5 | "docpress-core": {}, 6 | "docpress-search": {}, 7 | "docpress-base": {} 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-core/lib/log.js: -------------------------------------------------------------------------------- 1 | const debug = require('debug') 2 | module.exports = debug('docpress-core') 3 | module.exports.warn = debug('docpress-core') 4 | module.exports.error = debug('docpress-core') 5 | module.exports.info = debug('docpress-core') 6 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/with-anchors/metalsmith.js: -------------------------------------------------------------------------------- 1 | var app = require('../../ms')(__dirname) 2 | .use(require('../../')()) 3 | 4 | if (module.parent) { 5 | module.exports = app 6 | } else { 7 | app.build(function (err) { if (err) throw err }) 8 | } 9 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/custom-docs/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/root-config/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/tocless/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /src/css/components/404.styl: -------------------------------------------------------------------------------- 1 | .page-404 .markdown-body 2 | display: flex 3 | align-items: center 4 | justify-content: center 5 | font-weight: bold 6 | font-size: 100px 7 | padding-top: 200px !important 8 | 9 | .is-search .footer-nav .right 10 | .error404 .footer-nav 11 | display: none -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/markdown-plugin/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config-2/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config-3/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/package-config/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /src/css/base/base.styl: -------------------------------------------------------------------------------- 1 | * 2 | box-sizing: border-box 3 | 4 | html, body 5 | height: 100% 6 | 7 | html 8 | background: $bg 9 | 10 | body 11 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/css-file/metalsmith.js: -------------------------------------------------------------------------------- 1 | var app = require('docpress-core/ms')(__dirname) 2 | .use(require('docpress-core')()) 3 | .use(require('../../')()) 4 | 5 | if (module.parent) { 6 | module.exports = app 7 | } else { 8 | app.build(function (err) { if (err) throw err }) 9 | } 10 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/metalsmith.js: -------------------------------------------------------------------------------- 1 | var app = require('docpress-core/ms')(__dirname) 2 | .use(require('docpress-core')()) 3 | .use(require('../../')()) 4 | 5 | if (module.parent) { 6 | module.exports = app 7 | } else { 8 | app.build(function (err) { if (err) throw err }) 9 | } 10 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/external-css/metalsmith.js: -------------------------------------------------------------------------------- 1 | var app = require('docpress-core/ms')(__dirname) 2 | .use(require('docpress-core')()) 3 | .use(require('../../')()) 4 | 5 | if (module.parent) { 6 | module.exports = app 7 | } else { 8 | app.build(function (err) { if (err) throw err }) 9 | } 10 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/with-anchors/metalsmith.js: -------------------------------------------------------------------------------- 1 | var app = require('docpress-core/ms')(__dirname) 2 | .use(require('docpress-core')()) 3 | .use(require('../../')()) 4 | 5 | if (module.parent) { 6 | module.exports = app 7 | } else { 8 | app.build(function (err) { if (err) throw err }) 9 | } 10 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/markdown-plugin-invalid/metalsmith.js: -------------------------------------------------------------------------------- 1 | var docpress = require('../../ms') 2 | 3 | var app = docpress(__dirname) 4 | .use(require('../../')()) 5 | 6 | if (module.parent) { 7 | module.exports = app 8 | } else { 9 | app.build(function (err) { if (err) throw err }) 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/google-analytics/metalsmith.js: -------------------------------------------------------------------------------- 1 | var app = require('docpress-core/ms')(__dirname) 2 | .use(require('docpress-core')()) 3 | .use(require('../../')()) 4 | 5 | if (module.parent) { 6 | module.exports = app 7 | } else { 8 | app.build(function (err) { if (err) throw err }) 9 | } 10 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/stylus-imports/metalsmith.js: -------------------------------------------------------------------------------- 1 | var app = require('docpress-core/ms')(__dirname) 2 | .use(require('docpress-core')()) 3 | .use(require('../../')()) 4 | 5 | if (module.parent) { 6 | module.exports = app 7 | } else { 8 | app.build(function (err) { if (err) throw err }) 9 | } 10 | -------------------------------------------------------------------------------- /docpress/docpress-base/example/metalsmith.js: -------------------------------------------------------------------------------- 1 | var app = require('docpress-core/ms')(__dirname) 2 | .use(require('docpress-core')()) 3 | .use(require('../index')()) 4 | 5 | module.exports = app 6 | 7 | if (!module.parent) { 8 | app.build(function (err) { 9 | if (err) throw err 10 | process.exit(0) 11 | }) 12 | } 13 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /* 2 | Theme Name: Tide Documentation Theme 3 | Author: XWP 4 | Author URI: https://xwp.co/ 5 | Description: This is a custom DocPress-based theme that serves locally-built `*.md` files as a WordPress theme. We chose to store the content inside a repo so it could be more easily tracked over time within the commit history. 6 | Version: 0.1 7 | */ -------------------------------------------------------------------------------- /docpress/docpress-base/lib/helpers/use_cache.js: -------------------------------------------------------------------------------- 1 | const readFileSync = require('fs').readFileSync 2 | const join = require('path').join 3 | 4 | module.exports = function useCache (fname, callback) { 5 | try { 6 | callback(null, 7 | readFileSync(join(__dirname, '..', '..', fname), 'utf-8')) 8 | return true 9 | } catch (e) {} 10 | } 11 | -------------------------------------------------------------------------------- /docpress/docpress-base/example/README.md: -------------------------------------------------------------------------------- 1 | # Example site 2 | 3 | Use this site to test the Docpress theme as you make changes. It's a simple metalsmith site; you can use `node metalsmith.js` or [metalsmith-start](https://www.npmjs.com/package/metalsmith-start). 4 | 5 | Make sure to `rm -rf cache/` first, and restart metalsmith every time you change Stylus files. 6 | -------------------------------------------------------------------------------- /src/css/components/nprogress.styl: -------------------------------------------------------------------------------- 1 | @require './nprogress/nprogress.css' 2 | 3 | // 4 | // Nprogress 5 | // 6 | 7 | #nprogress 8 | .bar 9 | background: $accent 10 | 11 | .peg 12 | box-shadow: 0 0 10px $accent, 0 0 5px $accent 13 | display: block 14 | 15 | .spinner-icon 16 | border-top-color: $accent 17 | border-left-color: $accent 18 | -------------------------------------------------------------------------------- /src/css/variables.styl: -------------------------------------------------------------------------------- 1 | @require './iconfonts/stylesheets/ionicons' 2 | 3 | $bg ?= white 4 | $black ?= #111 5 | $slate ?= #505d6b 6 | $accent ?= #4078C0 7 | $nav-width ?= 250px 8 | $collapsed-nav-width ?= 64px 9 | $xpad ?= 24px 10 | $line ?= rgba($black, 0.1) 11 | 12 | clearfix() 13 | &:after 14 | content: '' 15 | display: table 16 | clear: both 17 | zoom: 1 18 | -------------------------------------------------------------------------------- /docpress/docpress-base/example/docs/README.md: -------------------------------------------------------------------------------- 1 | # TOC 2 | 3 | * [Hello](hello.md) 4 | * [Installation](install.md) 5 | * [Usage](usage.md) 6 | 7 | * Examples 8 | * [Simple](install.md#0) 9 | * [Basic](usage.md#4) 10 | * [Advanced](usage.md#5) 11 | 12 | * API reference 13 | * [Node.js API](install.md#1) 14 | * [Browser API](usage.md#2) 15 | * [HTTP API](usage.md#3) 16 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/cancelling.md: -------------------------------------------------------------------------------- 1 | # Cancelling 2 | 3 | You can cancel an initialization by returning `false`. This makes it so that the initialization will run again when `init` is triggered again. 4 | 5 | This is also available for exit callbacks. 6 | 7 | ```js 8 | $.onmount('.expandable-nav', function () { 9 | if ($(this).is(':hidden')) return false 10 | 11 | /* ... */ 12 | }) 13 | ``` 14 | 15 |
16 | -------------------------------------------------------------------------------- /docpress/docpress-base/lib/build_js.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const join = require('path').join 4 | 5 | module.exports = function buildJs (options, done) { 6 | const fname = join(__dirname, '../../../src/js/script.js') 7 | const browserify = require('browserify') 8 | const b = browserify() 9 | b.add(fname) 10 | if (options && options.compress) { 11 | b.transform(require('uglifyify'), { global: true, sourcemap: false }) 12 | } 13 | b.bundle(done) 14 | } 15 | -------------------------------------------------------------------------------- /bin/link: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Link docpress ..." 4 | cd docpress/docpress && npm link 5 | 6 | echo "Link docpress-base ..." 7 | cd ../docpress-base && npm link 8 | 9 | echo "Link docpress-core ..." 10 | cd ../docpress-core && npm link 11 | 12 | echo "Install docpress ..." 13 | cd ../docpress && npm install && npm link docpress-base && npm link docpress-core 14 | 15 | echo "Install docpress-base ..." 16 | cd ../docpress-base && npm install && npm link npm link docpress-core 17 | -------------------------------------------------------------------------------- /docpress/docpress-base/lib/helpers/each_cons.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Iterates through an array/object `list`, but tells you the previous/next 3 | * items as well. 4 | */ 5 | 6 | module.exports = function eachCons (list, fn) { 7 | var keys = Object.keys(list) 8 | keys.forEach((key, idx) => { 9 | const prevKey = keys[idx - 1] 10 | const nextKey = keys[idx + 1] 11 | fn(list[key], key, 12 | prevKey && list[prevKey], prevKey, 13 | nextKey && list[nextKey], nextKey) 14 | }) 15 | } 16 | -------------------------------------------------------------------------------- /docs/installation/index.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Setting up Tide locally is fairly straight forward and consists of the following steps: 4 | 5 | 1. Installing all the [prerequisite](prerequisites.md) software. 6 | 1. [Cloning](cloning.md) the Tide repository into your `$GOPATH`. 7 | 1. Finally. completing a handful of [setup](setup.md) steps in the form of `make` commands. 8 | 9 | _If you run into issues while getting Tide installed, please contact us so we can address it and update the documentation for others._ -------------------------------------------------------------------------------- /src/css/components/sponsors.styl: -------------------------------------------------------------------------------- 1 | .logo-grid 2 | display: grid 3 | grid-template-columns: 25% 25% 25% 25% 4 | grid-gap: 15px 5 | justify-content: center 6 | align-items: center 7 | margin: 50px 0 8 | position: relative 9 | left: -10px 10 | 11 | @media (max-width: 768px) 12 | grid-template-columns: 50% 50% 13 | grid-gap: 10px 14 | left: 0px 15 | 16 | .logo 17 | padding: 20px 18 | 19 | .logo.xwp 20 | padding: 40px 21 | 22 | .logo.wp-engine 23 | padding: 10px 24 | 25 | .logo.kinsta 26 | padding: 30px -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/role.md: -------------------------------------------------------------------------------- 1 | # Role attributes 2 | 3 | Some recommend [using the role attribute][rsjs] to bind your behaviors. To aid this, you can define behaviors as `@xxxx`, which is shorthand of `[role~="xxxx"]`. (This convention is taken from [jquery-role].) 4 | 5 | ```js 6 | $.onmount('@hiding-menu', function () { 7 | /* ... */ 8 | }) 9 | 10 | /* same as $.onmount('[role~="hiding-menu"]', ...) */ 11 | ``` 12 | 13 | [rsjs]: https://github.com/rstacruz/rsjs 14 | [jquery-role]: https://github.com/kossnocorp/role 15 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/role.md: -------------------------------------------------------------------------------- 1 | # Role attributes 2 | 3 | Some recommend [using the role attribute][rsjs] to bind your behaviors. To aid this, you can define behaviors as `@xxxx`, which is shorthand of `[role~="xxxx"]`. (This convention is taken from [jquery-role].) 4 | 5 | ```js 6 | $.onmount('@hiding-menu', function () { 7 | /* ... */ 8 | }) 9 | 10 | /* same as $.onmount('[role~="hiding-menu"]', ...) */ 11 | ``` 12 | 13 | [rsjs]: https://github.com/rstacruz/rsjs 14 | [jquery-role]: https://github.com/kossnocorp/role 15 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | To turn debug logging on, set `onmount.debug` to `true`. 4 | 5 | ```js 6 | onmount.debug = true 7 | ``` 8 | 9 | If you'd like to do this automatically, you can turn it on by a secret flag: 10 | 11 | ```js 12 | onmount.debug = (window.localStorage && 13 | window.localStorage['onmount_debug'] && 14 | true) 15 | ``` 16 | 17 | You can turn it on in your JavaScript console by typing `localStorage.onmount_debug = true`, and turn it off with `delete localStorage.onmount_debug`. 18 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | To turn debug logging on, set `onmount.debug` to `true`. 4 | 5 | ```js 6 | onmount.debug = true 7 | ``` 8 | 9 | If you'd like to do this automatically, you can turn it on by a secret flag: 10 | 11 | ```js 12 | onmount.debug = (window.localStorage && 13 | window.localStorage['onmount_debug'] && 14 | true) 15 | ``` 16 | 17 | You can turn it on in your JavaScript console by typing `localStorage.onmount_debug = true`, and turn it off with `delete localStorage.onmount_debug`. 18 | -------------------------------------------------------------------------------- /functions/docpress-get-dirs.php: -------------------------------------------------------------------------------- 1 | isDir(); 9 | } ); 10 | 11 | $relative_dirs = array_map( function ($file) { 12 | return str_replace( DOCS_PATH . '/', '', $file ); 13 | }, array_keys( $all_dirs ) ); 14 | 15 | return str_replace( '//', '/', $relative_dirs ); 16 | } -------------------------------------------------------------------------------- /docpress/docpress-core/lib/slugify.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const parameterize = require('slugify') 4 | 5 | /** 6 | * Turns a string into a normalized string that can be used for a CSS 7 | * id/classname. 8 | * 9 | * slugify('/foo/bar.html') 10 | * //=> 'foo-bar' 11 | */ 12 | 13 | module.exports = function slugify (str) { 14 | str = str.toLowerCase() 15 | str = str.replace(/\/index.html$/, '') 16 | str = str.replace(/.html$/, '') 17 | str = parameterize(str) 18 | str = str.replace(/[^a-zA-Z0-9\-_]/g, '') 19 | if (str.length) return str 20 | } 21 | -------------------------------------------------------------------------------- /docpress/docpress-base/bin/build: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // Builds the assets for caching in the published version. 3 | 4 | var argv = process.argv.slice(2) 5 | 6 | if (argv[0] === '--css') { 7 | buildWith(require('../lib/build_css')) 8 | } else if (argv[0] === '--js') { 9 | buildWith(require('../lib/build_js')) 10 | } else { 11 | console.log('usage: build --css|--js') 12 | process.exit(1) 13 | } 14 | 15 | function buildWith (render) { 16 | render({ compress: true }, (err, res) => { 17 | if (err) throw err 18 | process.stdout.write(res) 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/testing.md: -------------------------------------------------------------------------------- 1 | # Testing behaviors 2 | 3 | You can trigger just one onmount via `$.onmount(SELECTOR)`. This is useful for tests. 4 | 5 | ```js 6 | var $div 7 | 8 | beforeEach(function () { 9 | $div = $("
") 10 | .appendTo('body') 11 | 12 | $.onmount('.js-user-profile') 13 | }) 14 | 15 | afterEach(function () { 16 | $div.remove() 17 | }) 18 | 19 | it('renders an avatar', function () { 20 | expect($div.html()).to.include("") 21 | }) 22 | ``` 23 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/testing.md: -------------------------------------------------------------------------------- 1 | # Testing behaviors 2 | 3 | You can trigger just one onmount via `$.onmount(SELECTOR)`. This is useful for tests. 4 | 5 | ```js 6 | var $div 7 | 8 | beforeEach(function () { 9 | $div = $("
") 10 | .appendTo('body') 11 | 12 | $.onmount('.js-user-profile') 13 | }) 14 | 15 | afterEach(function () { 16 | $div.remove() 17 | }) 18 | 19 | it('renders an avatar', function () { 20 | expect($div.html()).to.include("") 21 | }) 22 | ``` 23 | -------------------------------------------------------------------------------- /src/js/polyfills/index.js: -------------------------------------------------------------------------------- 1 | // from:https://github.com/jserz/js_piece/blob/master/DOM/ChildNode/remove()/remove().md 2 | 3 | void (function (arr) { 4 | arr.forEach(function (item) { 5 | if (item.hasOwnProperty('remove')) { 6 | return; 7 | } 8 | Object.defineProperty(item, 'remove', { 9 | configurable: true, 10 | enumerable: true, 11 | writable: true, 12 | value: function remove() { 13 | this.parentNode.removeChild(this); 14 | } 15 | }); 16 | }); 17 | })([Element.prototype, CharacterData.prototype, DocumentType.prototype]); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wptide-docs", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "dev": "node docpress/docpress/bin/docpress", 8 | "build": "node docpress/docpress/bin/docpress b", 9 | "link": "bin/link" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/wptide/docs.git" 14 | }, 15 | "dependencies": { 16 | "debounce": "^1.1.0", 17 | "dom101": "^2.2.1", 18 | "nprogress": "^0.2.0", 19 | "onmount": "^1.3.0", 20 | "pjax": "^0.2.6" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/css/components/heading-list.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Headings menu 3 | // 4 | 5 | ul.heading-list 6 | $pad = 24px 7 | 8 | .hlink 9 | text-decoration: none 10 | padding: 6px $pad 11 | display: block 12 | height: 1em 13 | text-overflow: ellipsis 14 | overflow: hidden 15 | white-space: nowrap 16 | 17 | &, &:visited 18 | color: $slate 19 | 20 | .hlink:before 21 | content: '' 22 | display: inline-block 23 | vertical-align: middle 24 | margin-right: 8px 25 | height: 2px 26 | width: 12px 27 | background: $slate 28 | opacity: 0.3 29 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/unique-ids.md: -------------------------------------------------------------------------------- 1 | # Unique IDs 2 | 3 | The `init()` and `exit()` callbacks get passed an object with a unique ID. This ID is guaranteed to be unique for every behavior-element pair. It looks like this: 4 | 5 | > `{ id: 'c12' }` 6 | 7 | This makes it possible to assign event handlers with tags that are unique to that behavior-and-element so that it may be unbound later. 8 | 9 | ```js 10 | $.onmount('@hiding-menu', function (b) { 11 | $('html, body').on('scroll.' + b.id, function () { 12 | }) 13 | }, function (b) { 14 | $('html, body').off('scroll.' + b.id) 15 | }) 16 | ``` 17 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/unique-ids.md: -------------------------------------------------------------------------------- 1 | # Unique IDs 2 | 3 | The `init()` and `exit()` callbacks get passed an object with a unique ID. This ID is guaranteed to be unique for every behavior-element pair. It looks like this: 4 | 5 | > `{ id: 'c12' }` 6 | 7 | This makes it possible to assign event handlers with tags that are unique to that behavior-and-element so that it may be unbound later. 8 | 9 | ```js 10 | $.onmount('@hiding-menu', function (b) { 11 | $('html, body').on('scroll.' + b.id, function () { 12 | }) 13 | }, function (b) { 14 | $('html, body').off('scroll.' + b.id) 15 | }) 16 | ``` 17 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/README.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [onmount](/README.md) 4 | * [Premise](/docs/premise.md) 5 | * Features 6 | * [Role attributes](/docs/role.md) 7 | * [Cancelling](/docs/cancelling.md) 8 | * [Preforming cleanups](/docs/cleanup.md) 9 | * [Unique IDs](/docs/unique-ids.md) 10 | * [Idempotency](/docs/idempotency.md) 11 | * [Automatic observation](/docs/automatic-observation.md) 12 | * Testing 13 | * [Testing](/docs/testing.md) 14 | * [Debugging](/docs/debugging.md) 15 | * Integrations 16 | * [With Turbolinks](/docs/turbolinks.md) 17 | * [With Rails](/docs/rails.md) 18 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/README.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [onmount](/README.md) 4 | * [Premise](/docs/premise.md) 5 | * Features 6 | * [Role attributes](/docs/role.md) 7 | * [Cancelling](/docs/cancelling.md) 8 | * [Preforming cleanups](/docs/cleanup.md) 9 | * [Unique IDs](/docs/unique-ids.md) 10 | * [Idempotency](/docs/idempotency.md) 11 | * [Automatic observation](/docs/automatic-observation.md) 12 | * Testing 13 | * [Testing](/docs/testing.md) 14 | * [Debugging](/docs/debugging.md) 15 | * Integrations 16 | * [With Turbolinks](/docs/turbolinks.md) 17 | * [With Rails](/docs/rails.md) 18 | -------------------------------------------------------------------------------- /src/css/components/hero.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Homepage Hero section 3 | // 4 | 5 | .hero 6 | position: relative 7 | display: none 8 | flex-direction: column 9 | align-items: flex-start 10 | height: calc(100vh - 64px) 11 | padding-top: 15vh 12 | 13 | .hero__logo 14 | width: 500px 15 | max-width: 50% 16 | 17 | .hero__title 18 | font-size: 40px 19 | font-weight: 200 20 | margin-bottom: 20px 21 | 22 | .hero__canvas 23 | position: absolute 24 | bottom: 0 25 | left: 50% 26 | z-index: -1 27 | transform: translateX(-50%) 28 | display: block 29 | 30 | 31 | @media (min-width: 960px) 32 | .hero 33 | display: flex 34 | 35 | -------------------------------------------------------------------------------- /docpress/docpress-core/lib/memoize.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const LRU = require('lru-cache') 4 | let cache = LRU(500) 5 | 6 | /** 7 | * Memoizes the result of `fn()`. 8 | * 9 | * If it's been invoked recently, the last known result will be returned. This 10 | * is used to cache expensive calls such as Markdown parsing. 11 | * 12 | * html = memoize('hello', () => markdown('a long string goes here')) 13 | */ 14 | 15 | module.exports = function memoize (keyObject, fn) { 16 | const key = JSON.stringify(keyObject) 17 | if (cache.has(key)) return cache.get(key) 18 | 19 | const val = fn() 20 | cache.set(key, val) 21 | return val 22 | } 23 | -------------------------------------------------------------------------------- /functions/get-current-url.php: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | class="no-js"> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | > 21 | 22 |
23 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/rails.md: -------------------------------------------------------------------------------- 1 | # Using with Rails 2 | 3 | Use [rails-assets.org](https://rails-assets.org/) to bring `onmount` on your app. 4 | 5 | ```rb 6 | source 'https://rails-assets.org' do 7 | gem 'rails-assets-onmount' 8 | end 9 | ``` 10 | 11 | In your `application.js`, load it using `//= require`. If you're using jQuery, load it before onmount. 12 | 13 | ```js 14 | //= require jquery 15 | //= require onmount 16 | ``` 17 | 18 | You can then use onmount. 19 | 20 | ```js 21 | $(document).on('ready show.bs closed.bs load page:change', function () { 22 | $.onmount() 23 | }) 24 | 25 | $.onmount('.js-tooltip', function () { 26 | $(this).tooltip() 27 | }) 28 | ``` 29 | 30 | If you don't use jQuery, you can use `window.onmount` instead. 31 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/rails.md: -------------------------------------------------------------------------------- 1 | # Using with Rails 2 | 3 | Use [rails-assets.org](https://rails-assets.org/) to bring `onmount` on your app. 4 | 5 | ```rb 6 | source 'https://rails-assets.org' do 7 | gem 'rails-assets-onmount' 8 | end 9 | ``` 10 | 11 | In your `application.js`, load it using `//= require`. If you're using jQuery, load it before onmount. 12 | 13 | ```js 14 | //= require jquery 15 | //= require onmount 16 | ``` 17 | 18 | You can then use onmount. 19 | 20 | ```js 21 | $(document).on('ready show.bs closed.bs load page:change', function () { 22 | $.onmount() 23 | }) 24 | 25 | $.onmount('.js-tooltip', function () { 26 | $(this).tooltip() 27 | }) 28 | ``` 29 | 30 | If you don't use jQuery, you can use `window.onmount` instead. 31 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/automatic-observation.md: -------------------------------------------------------------------------------- 1 | # Automatic observation 2 | 3 | You can turn on automatic observation via the [MutationObserver] API. Not supported in Opera and IE10 and below. (*experimental*) 4 | 5 | ```js 6 | onmount.observe() 7 | ``` 8 | 9 | Considering not all browsers support this, you can set up fallbacks via: 10 | 11 | ```js 12 | if (!$.onmount.observe()) { 13 | $(document) 14 | .ready($.onmount) 15 | .on('show.bs hide.bs load', $.onmount) 16 | } 17 | ``` 18 | 19 | While this is convenient, it is not recommended as it can accrue some performance penalty by checking every DOM insertion that happens in realtime. Consider this an experimental feature and subject to future optimizations. 20 | 21 | [MutationObserver]: https://developer.mozilla.org/en/docs/Web/API/MutationObserver 22 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/automatic-observation.md: -------------------------------------------------------------------------------- 1 | # Automatic observation 2 | 3 | You can turn on automatic observation via the [MutationObserver] API. Not supported in Opera and IE10 and below. (*experimental*) 4 | 5 | ```js 6 | onmount.observe() 7 | ``` 8 | 9 | Considering not all browsers support this, you can set up fallbacks via: 10 | 11 | ```js 12 | if (!$.onmount.observe()) { 13 | $(document) 14 | .ready($.onmount) 15 | .on('show.bs hide.bs load', $.onmount) 16 | } 17 | ``` 18 | 19 | While this is convenient, it is not recommended as it can accrue some performance penalty by checking every DOM insertion that happens in realtime. Consider this an experimental feature and subject to future optimizations. 20 | 21 | [MutationObserver]: https://developer.mozilla.org/en/docs/Web/API/MutationObserver 22 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/cleanup.md: -------------------------------------------------------------------------------- 1 | # Performing cleanups 2 | 3 | When your behavior modifies things outside itself (eg, binds events to the `document` element), you might want to clean up when the behavior is removed. Just pass a 2nd function to `onmount()`. 4 | 5 | In this example below, behaviors are checked once dialog boxes are opened and closed (`$.onmount()`). When it's called after closing, it will see that the old `.js-sticky` element is not part of the document anymore, and its exit callback will be called. 6 | 7 | ```js 8 | $.onmount('.js-sticky', function () { 9 | $(document).on('scroll.sticky', function () { 10 | // do stuff 11 | }) 12 | }, function () { 13 | $(document).off('scroll.sticky') 14 | }) 15 | 16 | $(function () { $.onmount() }) 17 | $(document).on('show.bs.modal close.bs.modal', function () { $.onmount() }) 18 | ``` 19 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/cleanup.md: -------------------------------------------------------------------------------- 1 | # Performing cleanups 2 | 3 | When your behavior modifies things outside itself (eg, binds events to the `document` element), you might want to clean up when the behavior is removed. Just pass a 2nd function to `onmount()`. 4 | 5 | In this example below, behaviors are checked once dialog boxes are opened and closed (`$.onmount()`). When it's called after closing, it will see that the old `.js-sticky` element is not part of the document anymore, and its exit callback will be called. 6 | 7 | ```js 8 | $.onmount('.js-sticky', function () { 9 | $(document).on('scroll.sticky', function () { 10 | // do stuff 11 | }) 12 | }, function () { 13 | $(document).off('scroll.sticky') 14 | }) 15 | 16 | $(function () { $.onmount() }) 17 | $(document).on('show.bs.modal close.bs.modal', function () { $.onmount() }) 18 | ``` 19 | -------------------------------------------------------------------------------- /docpress/docpress-core/lib/syntax_highlight.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const hljs = require('highlight.js') 4 | 5 | // Mappings of highlight.js-to-github classes. 6 | const dict = { 7 | 'hljs-string': 'pl-s', 8 | 'hljs-comment': 'pl-c', 9 | 'hljs-keyword': 'pl-k', 10 | 'hljs-attribute': 'pl-e', 11 | 'hljs-built_in': 'pl-c1', 12 | 'hljs-title': 'pl-ent', 13 | 'hljs-value': 'pl-s', 14 | 'hljs-literal': 'pl-c1', 15 | 'hljs-code': 'pl-c1' // markdown code 16 | } 17 | 18 | /** 19 | * Internal: highlights HTML 20 | */ 21 | module.exports = function syntaxHighlight (code, lang) { 22 | try { 23 | return hljs.highlight(lang, code).value 24 | .replace(//g, (_, klass) => { 25 | return `` 26 | }) 27 | } catch (_) { 28 | return '' // use external default escaping 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /docs/installation/cloning.md: -------------------------------------------------------------------------------- 1 | # Cloning 2 | 3 | Tide needs to be cloned to a directory inside your Go workspace specified by the [`$GOPATH`](https://golang.org/doc/code#GOPATH) environment variable. Your `$GOPATH` defaults to a directory named `go` inside your home directory, so `$HOME/go` on Mac/Unix and `%USERPROFILE%\go` (usually `C:\Users\YourName\go`) on Windows. 4 | 5 | Create the following directory inside your Go workspace: 6 | 7 | ``` 8 | src/github.com/wptide 9 | ``` 10 | 11 | Open a shell and change into the directory: 12 | 13 | ``` 14 | cd $GOPATH/src/github.com/wptide 15 | ``` 16 | 17 | Clone Tide: 18 | 19 | ``` 20 | git clone -b develop --recursive https://github.com/wptide/wptide.git 21 | ``` 22 | 23 | Change to Tide working directory: 24 | 25 | ``` 26 | cd wptide 27 | ``` 28 | 29 | Update submodules: 30 | 31 | ``` 32 | git submodule update --init --recursive 33 | ``` -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/idempotency.md: -------------------------------------------------------------------------------- 1 | # Idempotency 2 | 3 | You can call `$.onmount()` as much as you like. This will skip any behavior initialization for DOM nodes that have already been initialized. This is done to account for any new elements that may appear in your DOM. 4 | 5 | ```js 6 | // add more content 7 | $('#content').append(...) 8 | 9 | $.onmount() 10 | ``` 11 | 12 | This allows you to set up polling checkpoints to trigger new behaviors on certain events. 13 | Great for events such as [Bootstrap events] or [Turbolinks load]. 14 | 15 | Also, when used with jQuery, `onmount` can be passed as an event handler, eg, 16 | `$(onmount)`. 17 | 18 | ```js 19 | $(document) 20 | .on('ready show.bs closed.bs load page:change', $.onmount) 21 | ``` 22 | 23 | [Bootstrap events]: http://getbootstrap.com/javascript/ 24 | [Turbolinks load]: https://github.com/rails/turbolinks#events 25 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/idempotency.md: -------------------------------------------------------------------------------- 1 | # Idempotency 2 | 3 | You can call `$.onmount()` as much as you like. This will skip any behavior initialization for DOM nodes that have already been initialized. This is done to account for any new elements that may appear in your DOM. 4 | 5 | ```js 6 | // add more content 7 | $('#content').append(...) 8 | 9 | $.onmount() 10 | ``` 11 | 12 | This allows you to set up polling checkpoints to trigger new behaviors on certain events. 13 | Great for events such as [Bootstrap events] or [Turbolinks load]. 14 | 15 | Also, when used with jQuery, `onmount` can be passed as an event handler, eg, 16 | `$(onmount)`. 17 | 18 | ```js 19 | $(document) 20 | .on('ready show.bs closed.bs load page:change', $.onmount) 21 | ``` 22 | 23 | [Bootstrap events]: http://getbootstrap.com/javascript/ 24 | [Turbolinks load]: https://github.com/rails/turbolinks#events 25 | -------------------------------------------------------------------------------- /docpress/docpress-core/lib/indexify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Turns a TOC into an index. 3 | * 4 | * { 5 | * 'docs/index.html': { source: 'docs/README.md' } 6 | * } 7 | */ 8 | 9 | module.exports = function indexify (toc) { 10 | const index = {} 11 | const sources = {} 12 | const title = toc.sections[0].title 13 | walk(toc, title) 14 | return { index, sources } 15 | 16 | function walk (item, rootTitle) { 17 | if (item.url) { 18 | sources[item.source] = item.url 19 | index[item.url] = { 20 | source: item.source, 21 | title: rootTitle !== item.title ? `${item.title} - ${rootTitle}` : item.title, 22 | pageTitle: item.title, 23 | slug: item.slug 24 | } 25 | 26 | if (item.headings) index[item.url].headings = item.headings 27 | } 28 | 29 | if (item.sections) { 30 | item.sections.forEach((s) => walk(s, rootTitle)) 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docpress/docpress-core/lib/helpers/strip_markdown.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | /** 4 | * Private: lol, not implemneted yet 5 | */ 6 | 7 | module.exports = function stripMarkdown (original) { 8 | let text = original 9 | 10 | do { 11 | text = text 12 | // code 13 | .replace(/`([^`]+)`/g, '$1') 14 | // bold/italic 15 | .replace(/\*\*([^\*]+)\*\*/g, '$1') 16 | .replace(/\*([^\*]+)\*/g, '$1') 17 | .replace(/\*([^\*]+)\*/g, '$1') 18 | .replace(/(?:^|\s)([\(\[]?)_([^`]*)_([\)\]]?[\.\!\?]?)(?:$|\s)/g, '$1$2$3') // eslint-disable-line 19 | // links and images 20 | .replace(/!?\[([^\]]*)\]\([^\)]*\)/g, '$1') 21 | .replace(/!?\[([^\]]*)\]\[[^\)]*\]/g, '$1') 22 | // html 23 | .replace(/<[^>]*>/g, '') 24 | if (text === original) break 25 | original = text 26 | } while (true) 27 | 28 | text = text 29 | .replace(/!?\[([^\]]*)\]/g, '$1') 30 | 31 | return text 32 | } 33 | -------------------------------------------------------------------------------- /docpress/docpress-core/lib/tocify_page.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const marked = require('marked') 4 | 5 | const slugify = require('slugify') 6 | 7 | module.exports = function tocifyPage (md) { 8 | const tokens = marked.lexer(md.toString()) 9 | const levels = { 1: { headings: [] } } 10 | let ctx = levels[1].headings 11 | let lastDepth 12 | 13 | tokens.forEach((token) => { 14 | if (token.type === 'heading' && [2, 3].indexOf(token.depth) > -1) { 15 | const item = { 16 | title: token.text, 17 | depth: token.depth, 18 | id: slugify(token.text).toLowerCase() 19 | } 20 | 21 | if (lastDepth && token.depth !== lastDepth) { 22 | const parent = levels[token.depth - 1] 23 | if (!parent.headings) parent.headings = [] 24 | ctx = parent.headings 25 | } 26 | 27 | ctx.push(item) 28 | lastDepth = token.depth 29 | levels[item.depth] = item 30 | } 31 | }) 32 | 33 | if (levels[1].headings.length) { 34 | return levels[1].headings 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /docpress/docpress/lib/delegate_bin.js: -------------------------------------------------------------------------------- 1 | const join = require('path').join 2 | const resolve = require('path').resolve 3 | const spawnSync = require('child_process').spawnSync 4 | 5 | /** 6 | * Delegates to a the local version of an executable if available. 7 | */ 8 | 9 | module.exports = function delegateBin (mod, bin) { 10 | var binPath = join(process.cwd(), 'node_modules', mod, bin) 11 | 12 | if (exists(binPath) && resolve(process.argv[1]) !== resolve(binPath)) { 13 | var node = process.argv[0] // /usr/bin/node 14 | var args = [binPath].concat(process.argv.slice(2)) 15 | var result = spawnSync(node, args, { stdio: 'inherit' }) 16 | if (result.error) { 17 | console.error('! Error: failed to invoke ' + bin + ' from node_modules.') 18 | console.error(' ' + result.error.message) 19 | process.exit(result.status || 1) 20 | } 21 | process.exit(result.status) 22 | } 23 | } 24 | 25 | function exists (filename) { 26 | try { 27 | return require('fs').statSync(filename) 28 | } catch (e) {} 29 | } 30 | -------------------------------------------------------------------------------- /docpress/docpress-base/lib/memoize.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | let cache = {} 4 | let hits = [] 5 | 6 | function memoize (keyObject, fn) { 7 | const key = JSON.stringify(keyObject) 8 | if (cache[key]) return cache[key] 9 | cache[key] = fn() 10 | hits.push(key) 11 | return cache[key] 12 | } 13 | 14 | // Ensure that the last X keys are always available 15 | memoize.keepKeys = 20 16 | 17 | // Truncate every now and then 18 | memoize.truncateInterval = 3 * 60 * 1000 19 | 20 | // truncate the cache to the last N keys used 21 | memoize.prune = function prune () { 22 | const preserved = hits.slice(hits.length - memoize.keepKeys) 23 | const newCache = {} 24 | 25 | preserved.forEach((key) => { 26 | newCache[key] = cache[key] 27 | }) 28 | 29 | hits = preserved 30 | cache = newCache 31 | } 32 | 33 | // Truncate every few minutes. 34 | // More hassle than its worth, really, since it prevents the Node 35 | // process from terminating. 36 | // memoize.timer = setInterval(memoize.prune, memoize.truncateInterval) 37 | 38 | module.exports = memoize 39 | -------------------------------------------------------------------------------- /docs/gcp/google-cloud-storage.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Storage 2 | 3 | If you want to upload Tide audit reports to GCS then you'll need to create a bucket for those reports. Open the [Cloud Storage Browser](https://console.cloud.google.com/storage/browser) and click **Create Bucket**. 4 | 5 | ## Environment Variables 6 | 7 | | Variable | Description | 8 | | :--- | :--- | 9 | | `GCS_BUCKET_NAME` | The name of the GCS bucket. | 10 | 11 | ## Media Uploads 12 | 13 | If you want to upload images to WordPress, then you'll need to create a bucket for those images to live (unless you opt to use the local file system). Open the [Cloud Storage Browser](https://console.cloud.google.com/storage/browser) and click **Create Bucket**. 14 | 15 | Run the following command to change the ACL's of your new bucket: 16 | 17 | ``` 18 | $ gsutil defacl ch -u AllUsers:R gs://YOUR_BUCKET_NAME 19 | ``` 20 | 21 | When the API is up and running, log into the WordPress admin and go to the plugin settings page for `GCS Upload` then add your bucket name to the form field and click **Save Settings**. -------------------------------------------------------------------------------- /src/css/components/menu-toggle.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Menu toggle 3 | // 4 | 5 | .menu-toggle 6 | $size = 40px 7 | 8 | & 9 | display: none 10 | box-sizing: content-box 11 | 12 | @media (min-width: 959px) 13 | display: block 14 | width: $size + 12px 15 | height: $size + 12px 16 | line-height: $size 17 | 18 | position: fixed 19 | padding-left: 12px 20 | left: 0 21 | bottom: 0 22 | color: $black 23 | z-index: 10 24 | cursor: pointer 25 | background: transparent 26 | 27 | & 28 | // keep the white visible 29 | transition: width 1ms linear 250ms, background-color 1ms linear 250ms, color 400ms linear 30 | 31 | .-menu-visible & 32 | width: $nav-width - 1px - 20px 33 | background-color: $bg 34 | transition: color 400ms linear 35 | 36 | &:before 37 | display: inline-block 38 | ion-icon('navicon', 24px) 39 | text-align: center 40 | width: $size 41 | 42 | &:hover 43 | color: $accent 44 | // transition: width 0 linear 250ms, background-color 0 linear 250ms, color 100ms linear 45 | -------------------------------------------------------------------------------- /docs/aws/index.md: -------------------------------------------------------------------------------- 1 | # Amazon Web Services 2 | 3 | We no longer support deploying to AWS. However, you can still use Amazon S3 for storage and Amazon SQS for the audit queue if you like. 4 | 5 | ## Environment Variables 6 | | Variable | Description | 7 | | :--- | :--- | 8 | | `AWS_API_KEY` | The AWS API key. | 9 | | `AWS_API_SECRET` | The AWS API secret. | 10 | | `AWS_S3_BUCKET_NAME` | The name of the S3 bucket. | 11 | | `AWS_S3_REGION` | The region of the S3 bucket. Default is `us-west-2`. See a list of available [AWS Regions and Enpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region). | 12 | | `AWS_S3_VERSION` | The S3 API version. Default is `2006-03-01`. | 13 | | `AWS_SQS_QUEUE_LH` | The name of the SQS queue for the Lighthouse Server. | 14 | | `AWS_SQS_QUEUE_PHPCS` | The name of the SQS queue for the PHPCS Server. | 15 | | `AWS_SQS_REGION` | The region of the SQS queue. Default is `us-west-2`. See a list of available [AWS Regions and Enpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#sqs_region). | 16 | | `AWS_SQS_VERSION` | The SQS API version. Default is `2012-11-05`. | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 XWP.co (https://xwp.co) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the Software), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/license.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2019 XWP.co (https://xwp.co) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the Software), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/roadmap.md: -------------------------------------------------------------------------------- 1 | # Roadmap 2 | 3 | We're using [ZenHub](https://www.zenhub.com/) to manage Tide and you will need to install the [ZenHub Browser Extension](https://www.zenhub.com/extension) to see our agile board. Feel free to view our backlog on [GitHub](https://github.com/wptide/wptide#boards?releases=5b7c70fee4dbc16531a27c3c&activeFilters=releases&repos=107737502). The following items are not an exhaustive list but are currently planned as part of the upcoming Tide roadmap. This page is evolving and expect to see more changes soon. 4 | 5 | ## Tide version 1.0.0 6 | 7 | Agile Board: ( [v1.0.0](https://github.com/wptide/wptide#boards?releases=5b030c381a00905b6c50f1df&repos=107737502) ) 8 | 9 | * Goal: Provides better SDKs for open source contributors to utilize in coding further Go solutions for Tide on GCP 10 | * Goal: Provides easier integration point (via Webhook/HTTP Listener) for .ORG 11 | * Goal: Provides documentation and working examples of Tide to help developers and contributors better utilize and improve Tide via demonstration website. 12 | * Goal: Begins integration on .ORG (via PHP Compatibility results) and first step in actually improving the quality of code on 30% of the web. -------------------------------------------------------------------------------- /docs/gcp/google-cloud-memorystore.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Memorystore 2 | 3 | Deploying a Redis instance to Cloud Memorystore for the WordPress API only requires a bit of configuration to the environment variables and then to run a few `make` commands. 4 | 5 | ## Environment Variables 6 | 7 | | Variable | Description | 8 | | :--- | :--- | 9 | | `GCM_INSTANCE_NAME` | The name of the Redis instance. | 10 | | `GCM_INSTANCE_SIZE` | The memory size of the instance in GiB. Must be an integer number between `1-300`. This setting dramatically changes costs, do your research before deploying an instance. | 11 | | `GCM_INSTANCE_TIER` | The service tier of the instance. Must be one of: `basic`, `standard`. Basic means the Redis instance will not have replication. Standard is a high-availability Redis instance with replication for failover. | 12 | 13 | ## Deploy 14 | 15 | Deploy the Google Cloud Memorystore Redis instance: 16 | 17 | ``` 18 | make api.deploy.redis 19 | ``` 20 | 21 | Get metadata, including the internal VPC IP address, for the Google Cloud Memorystore Redis instance: 22 | 23 | ``` 24 | make api.get.redis 25 | ``` 26 | 27 | Delete the Google Cloud Memorystore Redis instance: 28 | 29 | ``` 30 | make api.clean.redis 31 | ``` -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Table of contents 2 | 3 | * [Tide](index.md) 4 | * [Installation](installation/index.md) 5 | * [Prerequisites](installation/prerequisites.md) 6 | * [Cloning](installation/cloning.md) 7 | * [Setup](installation/setup.md) 8 | * [Services](services/index.md) 9 | * [API](services/api.md) 10 | * [Sync Server](services/sync-server.md) 11 | * [PHPCS Server](services/phpcs-server.md) 12 | * [Lighthouse Server](services/lighthouse-server.md) 13 | * [Google Cloud Platform](gcp/index.md) 14 | * [Google Cloud Storage](gcp/google-cloud-storage.md) 15 | * [Google Cloud Firestore](gcp/google-cloud-firestore.md) 16 | * [Google Cloud SQL](gcp/google-cloud-sql.md) 17 | * [Google Cloud Memorystore](gcp/google-cloud-memorystore.md) 18 | * [Google App Engine](gcp/google-app-engine.md) 19 | * [Google Kubernetes Engine](gcp/google-kubernetes-engine.md) 20 | * [Amazon Web Services](aws/index.md) 21 | * Important Links 22 | * [Help](help.md) 23 | * [Local Development](local-development.md) 24 | * [Contributing](contributing.md) 25 | * [Code of Conduct](code-of-conduct.md) 26 | * [Roadmap](roadmap.md) 27 | * [Sponsors](sponsors.md) 28 | * [License](license.md) 29 | * [API Search](search.md) 30 | * [404](404.md) -------------------------------------------------------------------------------- /src/css/components/doc-layout.styl: -------------------------------------------------------------------------------- 1 | .doc-layout 2 | width: 100% 3 | height: 100% 4 | 5 | .body 6 | padding-left: 24px 7 | padding-right: 24px 8 | padding-top: 16px 9 | padding-bottom: 128px 10 | 11 | 12 | // 13 | // Desktop layout 14 | // 15 | 16 | @media (min-width: 960px) 17 | .doc-layout 18 | .menu 19 | width: $nav-width 20 | position: fixed 21 | top: 0 22 | left: 0 23 | height: 100% 24 | overflow-y: auto 25 | 26 | .body 27 | padding-top: $xpad + 40px 28 | padding-bottom: 64px + 64px 29 | transition: all 250ms ease-in 30 | 31 | .menu 32 | display: block 33 | transform: translate3d(-1 * $nav-width, 0, 0) 34 | transition: all 250ms ease-in 35 | 36 | .header-nav, 37 | .footer-nav 38 | transition: all 250ms ease-in 39 | left: $collapsed-nav-width 40 | 41 | .-menu-visible & 42 | .header-nav, 43 | .footer-nav 44 | left: $nav-width 45 | 46 | .body 47 | padding-left: $nav-width + $xpad 48 | padding-right: $xpad 49 | 50 | .menu 51 | transform: translate3d(0, 0, 0) 52 | 53 | // compensate for toggle button 54 | &:after 55 | content: '' 56 | display: block 57 | height: 64px 58 | -------------------------------------------------------------------------------- /docpress/docpress-core/lib/ms.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* eslint-disable no-cond-assign */ 3 | 4 | const Metalsmith = require('metalsmith') 5 | const join = require('path').join 6 | const log = require('./log') 7 | const assign = Object.assign 8 | 9 | /** 10 | * Returns a metalsmith object. 11 | */ 12 | 13 | function docpress (cwd, options) { 14 | let meta = { 15 | docs: 'docs', 16 | dist: '_docpress' 17 | } 18 | assign(meta, loadConfig(cwd, meta.docs)) 19 | 20 | let app = Metalsmith(cwd) 21 | .source('.') 22 | .destination(meta.dist) 23 | .metadata(meta) 24 | .ignore('node_modules') 25 | .ignore(`!**/{${meta.docs}{,/**/*},*.md}`) 26 | 27 | return app 28 | } 29 | 30 | /** 31 | * Internal: loads configuration and returns it as an object. 32 | */ 33 | 34 | function loadConfig (cwd, docs) { 35 | let fn 36 | if (exists(fn = join(cwd, 'docpress.json'))) { 37 | log(`Using config: ${fn}`) 38 | return require(fn) 39 | } 40 | 41 | if (exists(fn = join(cwd, docs, 'docpress.json'))) { 42 | log(`Using config: ${fn}`) 43 | return require(fn) 44 | } 45 | 46 | if (exists(fn = join(cwd, 'package.json'))) { 47 | var pkg = require(fn) 48 | if (pkg && pkg.docpress) { 49 | log(`Using config: ${fn} (.docpress)`) 50 | return pkg.docpress 51 | } 52 | } 53 | } 54 | 55 | function exists (file) { 56 | try { 57 | require('fs').statSync(file) 58 | return true 59 | } catch (e) {} 60 | } 61 | 62 | module.exports = docpress 63 | -------------------------------------------------------------------------------- /docs/installation/prerequisites.md: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | 3 | ## Composer 4 | Install [Composer](https://getcomposer.org/) and test if it works by running `composer --version`. 5 | 6 | ## Docker 7 | Install [Docker](https://docs.docker.com/install/). _Note: you may not be able to setup and run Tide properly with legacy Docker Toolbox._ 8 | 9 | ## Go 10 | Install [Go](https://golang.org/doc/install) and test if your installation works by following the instructions on the installation page. 11 | 12 | ## Glide 13 | Install [Glide](https://glide.readthedocs.io/en/latest/#installing-glide), a package manager for Go. There are a few ways to install Glide: 14 | 15 | - Use the shell script to try an automatically install it. `curl https://glide.sh/get | sh` 16 | - Download a [versioned release](https://github.com/Masterminds/glide/releases). Glide releases are semantically versioned. 17 | - Use a system package manager to install Glide. For example, `brew install glide` can be used if you're using [Homebrew](http://brew.sh/) on Mac. 18 | - The latest development snapshot can be installed with go get. For example, `go get -u github.com/Masterminds/glide`. This is not a release version. 19 | 20 | ## Make 21 | 22 | Install [Make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm) _(Windows only)_ 23 | - The `make` command is not available on Windows by default and you must install it to be able to use the Tide `make` commands. 24 | - Add `C:\zlib\bin` to your `$PATH` once you've installed the package. -------------------------------------------------------------------------------- /docpress/docpress-core/lib/helpers/markdown.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const syntaxHighlight = require('../syntax_highlight') 4 | const markdownIt = require('markdown-it') 5 | const assign = Object.assign 6 | 7 | var mdCache = {} 8 | 9 | /** 10 | * Private: Returns a `markdown-it` instance with plugins loaded. 11 | * 12 | * md({ typographer: true }) 13 | * md({ plugins: { decorate: {} } }) 14 | */ 15 | 16 | module.exports = function md (options, cwd) { 17 | const plugins = (options && options.plugins) || {} 18 | const key = JSON.stringify(options) 19 | if (mdCache[key]) return mdCache[key] 20 | 21 | let newOptions = { 22 | langPrefix: 'lang-', 23 | highlight: syntaxHighlight, 24 | linkify: true, 25 | html: true 26 | } 27 | 28 | newOptions = assign({}, newOptions, options || {}, { plugins: undefined }) 29 | 30 | var md = markdownIt(newOptions) 31 | if (plugins) loadPlugins(md, plugins, cwd) 32 | 33 | mdCache[key] = md 34 | return md 35 | } 36 | 37 | function loadPlugins (md, plugins, cwd) { 38 | Object.keys(plugins).forEach((plugin) => { 39 | const options = plugins[plugin] 40 | let pluginPath = 41 | tryRequire(`markdown-it-${plugin}`) || 42 | (cwd && tryRequire(`${cwd}/node_modules/markdown-it-${plugin}`)) 43 | if (!pluginPath) throw new Error(`Can't find module 'markdown-it-${plugin}'`) 44 | md = md.use(require(pluginPath), options) 45 | }) 46 | } 47 | 48 | function tryRequire (name) { 49 | try { return require.resolve(name) } catch (e) {} 50 | } 51 | -------------------------------------------------------------------------------- /docpress/docpress-base/example/docs/hello.md: -------------------------------------------------------------------------------- 1 | # Hello 2 | 3 | > A broomstick seeing a rough artwork isn't artisanal 4 | 5 | A figure of speech isn't nowadays itself, then she is not unripe or a loud coyote building a calling of the wild now. 6 | 7 | Nothing was distinctly urban. The snake rushing something had me. We will be them and nothing won't be walking. We will drive ants seeing happy waiters to divine interventions showing women. 8 | 9 | ## Urban development 10 | 11 | A different fingernail did get it. It did learn. He is not you today. We were destructive softly, but on account of the happy elk, he was running. An unglued monkey did color a four-by-four to itself regularly. 12 | 13 | * Everything shouldn't speak them to us 14 | * Days of the week are following 15 | * Forces of nature building anxious faces 16 | * Enemies of the state owning everything are changing 17 | 18 | ## True strawberries 19 | 20 | She was standing. The saturated line giving an unanswered park did give the elk starting the artwork to a government agency and the bottom of the ocean felt itself. They will be government agencies. The piece of my mind, pieces of my mind will be gently something. But then again, a lizard starting the cold shoulder is not the depressed cat. 21 | 22 | A dish of the day had it, then it gave it for a poor strawberry behind the dawn of a new age. They will be following behind something, but the poor arm will be softly saturated. The compulsive caterpillar hiding the mongoose colored itself to itself and the impossible coconut was not you on a library. 23 | 24 | 25 | -------------------------------------------------------------------------------- /docpress/docpress-core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docpress-core", 3 | "description": "Metalsmith plugin to generate Docpress site data from a project. Part of the [Docpress] project.", 4 | "homepage": "https://github.com/docpress/docpress-core#readme", 5 | "version": "0.9.0", 6 | "main": "index.js", 7 | "author": { 8 | "email": "rico@ricostacruz.com", 9 | "name": "Rico Sta. Cruz" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/docpress/docpress-core.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/docpress/docpress-core/issues" 17 | }, 18 | "dependencies": { 19 | "cheerio": "0.22.0", 20 | "debug": "^4.1.0", 21 | "highlight.js": "^9.13.1", 22 | "lodash": "^4.17.11", 23 | "lru-cache": "^4.1.3", 24 | "markdown-it": "^8.4.2", 25 | "markdown-it-decorate": "1.2.2", 26 | "marked": ">=0.6.1", 27 | "metalsmith": "2.3.0", 28 | "slugify": "^1.3.2", 29 | "ware": "1.3.0" 30 | }, 31 | "devDependencies": { 32 | "coveralls": "^3.0.2", 33 | "expect": "^23.6.0", 34 | "mocha": "^5.2.0", 35 | "mocha-clean": "1.0.0", 36 | "nyc": "^13.1.0", 37 | "standard": "^12.0.1", 38 | "standard-version": "^4.3.0" 39 | }, 40 | "scripts": { 41 | "coveralls": "nyc report --reporter=text-lcov | coveralls", 42 | "lint": "standard", 43 | "pretest": "npm run lint", 44 | "test": "nyc mocha", 45 | "release": "standard-version" 46 | }, 47 | "license": "MIT", 48 | "standard": { 49 | "global": [ 50 | "before", 51 | "beforeEach", 52 | "describe", 53 | "expect", 54 | "it" 55 | ] 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /docs/services/index.md: -------------------------------------------------------------------------------- 1 | # Services 2 | 3 | Tide consists of the following services: 4 | 5 | * The [API](api.md) implements MySQL, PHP-FPM, and an Nginx web server with WordPress installed 6 | serving a theme and a REST API. 7 | * The [Sync Server](sync-server.md) polls the WordPress.org API’s for themes and plugins to process and writes them to a queue. 8 | * The [PHPCS Server](phpcs-server.md) reads messages from a queue and runs reports against both plugins and themes, then sends the results back to the Tide API. 9 | * The [Lighthouse Server](lighthouse-server.md) reads messages from a queue and runs Google Lighthouse reports against the themes only, then sends the results back to the Tide API. 10 | 11 | ## Commands 12 | 13 | There are several `make` commands you can use to manage the Tide services. Some you run manually, and some are ran by other `make` commands — these are the root level ones. There are additional commands associated with each service, which we'll see later in this section. If you run `make` from the root directory a full list of commands will output to your shell. 14 | 15 | | Command | Description | 16 | | :--- | :--- | 17 | | `make deps` | Install Glide dependencies. | 18 | | `make config` | Set GCP configurations. | 19 | | `make build.bins` | Build all the Go binaries. | 20 | | `make clean.bins` | Clean all the Go binaries. | 21 | | `make build.images` | Build all the Docker images. | 22 | | `make build.up` | Rebuild the Docker images & run the containers with docker-compose up. | 23 | | `make up` | Run the Docker containers with docker-compose up. | 24 | | `make down` | Stop the Docker containers with docker-compose down. | 25 | | `make test` | Run the Go test suite. | -------------------------------------------------------------------------------- /docpress/docpress/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docpress", 3 | "description": "Documentation website generator", 4 | "homepage": "https://github.com/docpress/docpress#readme", 5 | "version": "0.7.6", 6 | "main": "index.js", 7 | "bin": { 8 | "docpress": "bin/docpress" 9 | }, 10 | "author": { 11 | "email": "rico@ricostacruz.com", 12 | "name": "Rico Sta. Cruz" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/docpress/docpress.git" 17 | }, 18 | "bugs": { 19 | "url": "https://github.com/docpress/docpress/issues" 20 | }, 21 | "keywords": [ 22 | "documentation", 23 | "generator", 24 | "markdown", 25 | "painless", 26 | "static", 27 | "website" 28 | ], 29 | "dependencies": { 30 | "docpress-base": "../docpress-base", 31 | "docpress-core": "../docpress-core", 32 | "metalsmith-start": "~2.0.1", 33 | "yargs": "^12.0.2" 34 | }, 35 | "devDependencies": { 36 | "browserify": "^16.2.3", 37 | "coveralls": "^3.0.2", 38 | "expect": "^23.6.0", 39 | "git-update-ghpages": "1.3.0", 40 | "markdown-it-decorate": "1.2.2", 41 | "mocha": "^5.2.0", 42 | "nixt": "^0.5.1", 43 | "nyc": "^13.1.0", 44 | "standard": "^12.0.1", 45 | "standard-version": "^4.4.0", 46 | "uglifyify": "^5.0.1" 47 | }, 48 | "scripts": { 49 | "coveralls": "nyc report --reporter=text-lcov | coveralls", 50 | "deploy": "bin/docpress b && git-update-ghpages -b master docpress/docpress.github.io _docpress", 51 | "lint": "standard", 52 | "pretest": "npm run lint", 53 | "test": "nyc mocha", 54 | "release": "standard-version" 55 | }, 56 | "license": "MIT", 57 | "standard": { 58 | "global": [ 59 | "before", 60 | "describe", 61 | "expect", 62 | "it" 63 | ] 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/css/components/api-check.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Api Check Component 3 | // 4 | 5 | .api-check 6 | width: 100% 7 | margin-bottom: 100px 8 | margin-top: 32px 9 | 10 | .api-check__title 11 | margin-bottom: 20px 12 | font-size: 25px 13 | font-weight: 200 14 | text-align: center 15 | 16 | .api-check__form 17 | display: flex 18 | flex-wrap: wrap 19 | border: 1px solid #eee 20 | 21 | .api-check__radio 22 | position: absolute 23 | visibility: hidden 24 | 25 | .api-check__radio:checked + .api-check__label 26 | color: #fff 27 | background: #1626ff 28 | 29 | .api-check__label 30 | display: flex 31 | align-items: center 32 | justify-content: center 33 | width: 50% 34 | height: 50px 35 | cursor: pointer 36 | color: #1526FF 37 | transition: color .2s, background .2s 38 | 39 | .api-check__icon 40 | margin-right: 10px 41 | fill: currentColor 42 | 43 | .api-check__textfield 44 | position: relative 45 | width: 100% 46 | padding: 15px 47 | 48 | .api-check__searchfield 49 | display: flex 50 | align-items: center 51 | width: 100% 52 | padding: 0 10px 53 | height: 50px 54 | background: #F4F4F4 55 | border: 1px solid #DDDDDD 56 | outline: none 57 | 58 | .api-check__button 59 | position: absolute 60 | top: 15px 61 | right: 15px 62 | display: flex 63 | align-items: center 64 | justify-content: center 65 | height: 50px 66 | width: 50px 67 | appearance: none 68 | background: none 69 | border: none 70 | cursor: pointer 71 | outline: none 72 | 73 | .api-check pre 74 | position: relative 75 | margin-top: 50px 76 | 77 | .api-check pre.error 78 | padding-right: 100px 79 | white-space: pre-wrap 80 | white-space: -moz-pre-wrap 81 | white-space: -o-pre-wrap 82 | word-wrap: break-word 83 | 84 | .api-check__close 85 | position: absolute 86 | top: 15px 87 | right: 20px -------------------------------------------------------------------------------- /docpress/docpress-base/lib/build_css.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const join = require('path').join 4 | const readFileSync = require('fs').readFileSync 5 | const dirname = require('path').dirname 6 | 7 | /* 8 | * Builds the CSS files. 9 | * 10 | * This builds the CSS using Stylus and pipes it through postcss. It's roughly 11 | * equivalent to: 12 | * 13 | * stylus -I node_modules input.css | postcss -u autoprefixer 14 | * 15 | * Calls `done(err, res)` when done, where `res` is the final CSS string. 16 | * 17 | * Available options: 18 | * 19 | * - `compress` (Boolean) - compresses if true 20 | * - `import` (Array of strings) - adds files to be imported 21 | */ 22 | 23 | module.exports = function buildCss (options, done) { 24 | buildStylus(join(__dirname, '../../../src/css/docpress.styl'), options, done) 25 | } 26 | 27 | function buildStylus (filepath, options, done) { 28 | try { 29 | const stylus = require('stylus') 30 | const postcss = require('postcss') 31 | const autoprefixer = require('autoprefixer')({}) 32 | 33 | let data = readFileSync(filepath, 'utf-8') 34 | 35 | let s = stylus(data) 36 | .set('filename', filepath) 37 | .set('include css', true) 38 | .set('hoist atrules', true) 39 | .include(join(__dirname, '../node_modules')) 40 | 41 | if (options && options.compress) { 42 | s = s.set('compress', true) 43 | } 44 | 45 | if (options && options.imports) { 46 | options.imports.forEach((external) => { 47 | s = s 48 | .import(external) 49 | .include(dirname(external)) 50 | }) 51 | } 52 | 53 | s.render((err, result) => { 54 | if (err) return done(err) 55 | let css = result 56 | css = postcss([autoprefixer]).process(css).css 57 | done(null, css) 58 | }) 59 | } catch (err) { 60 | done(err) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/css/components/markdown-body.styl: -------------------------------------------------------------------------------- 1 | // github-markdown-css defines .markdown-body and its descendants 2 | @require './github-markdown-css/github-markdown.css' 3 | 4 | // 5 | // Markdown body 6 | // 7 | 8 | .markdown-body 9 | margin: 0 auto 10 | max-width: 960px 11 | overflow: visible 12 | padding-bottom: 24px + 16px + $xpad 13 | 14 | // 15 | // Heading overrides 16 | // 17 | 18 | .markdown-body 19 | & 20 | line-height: 1.65 21 | 22 | // Reduce font size in mobile screens 23 | @media (max-width: 768px) 24 | line-height: 1.6 25 | font-size: 15px 26 | 27 | @media (min-width: 959px) 28 | padding-left: 30px 29 | padding-right: 30px 30 | 31 | // Primary headings should be larger on sites. No need to stick to small 32 | // GitHub's small h1's, which are more appropriate for readme's on their 33 | // site, but not in Docpress sites. 34 | h1 35 | font-size: 2.5em 36 | font-weight: 300 37 | margin-bottom: .5em 38 | padding-bottom: .5em 39 | 40 | h1, h2, h3, h4, h5, h6 41 | border: none 42 | 43 | // The h2..h6 changes are in line with older Helvetica GitHub look. The larger 44 | // heading sizes are more appropriate for full-screen docs (rather than GitHub's 45 | // where readme's are confined in a panel). 46 | @media (min-width: 769px) 47 | h2 48 | margin-top: 50px 49 | margin-bottom: 20px 50 | font-size: 1.75em 51 | line-height: 1.225 52 | 53 | h3, h4, h5, h6 54 | line-height: 1.25 55 | margin-top: 24px 56 | 57 | h3 58 | font-size: 1.5em 59 | overflow: scroll 60 | white-space: nowrap 61 | 62 | h3::-webkit-scrollbar 63 | display: none 64 | 65 | h4 66 | font-size: 1.25em 67 | 68 | h5 69 | font-size: 1.1em 70 | 71 | h6 72 | font-size: .875em 73 | 74 | blockquote 75 | color: #555 76 | 77 | table 78 | display: table 79 | margin-top: 1.5em 80 | 81 | tr > td:first-child 82 | white-space: nowrap -------------------------------------------------------------------------------- /docpress/docpress-base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docpress-base", 3 | "description": "Base theme for Docpress.", 4 | "homepage": "https://github.com/docpress/docpress-base#readme", 5 | "version": "0.7.6", 6 | "main": "index.js", 7 | "author": { 8 | "email": "rico@ricostacruz.com", 9 | "name": "Rico Sta. Cruz" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/docpress/docpress-base.git" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/docpress/docpress-base/issues" 17 | }, 18 | "dependencies": { 19 | "autoprefixer": "6.5.3", 20 | "browserify": "13.1.1", 21 | "debounce": "1.0.0", 22 | "dom101": "1.3.0", 23 | "github-markdown-css": "2.4.1", 24 | "iconfonts": "0.10.0", 25 | "normalize.css": "5.0.0", 26 | "nprogress": "0.2.0", 27 | "onmount": "1.3.0", 28 | "pjax": "0.2.4", 29 | "postcss": "5.2.5", 30 | "pug": "^2.0.3", 31 | "stylus": "0.54.5", 32 | "uglifyify": "3.0.4", 33 | "ware": "1.3.0" 34 | }, 35 | "devDependencies": { 36 | "coveralls": "2.11.15", 37 | "docpress-core": "github:docpress/docpress-core", 38 | "expect": "1.20.2", 39 | "metalsmith": "2.3.0", 40 | "mocha": "^5.2.0", 41 | "mocha-clean": "1.0.0", 42 | "nyc": "9.0.1", 43 | "standard": "8.4.0", 44 | "standard-version": "^4.4.0", 45 | "superstatic": "4.0.3" 46 | }, 47 | "scripts": { 48 | "build": "mkdir -p cache && ./bin/build --css > cache/style.css && ./bin/build --js > cache/script.js", 49 | "coveralls": "nyc report --reporter=text-lcov | coveralls", 50 | "lint": "standard", 51 | "prepublish": "npm run build", 52 | "pretest": "npm run lint", 53 | "serve": "ss fixture/onmount/_docpress", 54 | "test": "nyc mocha", 55 | "watch": "mocha -R min --watch", 56 | "release": "standard-version" 57 | }, 58 | "license": "MIT", 59 | "standard": { 60 | "global": [ 61 | "before", 62 | "beforeEach", 63 | "describe", 64 | "expect", 65 | "it" 66 | ] 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /docpress/docpress/bin/docpress: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const delegateBin = require('../lib/delegate_bin') 3 | 4 | if (module.parent) { 5 | module.exports = docpress 6 | } else { 7 | delegateBin('docpress', 'bin/docpress') || 8 | run() 9 | } 10 | 11 | function run () { 12 | var cwd = process.cwd() 13 | var args = require('yargs').argv 14 | if (args._[0] === 'build' || args._[0] === 'b') { 15 | docpress(cwd).build((err, res) => { 16 | if (err) throw err 17 | process.exit(0) 18 | }) 19 | } else if (args.help || args.h) { 20 | help() 21 | process.exit(0) 22 | } else if (args.version || args.v) { 23 | console.log(require('../package.json').version) 24 | process.exit(0) 25 | } else { 26 | if (!process.env.NODE_ENV) process.env.NODE_ENV = 'development' 27 | var Runner = require('metalsmith-start').Runner 28 | var r = new Runner(docpress(cwd), { 29 | banner: 'Docpress', 30 | port: args.port || args.p || 3000 31 | }) 32 | r.start((err) => { 33 | if (err) throw (err) 34 | }) 35 | } 36 | } 37 | 38 | function help () { 39 | console.log('') 40 | console.log(' Documentation website builder') 41 | console.log('') 42 | console.log(' Usage:') 43 | console.log(' docpress [command] [options]') 44 | console.log('') 45 | console.log(' Commands:') 46 | console.log(' serve starts a server (default)') 47 | console.log(' build builds files') 48 | console.log('') 49 | console.log(' Options:') 50 | console.log(' -h, --help show usage information') 51 | console.log(' -v, --version print version info and exit') 52 | console.log('') 53 | } 54 | 55 | function docpress (cwd) { 56 | var app = require('docpress-core/ms')(cwd) 57 | const meta = app.metadata() 58 | 59 | // Set default plugins 60 | if (!meta.plugins) meta.plugins = { 61 | 'docpress-core': {}, 62 | 'docpress-base': {} 63 | } 64 | 65 | // Use plugins 66 | const plugins = meta.plugins 67 | Object.keys(plugins).forEach((plugin) => { 68 | const options = plugins[plugin] 69 | app = app.use(require(plugin)(options)) 70 | }) 71 | 72 | return app 73 | } 74 | -------------------------------------------------------------------------------- /src/js/script.js: -------------------------------------------------------------------------------- 1 | require('./polyfills') 2 | var onmount = require('onmount') 3 | var toggleClass = require('dom101/toggle-class') 4 | var ready = require('dom101/ready') 5 | var Scrolltrack = require('./scrolltrack') 6 | var Scrollclass = require('./scrollclass') 7 | var Waves = require('./waves') 8 | var ApiCheck = require('./apicheck') 9 | 10 | /* 11 | * onmount 12 | */ 13 | 14 | ready(function () { 15 | onmount() 16 | }) 17 | 18 | /* 19 | * menu toggle 20 | */ 21 | 22 | onmount('.js-menu-toggle', function () { 23 | this.addEventListener('click', function () { 24 | toggleClass(document.body, '-menu-visible') 25 | }) 26 | }) 27 | 28 | /* 29 | * scrolltrack 30 | */ 31 | 32 | void (function () { 33 | var st = new Scrolltrack({ 34 | menu: '.toc-menu', 35 | selector: 'h2, h3', 36 | onupdate: function (active, last) { 37 | var menu = document.querySelector('.toc-menu') 38 | var link = menu.querySelector('.link.-active, .link.-notactive') 39 | 40 | toggleClass(link, '-active', !active) 41 | toggleClass(link, '-notactive', active) 42 | } 43 | }) 44 | 45 | document.addEventListener('pjax:complete', function () { 46 | st.update() 47 | }) 48 | 49 | ready(function () { 50 | st.update() 51 | }) 52 | }()) 53 | 54 | /* 55 | * scrollclass 56 | */ 57 | 58 | onmount('.footer-nav', function (b) { 59 | b.sc = Scrollclass(this, { 60 | className: '-expanded', 61 | onscroll: function (y) { 62 | return this.maxScroll - y < 88 63 | } 64 | }) 65 | }) 66 | 67 | onmount('.header-nav', function (b) { 68 | b.sc = Scrollclass(this, { 69 | className: '-expanded', 70 | onscroll: function (y) { return y < 40 } 71 | }) 72 | }) 73 | 74 | /* 75 | * waves 76 | */ 77 | 78 | onmount('canvas', function (b) { 79 | var el = this 80 | function create() { 81 | if (b.waves) b.waves.stop() 82 | if (matchMedia('(min-width: 959px)')) { 83 | b.waves = new Waves(el) 84 | b.waves.run() 85 | } 86 | } 87 | 88 | create() 89 | window.addEventListener('resize', create) 90 | }) 91 | 92 | /* 93 | * apicheck 94 | */ 95 | 96 | onmount('[data-api-check]', function (b) { 97 | b.apicheck = new ApiCheck(this) 98 | }) 99 | -------------------------------------------------------------------------------- /docs/search.md: -------------------------------------------------------------------------------- 1 | # Search Plugins & Themes 2 | 3 | The search form makes a `GET` request to the Tide API and responds with a JSON object of an audit by searching for a plugin or theme slug from the wordpress.org repository. For example, you can search for the theme `twentyseventeen` or plugin `jetpack`. 4 | 5 |
6 |
7 | 8 | 14 | 15 | 21 |
22 | 23 | 28 |
29 |
30 |
31 | -------------------------------------------------------------------------------- /src/js/waves/index.js: -------------------------------------------------------------------------------- 1 | // Waves for homepage hero section 2 | 3 | function Waves (canvas) { 4 | var ctx = canvas.getContext('2d') 5 | var parentRect = canvas.parentNode.getBoundingClientRect() 6 | var height = canvas.height = parentRect.height 7 | var width = canvas.width = Math.min(parentRect.width + 300, window.innerWidth - 400) 8 | 9 | // Stage 10 | var fov = 1024 11 | var zRows = width / 60 12 | var xRows = width / 50 13 | var yBase = 800 14 | var spacing = width / xRows 15 | var dotSize = 2 16 | var tickDiv = 20 17 | var tick = 0 18 | var isStop = false 19 | 20 | // Points 21 | var points = [] 22 | 23 | for (var z = 0; z < zRows; z++) { 24 | for (var x = -xRows/2; x < xRows/2; x++) { 25 | points.push(new Point({ 26 | x: x * spacing + dotSize, 27 | y: yBase, 28 | z: z * spacing, 29 | yRange: 20, 30 | tickOffset: (z * 7) + (x * 5) 31 | })) 32 | } 33 | } 34 | 35 | function Point (config) { 36 | for (var key in config) this[key] = config[key] 37 | } 38 | 39 | Point.prototype.update = function () { 40 | var z2d = fov / (this.z + fov) 41 | 42 | this.yFloat = this.yRange * Math.sin((tick + this.tickOffset) / tickDiv) 43 | this.distance = (this.z / spacing) / zRows 44 | this.x2d = (this.x * z2d) + (width / 2) 45 | this.y2d = (this.y * z2d) + (height / 2) - (this.y * 0.7) + this.yFloat 46 | this.dotSize = dotSize * (1 - this.distance) 47 | this.alpha = 1 * (1 - this.distance) 48 | } 49 | 50 | Point.prototype.drawDot = function () { 51 | ctx.beginPath() 52 | ctx.arc(this.x2d, this.y2d, this.dotSize, 0, 2 * Math.PI) 53 | ctx.fillStyle = 'rgba(0,0,0,' + this.alpha + ')' 54 | ctx.fill() 55 | } 56 | 57 | function animate () { 58 | if (isStop) return 59 | ++tick 60 | ctx.clearRect(0,0,width,height) 61 | 62 | points.forEach(function (point, i) { 63 | var prevX = points[i-1] 64 | var prevY = points[i - xRows] 65 | point.update() 66 | point.drawDot() 67 | }) 68 | 69 | requestAnimationFrame(animate) 70 | } 71 | 72 | function stop () { 73 | isStop = true 74 | } 75 | 76 | return { 77 | run: animate, 78 | stop: stop 79 | } 80 | } 81 | 82 | module.exports = Waves -------------------------------------------------------------------------------- /functions/docpress-make-absolute-urls.php: -------------------------------------------------------------------------------- 1 | isFile() && 'html' === pathinfo($file, PATHINFO_EXTENSION); 8 | } ); 9 | 10 | $relative_paths = array_map( function ($file) { 11 | $path = str_replace( DOCS_PATH . '/', '', $file ); 12 | if ( $path ) { 13 | return $path; 14 | } 15 | }, array_keys( $all_files ) ); 16 | 17 | $href_match = array_map( function ($file) { 18 | return 'href="'. $file .'"'; 19 | }, $relative_paths); 20 | 21 | $href_replace = array_map( function ($file) { 22 | return 'href="'. site_url() . '/' . str_replace(array('/index.html', 'index.html', '.html', '/index'), '', $file) .'"'; 23 | }, $relative_paths ); 24 | 25 | $parts = explode( '/', get_current_url() ); 26 | $files = array( 27 | 'contributing', 28 | 'help', 29 | 'local-development', 30 | ); 31 | 32 | // Links 33 | $content = str_replace($href_match, $href_replace, $file_contents); // replace all relative href file matches with absolute urls and remove .html & index 34 | if ( in_array( end( $parts ), $files, true ) ) { 35 | $content = preg_replace('#href="(?!\/|https?:\/\/|mailto:|\#)(.*)"#im', 'href="'. site_url() .'/$1"', $content); // replace relative links inside root level files to other root level files 36 | } 37 | $content = preg_replace('#href="(?:\.\.\/)(.+)"#im', 'href="'. site_url() .'/$1"', $content); // replace ../ 38 | $content = preg_replace('#href="(.+)(?:(\/.*)\.html)"#im', 'href="$1$2"', $content); // replace .html links 39 | $content = preg_replace('#href="(.+)(\/index)"#im', 'href="$1"', $content); // replace /index links 40 | $content = preg_replace('#href="(?!mailto:)([^\/\#]+)(\#.+)*"#im', 'href="'. get_current_url() .'/$1"', $content); // replace sibling links 41 | $content = preg_replace('#href="' . site_url() . '(?:\/\/)([^"]*)"#im', 'href="' . site_url() . '/$1"', $content); // replace path//file links 42 | 43 | // Images 44 | $content = preg_replace('#src="(?!https?:\/\/)(?!data:)(.+)"#im', 'src="'. DOCS_URI .'/$1"', $content); // fix relative images 45 | $content = preg_replace('#src="(.+)(?:\.\.\/)(.+)"#im', 'src="$1$2"', $content); // replace ../ 46 | 47 | // @todo Find a better way to fix the invalid URL coming from `docpress`. 48 | $content = preg_replace('/trunk\/wordpress.org\/public\//', 'trunk/wordpress.org/public_html/', $content ); 49 | 50 | return $content; 51 | } -------------------------------------------------------------------------------- /docs/services/phpcs-server.md: -------------------------------------------------------------------------------- 1 | # PHPCS Server 2 | 3 | The PHPCS Server is a Go binary installed on an Alpine Linux Docker image that reads messages from a queue and runs PHPCS reports against both plugins and themes, then sends the results back to the Tide API. It is important to note that the PHPCS Server only does static analysis of PHP compatibility and WordPress coding standards and does not execute code or install themes and plugins into WordPress to run the audit. 4 | 5 | ## Environment Variables 6 | 7 | | Variable | Description | 8 | | :--- | :--- | 9 | | `PHPCS_CONCURRENT_AUDITS` | Sets the number of goroutines the server will perform concurrently. Default is `5`. _This is currently deactivated and will have no impact during runtime._ | 10 | | `PHPCS_MESSAGE_PROVIDER` | Queue audit messages using the local MongoDB, Google Cloud Firestore, or AWS SQS. Must be one of: `local`, `firestore`, `sqs`. Default is `local`. | 11 | | `PHPCS_STORAGE_PROVIDER` | Upload reports to the local file system, Google Cloud Storage, or AWS S3. Must be one of: `local`, `gcs`, `s3`. Default is `local`. | 12 | | `PHPCS_TEMP_FOLDER` | Sets the temporary folder inside the container used to store downloaded files. Default is `/tmp`. | 13 | 14 | ## Commands 15 | 16 | | Command | Description | 17 | | :--- | :--- | 18 | | `make phpcs.build.bin` | Build the PHPCS Server Go binary. | 19 | | `make phpcs.clean.bin` | Clean the PHPCS Server Go binary. | 20 | | `make phpcs.build.image` | Build the PHPCS Server Docker image. | 21 | | `make phpcs.build.up` | Rebuild the PHPCS Server Docker image and run the container in isolation with docker-compose up. | 22 | | `make phpcs.up` | Run the PHPCS Server Docker container in isolation with docker-compose up. | 23 | | `make phpcs.down` | Take the isolated PHPCS Server Docker container down. | 24 | | `make phpcs.stop` | Stop the isolated PHPCS Server Docker container with docker-compose stop. | 25 | | `make phpcs.rm` | Remove the stopped PHPCS Server Docker container with docker-compose rm. | 26 | | `make phpcs.push.image` | Push the PHPCS Server Docker image to GCR. | 27 | | `make phpcs.clean.image` | Clean the PHPCS Server Docker image from the host machine. | 28 | | `make phpcs.build.cluster` | Build the PHPCS Server GKE cluster. | 29 | | `make phpcs.creds` | Get the PHPCS Server GKE cluster credentials. | 30 | | `make phpcs.tpl` | Generate the PHPCS Server GKE YAML template. | 31 | | `make phpcs.deploy.cluster` | Deploy the PHPCS Server GKE cluster. | 32 | | `make phpcs.get.cluster` | Get the PHPCS Server GKE cluster status. | 33 | | `make phpcs.clean.cluster` | Clean the PHPCS Server GKE cluster. | -------------------------------------------------------------------------------- /docs/gcp/google-cloud-firestore.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Firestore 2 | 3 | If you want to use Cloud Firestore as the database provider for the Sync Server or as the message provider for the Lighthouse/PHPCS Server you'll need to setup Cloud Firestore for your project. 4 | 5 | ## Environment Variables 6 | 7 | | Variable | Description | 8 | | :--- | :--- | 9 | | `GCF_QUEUE_LH` | Specifies which collection in Cloud Firestore to use for the Lighthouse message queue. This is a Firestore collection **path**. Default is `queue-lighthouse`. | 10 | | `GCF_QUEUE_PHPCS` | Specifies which collection in CLoud Firestore to use for the PHPCS message queue. This is a Firestore collection **path**. Default is `queue-phpcs`. | 11 | 12 | ## Setup 13 | 14 | 1. If you don't already have a Firebase project, add one in the [Firebase console](https://console.firebase.google.com/u/0/project/_/database/firestore/data). The **Add project** dialog also gives you the option to add Firebase to an existing Google Cloud Platform project. 15 | 16 | 1. Allow read/write access on all documents to any user signed in to the application by replacing the previous [security rules](https://console.firebase.google.com/u/0/project/_/database/firestore/rules) with the following in the Cloud Firestore console. 17 | 18 | ``` 19 | service cloud.firestore { 20 | match /databases/{database}/documents { 21 | match /{document=**} { 22 | allow read, write: if request.auth.uid != null; 23 | } 24 | } 25 | } 26 | ``` 27 | 28 | 1. In order for the message queue to be queryable by the Go servers, you will need to add composite indexes for both the `GCF_QUEUE_LH` and `GCF_QUEUE_PHPCS` message queues. The following directions are going to be for `GCF_QUEUE_PHPCS`, but must be repeated for the `GCF_QUEUE_LH` queue. It's assumed you are using the default `queue-phpcs` value for `GCF_QUEUE_PHPCS`. 29 | 30 | 1. Open the [composite indexes](https://console.firebase.google.com/u/0/project/_/database/firestore/indexes) tab in the Firebase console. 31 | 1. Click `Add index manually` or the `Add Index` button if you already have created a composite index. 32 | 1. Add `queue-phpcs` as the collection name. 33 | 1. Add a new field named `retry_available` and set sort to ascending. 34 | 1. Add a new field named `lock` and set the sort to ascending. 35 | 1. Add a new field named `created` and set the sort to ascending. 36 | 1. Click `Create Index` and repeat for `queue-lighthouse`. 37 | 38 | _Note: If you change the values in your `.env` then the collection names in the third step should be the same as those values._ -------------------------------------------------------------------------------- /src/css/components/toc-menu.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Menu 3 | // 4 | 5 | .toc-menu 6 | $pad = 24px 7 | 8 | & 9 | position: relative 10 | padding: ($pad - 4px) 0 11 | // background: #fdfefe 12 | box-shadow: inset -1px 0 $line 13 | font-size: 13px 14 | transition: opacity 1500ms linear 15 | 16 | ul, li 17 | margin: 0 18 | padding: 0 19 | list-style: none 20 | 21 | .title 22 | display: block 23 | padding: 7px $pad 24 | height: 1em 25 | text-overflow: ellipsis 26 | overflow: hidden 27 | white-space: nowrap 28 | box-sizing: content-box 29 | 30 | .-level-1.-parent 31 | margin-bottom: 16px 32 | 33 | li.-level-1 > .title 34 | margin-top: 16px 35 | font-weight: bold 36 | color: $black 37 | font-size: 1.1em 38 | 39 | .-depth-3 40 | display: none 41 | 42 | .link 43 | &, &:visited 44 | color: $slate 45 | text-decoration: none 46 | position: relative 47 | 48 | .link, .hlink 49 | & 50 | transition: background-color 200ms linear, color 500ms linear, box-shadow 200ms linear 51 | box-shadow: inset -2px 0 rgba($accent, 0) 52 | box-sizing: content-box 53 | 54 | &:hover 55 | background-color: rgba($accent, 0.02) 56 | color: darken($slate, 20%) 57 | transition: box-shadow 200ms linear 58 | 59 | &:active 60 | background-color: rgba($accent, 0.1) 61 | color: $black 62 | transition: box-shadow 200ms linear 63 | 64 | &.-active 65 | box-shadow: inset -2px 0 $accent 66 | transition: background-color 200ms linear, color 500ms linear 67 | 68 | // The readme 69 | .-level-1:first-child 70 | margin-bottom: 16px 71 | 72 | // The readme's headings 73 | .-level-1:first-child > .heading-list 74 | margin-top: 16px 75 | margin-bottom: 16px 76 | 77 | // The readme's title 78 | .-level-1:first-child > .title 79 | margin-top: 0 80 | font-size: 1.5em 81 | font-weight: 300 82 | color: $black 83 | 84 | .-level-3 .title 85 | padding-left: $pad + 8px * 1 86 | 87 | .-level-4 .title 88 | padding-left: $pad + 8px * 2 89 | 90 | .link-index 91 | text-transform: lowercase 92 | 93 | .submenu:first-child > li:last-child 94 | display: none 95 | visibility: hidden 96 | 97 | // 98 | // Hover fade 99 | // 100 | 101 | .toc-menu.-faded 102 | .title:not(.-active) 103 | opacity: 0.2 104 | transition: opacity 1500ms linear 105 | 106 | &:hover .title 107 | opacity: 1 108 | transition: opacity 200ms linear 109 | -------------------------------------------------------------------------------- /docpress/docpress-core/lib/fix_html.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | /* eslint-disable no-cond-assign */ 3 | 4 | const slugify = require('slugify') 5 | const resolve = require('path').resolve 6 | const dirname = require('path').dirname 7 | const relative = require('path').relative 8 | 9 | /** 10 | * Internal: Performs in-place HTML filters (such as fixing URLs). 11 | */ 12 | 13 | module.exports = function fixHtml ($, fname, sources, files, page) { 14 | idify($) 15 | fixReferences($, fname, sources, files, page) 16 | } 17 | 18 | /** 19 | * Private: Add IDs to headings. 20 | */ 21 | 22 | function idify ($) { 23 | $('h1, h2, h3, h4, h5, h6').each(function () { 24 | var $this = $(this) 25 | $this.attr('id', slugify($this.text()).toLowerCase()) 26 | }) 27 | } 28 | 29 | /** 30 | * Private: Fixes `` and `` references. Converts links to 31 | * Markdown files (eg, `/docs/usage.md`) into relative links to HTML files 32 | * (eg, `./usage.html`). 33 | */ 34 | 35 | function fixReferences ($, fname, sources, files, page) { 36 | var base = page.source 37 | var m 38 | 39 | $('[href], [src]').each(function () { 40 | var $this = $(this) 41 | if ($this.attr('href')) fix($this, 'href') 42 | if ($this.attr('src')) fix($this, 'src') 43 | }) 44 | 45 | function fix ($this, attr) { 46 | var origUrl = $this.attr(attr) 47 | var anchor = '' 48 | 49 | // Ignore http://, #anchor, mailto:, and links that don't end with .md. 50 | if (origUrl.match(/^https?:\/\//) || 51 | origUrl.match(/^mailto:/) || 52 | origUrl.match(/^#/) || 53 | origUrl.match(/^((?!(.*\.md)).)*$/)) return 54 | 55 | if (m = origUrl.match(/^([^#]+)(#.*)$/)) { 56 | origUrl = m[1] 57 | anchor = m[2] 58 | } 59 | 60 | // Get the target source file it points to (eg, `docs/usage.md`). 61 | var target = getTarget(origUrl, base) 62 | 63 | // Ensure that it's available. 64 | if (!sources[target]) { 65 | throw new Error(`${base}: Unknown reference '${origUrl}'`) 66 | } 67 | 68 | // Relativize that absolute URL. 69 | target = relative('/' + dirname(sources[base]), '/' + sources[target]) + anchor 70 | $this.attr(attr, target) 71 | } 72 | } 73 | 74 | /* 75 | * Private: Transform `target` into an absolute URL (without `/`). 76 | * 77 | * getTarget('/foo.md') //=> 'foo.md' 78 | * getTarget('foo.md', 'docs/x.md') //=> 'docs/foo.md' 79 | */ 80 | 81 | function getTarget (url, base) { 82 | if (url.substr(0, 1) === '/') { 83 | return url.substr(1) 84 | } else { 85 | return resolve('/' + dirname(base) + '/' + url).substr(1) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/docs/premise.md: -------------------------------------------------------------------------------- 1 | # Premise 2 | 3 | Onmount is a safe, reliable, idempotent, and testable way to attach JavaScript behaviors to DOM nodes. 4 | 5 | * It's great for common websites that are not Single-Page Apps. 6 | * It goes hand-in-hand with Turbolinks. 7 | 8 | ## Example 9 | 10 | Given this HTML snippet: 11 | 12 | ```html 13 |
14 | Home 15 | Inbox 16 | Messages 17 | 18 |
19 | Help 20 | Support 21 |
22 | 23 | 24 |
25 | ``` 26 | 27 | Typically, to make this work, you'll make code like this: 28 | 29 | ```js 30 | $(function () { 31 | $('.js-expandable-nav button').on('click', function () { 32 | $('.js-expandable-nav .more').show() 33 | $('.js-expandable-nav button').hide() 34 | }) 35 | }) 36 | ``` 37 | 38 | ## Problems 39 | 40 | However, you have a few problems with this approach. 41 | 42 | * __It's not testable.__ You can't make unit tests from this code. 43 | * __Assumes just one instance.__ When there are 2 .js-expandable-nav elements in the page, this will break. 44 | * __It doesn't work in modal dialogs.__ Since it works in `$(function() { ... })`, it doesn't work on elements loaded later. 45 | * __There's no provision for cleanups.__ What happens when `.js-expandable-nav` exits the DOM (eg, the dialog box was closed)? 46 | 47 | ## Solution 48 | 49 | Behaviors solve that. You don't write your code any differently, but it will be accessible in a way that it's testable, isolated, and idempotent. 50 | 51 | ```js 52 | /* 53 | * initializes behaviors on jQuery document.ready, Turbolinks page:change, and 54 | * on bootstrap modal show. 55 | */ 56 | 57 | $(document).on('ready page:change show.bs.modal', function () { $.onmount() }) 58 | 59 | /* 60 | * attach a behavior to `.js-expandable-nav` 61 | */ 62 | 63 | $.onmount('.js-expandable-nav', function () { 64 | var $this = $(this) 65 | var $button = $this.find('button') 66 | var $more = $this.find('.more') 67 | 68 | $button.on('click', function () { 69 | $more.toggle() 70 | $button.hide() 71 | }) 72 | }) 73 | ``` 74 | 75 | ## Benefits 76 | 77 | By simply wrapping your code in `$.onmount(...)` instead of `$(function)`, it gives you the power of a few features: 78 | 79 | * You're assured that the block will only run once for every `.js-expandable-nav` element. 80 | 81 | * You can retrigger this behavior for tests. 82 | 83 | * You can call behaviors again and again (`$.onmount()`) every time your DOM changes to make it work for any new elements. 84 | -------------------------------------------------------------------------------- /src/css/components/footer-nav.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Footer nav 3 | // 4 | 5 | .footer-nav 6 | & 7 | position: fixed 8 | bottom: 0 9 | right: 0 10 | left: 0 11 | border-top: solid 1px transparent 12 | background-color: rgba(white, 0) 13 | clearfix() 14 | 15 | @media (max-width: 959px) 16 | opacity: 0 17 | transition: opacity .3s 18 | 19 | &.-expanded 20 | opacity: 1 21 | 22 | &, a 23 | height: 24px + 16px + $xpad 24 | line-height: 24px 25 | 26 | a 27 | display: block 28 | align-items: center 29 | white-space: nowrap 30 | text-overflow: ellipsis 31 | 32 | // Expanded: background 33 | &.-expanded 34 | background-color: rgba(white, 1) 35 | 36 | &:before 37 | content: '' 38 | position: absolute 39 | left: $xpad 40 | right: $xpad 41 | top: 0 42 | height: 1px 43 | background: $line 44 | 45 | // Layout 46 | .left 47 | position: absolute 48 | left: 0 49 | top: 0 50 | 51 | .right 52 | position: absolute 53 | right: 0 54 | top: 0 55 | text-align: right 56 | 57 | &.-expanded .right 58 | width: 60% 59 | 60 | // Title and labels 61 | .title 62 | white-space: nowrap 63 | overflow: hidden 64 | text-overflow: ellipsis 65 | 66 | .title, 67 | .label 68 | opacity: 0 69 | pointer-events: none 70 | 71 | // Fly the 'next: ___' from the left 72 | .right .title, 73 | .right .label 74 | transform: translate3d(-8px, 0, 0) 75 | 76 | .title, 77 | .label, 78 | a:before, 79 | a:after 80 | transition: all 250ms ease-in 81 | 82 | &.-expanded .title, 83 | &.-expanded .label 84 | opacity: 1 85 | transform: translate3d(0, 0, 0) 86 | pointer-events: auto 87 | 88 | // Link styles 89 | a 90 | text-decoration: none 91 | color: $slate 92 | padding: 16px $xpad $xpad $xpad 93 | 94 | .label, 95 | .left .title 96 | color: rgba($slate, 0.5) 97 | 98 | .right .title 99 | margin-right: 0.1em 100 | margin-left: auto 101 | color: $black 102 | 103 | .left a:hover:before, 104 | .right a:hover:after 105 | color: $accent 106 | 107 | a:hover .title 108 | color: $accent 109 | 110 | .left a:before, 111 | .right a:after 112 | display: inline-block 113 | font-size: 20px 114 | vertical-align: middle 115 | position: relative 116 | top: -1px 117 | 118 | .left a:before 119 | ion-icon('chevron-left') 120 | margin-right: 16px 121 | 122 | .right a:after 123 | ion-icon('chevron-right') 124 | margin-left: 16px 125 | -------------------------------------------------------------------------------- /docs/gcp/google-cloud-sql.md: -------------------------------------------------------------------------------- 1 | # Google Cloud SQL 2 | 3 | Deploying a database to Cloud SQL for the WordPress API only requires a bit of configuration to the environment variables and then to run a single `make` command. 4 | 5 | ## Environment Variables 6 | 7 | | Variable | Description | 8 | | :--- | :--- | 9 | | `GCSQL_API_BACKUP_START_TIME` | he start time of daily backups, specified in the 24 hour format - HH:MM, in the UTC timezone. This is the window of time when you would like backups to start. [Learn more](https://cloud.google.com/sql/docs/mysql/instance-settings#backups-and-binary-logging-2ndgen). | 10 | | `GCSQL_API_DATABASE_VERSION` | The database engine type and version. Must be one of: `MYSQL_5_6`, `MYSQL_5_7`. | 11 | | `GCSQL_API_DB_NAME` | Name of the database. | 12 | | `GCSQL_API_DB_PASSWORD` | Password used to access the database. | 13 | | `GCSQL_API_DB_ROOT_PASSWORD` | The database root password. | 14 | | `GCSQL_API_DB_USER` | Username used to access the database. | 15 | | `GCSQL_API_INSTANCE` | Second Generation instance name. Do not include sensitive or personally identifiable information in your instance name; it is externally visible. | 16 | | `GCSQL_API_FAILOVER_REPLICA_NAME` | The name of the failover replica to be created for the new instance. | 17 | | `GCSQL_API_TIER` | The tier for this instance. For Second Generation instances, this is the instance's machine type (e.g., db-n1-standard-1). The machine type determines the number of CPUs and the amount of memory your instance has. [See valid values](https://cloud.google.com/sql/docs/mysql/instance-settings#tier-values). [Learn more](https://cloud.google.com/sql/docs/mysql/instance-settings#machine-type-2ndgen). | 18 | | `GCSQL_API_MAINTENANCE_RELEASE_CHANNEL` | Your preferred timing for instance updates, relative to other instances in the same project. Use `preview` for earlier updates, and `production` for later updates. [Learn more](https://cloud.google.com/sql/docs/mysql/instance-settings#maintenance-timing-2ndgen). | 19 | | `GCSQL_API_MAINTENANCE_WINDOW_DAY` | Day of week for a maintenance window, in the UTC time zone. Must be one of: `SUN`, `MON`, `TUE`, `WED`, `THU`, `FRI`, `SAT`. | 20 | | `GCSQL_API_MAINTENANCE_WINDOW_HOUR` | Hour of day - `0` to `23`. Determines a one-hour window when Cloud SQL can perform disruptive maintenance on your instance. | 21 | | `GCSQL_API_STORAGE_SIZE` | Amount of storage allocated to the instance. Must be an integer number of `GB` between `10GB` and `10230GB` inclusive. | 22 | 23 | ## Deploy 24 | 25 | Create the Cloud SQL database: 26 | 27 | ``` 28 | make api.deploy.sql 29 | ``` 30 | 31 | _This command will create a database instance and failover instance set the root password, create a database for WordPress, and create a user for that database._ -------------------------------------------------------------------------------- /src/css/components/header-nav.styl: -------------------------------------------------------------------------------- 1 | // 2 | // Header 3 | // 4 | 5 | .header-nav 6 | & 7 | font-size: 16px 8 | margin: 12px 9 | 10 | & 11 | position: fixed 12 | top: 0 13 | right: 0 14 | left: 0 15 | height: 40px + $xpad + $xpad 16 | line-height: 40px 17 | text-align: center 18 | 19 | & 20 | opacity: 0 21 | transition: opacity 250ms linear 22 | pointer-events: none 23 | 24 | &.-expanded 25 | opacity: 1 26 | pointer-events: auto 27 | 28 | .left 29 | position: absolute 30 | left: 0 31 | top: 0 32 | text-align: left 33 | 34 | .right 35 | position: absolute 36 | right: 0 37 | top: 0 38 | text-align: right 39 | 40 | .iconlink 41 | position: relative 42 | display: inline-block 43 | vertical-align: middle 44 | height: 32px 45 | line-height: 1em 46 | color: rgba($slate, 0.75) 47 | transition: all 150ms linear 48 | padding: 12px 49 | svg 50 | position: relative 51 | top: 1px 52 | width: 22px 53 | height: 22px 54 | .label 55 | display: none 56 | 57 | .iconlink:hover 58 | color: $accent 59 | .icon 60 | color: #1626ff 61 | svg 62 | fill: #1626ff 63 | 64 | .iconlink 65 | white-space: nowrap 66 | text-decoration: none 67 | 68 | .title, .label 69 | white-space: nowrap 70 | margin: 0 8px 71 | 72 | position: relative 73 | top: -4px 74 | 75 | // Tooltip 76 | .iconlink[data-title]:before 77 | content: attr(data-title) 78 | display: inline-block 79 | position: absolute 80 | bottom: -24px - $xpad 81 | right: $xpad 82 | font-size: 13px 83 | padding: 3px 10px 84 | background: rgba($black, 0.8) 85 | color: white 86 | border: solid 1px rgba($black, 0.2) 87 | border-radius: 2px 88 | text-decoration: none 89 | height: 22px 90 | line-height: 22px 91 | width: auto 92 | white-space: nowrap 93 | pointer-events: none 94 | opacity: 0 95 | transition: opacity 150ms linear, transform 150ms linear 96 | transform: translate3d(0, -8px, 0) 97 | 98 | .iconlink[data-title]:hover:before 99 | opacity: 1 100 | transform: translate3d(0, 0, 0) 101 | pointer-events: auto 102 | 103 | .icon:after 104 | font-size: 24px 105 | width: 32px 106 | height: 32px 107 | text-align: center 108 | 109 | .icon 110 | color: rgba($slate, 0.5) 111 | transition: color 150ms linear 112 | 113 | &.-expanded .icon 114 | color: $black 115 | 116 | .iconlink:hover .icon 117 | color: $accent 118 | 119 | // Icons 120 | .icon.-github:after 121 | ion-icon('social-github') 122 | -------------------------------------------------------------------------------- /src/js/apicheck/index.js: -------------------------------------------------------------------------------- 1 | // Check API component 2 | 3 | function ApiCheck (el) { 4 | var form = el.querySelector('[data-api-check-form]') 5 | var button = el.querySelector('button') 6 | var input = el.querySelector('input[type=text]') 7 | 8 | button.addEventListener('click', handleSubmit) 9 | 10 | function handleSubmit (e) { 11 | e.preventDefault() 12 | var option = form.querySelector('input[type=radio]:checked') 13 | if (option && input.value) { 14 | fetchApi(option.value, input.value) 15 | } 16 | } 17 | 18 | function handleClose (e) { 19 | e.preventDefault() 20 | removeResponse() 21 | } 22 | 23 | function showResponse (msg, status) { 24 | removeResponse() 25 | var pre = document.createElement('pre') 26 | var closeLink = document.createElement('a') 27 | pre.classList.add('api-check__pre') 28 | pre.classList.add(status) 29 | closeLink.setAttribute('href', '#') 30 | closeLink.classList.add('api-check__close') 31 | closeLink.innerText = 'Close' 32 | el.appendChild(pre).innerHTML = syntaxHighlight(msg) 33 | pre.appendChild(closeLink) 34 | closeLink.addEventListener('click', handleClose) 35 | } 36 | 37 | function removeResponse () { 38 | var previousPre = el.querySelector('pre') 39 | if (previousPre) previousPre.remove() 40 | } 41 | 42 | function fetchApi (type, name, cb) { 43 | var req = new XMLHttpRequest() 44 | req.open('GET', 'https://wptide.org/api/tide/v1/audit/wporg/'+ type +'/'+ name, true) 45 | req.onreadystatechange = function () { 46 | if (req.readyState == 4) { 47 | if(req.status == 200) showResponse(JSON.parse(req.responseText), 'success') 48 | else showResponse('The '+type+' you\'re looking for does not exist in our database. Make sure you entered a right name or try to search for something else.', 'error') 49 | } 50 | } 51 | req.send(null) 52 | } 53 | 54 | function syntaxHighlight(json) { 55 | if (typeof json != 'string') { 56 | json = JSON.stringify(json, undefined, 2); 57 | } 58 | 59 | json = json.replace(/&/g, '&').replace(//g, '>'); 60 | 61 | return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) { 62 | var cls = 'hljs-number'; 63 | if (/^"/.test(match)) { 64 | if (/:$/.test(match)) { 65 | cls = 'hljs-attr'; 66 | } else { 67 | cls = 'pl-s'; 68 | } 69 | } else if (/true|false/.test(match)) { 70 | cls = 'pl-c1'; 71 | } else if (/null/.test(match)) { 72 | cls = 'pl-c1'; 73 | } 74 | return '' + match + ''; 75 | }); 76 | } 77 | } 78 | 79 | module.exports = ApiCheck -------------------------------------------------------------------------------- /docs/help.md: -------------------------------------------------------------------------------- 1 | # Help 2 | 3 | ## Failed Audit Request 4 | 5 | If you attempt to audit a theme or plugin without adding a version number to the endpoint, or an invalid version, the API will respond with the following error message. 6 | 7 | ``` 8 | { 9 | "code": "rest_post_invalid_altid_lookup", 10 | "message": "Invalid post lookup.", 11 | "data": { 12 | "status": 404 13 | } 14 | } 15 | ``` 16 | 17 | This also means that if you attempt to view an audit that doesn't exist, you will get the same error. For example, if you try to go to the following endpoint and Tide does not have an audit yet. 18 | 19 | ``` 20 | https://wptide.org/api/tide/v1/audit/wporg/plugin/akismet 21 | ``` 22 | 23 | You would need to initiate an audit for the plugin with the version first: 24 | 25 | ``` 26 | https://wptide.org/api/tide/v1/audit/wporg/plugin/akismet/4.1.1 27 | ``` 28 | 29 | Then the endpoint without a version would work as expected. 30 | 31 | ## Mounts Denied 32 | 33 | If you see the following error in your OS X terminal when bringing up the API you need to add the `/Users` directory to the `Preferences -> File Sharing` section of the Docker for Mac app, or whatever the root directory is for you `$GOPATH`. 34 | 35 | ``` 36 | ERROR: for wptide_api-mysql_1 Cannot start service api-mysql: b'Mounts denied: ...' 37 | ``` 38 | 39 | ## Local Development 40 | 41 | If you run any of the `phpcs` commands on the [Local Development](local-development.md) page and get an error, here are a couple hints that might unblock you. 42 | 43 | ### Bad Substitution 44 | 45 | You get a bad substitution error because your OS doesn't like the `${1:.}` string in the `composer.json`: 46 | 47 | ``` 48 | ./vendor/bin/phpcs ${1:.} --standard=.phpcs.ruleset.xml 49 | sh: 1: Bad substitution 50 | ``` 51 | 52 | Replace both instances of the `${1:.}` string inside the `composer.json` file with either a `.` or `$1`. The `.` will mean that the `composer phpcs filename.php` and `composer phpcbf filename.php` commands will no longer function and you must process every file. However, if you change it to `$1` and it works that means you must always supply a path like `composer phpcs .` or `composer phpcs filname.php` and running the command without a path will fail. 53 | 54 | ### Error Code 55 | 56 | Sometimes your plugin or theme will cause the `phpcs` script to choke and give you back various error codes: 57 | 58 | ``` 59 | Script ./vendor/bin/phpcs ${1:.} --standard=.phpcs.ruleset.xml handling the phpcs event returned with error code 2 60 | ``` 61 | 62 | If that happens you need to troubleshoot the issue by running the `PHPCompatibilityWP` and `WordPress` standards separately to isolate the error. 63 | 64 | ``` 65 | ./vendor/bin/phpcs . --standard=PHPCompatibilityWP --extensions=php --ignore="*/vendor/*,*/node_modules/*" --runtime-set testVersion 5.2- 66 | ``` 67 | 68 | ``` 69 | ./vendor/bin/phpcs . --standard=WordPress --extensions=php --ignore="*/vendor/*,*/node_modules/*" 70 | ``` -------------------------------------------------------------------------------- /docs/gcp/index.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Platform 2 | 3 | If you are going to use any GCP resources for local development or plan to deploy Tide to the cloud, then you will have to install some prerequisites and get everything properly setup first. 4 | 5 | ## Prerequisites 6 | 7 | * Create a new Cloud Project using the [Cloud Console](https://console.cloud.google.com/) 8 | * Enable Billing on that project 9 | * Enable the [Cloud SQL API](https://console.cloud.google.com/flows/enableapi?apiid=sqladmin) 10 | * Enable [App Engine](https://console.cloud.google.com/appengine) 11 | * Create a `service-account.json` 12 | * Install [Google Cloud SDK](https://cloud.google.com/sdk/) 13 | * Install [`gsutil`](https://cloud.google.com/storage/docs/gsutil_install) 14 | 15 | ## Service Account 16 | 17 | Go to the [Credentials](https://console.cloud.google.com/apis/credentials/) section of your project in the Console. Click **Create credentials** and then click **Service account key**. For the Service account, select **App Engine app default service account**. Then click **Create** to generate and download the JSON service account key file to your local machine. Save the file as `service-account.json` in the projects root directory. We will use this file to connect to Google Cloud Platform services and API's like Cloud Storage and Cloud SQL. 18 | 19 | _If **App Engine app default service account** is missing from the list of service accounts, then you haven't activated App Engine for your project or it is still initializing._ 20 | 21 | Deploying to GCP is optional and not required for local development. In this 22 | section we've included some of the basic steps required to get setup on GCP. 23 | 24 | ## Environment Variables 25 | 26 | You are required to create an `.env.gcp` file in the project root. You should also add the correct values to the variables in the `.env` file only if you plan to deploy or test real GCP resources. However, the `.env.gcp` file makes deploying services to GCP a lot easier, since the `.env.gcp` file will override values in the `.env` file to update any YAML deployment files, but not environment variables. 27 | 28 | These three variables are required for both local development and deployments to GCP. 29 | 30 | | Variable | Description | 31 | | :--- | :--- | 32 | | `GCP_PROJECT` | The unique ID of your Google project. Default is `tide-local`. _Note: you must update this value if you plan to use **any** GCP resources, for purely local development the default value will work as-is._ | 33 | | `GCP_REGION` | The [region][regions-and-zones] where all your resources will be created. For example, `us-west1`. | 34 | | `GCP_ZONE` | The preferred [zone][regions-and-zones] in your region that resources will be created, For example, `us-west1-a`. | 35 | 36 | _Remember to add the region you end up using during the `gcloud app create` step on the [Google App Engine](google-app-engine.md) page or you'll be troubleshooting the reason things are not working for hours._ 37 | 38 | [regions-and-zones]: https://cloud.google.com/compute/docs/regions-zones/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Tide Docs 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](CONTRIBUTING.md) [![Shipping faster with ZenHub.io](https://img.shields.io/badge/Shipping_faster_with-ZenHub.io-6567bd.svg?style=flat)](https://www.zenhub.com/) 4 | 5 | Documentation for [wptide.org](http://wptide.org). 6 | 7 | This repo uses a modified version of [Docpress](https://github.com/docpress/docpress) to allow integrating with WordPress. It's a very basic WordPress theme that resolves all routes into the main `index.php` file where they pull the static content generated by Docpress. 8 | 9 | ## Installation 10 | 11 | To develop locally, run: 12 | 1. `git clone` to clone this repo to WordPress theme folder. 13 | 2. `npm install` to install the repo's dependencies. 14 | 3. `npm run link` to link the local docpress packages and install their dependencies. 15 | 4. `npm run dev` to build and watch assets or `npm run build` to just build the assets. 16 | 5. Activate the theme and visit the homepage. 17 | 18 | ## Development Notes 19 | 20 | * `docpress` customized Docpress generator that we bundle with the theme 21 | * `docs` is the root of the content source 22 | * `src` contains all styles, scripts and layout 23 | * `_docpress` is the build folder, never place anything here as it will get overwritten 24 | 25 | ### Contributing 26 | 27 | Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us. 28 | 29 | ### Contact Us 30 | 31 | Have questions? Don't open an Issue, come join us in the [`#tide` channel](https://wordpress.slack.com/messages/C7TK8FBUJ/) in [WordPress Slack](https://make.wordpress.org/chat/). Even though Slack is a chat service, sometimes it takes several hours for community members to respond — please be patient. 32 | 33 | ### Maintainers 34 | 35 | [Derek Herman (@valendesigns)](https://github.com/valendesigns), and 36 | [Jeffrey Paul (@jeffpaul)](https://github.com/jeffpaul) 37 | 38 | ### Credits 39 | 40 | Props: [Arslan Ahmed (@akkspros)](https://github.com/akkspros), 41 | [Bartek Makoś (@MakiBM)](https://github.com/MakiBM), 42 | [Cathi Bosco (@cathibosco)](https://github.com/cathibosco), 43 | [Derek Herman (@valendesigns)](https://github.com/valendesigns), 44 | [Janki Moradiya (@jankimoradiya)](https://github.com/jankimoradiya), 45 | [Jeffrey Paul (@jeffpaul)](https://github.com/jeffpaul), 46 | [Keanan Koppenhaver (@kkoppenhaver)](https://github.com/kkoppenhaver), 47 | [Leo Postovoit (@postphotos)](https://github.com/postphotos), 48 | [Morteza (@man4toman)](https://github.com/man4toman), 49 | [Mukesh Panchal (@mukeshpanchal27)](https://github.com/mukeshpanchal27), 50 | [Otto Kekäläinen (@ottok)](https://github.com/ottok), 51 | [Pierre Gordon (@pierlon)](https://github.com/pierlon), 52 | [Prashant Baldha (@pmbaldha)](https://github.com/pmbaldha), 53 | [Scott Reilly (@coffee2code)](https://github.com/coffee2code) 54 | 55 | ### License 56 | 57 | Tide Docs utilizes an [MIT license](LICENSE). 58 | -------------------------------------------------------------------------------- /src/js/scrollclass/index.js: -------------------------------------------------------------------------------- 1 | var debounce = require('debounce') 2 | var documentHeight = require('dom101/document-height') 3 | var toggleClass = require('dom101/toggle-class') 4 | var scrollTop = require('dom101/scroll-top') 5 | 6 | /** 7 | * Listens for scrolling. 8 | * Available options: 9 | * 10 | * * `parent` (Element) — the parent to listen for scroll events to. Defaults 11 | * to `document.` 12 | * * `className` (String) — classname to apply to the function. 13 | * * `onresize` (Function) — callback to run when the window resizes. Use 14 | * this to cache metrics. 15 | * * `onscroll` (Function) — callback to run when scrolling. When this returns 16 | * true, `className` will be applied; if false, it'll be removed. 17 | */ 18 | 19 | function Scrollclass (el, options) { 20 | if (!(this instanceof Scrollclass)) return new Scrollclass(el, options) 21 | if (!options) options = {} 22 | 23 | this.el = q(el) 24 | this.parent = q(options.parent || document) 25 | this.className = options.className || 'active' 26 | this.onresize = (options.onresize || noop).bind(this) 27 | this.onscroll = (options.onscroll || noop).bind(this) 28 | 29 | this._onscroll = debounce(this.poll.bind(this), 5) 30 | this._onresize = debounce(this.update.bind(this), 5) 31 | 32 | this.listen() 33 | } 34 | 35 | /** 36 | * Fires event listeners. 37 | */ 38 | 39 | Scrollclass.prototype.listen = function () { 40 | window.addEventListener('resize', this._onresize) 41 | window.addEventListener('resize', this._onscroll) 42 | document.addEventListener('load', this._onresize, true) // image events 43 | document.addEventListener('load', this._onscroll, true) 44 | this.parent.addEventListener('scroll', this._onscroll) 45 | this._onresize() 46 | this._onscroll() 47 | } 48 | 49 | /** 50 | * Destroys all event listeners. 51 | */ 52 | 53 | Scrollclass.prototype.destroy = function () { 54 | window.removeEventListener('resize', this._onresize) 55 | window.removeEventListener('resize', this._onscroll) 56 | document.removeEventListener('load', this._onresize, true) 57 | document.removeEventListener('load', this._onscroll, true) 58 | this.parent.removeEventListener('scroll', this._onscroll) 59 | } 60 | 61 | /** 62 | * Internal: Updates data on window resize. This sets some useful stuff that 63 | * Can be used by the `onscroll` handler. 64 | */ 65 | 66 | Scrollclass.prototype.update = function () { 67 | this.documentHeight = documentHeight() 68 | this.winHeight = window.innerHeight 69 | this.maxScroll = this.documentHeight - this.winHeight 70 | this.onresize() 71 | } 72 | 73 | /** 74 | * Internal: scroll handler. 75 | */ 76 | 77 | Scrollclass.prototype.poll = function () { 78 | var result = this.onscroll(scrollTop()) 79 | toggleClass(this.el, this.className, result) 80 | } 81 | 82 | function noop () {} 83 | 84 | /** 85 | * Internal: helper to normalize between CSS selectors, DOM elements and 86 | * jQuery objects. 87 | */ 88 | 89 | function q (el) { 90 | if (typeof el === 'string') return document.querySelector(el) 91 | else if (typeof el === 'object' && el[0]) return el[0] 92 | else return el 93 | } 94 | 95 | module.exports = Scrollclass 96 | -------------------------------------------------------------------------------- /docs/code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at support@wptide.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at support@wptide.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /src/layout.pug: -------------------------------------------------------------------------------- 1 | //- Menu: 2 | //- renders the menu item recursively 3 | 4 | mixin menu(m, depth) 5 | li.menu-item(class=('-level-' + depth + (m.sections ? ' -parent' : ''))) 6 | if m.url 7 | a.link.title(href=(m.url + (m.anchor || '')) class=((active === m.url && !m.anchor ? '-active' : '') + (' link-' + m.slug)))= m.title 8 | else if m.title 9 | span.title= m.title 10 | 11 | //- Headings 12 | if m.headings && m.url === active && !m.expand && !m.anchor 13 | ul.headings.heading-list 14 | - for (var key in m.headings) 15 | +heading(m.headings[key], 0) 16 | 17 | //- Sub-pages 18 | if m.sections 19 | ul.submenu 20 | - for (var key in m.sections) 21 | +menu(m.sections[key], depth + 1) 22 | 23 | //- Headings as subpages 24 | if m.headings && m.url === active && m.expand && !m.anchor 25 | - for (var key in m.headings) 26 | +heading-menu(m.headings[key], depth) 27 | 28 | //- Heading: 29 | //- renders the heading item recursively 30 | 31 | mixin heading(h, depth) 32 | li.heading-item(class=('-depth-' + h.depth)) 33 | a.hlink(href=('#' + h.id) class=('link-' + h.id)) 34 | = h.title 35 | if h.headings 36 | ul.heading-list(class=('-depth-' + h.depth)) 37 | - for (var key in h.headings) 38 | +heading(h.headings[key], depth + 1) 39 | 40 | //- Heading-menu: 41 | //- Renders the heading item recursively, but in the markup of a regular menu. 42 | //- Used for single-page sites 43 | 44 | mixin heading-menu(h, depth) 45 | li.menu-item(class=('-level-' + depth + (h.headings ? ' -parent' : ''))) 46 | a.link.title(href=('#' + h.id) class=('link-' + h.id)) 47 | = h.title 48 | if h.headings 49 | ul.submenu 50 | - for (var key in h.headings) 51 | +heading-menu(h.headings[key], depth + 1) 52 | 53 | //- 54 | //- Heading 55 | //- 56 | 57 | mixin header-nav 58 | .header-nav 59 | .right 60 | a.iconlink(href='https://github.com/wptide/docs', data-title='wptide/docs' title='GitHub') 61 | span.icon.-github 62 | a.iconlink(href='https://make.wordpress.org/tide/', data-title='make.wordpress.org/tide' title='WordPress') 63 | 64 | 65 | mixin footer-nav(prev, next) 66 | if prev || next 67 | .footer-nav 68 | if prev 69 | .left 70 | a(href=prev.url) 71 | span.title= prev.pageTitle 72 | if next 73 | .right 74 | a(href=next.url) 75 | span.label= "Next: " 76 | span.title= next.pageTitle 77 | 78 | //- 79 | //- Content 80 | //- 81 | 82 | .doc-layout 83 | .toggle.menu-toggle.js-menu-toggle 84 | ul.menu.toc-menu 85 | +menu(toc, 0) 86 | .body(class=('page-' + slug)) 87 | +header-nav 88 | .markdown-body 89 | != contents.replace(/.html/g, '') 90 | 91 | +footer-nav(prev, next) 92 | -------------------------------------------------------------------------------- /docs/contributing.md: -------------------------------------------------------------------------------- 1 | # Tide Contributing Guide 2 | 3 | There are many ways to contribute to Tide. You can help us champion the adoption of quality testing results in the WordPress project. You can also help by contributing code or documentation to Tide itself. 4 | 5 | Note that you can also contribute to [WordPress meta](https://make.wordpress.org/meta/handbook/documentation/contributing-with-git/) to improve the WordPress plugin directory. 6 | 7 | Before submitting your contribution, please make sure to take a moment and read through the following guidelines. 8 | 9 | ## Code of Conduct 10 | 11 | This project and everyone participating in it is governed by the [Tide Code of Conduct](code-of-conduct.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to support@wptide.org. 12 | 13 | ## Issue Reporting Guidelines 14 | 15 | - The Issue list of this repo is **exclusively** for bug reports and feature requests. 16 | - Try to search for your issue, it may have already been answered or even fixed in the `develop` branch. 17 | - Check if the issue is reproducible with the latest stable version. If you are using a pre-release, please indicate the specific version you are using. 18 | - It is **required** that you clearly describe the steps necessary to reproduce the issue you are running into. Issues without clear reproducible steps will be closed immediately. 19 | - If your issue is resolved but still open, don't hesitate to close it. In case you found a solution by yourself, it could be helpful to explain how you fixed it. 20 | 21 | ## Pull Request Guidelines 22 | 23 | - Checkout a topic branch from `develop` and merge back against `develop`. 24 | - If you are not familiar with branching please read [_A successful Git branching model_](http://nvie.com/posts/a-successful-git-branching-model/) before you go any further. 25 | - If adding a new feature: 26 | - Add accompanying test case. 27 | - Provide convincing reason to add this feature. Ideally you should open a suggestion issue first and have it green-lit before working on it. 28 | - If fixing a bug: 29 | - Provide detailed description of the bug in the PR. Live demo preferred. 30 | - Add appropriate test coverage if applicable. 31 | 32 | Travis CI will run the unit tests whenever you push changes to your PR. Tests are required to pass successfully for a merge to be considered. 33 | 34 | ## Profile Badges 35 | 36 | As outlined in [the announcement post](https://make.wordpress.org/tide/2019/06/20/tide-profile-badges/), badges related to work on Tide are awarded as follows: 37 | 38 | ### Tide Team 39 | 40 | ![](images/Tide-Team.png) 41 | 42 | The Tide Team badge will be manually assigned to all active Tide maintainers – i.e those who are listed as “Maintainers” on [this page](https://github.com/wptide/wptide#maintainers) (also [here](https://github.com/wptide/docs#maintainers)). 43 | 44 | ### Tide Contributor 45 | 46 | ![](images/Tide-Contributor.png) 47 | 48 | The Tide Contributor badge will be manually assigned to those who provide valuable contributions to Tide -- i.e. those who are listed as “Contributors” on [this page](https://github.com/wptide/wptide#contributors) (also [here](https://github.com/wptide/docs#credits), [here](https://github.com/wptide/pkg#props), and [here](https://github.com/wptide/wp-tide-api#props)). 49 | 50 | *The easiest way to have the Tide Team or Tide Contributor badges assigned to you is for you to request them (the system doesn’t allow us to add the badge to your profile until you submit a request). To make this request please go the [Tide Team](https://profiles.wordpress.org/associations/tide-team/) or [Tide Contributor](https://profiles.wordpress.org/associations/tide-contributor/) pages and request membership for the group.* 51 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Tide Contributing Guide 2 | 3 | There are many ways to contribute to Tide. You can help us champion the adoption of quality testing results in the WordPress project. You can also help by contributing code or documentation to Tide itself. 4 | 5 | Note that you can also contribute to [WordPress meta](https://make.wordpress.org/meta/handbook/documentation/contributing-with-git/) to improve the WordPress plugin directory. 6 | 7 | Before submitting your contribution, please make sure to take a moment and read through the following guidelines. 8 | 9 | ## Code of Conduct 10 | 11 | This project and everyone participating in it is governed by the [Tide Code of Conduct](code-of-conduct.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to support@wptide.org. 12 | 13 | ## Issue Reporting Guidelines 14 | 15 | - The Issue list of this repo is **exclusively** for bug reports and feature requests. 16 | - Try to search for your issue, it may have already been answered or even fixed in the `develop` branch. 17 | - Check if the issue is reproducible with the latest stable version. If you are using a pre-release, please indicate the specific version you are using. 18 | - It is **required** that you clearly describe the steps necessary to reproduce the issue you are running into. Issues without clear reproducible steps will be closed immediately. 19 | - If your issue is resolved but still open, don't hesitate to close it. In case you found a solution by yourself, it could be helpful to explain how you fixed it. 20 | 21 | ## Pull Request Guidelines 22 | 23 | - Checkout a topic branch from `develop` and merge back against `develop`. 24 | - If you are not familiar with branching please read [_A successful Git branching model_](http://nvie.com/posts/a-successful-git-branching-model/) before you go any further. 25 | - If adding a new feature: 26 | - Add accompanying test case. 27 | - Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first and have it green-lit before working on it. 28 | - If fixing a bug: 29 | - Provide a detailed description of the bug in the PR. Live demo preferred. 30 | - Add appropriate test coverage if applicable. 31 | 32 | Travis CI will run the unit tests whenever you push changes to your PR. Tests are required to pass successfully for a merge to be considered. 33 | 34 | ## Profile Badges 35 | 36 | As outlined in [the announcement post](https://make.wordpress.org/tide/2019/06/20/tide-profile-badges/), badges related to work on Tide are awarded as follows: 37 | 38 | ### Tide Team 39 | 40 | ![](docs/images/Tide-Team.png) 41 | 42 | The Tide Team badge will be manually assigned to all active Tide maintainers – i.e those who are listed as “Maintainers” on [this page](https://github.com/wptide/wptide#maintainers) (also [here](https://github.com/wptide/docs#maintainers)). 43 | 44 | ### Tide Contributor 45 | 46 | ![](docs/images/Tide-Contributor.png) 47 | 48 | The Tide Contributor badge will be manually assigned to those who provide valuable contributions to Tide -- i.e. those who are listed as “Contributors” on [this page](https://github.com/wptide/wptide#contributors) (also [here](https://github.com/wptide/docs#credits), [here](https://github.com/wptide/pkg#props), and [here](https://github.com/wptide/wp-tide-api#props)). 49 | 50 | *The easiest way to have the Tide Team or Tide Contributor badges assigned to you is for you to request them (the system doesn’t allow us to add the badge to your profile until you submit a request). To make this request please go the [Tide Team](https://profiles.wordpress.org/associations/tide-team/) or [Tide Contributor](https://profiles.wordpress.org/associations/tide-contributor/) pages and request membership for the group.* 51 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | is_404 = false; 81 | } 82 | } ); 83 | 84 | /** 85 | * Filter to override a 404. 86 | * 87 | * The links are actually 404 errors, the pages don't exist really. We're faking status 200 88 | * We just use the routes to pass in info on what file we want to include within index.php. 89 | */ 90 | add_filter( 'body_class', function( $classes ) { 91 | global $wp_query; 92 | 93 | if ( strpos( DOCS_FILE_PATH, '404.html' ) !== false && file_exists( DOCS_FILE_PATH ) ) { 94 | $classes[] = 'error404'; 95 | } 96 | 97 | if ( strpos( DOCS_FILE_PATH, 'search.html' ) !== false && file_exists( DOCS_FILE_PATH ) ) { 98 | $classes[] = 'is-search'; 99 | } 100 | 101 | return $classes; 102 | } ); 103 | 104 | /** 105 | * Add GA tracking code to the HEAD. 106 | */ 107 | add_action( 'wp_head', function() { 108 | if ( strpos( get_home_url(), 'wptide.org' ) !== false ) { ?> 109 | 110 | 111 | 112 | 118 | 119 | 39 | 40 | Custom ruleset for the {{NAME}} plugin. 41 | 42 | 43 | 44 | 45 | 46 | . 47 | 49 | /vendor/* 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 60 | 61 | 62 | 64 | 65 | 66 | 68 | 69 | 70 | 71 | 72 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | ``` 86 | 87 | ## Usage 88 | 89 | Run the PHP Code Sniffer on every file: 90 | 91 | ``` 92 | composer phpcs 93 | ``` 94 | 95 | Run the PHP Code Sniffer on a single file: 96 | 97 | ``` 98 | composer phpcs filename.php 99 | ``` 100 | 101 | Run PHP Code Beautifier on every file: 102 | 103 | ``` 104 | composer phpcbf 105 | ``` 106 | 107 | Run PHP Code Beautifier on a single file: 108 | 109 | ``` 110 | composer phpcbf filename.php 111 | ``` 112 | 113 | _If you get an error when running these commands see the [Help](help.md#local-development) page._ 114 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/docs/premise.md: -------------------------------------------------------------------------------- 1 | # Premise 2 | 3 | Onmount is a safe, reliable, idempotent, and testable way to attach JavaScript behaviors to DOM nodes. It's great for common websites that are not Single-Page Apps, and it goes hand-in-hand with Turbolinks. 4 | 5 | #### Once and only once 6 | 7 | It solves many problems that crop up on sites where the DOM changes often, such as when using with Turbolinks or Pjax. Onmount assures you that each behavior is only applied *once* to an element and never again so you don't get duplicate event handlers and such. This is a concept called [idempotence]. 8 | 9 | [idempotence]: https://en.wikipedia.org/wiki/Idempotence 10 | 11 | #### Testability 12 | 13 | Onmount allows you to re-run certain behaviors. This is great for making isolated unit tests of your code. 14 | 15 | #### Reusable 16 | 17 | Code written in `onmount` blocks operate in the context of a single DOM element. It can be applied again other DOM elements later on and will be running in isolation from other instances. 18 | 19 | ## Example 20 | 21 | Let's build a navigation with some elements hidden under a *more...* button. Given this HTML snippet: 22 | 23 | ```html 24 |
25 | Home 26 | Inbox 27 | Messages 28 | 29 |
30 | Help 31 | Support 32 |
33 | 34 | 35 |
36 | ``` 37 | 38 | To make this work, you'll typically write JavaScript code like this: 39 | 40 | ```js 41 | $(function () { 42 | $('.js-expandable-nav button').on('click', function () { 43 | $('.js-expandable-nav .more').show() 44 | $('.js-expandable-nav button').hide() 45 | }) 46 | }) 47 | ``` 48 | 49 | ## Problems 50 | 51 | However, you have a few problems with this approach. 52 | 53 | - **Not testable** — You can't make unit tests from this code. To test this, you will need to load the entire page, simulate a click, and see if it worked. There's no easy way to test it in isolation. 54 | - **Not reusable** — When there are 2 `.js-expandable-nav` elements on the page, this will break. This isn't a concern at first, but it certainly hampers code reusability. 55 | - **Not for dialog boxes** — Since it triggers on a `document.ready` event, it doesn't work on elements loaded later. There's no easy way to retrigger this code, either, which you would want to do for when content is loaded remotely (like in a dialog box). 56 | - **No cleanups** — What happens when `.js-expandable-nav` exits the DOM (eg, the dialog box was closed)? In a more complex scenario, you will want to do cleanup such as unbinding event handlers. 57 | 58 | ## Solution 59 | 60 | By writing your code in an `onmount` block, this will solve the issues above. You don't write your code any differently, but it will be accessible in a way that it's testable, isolated, and idempotent. 61 | 62 | ```js 63 | /* 64 | * attach a behavior to `.js-expandable-nav` 65 | */ 66 | 67 | $.onmount('.js-expandable-nav', function () { 68 | var $this = $(this) 69 | var $button = $this.find('button') 70 | var $more = $this.find('.more') 71 | 72 | $button.on('click', function () { 73 | $more.toggle() 74 | $button.hide() 75 | }) 76 | }) 77 | ``` 78 | 79 | This block is called a *behavior*—that is, a piece of JavaScript that defines what dynamic behavior happens (eg, the menu expands on button click) for a given selector (eg, `.js-expandable-nav`). This is a concept first seen in legacy IE as [DHTML behaviors]. 80 | 81 | [DHTML behaviors]: https://msdn.microsoft.com/en-us/library/ms531079%28v=vs.85%29.aspx 82 | 83 | ```js 84 | /* 85 | * initializes behaviors on jQuery document.ready, Turbolinks page:change, and 86 | * on bootstrap modal show. 87 | */ 88 | 89 | $(document).on('ready page:change show.bs.modal', function () { $.onmount() }) 90 | ``` 91 | 92 | ## Benefits 93 | 94 | By simply wrapping your code in `$.onmount(...)` instead of `$(function)` (aka `document.ready`), it gives you the power of a few features: 95 | 96 | * **Idempotent** — You're assured that the block will only run once for every `.js-expandable-nav` element. If it has been applied before, it will not apply again. 97 | * **Reusable** — You can retrigger this behavior for tests. This allows you to create an isolated test for the behavior. 98 | * **Reusable** — You can call behaviors again and again (`$.onmount()`) every time your DOM changes to make it work for any new elements. This is useful for in-page transitions with Turbolinks or Pjax, or dynamically-loaded content such as modal boxes. 99 | -------------------------------------------------------------------------------- /docs/services/sync-server.md: -------------------------------------------------------------------------------- 1 | # Sync server 2 | 3 | The Sync Server is a Go binary installed on an Alpine Linux Docker image that polls the wp.org API's for themes and plugins to process and writes them to a queue. 4 | 5 | Unless you have good reason to set the `SYNC_ACTIVE` environment variable to `on` you should leave the server set to `off` and not bring up the container by running `make sync.up`. Turning on the Sync Server will put around 50k audits in the queue and will take days to process locally and potentially lock up all your computers resources. A better way to audit wp.org themes and plugins would be to follow the instructions found in the [Run Audits](../installation/setup.md#run-audits) section of the setup page. 6 | 7 | If you do decide that you would like to seed the queue with plugins and themes, or are testing changes you've made to the Go binary, you can run `make sync.up` for a second or two and then in a different shell run `make sync.down` which should add a few hundred items to the queue. 8 | 9 | ## Environment Variables 10 | 11 | | Variable | Description | 12 | | :--- | :--- | 13 | | `SYNC_ACTIVE` | Whether the Sync Server is active or not. Must be one of: `on`, `off`. Default is `off`. | 14 | | `SYNC_API_BROWSE_CATEGORY` | The API category used to ingest the wp.org themes and plugins. Must be one of: `popular`, `featured`, `updated`, `new`. Default is `updated`. | 15 | | `SYNC_DATA` | When the database provider is set to `local` this will be where the data is stored relative to the `/srv/data` working directory. Default is `./db`. | 16 | | `SYNC_DATABASE_DOCUMENT_PATH` | When the database provider is set to `firestore` this value is the path to the document in Cloud Firestore. Must be in the form of `/`. Default is `sync-server/wporg`. | 17 | | `SYNC_DATABASE_PROVIDER` | Tells the Sync Server which database provider to use; either the local file system or Google Cloud Firestore. Must be one of: `local`, `firestore`. Default is `local`. | 18 | | `SYNC_DEFAULT_CLIENT` | The API client used to make requests by the audit servers; also associated with the key and secret those server use. Default is `wporg`. | 19 | | `SYNC_DEFAULT_VISIBILITY` | The audit and report visibility. Must be one of: `public`, `private`. Default is `public`. | 20 | | `SYNC_FORCE_AUDITS` | Forces audit reports to be generated even if a report exists for the checksum and standard. Must be one of: `yes`, `no`. Default is `no`. | 21 | | `SYNC_ITEMS_PER_PAGE` | The number of plugins or themes per page in the API request. Default is `250`. | 22 | | `SYNC_LH_ACTIVE` | Send messages to the Lighthouse SQS queue. Must be one of: `on`, `off`. Default is `on`. | 23 | | `SYNC_MESSAGE_PROVIDER` | Queue audit messages using the local MongoDB, Google Cloud Firestore, or AWS SQS. Must be one of: `local`, `firestore`, `sqs`. Default is `local`. | 24 | | `SYNC_PHPCS_ACTIVE` | Send messages to the PHPCS SQS queue. Must be one of: `on`, `off`. Default is `on`. | 25 | | `SYNC_POOL_DELAY` | The wait time in seconds between the wp.org theme and plugin ingests. Default is `600`. | 26 | | `SYNC_POOL_WORKERS` | The number of workers (concurrent goroutines) the server will create to ingest the wp.org API. Default is `125`. | 27 | 28 | ## Commands 29 | 30 | | Command | Description | 31 | | :--- | :--- | 32 | | `make sync.build.bin` | Build the Sync Server Go binary. | 33 | | `make sync.clean.bin` | Clean the Sync Server Go binary. | 34 | | `make sync.build.image` | Build the Sync Server Docker image. | 35 | | `make sync.build.up` | Rebuild the Sync Server Docker image & run the container in isolation with docker-compose up. | 36 | | `make sync.up` | Run the Sync Server Docker container in isolation with docker-compose up. | 37 | | `make sync.down` | Take the isolated Sync Server Docker container down. | 38 | | `make sync.stop` | Stop the isolated Sync Server Docker container with docker-compose stop. | 39 | | `make sync.rm` | Remove the stopped Sync Server Docker container with docker-compose rm. | 40 | | `make sync.push.image` | Push the Sync Server Docker image to GCR. | 41 | | `make sync.clean.image` | Clean the Sync Server Docker image from the host machine. | 42 | | `make sync.build.disk` | Build the Sync Server GKE persistent disk. | 43 | | `make sync.build.cluster` | Build the Sync Server GKE cluster. | 44 | | `make sync.creds` | Get the Sync Server GKE cluster credentials. | 45 | | `make sync.tpl` | Generate the Sync Server GKE YAML template. | 46 | | `make sync.deploy.cluster` | Deploy the Sync Server GKE cluster. | 47 | | `make sync.get.cluster` | Get the Sync Server GKE cluster status. | 48 | | `make sync.clean.cluster` | Clean the Sync Server GKE cluster. | -------------------------------------------------------------------------------- /docs/gcp/google-kubernetes-engine.md: -------------------------------------------------------------------------------- 1 | # Google Kubernetes Engine 2 | 3 | All the goroutines are deployed to a Kubernetes cluster with the same basic steps, but first a bit of configuration to the environment variables for each server is required. 4 | 5 | ## Environment Variables 6 | 7 | ### Lighthouse Server 8 | 9 | | Variable | Description | 10 | | :--- | :--- | 11 | | `GKE_LH_CLUSTER` | The name of the cluster. Default is`lighthouse-server`. | 12 | | `GKE_LH_CLUSTER_VERSION` | The Kubernetes version to use for the master and nodes. You can check which Kubernetes versions are default and available in a given zone by running the following command: | 13 | | | `gcloud container get-server-config --zone [COMPUTE-ZONE]` | 14 | | `GKE_LH_CPU_PERCENT` | The average percent CPU utilization across all pods. Must be a range of `1-100`. | 15 | | `GKE_LH_DISK_SIZE` | Size in GB for node VM boot disks. An example value is `100`. | 16 | | `GKE_LH_IMAGE` | The name of the Docker image. Default is`lighthouse-server`. | 17 | | `GKE_LH_MACHINE_TYPE` | The type of machine to use for nodes. An example value is `n1-standard-1`. | 18 | | `GKE_LH_MAX_NODES` | Maximum number of nodes to which the node pool can scale. | 19 | | `GKE_LH_MAX_PODS` | Maximum number of Pods you want to run based on the CPU utilization of your existing Pods. | 20 | | `GKE_LH_MIN_NODES` | Minimum number of nodes to which the node pool can scale. | 21 | | `GKE_LH_MIN_PODS` | Minimum number of Pods you want to run based on the CPU utilization of your existing Pods. | 22 | | `GKE_LH_NUM_NODES` | The number of nodes to be created in each of the cluster's zones. | 23 | | `GKE_LH_REPLICAS` | The number of desired Pods in the initial deployment. | 24 | 25 | ### PHPCS Server 26 | 27 | | Variable | Description | 28 | | :--- | :--- | 29 | | `GKE_PHPCS_CLUSTER` | The name of the cluster. Default is `phpcs-server`. | 30 | | `GKE_PHPCS_CLUSTER_VERSION` | The Kubernetes version to use for the master and nodes. You can check which Kubernetes versions are default and available in a given zone by running the following command: | 31 | | | `gcloud container get-server-config --zone [COMPUTE-ZONE]` | 32 | | `GKE_PHPCS_CPU_PERCENT` | The average percent CPU utilization across all pods. Must be a range of `1-100`. | 33 | | `GKE_PHPCS_DISK_SIZE` | Size in GB for node VM boot disks. An example value is `100`. | 34 | | `GKE_PHPCS_IMAGE` | The name of the Docker image. Default is `phpcs-server`. | 35 | | `GKE_PHPCS_MACHINE_TYPE` | The type of machine to use for nodes. An example value is `n1-standard-1`. | 36 | | `GKE_PHPCS_MAX_NODES` | Maximum number of nodes to which the node pool can scale. | 37 | | `GKE_PHPCS_MAX_PODS` | Maximum number of Pods you want to run based on the CPU utilization of your existing Pods. | 38 | | `GKE_PHPCS_MIN_NODES` | Minimum number of nodes to which the node pool can scale. | 39 | | `GKE_PHPCS_MIN_PODS` | Minimum number of Pods you want to run based on the CPU utilization of your existing Pods. | 40 | | `GKE_PHPCS_NUM_NODES` | The number of nodes to be created in each of the cluster's zones. | 41 | | `GKE_PHPCS_REPLICAS` | The number of desired Pods in the initial deployment. | 42 | 43 | ### Sync Server 44 | 45 | | Variable | Description | 46 | | :--- | :--- | 47 | | `GKE_SYNC_CLUSTER` | The name of the cluster. Default is `sync-server`. | 48 | | `GKE_SYNC_CLUSTER_VERSION` | The Kubernetes version to use for the master and nodes. You can check which Kubernetes versions are default and available in a given zone by running the following command: | 49 | | | `gcloud container get-server-config --zone [COMPUTE-ZONE]` | 50 | | `GKE_SYNC_DISK_SIZE` | Size in GB for node VM boot disks. An example value is `100`. | 51 | | `GKE_SYNC_IMAGE` | The name of the Docker image. Default is `sync-server`. | 52 | | `GKE_SYNC_MACHINE_TYPE` | The type of machine to use for nodes. An example value is `n1-standard-1`. | 53 | | `GKE_SYNC_PERSISTENT_DISK_TYPE` | Type of persistent disk. Must be one of: `pd-standard`, `pd-ssd`. | 54 | | `GKE_SYNC_PERSISTENT_DISK_SIZE` | Size in GB for the persistent disk. An example value is `100GB`. | 55 | 56 | ## Deploy 57 | 58 | Once you've got the variables setup it's basically push the image to Google Container Registry (GCR), create the Kubernetes cluster, and then create a Kubernetes deployment. I'll demonstrate it with the PHPCS Server. Other than specific `make` commands for each service, these steps are all the same. 59 | 60 | Push the image to GCR: 61 | 62 | ``` 63 | make phpcs.push.image 64 | ``` 65 | 66 | Create the GKE cluster: 67 | 68 | ``` 69 | make phpcs.build.cluster 70 | ``` 71 | 72 | Deploy the GKE cluster: 73 | 74 | ``` 75 | make phpcs.deploy.cluster 76 | ``` 77 | 78 | Delete the GKE cluster: 79 | 80 | ``` 81 | make phpcs.clean.cluster 82 | ``` -------------------------------------------------------------------------------- /docpress/docpress-core/fixture/onmount/README.md: -------------------------------------------------------------------------------- 1 | # onmount 2 | 3 | **Run something when a DOM element appears and when it exits.**
4 | No dependencies. Legacy IE compatible. 1kb .min.gz. 5 | 6 | [![Status](https://travis-ci.org/rstacruz/onmount.svg?branch=master)](https://travis-ci.org/rstacruz/onmount "See test builds") 7 | 8 |
9 | 10 | ## Overview 11 | 12 | **Detecting elements:** 13 | Run something to initialize an element on its first appearance. 14 | 15 | ```js 16 | onmount = require('onmount') 17 | 18 | onmount('.push-button', function () { 19 | $(this).on('click', function () { 20 | alert('working...') 21 | }) 22 | }) 23 | ``` 24 | 25 | **Polling for changes:** 26 | Call `$.onmount()` everytime your code changes. 27 | [(more...)](/docs/idempotency.md) 28 | [(automatic?)](/docs/automatic-observation.md) 29 | 30 | ```js 31 | $('') 32 | .appendTo('body') 33 | 34 | $.onmount() 35 | 36 | $(".push-button").click() //=> 'working...' 37 | ``` 38 | 39 | **jQuery integration:** 40 | jQuery is optional; use it to poll on popular events. [(more...)](/docs/idempotency.md) 41 | 42 | ```js 43 | $(document).on('ready show.bs closed.bs load page:change', function () { 44 | $.onmount() 45 | }) 46 | ``` 47 | 48 | **Cleanups:** 49 | Supply a 2nd function to *onmount()* to execute something when the node is first detached. 50 | [(more...)](/docs/cleanup.md) 51 | 52 | ```js 53 | $.onmount('.push-button', function () { 54 | /*...*/ 55 | }, function () { 56 | alert('button was removed') 57 | }) 58 | 59 | document.body.innerHTML = '' 60 | 61 | $.onmount() //=> 'button was removed' 62 | ``` 63 | 64 |
65 | 66 | ## What for? 67 | 68 | Onmount is a safe, reliable, idempotent, and testable way to attach JavaScript behaviors to DOM nodes. It's great for common websites that are not Single-Page Apps. Read: 69 | 70 | - [Premise](/docs/premise.md) 71 | - [rsjs][rsjs] (Reasonable System for JavaScript Structure) 72 | 73 |
74 | 75 | ## Usage 76 | 77 | ``` 78 | npm install onmount 79 | bower install onmount 80 | ``` 81 | 82 | ```js 83 | // With CommonJS/AMD (ie, Browserify): 84 | onmount = require('onmount') 85 | 86 | // with no module loaders: 87 | window.onmount 88 | 89 | // with jQuery: 90 | $.onmount 91 | ``` 92 | 93 | [Bootstrap events]: http://getbootstrap.com/javascript/ 94 | [Turbolinks load]: https://github.com/rails/turbolinks#events 95 | [idempotent]: https://en.wiktionary.org/wiki/idempotent 96 | [Browserify]: http://browserify.org/ 97 | 98 | 99 |
100 | 101 | ## API 102 | 103 | * `onmount()` 104 | 105 | > Runs all behaviors. 106 | > 107 | > When used with jQuery, this can be passed as an event handler, eg, `$(onmount)` or `$(document).on('load', onmount)`. 108 | 109 | * `onmount(selector)` 110 | 111 | > Runs all behaviors registered for `selector`. 112 | 113 | * `onmount(selector, init())` 114 | 115 | > Registers a behavior for `selector` to run the callback `init()`. 116 | 117 | * `onmount(selector, init(b), exit(b))` 118 | 119 | > Registers a behavior for `selector` to run the callback `init()`. The `exit()` callback will be called once the behavior is triggered again but the element is no longer attached to the DOM. 120 | > 121 | > The callbacks are passed an object `b`, and the same object is passed for both `init` and `exit`. This allows them to communicate and keep aware of the state. 122 | > 123 | > An ID is also provided, `b.id`, which is guaranteed unique for every behavior-element pair. 124 | 125 | * `onmount.reset()` 126 | 127 | > Clears all defined behaviors. Useful for tests. 128 | 129 | * `onmount.observe()` 130 | 131 | > Automatically invoke when new DOM elements appear using MutationObserver API. Returns `true` if it succeeds. 132 | 133 | * `onmount.unobserve()` 134 | 135 | > Turns off observation previously turned on via `onmount.observe()`. 136 | 137 | * `onmount.debug` 138 | 139 | > Set this to `true` to see debug messages. 140 | 141 |
142 | 143 | ## Browser compatibility 144 | 145 | All modern browsers and IE8+. For legacy IE, use it with jQuery 1.x. 146 | 147 | Try the [test suite](https://rawgit.com/rstacruz/onmount/master/test/index.html) in your browser. Try it [with jQuery 1.x](https://rawgit.com/rstacruz/onmount/master/test/jquery.html) for legacy browsers. 148 | 149 |
150 | 151 | ## Read more 152 | 153 | * [Read documentation →](http://ricostacruz.com/onmount/) 154 | * [See examples →](https://github.com/rstacruz/onmount/examples) 155 | 156 |
157 | 158 | ## Thanks 159 | 160 | **onmount** © 2015+, Rico Sta. Cruz. Released under the [MIT] License.
161 | Authored and maintained by Rico Sta. Cruz with help from contributors ([list][contributors]). 162 | 163 | > [ricostacruz.com](http://ricostacruz.com)  ·  164 | > GitHub [@rstacruz](https://github.com/rstacruz)  ·  165 | > Twitter [@rstacruz](https://twitter.com/rstacruz) 166 | 167 | [MIT]: http://mit-license.org/ 168 | [contributors]: http://github.com/rstacruz/onmount/contributors 169 | [rsjs]: https://github.com/rstacruz/rsjs 170 | 171 | [![](https://img.shields.io/badge/%E2%9C%93-collaborative_etiquette-brightgreen.svg)](http://git.io/col) 172 | -------------------------------------------------------------------------------- /docpress/docpress-base/fixture/onmount/README.md: -------------------------------------------------------------------------------- 1 | # onmount 2 | 3 | Run something when a DOM element appears and when it exits.
4 | No dependencies. Legacy IE compatible. 1kb .min.gz. 5 | 6 | [![Status](https://travis-ci.org/rstacruz/onmount.svg?branch=master)](https://travis-ci.org/rstacruz/onmount "See test builds") 7 | 8 | ## Overview 9 | 10 | #### Detecting elements 11 | 12 | Run something to initialize an element on its first appearance. 13 | 14 | ```js 15 | onmount = require('onmount') 16 | 17 | onmount('.push-button', function () { 18 | $(this).on('click', function () { 19 | alert('working...') 20 | }) 21 | }) 22 | ``` 23 | 24 | #### Polling for changes 25 | 26 | Call `$.onmount()` everytime your code changes. 27 | [→](/docs/idempotency.md) 28 | 29 | ```js 30 | $('') 31 | .appendTo('body') 32 | 33 | $.onmount() 34 | 35 | $(".push-button").click() //=> 'working...' 36 | ``` 37 | 38 | #### jQuery integration 39 | 40 | jQuery is optional; use it to poll on popular events. 41 | [→](/docs/idempotency.md) 42 | 43 | ```js 44 | $(document).on('ready show.bs closed.bs load page:change', function () { 45 | $.onmount() 46 | }) 47 | ``` 48 | 49 | #### Cleanups 50 | 51 | Supply a 2nd function to *onmount()* to execute something when the node is first detached. 52 | [→](/docs/cleanup.md) 53 | 54 | ```js 55 | $.onmount('.push-button', function () { 56 | /*...*/ 57 | }, function () { 58 | alert('button was removed') 59 | }) 60 | 61 | document.body.innerHTML = '' 62 | 63 | $.onmount() //=> 'button was removed' 64 | ``` 65 | 66 | ## What for? 67 | 68 | Onmount is a safe, reliable, idempotent, and testable way to attach JavaScript behaviors to DOM nodes. It's great for common websites that are not Single-Page Apps. Read more on its [premise and motivation](docs/premise.md). 69 | 70 | [rsjs][rsjs] (Reasonable System for JavaScript Structure) is a great standard that onmount fits perfectly into. 71 | 72 | ## Usage 73 | 74 | Onmount is available via [npm](https://www.npmjs.com/package/onmount) and Bower. 75 | 76 | ``` 77 | npm install onmount 78 | bower install onmount 79 | ``` 80 | 81 | ### Usage info 82 | 83 | It can be used as a CommonJS module or on its own. It doesn't require jQuery, but if jQuery is found, it'll attach itself to it as `$.onmount`. 84 | 85 | ```js 86 | onmount = require('onmount') // With CommonJS (ie, Browserify) 87 | window.onmount // with no module loaders: 88 | $.onmount // with jQuery 89 | ``` 90 | 91 | [Bootstrap events]: http://getbootstrap.com/javascript/ 92 | [Turbolinks load]: https://github.com/rails/turbolinks#events 93 | [idempotent]: https://en.wiktionary.org/wiki/idempotent 94 | [Browserify]: http://browserify.org/ 95 | 96 | ## API 97 | 98 | #### onmount() 99 | Runs all behaviors. 100 | 101 | > When used with jQuery, this can be passed as an event handler, eg, `$(onmount)` or `$(document).on('load', onmount)`. 102 | 103 | #### onmount(`selector`) 104 | Runs all behaviors registered for `selector`. 105 | 106 | #### onmount(`selector`, `init()`) 107 | Registers a behavior for `selector` to run the callback `init()`. 108 | 109 | #### onmount(`selector`, `init(b)`, `exit(b)`) 110 | Registers a behavior for `selector` to run the callback `init()`. The `exit()` callback will be called once the behavior is triggered again but the element is no longer attached to the DOM. 111 | 112 | > The callbacks are passed an object `b`, and the same object is passed for both `init` and `exit`. This allows them to communicate and keep aware of state. A string ID is also provided, `b.id`, which is guaranteed unique for every behavior-element pair. 113 | 114 | #### onmount.reset() 115 | 116 | Clears all defined behaviors. Useful for tests. 117 | 118 | #### onmount.observe() 119 | 120 | Automatically invoke when new DOM elements appear using MutationObserver API. Returns `true` if it succeeds. 121 | 122 | #### onmount.unobserve() 123 | 124 | Turns off observation previously turned on via `onmount.observe()`. 125 | 126 | #### onmount.debug 127 | 128 | Set this to `true` to see debug messages. 129 | 130 | ## Browser compatibility 131 | 132 | All modern browsers and IE8+. For legacy IE, use it with jQuery 1.x. Try the [test suite](https://rawgit.com/rstacruz/onmount/master/test/index.html) in your browser. Try it [with jQuery 1.x](https://rawgit.com/rstacruz/onmount/master/test/jquery.html) for legacy browsers. 133 | 134 | ## Examples 135 | 136 | Examples are available in the source repo. [See examples →](https://github.com/rstacruz/onmount/examples) 137 | 138 | ## Thanks 139 | 140 | **onmount** © 2015+, Rico Sta. Cruz. Released under the [MIT] License.
141 | Authored and maintained by Rico Sta. Cruz with help from contributors ([list][contributors]). 142 | 143 | > [ricostacruz.com](http://ricostacruz.com)  ·  144 | > GitHub [@rstacruz](https://github.com/rstacruz)  ·  145 | > Twitter [@rstacruz](https://twitter.com/rstacruz) 146 | 147 | [MIT]: http://mit-license.org/ 148 | [contributors]: http://github.com/rstacruz/onmount/contributors 149 | [rsjs]: https://github.com/rstacruz/rsjs 150 | 151 | [![](https://img.shields.io/badge/%E2%9C%93-collaborative_etiquette-brightgreen.svg)](http://git.io/col) 152 | -------------------------------------------------------------------------------- /src/js/scrolltrack/index.js: -------------------------------------------------------------------------------- 1 | var toggleClass = require('dom101/toggle-class') 2 | var scrollTop = require('dom101/scroll-top') 3 | var documentHeight = require('dom101/document-height') 4 | var debounce = require('debounce') 5 | var each = require('dom101/each') 6 | 7 | /** 8 | * Tracks scrolling. Options: 9 | * 10 | * - `selectors` (String) 11 | * - `parent` (String) - where headings are. defaults to `document` 12 | * - `menu` (String | Element) - where links are. 13 | * - `scrollParent` (String | Element) - where to listen for scroll events. 14 | * - `onupdate` (Function) - callback to invoke when links change. 15 | */ 16 | 17 | function Scrolltrack (options) { 18 | if (!(this instanceof Scrolltrack)) return new Scrolltrack(options) 19 | if (!options) options = {} 20 | 21 | this.selector = options.selector || 'h1, h2, h3, h4, h5, h6' 22 | this.parent = options.parent || document 23 | this.onupdate = options.onupdate || function () {} 24 | this.menu = options.menu || document 25 | this.scrollParent = options.scrollParent || document 26 | this.offsetPercent = options.offsetPercent || 0.1 27 | 28 | this.listener = debounce(this.onScroll, 5).bind(this) 29 | this.update = debounce(this._update, 20).bind(this) 30 | this.active = undefined 31 | this.index = [] 32 | 33 | this.listen() 34 | this.update() 35 | } 36 | 37 | /** 38 | * Internal: Attaches event listeners. 39 | * No need to call this; the constructor already does this. 40 | */ 41 | 42 | Scrolltrack.prototype.listen = function () { 43 | q(this.scrollParent).addEventListener('scroll', this.listener) 44 | document.addEventListener('load', this.update, true) // image events 45 | document.addEventListener('load', this.listener, true) 46 | window.addEventListener('resize', this.update) 47 | window.addEventListener('resize', this.listener) 48 | } 49 | 50 | /** 51 | * Stops listening for events. 52 | */ 53 | 54 | Scrolltrack.prototype.destroy = function () { 55 | q(this.scrollParent).removeEventListener('scroll', this.listener) 56 | document.removeEventListener('load', this.update, true) 57 | document.removeEventListener('load', this.listener, true) 58 | window.removeEventListener('resize', this.update) 59 | window.removeEventListener('resize', this.listener) 60 | } 61 | 62 | /** 63 | * Internal: Updates the index of the headings and links. 64 | * Used by `update()`. 65 | */ 66 | 67 | Scrolltrack.prototype.reindex = function () { 68 | var headings = this.parent.querySelectorAll(this.selector) 69 | var index = this.index = [] 70 | var ids = {} 71 | 72 | var menu = q(this.menu) 73 | 74 | each(headings, function (heading) { 75 | var rect = heading.getBoundingClientRect() 76 | var id = heading.getAttribute('id') 77 | 78 | if (!ids[id]) ids[id] = 0 79 | else ids[id]++ 80 | 81 | var links = menu.querySelectorAll('[href=' + JSON.stringify('#' + id) + ']') 82 | 83 | index.push({ 84 | el: heading, 85 | id: id, 86 | link: links[ids[id]], 87 | top: rect.top + scrollTop() 88 | }) 89 | }) 90 | 91 | this.metrics = { 92 | windowHeight: window.innerHeight, 93 | documentHeight: documentHeight() 94 | } 95 | } 96 | 97 | /** 98 | * update : update() 99 | * Updates indices. Call this when the DOM changes. 100 | */ 101 | 102 | Scrolltrack.prototype._update = function () { 103 | this.reindex() 104 | this.onScroll() 105 | } 106 | 107 | /** 108 | * Internal: check for updates when scrolling. This is attached to the 109 | * document's scroll event. 110 | */ 111 | 112 | Scrolltrack.prototype.onScroll = function () { 113 | var y = this.scrollTop() 114 | var active 115 | 116 | each(this.index, function (heading) { 117 | if (heading.top < y) active = heading 118 | }) 119 | 120 | if (active !== this.active) { 121 | var last = this.active 122 | this.active = active 123 | this.follow(active, last) 124 | this.onupdate(active, last) 125 | } 126 | } 127 | 128 | /** 129 | * Returns the scroll position. This also takes care of scaling it to go all 130 | * the way to the bottom. 131 | */ 132 | 133 | Scrolltrack.prototype.scrollTop = function () { 134 | var y = scrollTop() 135 | var offset = 0 136 | var k = this.offsetPercent 137 | 138 | if (this.metrics) { 139 | var screen = this.metrics.windowHeight 140 | var maxY = this.metrics.documentHeight - screen 141 | var fold = maxY - screen * 1.2 142 | 143 | if (y > fold) { 144 | var lastPercent = (y - fold) / screen 145 | offset = screen * (k + (1 - k) * lastPercent) 146 | } else { 147 | offset = screen * k 148 | } 149 | } 150 | 151 | return y + offset 152 | } 153 | 154 | /** 155 | * Updates the selected link. 156 | */ 157 | 158 | Scrolltrack.prototype.follow = function (heading, last) { 159 | if (this.lastlink) { 160 | toggleClass(this.lastlink, '-active', false) 161 | this.lastlink = null 162 | } 163 | 164 | if (heading && heading.link) { 165 | toggleClass(heading.link, '-active', true) 166 | this.lastlink = heading.link 167 | } 168 | } 169 | 170 | /** 171 | * Internal: helper to normalize between CSS selectors, DOM elements and 172 | * jQuery objects. 173 | */ 174 | 175 | function q (el) { 176 | if (typeof el === 'string') return document.querySelector(el) 177 | else if (typeof el === 'object' && el[0]) return el[0] 178 | else return el 179 | } 180 | 181 | module.exports = Scrolltrack 182 | -------------------------------------------------------------------------------- /_docpress/404.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 74 |
75 |
76 |
77 |
78 |

404

79 | 80 |
81 | 84 |
85 |
-------------------------------------------------------------------------------- /docs/services/lighthouse-server.md: -------------------------------------------------------------------------------- 1 | # Lighthouse Server 2 | 3 | The Lighthouse Server is a Go binary installed on an Alpine Linux Docker image that reads messages from a queue and runs Google Lighthouse reports against themes, then sends the results back to the Tide API. 4 | 5 | It is important to note that the server only works for wp.org themes and the most recent version of it. This means that in a headless instance of Chromium the Lighthouse CLI audits each theme by loading the demo version found on wp-themes.com, which is always the latest version so if you request a theme audit for a previous version the results will be for the latest one. Eventually, we will look into a way to load the theme into the container and audit any version on request. 6 | 7 | ## Environment Variables 8 | 9 | | Variable | Description | 10 | | :--- | :--- | 11 | | `LH_CONCURRENT_AUDITS` | Sets the number of goroutines the server will perform concurrently. Default is `5`. _This is currently deactivated and will have no impact during runtime._ | 12 | | `LH_MESSAGE_PROVIDER` | Queue audit messages using the local MongoDB, Google Cloud Firestore, or AWS SQS. Must be one of: `local`, `firestore`, `sqs`. Default is `local`. | 13 | | `LH_STORAGE_PROVIDER` | Upload reports to the local file system, Google Cloud Storage, or AWS S3. Must be one of: `local`, `gcs`, `s3`. Default is `local`. | 14 | | `LH_TEMP_FOLDER` | Sets the temporary folder inside the container used to store downloaded files. Default is `/tmp`. | 15 | 16 | ## Commands 17 | 18 | | Command | Description | 19 | | :--- | :--- | 20 | | `make lighthouse.build.bin` | Build the Lighthouse Server Go binary. | 21 | | `make lighthouse.clean.bin` | Clean the Lighthouse Server Go binary. | 22 | | `make lighthouse.build.image` | Build the Lighthouse Server Docker image. | 23 | | `make lighthouse.build.up` | Rebuild the Lighthouse Server Docker image and run the container in isolation with docker-compose up. | 24 | | `make lighthouse.up` | Run the Lighthouse Server Docker image in isolation with docker-compose up. | 25 | | `make lighthouse.down` | Take the isolated Lighthouse Server Docker container down. | 26 | | `make lighthouse.stop` | Stop the isolated Lighthouse Server Docker container with docker-compose stop. | 27 | | `make lighthouse.rm` | Remove the stopped Lighthouse Server Docker container with docker-compose rm. | 28 | | `make lighthouse.push.image` | Push the Lighthouse Server Docker image to GCR. | 29 | | `make lighthouse.clean.image` | Clean the Lighthouse Server Docker image from the host machine. | 30 | | `make lighthouse.build.cluster` | Build the Lighthouse Server GKE cluster. | 31 | | `make lighthouse.creds` | Get the Lighthouse Server GKE cluster credentials. | 32 | | `make lighthouse.tpl` | Generate the Lighthouse Server GKE YAML template. | 33 | | `make lighthouse.deploy.cluster` | Deploy the Lighthouse Server GKE cluster. | 34 | | `make lighthouse.get.cluster` | Get the Lighthouse Server GKE cluster status. | 35 | | `make lighthouse.clean.cluster` | Clean the Lighthouse Server GKE cluster. | 36 | 37 | ## Running audits 38 | 39 | This section described the components included in the Lighthouse integration with Tide, demonstrates the Lighthouse audit process, and provides example Tide API audit results. 40 | 41 | ### Components 42 | 43 | The following outlines the components needed to integrate Lighthouse auditing of WordPress themes into the Tide API. 44 | 45 | 1. Docker Container `lighthouse-server` 46 | - Chromium 47 | - Lighthouse CLI 48 | - Lighthouse Server Go binary 49 | 2. Lighthouse Server Source Code 50 | - `bin/lighthouse-server` built Lighthouse Server Go binary. 51 | - `cmd/lighthouse-server` Lighthouse Server Go source code. 52 | - `service/lighthouse-server` `make` , Docker, and Kubernetes configurations. 53 | - `vendor` imported Go dependencies. 54 | 55 | ### Process 56 | 57 | The following demonstrates how a WordPress theme is run through a Lighthouse audit and has its results stored and returned via the Tide API. 58 | 59 | 1. The Tide API starts and listens for requests. 60 | 61 | ![](../images/api-php-start.png) 62 | 63 | 1. The Lighthouse Server starts and attempts to authenticate with the Tide API. 64 | 65 | ![](../images/lighthouse-server-auth.png) 66 | 67 | 1. The Tide API receives an authentication request from the Lighthouse Server. 68 | 69 | ![](../images/api-php-auth.png) 70 | 71 | 1. The Lighthouse Server is authenticated and starts polling the message queue. 72 | 73 | ![](../images/lighthouse-server-poll.png) 74 | 75 | 1. The theme is downloaded and a checksum is calculated. 76 | 77 | ![](../images/lighthouse-server-checksum.png) 78 | 79 | 1. The source code is ran through `gocloc` to get code information. 80 | 81 | ![](../images/lighthouse-server-code-info.png) 82 | 83 | 1. The source is scanned for the Theme header information. 84 | 85 | ![](../images/lighthouse-server-header.png) 86 | 87 | 1. Runs the theme preview URL (`https://wp-themes.com/`) through a `lighthouse` audit and keeps polling for the next job. 88 | 89 | ![](../images/lighthouse-server-audit.png) 90 | 91 | 1. Uploads the raw report to a storage provider (GCS, S3, or local) and generates a summary report. 92 | 93 | ![](../images/lighthouse-server-audit-complete.png) 94 | 95 | 1. The Lighthouse Server bundles the summary report and reference to the raw report as a message payload and sends the payload to the Tide API. 96 | 97 | ![](../images/lighthouse-server-payload.png) 98 | 99 | 1. The Tide API updates the audit endpoint after receiving the `POST` request from the Lighthouse Server. 100 | 101 | ![](../images/api-php-payload.png) 102 | 103 | 1. Finally the message is removed from the queue. 104 | 105 | ![](../images/lighthouse-server-queue.png) 106 | 107 | ### Reports 108 | 109 | The following is a Tide API audit object showing a Lighthouse summary report. 110 | 111 | #### `http://tide.local/api/tide/v1/audit/wporg/theme/twentyseventeen/2.1` 112 | 113 | ![Lighthouse Summary Report](../images/lighthouse-server-summary-report.png) 114 | 115 | The following is a Tide API report object showing a download link to the original Lighthouse report. This demonstrates the local disk storage, a cloud provider will look a bit different and the URL will expire. 116 | 117 | #### `http://tide.local/api/tide/v1/report/236/raw/lighthouse` 118 | 119 | ![Lighthouse Summary Report](../images/lighthouse-server-raw-report.png) --------------------------------------------------------------------------------