diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index f95d6907..18c91471 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -125,4 +125,4 @@ enforcement ladder](https://github.com/mozilla/diversity). For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at -https://www.contributor-covenant.org/translations. \ No newline at end of file +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e69de29b..f6ebb812 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -0,0 +1,39 @@ +## Contributing + +[fork]: /fork +[pr]: /compare +[code-of-conduct]: CODE_OF_CONDUCT.md + +Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. + +Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms. + +## Issues and PRs + +If you have suggestions for how this project could be improved, or want to report a bug, open an issue! We'd love all and any contributions. If you have questions, too, we'd love to hear them. + +We'd also love PRs. If you're thinking of a large PR, we advise opening up an issue first to talk about it, though! Look at the links below if you're not sure how to open a PR. + +## Submitting a pull request + +1. [Fork][fork] and clone the repository. +1. Configure and install the dependencies: `npm install`. +1. Make sure the tests pass on your machine: `npm test`, note: these tests also apply the linter, so there's no need to lint separately. +1. Create a new branch: `git checkout -b my-branch-name`. +1. Make your change, add tests, and make sure the tests still pass. +1. Push to your fork and [submit a pull request][pr]. +1. Pat your self on the back and wait for your pull request to be reviewed and merged. + +Here are a few things you can do that will increase the likelihood of your pull request being accepted: + +- Write and update tests. +- Keep your changes as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. +- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). + +Work in Progress pull requests are also welcome to get feedback early on, or if there is something blocked you. + +## Resources + +- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) +- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/) +- [GitHub Help](https://help.github.com) diff --git a/LICENSE b/LICENSE index a4121939..67390133 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [2021] [incubator-dbm of copyright EdurtIO] + Copyright [2021] [dbm of copyright EdurtIO] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 58125e6a..6d782221 100644 --- a/README.md +++ b/README.md @@ -3,20 +3,20 @@ Logo -

DBM

-

- An awesome database management tool specified for ClickHouse. For more information: https://dbm.incubator.edurt.io. -
-

---- - -Contributors: +[![Typing SVG](https://readme-typing-svg.herokuapp.com?size=25&width=750&lines=DBM+is+a+open+source+database+management+system.)](https://git.io/typing-svg) ![GitHub Contributors Image](https://contrib.rocks/image?repo=EdurtIO/dbm) -Basic: +**Documentation** + +[中文](http://dbm-zh.edurt.io/)
+[English](https://dbm.edurt.io/) + +## Overview + +--- ![](https://visitor-badge.glitch.me/badge?page_id=dbm) ![version](https://img.shields.io/github/v/release/EdurtIO/dbm.svg) @@ -31,39 +31,57 @@ Basic: ![GitHub contributors](https://img.shields.io/github/contributors-anon/EdurtIO/dbm?style=flat-square) ![GitHub last commit](https://img.shields.io/github/last-commit/EdurtIO/dbm?style=flat-square) -Workflow: +## Workflow -[![Test by push](https://github.com/EdurtIO/dbm/actions/workflows/push-compile-test.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/push-compile-test.yml) +--- -[![Publish New Release](https://github.com/EdurtIO/dbm/actions/workflows/publish-release.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/upload-to-release.yml) +**GitHub Actions workflow** +[![Test by push](https://github.com/EdurtIO/dbm/actions/workflows/push-compile-test.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/push-compile-test.yml) +[![Publish New Release](https://github.com/EdurtIO/dbm/actions/workflows/publish-release.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/upload-to-release.yml) [![Publish docs via GitHub Pages](https://github.com/EdurtIO/dbm/actions/workflows/publish-docs.yml/badge.svg)](https://github.com/EdurtIO/dbm/actions/workflows/publish-docs.yml) -Development: +**Development workflow** [![codebeat badge](https://codebeat.co/badges/a291d700-2d4b-435f-aa70-468bd1800d19)](https://codebeat.co/projects/github-com-edurtio-incubator-dbm-master) [![With Electron](https://img.shields.io/badge/with-electron-blue.svg)](https://electronjs.org/) [![With Angular](https://img.shields.io/badge/with-angular-blue.svg)](https://angular.io/) [![With Jetbrains](https://img.shields.io/badge/with-Jetbrains-blue.svg)](https://www.jetbrains.com/) -GitHub: +## Mirror + +--- + +**GitHub** [![GitHub stars](https://img.shields.io/github/stars/EdurtIO/incubator-dbm?style=for-the-badge)](https://github.com/EdurtIO/incubator-dbm/stargazers) [![GitHub license](https://img.shields.io/github/license/EdurtIO/incubator-dbm?style=for-the-badge)](https://github.com/EdurtIO/incubator-dbm/blob/master/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/EdurtIO/incubator-dbm?style=for-the-badge)](https://github.com/EdurtIO/incubator-dbm/issues) [![GitHub forks](https://img.shields.io/github/forks/EdurtIO/incubator-dbm?style=for-the-badge)](https://github.com/EdurtIO/incubator-dbm/network) -## Join Us +**Gitee** -Open the DingTalk software and scan the following QR code to join +[![star](https://gitee.com/EdurtIO/dbm/badge/star.svg?theme=dark)](https://gitee.com/EdurtIO/dbm/stargazers) +[![fork](https://gitee.com/EdurtIO/dbm/badge/fork.svg?theme=white)](https://gitee.com/EdurtIO/dbm/members) +[![Fork me on Gitee](https://gitee.com/EdurtIO/dbm/widgets/widget_3.svg)](https://gitee.com/EdurtIO/dbm) - +## Supported Databases -## Thank you +--- -- [Jetbrains](https://www.jetbrains.com/) +DBM can query data from any SQL-speaking datastore or data engine (ClickHouse and more). + +Here are some of the major database solutions that are supported: + +

+ clickhouse + trino + presto +

+ +## Features -## :rocket: Features +--- - Support query history (pagination, clear all, etc.) - Support selected sql clauses query @@ -86,52 +104,22 @@ Open the DingTalk software and scan the following QR code to join - Support monitor (processor, connection, query) - Support migrate data -## :laughing: Download - -- [Windows](https://github.com/EdurtIO/incubator-dbm/releases/download/1.4.0/dbm-win.zip) -- [Mac](https://github.com/EdurtIO/incubator-dbm/releases/download/1.4.0/dbm-mac.tar.gz) - -## :gear: Installation - -macOS and Windows - -- Download zip from [here](https://github.com/EdurtIO/incubator-dbm/releases). -- Unzip the archive, and install to macOS Applications. - -Other platforms - -- Unsupported temporarily. You can install the DBM by [building from source](#hammer_and_wrench-build-from-source). - -Install other versions? - -- Go ahead to [Github Release](https://github.com/EdurtIO/incubator-dbm/releases) for all releases. - -## :hammer_and_wrench: Build from source - -1. Install dependencies +## Join Us -```bash -npm install -g node-sass +--- -yarn install -``` +Open the DingTalk software and scan the following QR code to join -2. Build electron app for production + -```bash -yarn run build -``` +## Thank you -3. Install from built zip: `./build/dbm-.*` +--- -4. Run dev mode +- [Jetbrains](https://www.jetbrains.com/) -```bash -yarn run dev -``` +## Installation and Configuration -or +--- -```bash -npm start -``` +[Extended documentation for DBM](http://dbm-zh.edurt.io/reference/get_started/install.html) diff --git a/angular.json b/angular.json index 0277f27e..588f0c0d 100644 --- a/angular.json +++ b/angular.json @@ -31,7 +31,12 @@ "inlineStyleLanguage": "scss", "assets": [ "src/shared/assets", - "src/renderer/assets" + "src/renderer/assets", + { + "glob": "**/*", + "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/", + "output": "/assets/" + } ], "styles": [ "src/renderer/styles.scss", diff --git a/docs/docs/assets/images/others/management/datasource/clickhouse/img.png b/docs/docs/assets/images/others/management/datasource/clickhouse/img.png new file mode 100644 index 00000000..4cb1f0bc Binary files /dev/null and b/docs/docs/assets/images/others/management/datasource/clickhouse/img.png differ diff --git a/docs/docs/assets/images/others/management/datasource/clickhouse/img_1.png b/docs/docs/assets/images/others/management/datasource/clickhouse/img_1.png new file mode 100644 index 00000000..129c9dc2 Binary files /dev/null and b/docs/docs/assets/images/others/management/datasource/clickhouse/img_1.png differ diff --git a/docs/docs/assets/images/others/management/datasource/datasource_type.png b/docs/docs/assets/images/others/management/datasource/datasource_type.png new file mode 100644 index 00000000..0be5cfff Binary files /dev/null and b/docs/docs/assets/images/others/management/datasource/datasource_type.png differ diff --git a/docs/docs/assets/images/others/management/datasource/presto_trino/img.png b/docs/docs/assets/images/others/management/datasource/presto_trino/img.png new file mode 100644 index 00000000..e6b808b9 Binary files /dev/null and b/docs/docs/assets/images/others/management/datasource/presto_trino/img.png differ diff --git a/docs/docs/assets/images/versions/1.17.0/img.png b/docs/docs/assets/images/versions/1.17.0/img.png new file mode 100644 index 00000000..4b68d5f7 Binary files /dev/null and b/docs/docs/assets/images/versions/1.17.0/img.png differ diff --git a/docs/docs/assets/images/versions/1.17.0/img_1.png b/docs/docs/assets/images/versions/1.17.0/img_1.png new file mode 100644 index 00000000..953c4a94 Binary files /dev/null and b/docs/docs/assets/images/versions/1.17.0/img_1.png differ diff --git a/docs/docs/assets/images/versions/1.17.0/img_2.png b/docs/docs/assets/images/versions/1.17.0/img_2.png new file mode 100644 index 00000000..7293c8b9 Binary files /dev/null and b/docs/docs/assets/images/versions/1.17.0/img_2.png differ diff --git a/docs/docs/assets/images/versions/1.17.0/img_3.png b/docs/docs/assets/images/versions/1.17.0/img_3.png new file mode 100644 index 00000000..190db3df Binary files /dev/null and b/docs/docs/assets/images/versions/1.17.0/img_3.png differ diff --git a/docs/docs/assets/images/versions/1.17.0/img_4.png b/docs/docs/assets/images/versions/1.17.0/img_4.png new file mode 100644 index 00000000..fc9cbc32 Binary files /dev/null and b/docs/docs/assets/images/versions/1.17.0/img_4.png differ diff --git a/docs/docs/assets/images/versions/1.17.0/img_5.png b/docs/docs/assets/images/versions/1.17.0/img_5.png new file mode 100644 index 00000000..c5cdda63 Binary files /dev/null and b/docs/docs/assets/images/versions/1.17.0/img_5.png differ diff --git a/docs/docs/assets/images/versions/1.17.0/img_6.png b/docs/docs/assets/images/versions/1.17.0/img_6.png new file mode 100644 index 00000000..e3ac2d0b Binary files /dev/null and b/docs/docs/assets/images/versions/1.17.0/img_6.png differ diff --git a/src/renderer/assets/icon/source/clickhouse.svg b/docs/docs/assets/integrate/ClickHouse.svg similarity index 100% rename from src/renderer/assets/icon/source/clickhouse.svg rename to docs/docs/assets/integrate/ClickHouse.svg diff --git a/docs/docs/assets/integrate/Presto.svg b/docs/docs/assets/integrate/Presto.svg new file mode 100644 index 00000000..bf0e662a --- /dev/null +++ b/docs/docs/assets/integrate/Presto.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/docs/assets/integrate/Trino.svg b/docs/docs/assets/integrate/Trino.svg new file mode 100644 index 00000000..1c83e1ef --- /dev/null +++ b/docs/docs/assets/integrate/Trino.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/docs/development/version/1.17.0-development.md b/docs/docs/development/version/1.17.0-development.md index e8dca3d4..0982565f 100644 --- a/docs/docs/development/version/1.17.0-development.md +++ b/docs/docs/development/version/1.17.0-development.md @@ -29,7 +29,6 @@ DBM Version for `1.17.0` is development! --- -#### Contributors (In no particular order) --- diff --git a/docs/docs/reference/get_started/install.md b/docs/docs/reference/get_started/install.md index c738b173..fb59b61f 100644 --- a/docs/docs/reference/get_started/install.md +++ b/docs/docs/reference/get_started/install.md @@ -2,7 +2,7 @@ template: overrides/main.html --- -DBM is a cross-platform ClickHouse GUI desktop tool. +DBM is a cross-platform Database GUI desktop tool. #### System requirements diff --git a/docs/docs/reference/management/datasource/clickhouse.md b/docs/docs/reference/management/datasource/clickhouse.md new file mode 100644 index 00000000..7689c76f --- /dev/null +++ b/docs/docs/reference/management/datasource/clickhouse.md @@ -0,0 +1,88 @@ +--- +template: overrides/main.html +--- + +!!! note "ClickHouse" + + It is mainly used to describe how the software builds the ClickHouse data source for subsequent operations. + +!!! warning "System requirements" + + \>= `1.0.0-SNAPSHOT` + +### Supported Versions + +--- + +| Version | Tested? | +|-----------|---------------------------------------------| +| `19.10.x` | :material-checkbox-marked-circle:{.success} | +| `20.11.x` | :material-checkbox-marked-circle:{.success} | +| `21.3.x` | :material-checkbox-marked-circle:{.success} | +| `22.12.x` | :material-checkbox-marked-circle:{.success} | + +!!! note "Supported versions" + + Most versions have been tested, please submit issues for non-adapted versions. + +### Created a Source + +--- + +After entering the data source management page, click the Add data source button. + +![img.png](../../../assets/images/others/management/datasource/datasource_type.png) + +Select the ClickHouse icon in the `Basic` type (the first one). + +After selecting the type, click the `Next` button at the bottom to configure the relevant information. + +![img_1.png](../../../assets/images/others/management/datasource/clickhouse/img_1.png) + +!!! note "Supported protocols" + + - [x] `HTTP` + - [x] `SSH` + +#### HTTP Protocol + +--- + +!!! note "HTTP Protocol" + + Use the HTTP interface provided by ClickHouse to connect to the service. + +| Parameter | Description | Required | Unique | Default | +|-------------|-----------------------------------------------------------------------------------------------------|----------|--------|---------| +| `Alias` | The alias of the data source, which will be displayed later in the selected data source on the page | Yes | Yes | | +| `Host` | The host of the ClickHouse server | Yes | Yes | | +| `Port` | The port of the ClickHouse server | Yes | Yes | `8123` | +| `User Name` | The user name of the ClickHouse server | Yes | No | | +| `Password` | The password of the ClickHouse server | Yes | No | | + +When we have configured the above parameters, click the `Test` button at the bottom. If the service can be accessed normally, the `OK` button can be used. Click it and it will be saved. + +#### SSH Protocol + +--- + +!!! note "SSH Protocol" + + The SSH protocol will remotely access the target ClickHouse service through the springboard machine (configured SSH server). + +The SSH protocol first needs to fill in the relevant configuration information in the HTTP protocol. + +![img.png](../../../assets/images/others/management/datasource/clickhouse/img.png) + +!!! warning "SSH Configuration" + + The difference is that the SSH protocol has the following configurations. + +| Parameter | Description | Required | Unique | Default | +|-------------|---------------------------------|----------|--------|----------| +| `SSH Host` | The host of the SSH server | Yes | Yes | | +| `SSH Port` | The port of the SSH server | Yes | Yes | `22` | +| `User Name` | The user name of the SSH server | Yes | Yes | `root` | +| `Password` | The password of the SSH server | Yes | Yes | `123456` | + +When we have configured the above parameters, click the `Test` button at the bottom. If the service can be accessed normally, the `OK` button can be used. Click it and it will be saved. diff --git a/docs/docs/reference/management/datasource/presto_trino.md b/docs/docs/reference/management/datasource/presto_trino.md new file mode 100644 index 00000000..9751da34 --- /dev/null +++ b/docs/docs/reference/management/datasource/presto_trino.md @@ -0,0 +1,58 @@ +--- +template: overrides/main.html +--- + +!!! note "Presto & Trino" + + It is mainly used to describe how the software builds the Presto & Trino data source for subsequent operations. + +!!! warning "System requirements" + + \>= `1.17.0` + +### Supported Versions + +--- + +| Version | Tested? | +|-----------|---------------------------------------------| +| `Presto` | :material-checkbox-marked-circle:{.success} | +| `Trino` | :material-checkbox-marked-circle:{.success} | + +!!! note "Supported versions" + + Most versions have been tested, please submit issues for non-adapted versions. + +### Created a Source + +--- + +After entering the data source management page, click the Add data source button. + +![img.png](../../../assets/images/others/management/datasource/datasource_type.png) + +Select the ClickHouse icon in the `Basic` type (Presto is the second, Trino is the third). + +After selecting the type, click the `Next` button at the bottom to configure the relevant information. + +![img.png](../../../assets/images/others/management/datasource/presto_trino/img.png) + +!!! note "Supported protocols" + + - [x] `HTTP` + +#### HTTP Protocol + +--- + +!!! note "HTTP Protocol" + + Use the HTTP interface provided by Presto & Trino to connect to the service. + +| Parameter | Description | Required | Unique | Default | +|-------------|-----------------------------------------------------------------------------------------------------|----------|--------|---------| +| `Alias` | The alias of the data source, which will be displayed later in the selected data source on the page | Yes | Yes | | +| `Host` | The host of the Presto & Trino server | Yes | Yes | | +| `Port` | The port of the Presto & Trino server | Yes | Yes | | +| `User Name` | The user name of the Presto & Trino server | Yes | No | | +| `Password` | The password of the Presto & Trino server | Yes | No | | diff --git a/docs/docs/release/1.17.0-20220529.md b/docs/docs/release/1.17.0-20220529.md new file mode 100644 index 00000000..43baeed4 --- /dev/null +++ b/docs/docs/release/1.17.0-20220529.md @@ -0,0 +1,59 @@ +--- +template: overrides/main.html +icon: material/gesture-tap-button +--- + +DBM Version for `1.17.0` is released! + +Release Time: `2022-05-29` + +#### Enhancement + +--- + +- Support metadata management to filter the table
+![img.png](../assets/images/versions/1.17.0/img.png)
+![img_1.png](../assets/images/versions/1.17.0/img_1.png)
+![img_2.png](../assets/images/versions/1.17.0/img_2.png)
+- Support trino and presto for query
+![img_3.png](../assets/images/versions/1.17.0/img_3.png)
+- Support trino and presto for monitor --> processors
+- Support trino and presto for monitor --> connection
+- Support trino and presto for monitor --> slow query
+ +#### UI + +--- + +- Add multiple editor themes
+- Query the list of data sources on the page, support the display of logo
+![img_6.png](../assets/images/versions/1.17.0/img_6.png)
+ +#### Optimize + +---- + +- Optimize project description and introduction
+- Optimize the homepage is not available & does not support data source charts
+![img_4.png](../assets/images/versions/1.17.0/img_4.png)
+![img_5.png](../assets/images/versions/1.17.0/img_5.png)
+ +#### Docs + +--- + +- Refactoring software homepage
+- Add clickhouse datasource docs
+- Add presto & trino datasource docs
+ +#### Bug + +--- + +- Fix the exception that the data source is not selected in the track, the Track list can be selected
+ +#### Contributors (In no particular order) + +--- + +- @qianmoQ diff --git a/docs/docs/stylesheets/extra.css b/docs/docs/stylesheets/extra.css index 52d52b2a..5e40b791 100644 --- a/docs/docs/stylesheets/extra.css +++ b/docs/docs/stylesheets/extra.css @@ -5,3 +5,200 @@ .blue { color: #1890ff; } + +.success { + color: #52c41a; +} + +.md-typeset .grid { + grid-gap: .4rem; + display: grid; + grid-template-columns:repeat(auto-fit, minmax(16rem, 1fr)); + margin: 1em 0 +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) { + display: contents +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) { + display: contents +} + +.md-typeset .grid.cards > :is(ul,ol) { + display: contents +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li, .md-typeset .grid > .card { + border: .05rem solid var(--md-default-fg-color--lightest); + border-radius: .1rem; + display: block; + margin: 0; + padding: .8rem; + -webkit-transition: border .25s, box-shadow .25s; + transition: border .25s, box-shadow .25s +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li, .md-typeset .grid > .card { + border: .05rem solid var(--md-default-fg-color--lightest); + border-radius: .1rem; + display: block; + margin: 0; + padding: .8rem; + -moz-transition: border .25s, box-shadow .25s; + transition: border .25s, box-shadow .25s +} + +.md-typeset .grid.cards > :is(ul,ol) > li, .md-typeset .grid > .card { + border: .05rem solid var(--md-default-fg-color--lightest); + border-radius: .1rem; + display: block; + margin: 0; + padding: .8rem; + transition: border .25s, box-shadow .25s +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li:-webkit-any(:focus-within,:hover), .md-typeset .grid > .card:-webkit-any(:focus-within,:hover) { + border-color: transparent; + box-shadow: 0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25); +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li:-moz-any(:focus-within,:hover), .md-typeset .grid > .card:-moz-any(:focus-within,:hover) { + border-color: transparent; + box-shadow: 0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25); +} + +.md-typeset .grid.cards > :is(ul,ol) > li:is(:focus-within,:hover), .md-typeset .grid > .card:is(:focus-within,:hover) { + border-color: transparent; + box-shadow: 0 0.2rem 0.5rem rgba(0,0,0,.1),0 0 0.05rem rgba(0,0,0,.25); +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li > hr, .md-typeset .grid > .card > hr { + margin-bottom: 1em; + margin-top: 1em +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li > hr, .md-typeset .grid > .card > hr { + margin-bottom: 1em; + margin-top: 1em +} + +.md-typeset .grid.cards > :is(ul,ol) > li > hr, .md-typeset .grid > .card > hr { + margin-bottom: 1em; + margin-top: 1em +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li > :first-child, .md-typeset .grid > .card > :first-child { + margin-top: 0 +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li > :first-child, .md-typeset .grid > .card > :first-child { + margin-top: 0 +} + +.md-typeset .grid.cards > :is(ul,ol) > li > :first-child, .md-typeset .grid > .card > :first-child { + margin-top: 0 +} + +.md-typeset .grid.cards > :-webkit-any(ul,ol) > li > :last-child, .md-typeset .grid > .card > :last-child { + margin-bottom: 0 +} + +.md-typeset .grid.cards > :-moz-any(ul,ol) > li > :last-child, .md-typeset .grid > .card > :last-child { + margin-bottom: 0 +} + +.md-typeset .grid.cards > :is(ul,ol) > li > :last-child, .md-typeset .grid > .card > :last-child { + margin-bottom: 0 +} + +.md-typeset .grid > * { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > :-webkit-any(.admonition,details) { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > :-moz-any(.admonition,details) { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > :is(.admonition,details) { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > .highlight > *, .md-typeset .grid > .highlighttable, .md-typeset .grid > pre { + margin-bottom: 0; + margin-top: 0 +} + +.md-typeset .grid > .highlight > pre:only-child, .md-typeset .grid > .highlight > pre > code, .md-typeset .grid > .highlighttable, .md-typeset .grid > .highlighttable > tbody, .md-typeset .grid > .highlighttable > tbody > tr, .md-typeset .grid > .highlighttable > tbody > tr > .code, .md-typeset .grid > .highlighttable > tbody > tr > .code > .highlight, .md-typeset .grid > .highlighttable > tbody > tr > .code > .highlight > pre, .md-typeset .grid > .highlighttable > tbody > tr > .code > .highlight > pre > code { + height: 100% +} + +.md-typeset .grid > .tabbed-set { + margin-bottom: 0; + margin-top: 0 +} + +@media screen and (min-width: 45em) { + [dir=ltr] .md-typeset .inline { + margin-right: .8rem + } + + [dir=rtl] .md-typeset .inline { + margin-left: .8rem + } + + .md-typeset .inline { + float: left; + margin-bottom: .8rem; + margin-top: 0; + width: 11.7rem + } + + [dir=rtl] .md-typeset .inline { + float: right + } + + [dir=ltr] .md-typeset .inline.end { + margin-left: .8rem; + margin-right: 0 + } + + [dir=rtl] .md-typeset .inline.end { + margin-left: 0; + margin-right: .8rem + } + + .md-typeset .inline.end { + float: right + } + + [dir=rtl] .md-typeset .inline.end { + float: left + } +} + +.mdx-container { + background: url(data:image/svg+xml;utf8,) no-repeat bottom, linear-gradient(to bottom, var(--md-primary-fg-color), #a63fd9 99 %, var(--md-default-bg-color) 99 %); + padding-top: 1rem; + max-height: 600px; +} + +.font-center { + text-align: center; +} + +.bottom-margin { + margin-bottom: 10px; +} + +.top-margin { + margin-top: 10px; +} diff --git a/docs/material/overrides/home.html b/docs/material/overrides/home.html index 7f188ebf..33f3c746 100644 --- a/docs/material/overrides/home.html +++ b/docs/material/overrides/home.html @@ -13,19 +13,102 @@

What is DBM?

-

DBM is a 100% open source ClickHouse database management system.

-

✓ Easy to install

-

✓ Simple development

-

✓ Git-based source control

-

✓ Cross Platform

+

DBM is a set of open source database management desktop software, it will support more data sources, masterpiece-friendly database desktop management tools.

Quick start
+ +
+

Overview

+
+
    +
  • +
    + + + + Easy to install +
    +
    + Simple installation method, download the binary file directly from the official website to install +
    +
  • +
  • +
    + + + + Cross Platform +
    +
    + DBM binary can be quickly installed in macOS, Windows and other systems. +
    +
  • +
  • +
    + + + + Git-based source control +
    +
    + The source code uses the Git system for version control, and the source code can be downloaded in various regions at any time. +
    +
  • +
+
+
+ +
+ +
+

Supported Databases

+
+
    +
  • +
    + + + + ClickHouse +
    +
    + ClickHouse as a Service, built by the creators of the fastest OLAP database on Earth. +
    +
  • +
  • +
    + + + + Presto +
    +
    + Presto is an open source distributed SQL query engine for running interactive analytic queries against data sources of all sizes ranging from gigabytes to petabytes. +
    +
  • +
  • +
    + + + + Trino +
    +
    + Trino, a query engine that runs at ludicrous speed Fast distributed SQL query engine for big data analytics that helps you explore your data universe. +
    +
  • +
+
+
- +
+ + {% endblock %} {% block content %}{% endblock %} {% block footer %}{% endblock %} + diff --git a/docs/material/overrides/home.zh.html b/docs/material/overrides/home.zh.html index 28b34811..6b929dfc 100644 --- a/docs/material/overrides/home.zh.html +++ b/docs/material/overrides/home.zh.html @@ -1,31 +1,113 @@ {#- - This file was automatically generated - do not edit +This file was automatically generated - do not edit -#} {% extends "overrides/main.html" %} {% block tabs %} - {{ super() }} - -
-
-
-
- -
-
-

什么是DBM?

-

DBM是一套完整开源的ClickHouse数据库管理客户端.

-

✓ 便捷安装

-

✓ 开发简单

-

✓ Git-based源代码控制

-

✓ 跨平台

- - 快速启动 - -
+{{ super() }} + +
+
+
+
+ +
+
+

What is DBM?

+

DBM is a set of open source database management desktop software, it will support more data sources, masterpiece-friendly database desktop management tools.

+ + Quick start +
-
+
+

Overview

+
+
    +
  • +
    + + + + Easy to install +
    +
    + Simple installation method, download the binary file directly from the official website to install +
    +
  • +
  • +
    + + + + Cross Platform +
    +
    + DBM binary can be quickly installed in macOS, Windows and other systems. +
    +
  • +
  • +
    + + + + Git-based source control +
    +
    + The source code uses the Git system for version control, and the source code can be downloaded in various regions at any time. +
    +
  • +
+
+
+ +
+ +
+

Supported Databases

+
+
    +
  • +
    + + + + ClickHouse +
    +
    + ClickHouse as a Service, built by the creators of the fastest OLAP database on Earth. +
    +
  • +
  • +
    + + + + Presto +
    +
    + Presto is an open source distributed SQL query engine for running interactive analytic queries against data sources of all sizes ranging from gigabytes to petabytes. +
    +
  • +
  • +
    + + + + Trino +
    +
    + Trino, a query engine that runs at ludicrous speed Fast distributed SQL query engine for big data analytics that helps you explore your data universe. +
    +
  • +
+
+
+
+ +
+ +
{% endblock %} {% block content %}{% endblock %} {% block footer %}{% endblock %} diff --git a/docs/material/overrides/main.html b/docs/material/overrides/main.html index 6b94dbca..046f6e4f 100644 --- a/docs/material/overrides/main.html +++ b/docs/material/overrides/main.html @@ -3,7 +3,8 @@ -#} {% extends "base.html" %} {% block extrahead %} - + + {% endblock %} {% block announce %} diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 76d58c45..c72d1797 100755 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -1,8 +1,8 @@ -site_name: ClickHouse Gui Tools DBM +site_name: DBM - Database GUI site_url: https://dbm.incubator.edurt.io/ site_author: qinamoQ site_description: >- - ClickHouse Database Gui Tools! + Database Gui! repo_name: EdurtIO/dbm repo_url: https://github.com/EdurtIO/dbm @@ -154,14 +154,18 @@ nav: - History: reference/query/query_history.md - Snippet: reference/query/snippet/snippet.md - Management: - - Datasource: reference/management/management_datasource.md + - Datasource: + - ClickHouse: reference/management/datasource/clickhouse.md + - Presto: reference/management/datasource/presto_trino.md + - Trino: reference/management/datasource/presto_trino.md - Monitor: - Processor: reference/monitor/monitor-processor.md - Connection: reference/monitor/monitor_connection.md - Mutations: reference/monitor/monitor_mutations.md - Query: reference/monitor/monitor_query.md - Release Note: - - 1.16.0 (latest): release/1.16.0-20220513.md + - 1.17.0 (latest): release/1.17.0-20220529.md + - 1.16.0: release/1.16.0-20220513.md - 1.15.0: release/1.15.0-20220425.md - 1.14.0: release/1.14.0-20220410.md - 1.13.0: release/1.13.0-20220329.md diff --git a/docs/src/.icons/logo.afdesign b/docs/src/.icons/logo.afdesign deleted file mode 100644 index 07f57d0a..00000000 Binary files a/docs/src/.icons/logo.afdesign and /dev/null differ diff --git a/docs/src/.icons/logo.svg b/docs/src/.icons/logo.svg deleted file mode 100644 index 763eb2c2..00000000 --- a/docs/src/.icons/logo.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/docs/src/404.html b/docs/src/404.html deleted file mode 100644 index 27941f8c..00000000 --- a/docs/src/404.html +++ /dev/null @@ -1,31 +0,0 @@ - - -{% extends "main.html" %} - - -{% block content %} -

404 - Not found

-{% endblock %} - - -{% block disqus %}{% endblock %} diff --git a/docs/src/__init__.py b/docs/src/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/src/assets/images/favicon.png b/docs/src/assets/images/favicon.png deleted file mode 100644 index 1cf13b9f..00000000 Binary files a/docs/src/assets/images/favicon.png and /dev/null differ diff --git a/docs/src/assets/javascripts/_/index.ts b/docs/src/assets/javascripts/_/index.ts deleted file mode 100644 index b00cda9c..00000000 --- a/docs/src/assets/javascripts/_/index.ts +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { getElementOrThrow, getLocation } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Feature flag - */ -export type Flag = - | "header.autohide" /* Hide header */ - | "navigation.expand" /* Automatic expansion */ - | "navigation.instant" /* Instant loading */ - | "navigation.indexes" /* Section pages */ - | "navigation.sections" /* Section navigation */ - | "navigation.tabs" /* Tabs navigation */ - | "navigation.tabs.sticky" /* Tabs navigation (sticky) */ - | "navigation.top" /* Back-to-top button */ - | "search.highlight" /* Search highlighting */ - | "search.share" /* Search sharing */ - | "search.suggest" /* Search suggestions */ - | "toc.integrate" /* Integrated table of contents */ - -/* ------------------------------------------------------------------------- */ - -/** - * Translation - */ -export type Translation = - | "clipboard.copy" /* Copy to clipboard */ - | "clipboard.copied" /* Copied to clipboard */ - | "search.config.lang" /* Search language */ - | "search.config.pipeline" /* Search pipeline */ - | "search.config.separator" /* Search separator */ - | "search.placeholder" /* Search */ - | "search.result.placeholder" /* Type to start searching */ - | "search.result.none" /* No matching documents */ - | "search.result.one" /* 1 matching document */ - | "search.result.other" /* # matching documents */ - | "search.result.more.one" /* 1 more on this page */ - | "search.result.more.other" /* # more on this page */ - | "search.result.term.missing" /* Missing */ - | "select.version.title" /* Version selector */ - -/** - * Translations - */ -export type Translations = Record - -/* ------------------------------------------------------------------------- */ - -/** - * Versioning - */ -export interface Versioning { - provider: "mike" /* Version provider */ -} - -/** - * Configuration - */ -export interface Config { - base: string /* Base URL */ - features: Flag[] /* Feature flags */ - translations: Translations /* Translations */ - search: string /* Search worker URL */ - version?: Versioning /* Versioning */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Retrieve global configuration and make base URL absolute - */ -const script = getElementOrThrow("#__config") -const config: Config = JSON.parse(script.textContent!) -config.base = `${new URL(config.base, getLocation())}` - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve global configuration - * - * @returns Global configuration - */ -export function configuration(): Config { - return config -} - -/** - * Check whether a feature flag is enabled - * - * @param flag - Feature flag - * - * @returns Test result - */ -export function feature(flag: Flag): boolean { - return config.features.includes(flag) -} - -/** - * Retrieve the translation for the given key - * - * @param key - Key to be translated - * @param value - Positional value, if any - * - * @returns Translation - */ -export function translation( - key: Translation, value?: string | number -): string { - return typeof value !== "undefined" - ? config.translations[key].replace("#", value.toString()) - : config.translations[key] -} diff --git a/docs/src/assets/javascripts/actions/_/index.ts b/docs/src/assets/javascripts/actions/_/index.ts deleted file mode 100644 index babb9d33..00000000 --- a/docs/src/assets/javascripts/actions/_/index.ts +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set focusable property - * - * @param el - Element - * @param value - Tabindex value - */ -export function setFocusable( - el: HTMLElement, value = 0 -): void { - el.setAttribute("tabindex", value.toString()) -} - -/** - * Reset focusable property - * - * @param el - Element - */ -export function resetFocusable( - el: HTMLElement -): void { - el.removeAttribute("tabindex") -} - -/** - * Set scroll lock - * - * @param el - Scrollable element - * @param value - Vertical offset - */ -export function setScrollLock( - el: HTMLElement, value: number -): void { - el.setAttribute("data-md-state", "lock") - el.style.top = `-${value}px` -} - -/** - * Reset scroll lock - * - * @param el - Scrollable element - */ -export function resetScrollLock( - el: HTMLElement -): void { - const value = -1 * parseInt(el.style.top, 10) - el.removeAttribute("data-md-state") - el.style.top = "" - if (value) - window.scrollTo(0, value) -} diff --git a/docs/src/assets/javascripts/actions/anchor/index.ts b/docs/src/assets/javascripts/actions/anchor/index.ts deleted file mode 100644 index b1d3c896..00000000 --- a/docs/src/assets/javascripts/actions/anchor/index.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set anchor state - * - * @param el - Anchor element - * @param state - Anchor state - */ -export function setAnchorState( - el: HTMLElement, state: "blur" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset anchor state - * - * @param el - Anchor element - */ -export function resetAnchorState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set anchor active - * - * @param el - Anchor element - * @param value - Whether the anchor is active - */ -export function setAnchorActive( - el: HTMLElement, value: boolean -): void { - el.classList.toggle("md-nav__link--active", value) -} - -/** - * Reset anchor active - * - * @param el - Anchor element - */ -export function resetAnchorActive( - el: HTMLElement -): void { - el.classList.remove("md-nav__link--active") -} diff --git a/docs/src/assets/javascripts/actions/dialog/index.ts b/docs/src/assets/javascripts/actions/dialog/index.ts deleted file mode 100644 index d951d34d..00000000 --- a/docs/src/assets/javascripts/actions/dialog/index.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set dialog message - * - * @param el - Dialog element - * @param value - Dialog message - */ -export function setDialogMessage( - el: HTMLElement, value: string -): void { - el.firstElementChild!.innerHTML = value -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set dialog state - * - * @param el - Dialog element - * @param state - Dialog state - */ -export function setDialogState( - el: HTMLElement, state: "open" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset dialog state - * - * @param el - Dialog element - */ -export function resetDialogState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} diff --git a/docs/src/assets/javascripts/actions/header/_/index.ts b/docs/src/assets/javascripts/actions/header/_/index.ts deleted file mode 100644 index 400f44bd..00000000 --- a/docs/src/assets/javascripts/actions/header/_/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set header state - * - * @param el - Header element - * @param state - Header state - */ -export function setHeaderState( - el: HTMLElement, state: "shadow" | "hidden" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset header state - * - * @param el - Header element - */ -export function resetHeaderState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} diff --git a/docs/src/assets/javascripts/actions/header/index.ts b/docs/src/assets/javascripts/actions/header/index.ts deleted file mode 100644 index e98ef06a..00000000 --- a/docs/src/assets/javascripts/actions/header/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./title" diff --git a/docs/src/assets/javascripts/actions/header/title/index.ts b/docs/src/assets/javascripts/actions/header/title/index.ts deleted file mode 100644 index 62e24798..00000000 --- a/docs/src/assets/javascripts/actions/header/title/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set header title state - * - * @param el - Header title element - * @param state - Header title state - */ -export function setHeaderTitleState( - el: HTMLElement, state: "active" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset header title state - * - * @param el - Header title element - */ -export function resetHeaderTitleState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} diff --git a/docs/src/assets/javascripts/actions/index.ts b/docs/src/assets/javascripts/actions/index.ts deleted file mode 100644 index 24f2676d..00000000 --- a/docs/src/assets/javascripts/actions/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./anchor" -export * from "./dialog" -export * from "./header" -export * from "./search" -export * from "./sidebar" -export * from "./source" -export * from "./tabs" -export * from "./top" diff --git a/docs/src/assets/javascripts/actions/search/index.ts b/docs/src/assets/javascripts/actions/search/index.ts deleted file mode 100644 index efacc39d..00000000 --- a/docs/src/assets/javascripts/actions/search/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./query" -export * from "./result" diff --git a/docs/src/assets/javascripts/actions/search/query/index.ts b/docs/src/assets/javascripts/actions/search/query/index.ts deleted file mode 100644 index 42696fa0..00000000 --- a/docs/src/assets/javascripts/actions/search/query/index.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { translation } from "~/_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set search query placeholder - * - * @param el - Search query element - * @param value - Placeholder - */ -export function setSearchQueryPlaceholder( - el: HTMLInputElement, value: string -): void { - el.placeholder = value -} - -/** - * Reset search query placeholder - * - * @param el - Search query element - */ -export function resetSearchQueryPlaceholder( - el: HTMLInputElement -): void { - el.placeholder = translation("search.placeholder") -} diff --git a/docs/src/assets/javascripts/actions/search/result/index.ts b/docs/src/assets/javascripts/actions/search/result/index.ts deleted file mode 100644 index b9d23952..00000000 --- a/docs/src/assets/javascripts/actions/search/result/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { translation } from "~/_" -import { round } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set number of search results - * - * @param el - Search result metadata element - * @param value - Number of results - */ -export function setSearchResultMeta( - el: HTMLElement, value: number -): void { - switch (value) { - - /* No results */ - case 0: - el.textContent = translation("search.result.none") - break - - /* One result */ - case 1: - el.textContent = translation("search.result.one") - break - - /* Multiple result */ - default: - el.textContent = translation("search.result.other", round(value)) - } -} - -/** - * Reset number of search results - * - * @param el - Search result metadata element - */ -export function resetSearchResultMeta( - el: HTMLElement -): void { - el.textContent = translation("search.result.placeholder") -} - -/* ------------------------------------------------------------------------- */ - -/** - * Add an element to the search result list - * - * @param el - Search result list element - * @param child - Search result element - */ -export function addToSearchResultList( - el: HTMLElement, child: Element -): void { - el.appendChild(child) -} - -/** - * Reset search result list - * - * @param el - Search result list element - */ -export function resetSearchResultList( - el: HTMLElement -): void { - el.innerHTML = "" -} diff --git a/docs/src/assets/javascripts/actions/sidebar/index.ts b/docs/src/assets/javascripts/actions/sidebar/index.ts deleted file mode 100644 index 403bcc60..00000000 --- a/docs/src/assets/javascripts/actions/sidebar/index.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set sidebar offset - * - * @param el - Sidebar element - * @param value - Sidebar offset - */ -export function setSidebarOffset( - el: HTMLElement, value: number -): void { - el.style.top = `${value}px` -} - -/** - * Reset sidebar offset - * - * @param el - Sidebar element - */ -export function resetSidebarOffset( - el: HTMLElement -): void { - el.style.top = "" -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set sidebar height - * - * This function doesn't set the height of the actual sidebar, but of its first - * child – the `.md-sidebar__scrollwrap` element in order to mitigiate jittery - * sidebars when the footer is scrolled into view. At some point we switched - * from `absolute` / `fixed` positioning to `sticky` positioning, significantly - * reducing jitter in some browsers (respectively Firefox and Safari) when - * scrolling from the top. However, top-aligned sticky positioning means that - * the sidebar snaps to the bottom when the end of the container is reached. - * This is what leads to the mentioned jitter, as the sidebar's height may be - * updated too slowly. - * - * This behaviour can be mitigiated by setting the height of the sidebar to `0` - * while preserving the padding, and the height on its first element. - * - * @param el - Sidebar element - * @param value - Sidebar height - */ -export function setSidebarHeight( - el: HTMLElement, value: number -): void { - const scrollwrap = el.firstElementChild as HTMLElement - scrollwrap.style.height = `${value - 2 * scrollwrap.offsetTop}px` -} - -/** - * Reset sidebar height - * - * @param el - Sidebar element - */ -export function resetSidebarHeight( - el: HTMLElement -): void { - const scrollwrap = el.firstElementChild as HTMLElement - scrollwrap.style.height = "" -} diff --git a/docs/src/assets/javascripts/actions/source/index.ts b/docs/src/assets/javascripts/actions/source/index.ts deleted file mode 100644 index d2074e0a..00000000 --- a/docs/src/assets/javascripts/actions/source/index.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set repository facts - * - * @param el - Repository element - * @param child - Repository facts element - */ -export function setSourceFacts( - el: HTMLElement, child: Element -): void { - el.lastElementChild!.appendChild(child) -} - -/** - * Set repository state - * - * @param el - Repository element - * @param state - Repository state - */ -export function setSourceState( - el: HTMLElement, state: "done" -): void { - el.lastElementChild!.setAttribute("data-md-state", state) -} diff --git a/docs/src/assets/javascripts/actions/tabs/index.ts b/docs/src/assets/javascripts/actions/tabs/index.ts deleted file mode 100644 index 5fd31afe..00000000 --- a/docs/src/assets/javascripts/actions/tabs/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set tabs state - * - * @param el - Tabs element - * @param state - Tabs state - */ -export function setTabsState( - el: HTMLElement, state: "hidden" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset tabs state - * - * @param el - Tabs element - */ -export function resetTabsState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} diff --git a/docs/src/assets/javascripts/actions/top/index.ts b/docs/src/assets/javascripts/actions/top/index.ts deleted file mode 100644 index 483e5ef7..00000000 --- a/docs/src/assets/javascripts/actions/top/index.ts +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set back-to-top state - * - * @param el - Back-to-top element - * @param state - Back-to-top state - */ -export function setBackToTopState( - el: HTMLElement, state: "hidden" -): void { - el.setAttribute("data-md-state", state) -} - -/** - * Reset back-to-top state - * - * @param el - Back-to-top element - */ -export function resetBackToTopState( - el: HTMLElement -): void { - el.removeAttribute("data-md-state") -} - -/* ------------------------------------------------------------------------- */ - -/** - * Set back-to-top offset - * - * @param el - Back-to-top element - * @param value - Back-to-top offset - */ -export function setBackToTopOffset( - el: HTMLElement, value: number -): void { - el.style.top = `${value}px` -} - -/** - * Reset back-to-top offset - * - * @param el - Back-to-top element - */ -export function resetBackToTopOffset( - el: HTMLElement -): void { - el.style.top = "" -} diff --git a/docs/src/assets/javascripts/browser/document/index.ts b/docs/src/assets/javascripts/browser/document/index.ts deleted file mode 100644 index dbb290ad..00000000 --- a/docs/src/assets/javascripts/browser/document/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { ReplaySubject, Subject, fromEvent } from "rxjs" -import { mapTo } from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch document - * - * Documents are implemented as subjects, so all downstream observables are - * automatically updated when a new document is emitted. - * - * @returns Document subject - */ -export function watchDocument(): Subject { - const document$ = new ReplaySubject() - fromEvent(document, "DOMContentLoaded") - .pipe( - mapTo(document) - ) - .subscribe(document$) - - /* Return document */ - return document$ -} diff --git a/docs/src/assets/javascripts/browser/element/_/.eslintrc b/docs/src/assets/javascripts/browser/element/_/.eslintrc deleted file mode 100644 index 82472629..00000000 --- a/docs/src/assets/javascripts/browser/element/_/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "jsdoc/require-jsdoc": "off" - } -} diff --git a/docs/src/assets/javascripts/browser/element/_/index.ts b/docs/src/assets/javascripts/browser/element/_/index.ts deleted file mode 100644 index 5fc98e69..00000000 --- a/docs/src/assets/javascripts/browser/element/_/index.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve an element matching the query selector - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Element or nothing - */ -export function getElement( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T] | undefined - -export function getElement( - selector: string, node?: ParentNode -): T | undefined - -export function getElement( - selector: string, node: ParentNode = document -): T | undefined { - return node.querySelector(selector) || undefined -} - -/** - * Retrieve an element matching a query selector or throw a reference error - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Element - */ -export function getElementOrThrow( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T] - -export function getElementOrThrow( - selector: string, node?: ParentNode -): T - -export function getElementOrThrow( - selector: string, node: ParentNode = document -): T { - const el = getElement(selector, node) - if (typeof el === "undefined") - throw new ReferenceError( - `Missing element: expected "${selector}" to be present` - ) - - /* Return element */ - return el -} - -/** - * Retrieve the currently active element - * - * @returns Element or nothing - */ -export function getActiveElement(): HTMLElement | undefined { - return document.activeElement instanceof HTMLElement - ? document.activeElement - : undefined -} - -/** - * Retrieve all elements matching the query selector - * - * @template T - Element type - * - * @param selector - Query selector - * @param node - Node of reference - * - * @returns Elements - */ -export function getElements( - selector: T, node?: ParentNode -): HTMLElementTagNameMap[T][] - -export function getElements( - selector: string, node?: ParentNode -): T[] - -export function getElements( - selector: string, node: ParentNode = document -): T[] { - return Array.from(node.querySelectorAll(selector)) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Replace an element with the given list of nodes - * - * @param el - Element - * @param nodes - Replacement nodes - */ -export function replaceElement( - el: HTMLElement, ...nodes: Node[] -): void { - el.replaceWith(...nodes) -} diff --git a/docs/src/assets/javascripts/browser/element/focus/index.ts b/docs/src/assets/javascripts/browser/element/focus/index.ts deleted file mode 100644 index 292a5f87..00000000 --- a/docs/src/assets/javascripts/browser/element/focus/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, merge } from "rxjs" -import { map, startWith } from "rxjs/operators" - -import { getActiveElement } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set element focus - * - * @param el - Element - * @param value - Whether the element should be focused - */ -export function setElementFocus( - el: HTMLElement, value = true -): void { - if (value) - el.focus() - else - el.blur() -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element focus - * - * @param el - Element - * - * @returns Element focus observable - */ -export function watchElementFocus( - el: HTMLElement -): Observable { - return merge( - fromEvent(el, "focus"), - fromEvent(el, "blur") - ) - .pipe( - map(({ type }) => type === "focus"), - startWith(el === getActiveElement()) - ) -} diff --git a/docs/src/assets/javascripts/browser/element/index.ts b/docs/src/assets/javascripts/browser/element/index.ts deleted file mode 100644 index 4cbe7f98..00000000 --- a/docs/src/assets/javascripts/browser/element/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./focus" -export * from "./offset" -export * from "./selection" -export * from "./size" diff --git a/docs/src/assets/javascripts/browser/element/offset/index.ts b/docs/src/assets/javascripts/browser/element/offset/index.ts deleted file mode 100644 index e51f784f..00000000 --- a/docs/src/assets/javascripts/browser/element/offset/index.ts +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, merge } from "rxjs" -import { - distinctUntilChanged, - map, - startWith -} from "rxjs/operators" - -import { - getElementContentSize, - getElementSize -} from "../size" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Element offset - */ -export interface ElementOffset { - x: number /* Horizontal offset */ - y: number /* Vertical offset */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element offset - * - * @param el - Element - * - * @returns Element offset - */ -export function getElementOffset(el: HTMLElement): ElementOffset { - return { - x: el.scrollLeft, - y: el.scrollTop - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element offset - * - * @param el - Element - * - * @returns Element offset observable - */ -export function watchElementOffset( - el: HTMLElement -): Observable { - return merge( - fromEvent(el, "scroll"), - fromEvent(window, "resize") - ) - .pipe( - map(() => getElementOffset(el)), - startWith(getElementOffset(el)) - ) -} - -/** - * Watch element threshold - * - * This function returns an observable which emits whether the bottom scroll - * offset of an elements is within a certain threshold. - * - * @param el - Element - * @param threshold - Threshold - * - * @returns Element threshold observable - */ -export function watchElementThreshold( - el: HTMLElement, threshold = 16 -): Observable { - return watchElementOffset(el) - .pipe( - map(({ y }) => { - const visible = getElementSize(el) - const content = getElementContentSize(el) - return y >= ( - content.height - visible.height - threshold - ) - }), - distinctUntilChanged() - ) -} diff --git a/docs/src/assets/javascripts/browser/element/selection/index.ts b/docs/src/assets/javascripts/browser/element/selection/index.ts deleted file mode 100644 index ebbbaee0..00000000 --- a/docs/src/assets/javascripts/browser/element/selection/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set element text selection - * - * @param el - Element - */ -export function setElementSelection( - el: HTMLElement -): void { - if (el instanceof HTMLInputElement) - el.select() - else - throw new Error("Not implemented") -} diff --git a/docs/src/assets/javascripts/browser/element/size/index.ts b/docs/src/assets/javascripts/browser/element/size/index.ts deleted file mode 100644 index b45c29fb..00000000 --- a/docs/src/assets/javascripts/browser/element/size/index.ts +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - NEVER, - Observable, - Subject, - defer, - of -} from "rxjs" -import { - filter, - finalize, - map, - shareReplay, - startWith, - switchMap, - tap -} from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Element offset - */ -export interface ElementSize { - width: number /* Element width */ - height: number /* Element height */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Resize observer entry subject - */ -const entry$ = new Subject() - -/** - * Resize observer observable - * - * This observable will create a `ResizeObserver` on the first subscription - * and will automatically terminate it when there are no more subscribers. - * It's quite important to centralize observation in a single `ResizeObserver`, - * as the performance difference can be quite dramatic, as the link shows. - * - * @see https://bit.ly/3iIYfEm - Google Groups on performance - */ -const observer$ = defer(() => of( - new ResizeObserver(entries => { - for (const entry of entries) - entry$.next(entry) - }) -)) - .pipe( - switchMap(resize => NEVER.pipe(startWith(resize)) - .pipe( - finalize(() => resize.disconnect()) - ) - ), - shareReplay(1) - ) - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve element size - * - * @param el - Element - * - * @returns Element size - */ -export function getElementSize(el: HTMLElement): ElementSize { - return { - width: el.offsetWidth, - height: el.offsetHeight - } -} - -/** - * Retrieve element content size, i.e. including overflowing content - * - * @param el - Element - * - * @returns Element size - */ -export function getElementContentSize(el: HTMLElement): ElementSize { - return { - width: el.scrollWidth, - height: el.scrollHeight - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch element size - * - * This function returns an observable that subscribes to a single internal - * instance of `ResizeObserver` upon subscription, and emit resize events until - * termination. Note that this function should not be called with the same - * element twice, as the first unsubscription will terminate observation. - * - * Sadly, we can't use the `DOMRect` objects returned by the observer, because - * we need the emitted values to be consistent with `getElementSize`, which will - * return the used values (rounded) and not actual values (unrounded). Thus, we - * use the `offset*` properties. See the linked GitHub issue. - * - * @see https://bit.ly/3m0k3he - GitHub issue - * - * @param el - Element - * - * @returns Element size observable - */ -export function watchElementSize( - el: HTMLElement -): Observable { - return observer$ - .pipe( - tap(observer => observer.observe(el)), - switchMap(observer => entry$ - .pipe( - filter(({ target }) => target === el), - finalize(() => observer.unobserve(el)), - map(() => getElementSize(el)) - ) - ), - startWith(getElementSize(el)) - ) -} diff --git a/docs/src/assets/javascripts/browser/index.ts b/docs/src/assets/javascripts/browser/index.ts deleted file mode 100644 index 4c802761..00000000 --- a/docs/src/assets/javascripts/browser/index.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./document" -export * from "./element" -export * from "./keyboard" -export * from "./location" -export * from "./media" -export * from "./request" -export * from "./toggle" -export * from "./viewport" -export * from "./worker" diff --git a/docs/src/assets/javascripts/browser/keyboard/index.ts b/docs/src/assets/javascripts/browser/keyboard/index.ts deleted file mode 100644 index 8c7a46df..00000000 --- a/docs/src/assets/javascripts/browser/keyboard/index.ts +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent } from "rxjs" -import { filter, map, share } from "rxjs/operators" - -import { getActiveElement } from "../element" -import { getToggle } from "../toggle" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Keyboard mode - */ -export type KeyboardMode = - | "global" /* Global */ - | "search" /* Search is open */ - -/* ------------------------------------------------------------------------- */ - -/** - * Keyboard - */ -export interface Keyboard { - mode: KeyboardMode /* Keyboard mode */ - type: string /* Key type */ - claim(): void /* Key claim */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Check whether an element may receive keyboard input - * - * @param el - Element - * - * @returns Test result - */ -function isSusceptibleToKeyboard(el: HTMLElement): boolean { - switch (el.tagName) { - - /* Form elements */ - case "INPUT": - case "SELECT": - case "TEXTAREA": - return true - - /* Everything else */ - default: - return el.isContentEditable - } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch keyboard - * - * @returns Keyboard observable - */ -export function watchKeyboard(): Observable { - return fromEvent(window, "keydown") - .pipe( - filter(ev => !(ev.metaKey || ev.ctrlKey)), - map(ev => ({ - mode: getToggle("search") ? "search" : "global", - type: ev.key, - claim() { - ev.preventDefault() - ev.stopPropagation() - } - } as Keyboard)), - filter(({ mode }) => { - if (mode === "global") { - const active = getActiveElement() - if (typeof active !== "undefined") - return !isSusceptibleToKeyboard(active) - } - return true - }), - share() - ) -} diff --git a/docs/src/assets/javascripts/browser/location/_/index.ts b/docs/src/assets/javascripts/browser/location/_/index.ts deleted file mode 100644 index a2ab32dc..00000000 --- a/docs/src/assets/javascripts/browser/location/_/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Subject } from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve location - * - * This function returns a `URL` object (and not `Location`) to normalize the - * typings across the application. Furthermore, locations need to be tracked - * without setting them and `Location` is a singleton which represents the - * current location. - * - * @returns URL - */ -export function getLocation(): URL { - return new URL(location.href) -} - -/** - * Set location - * - * @param url - URL to change to - */ -export function setLocation(url: URL): void { - location.href = url.href -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch location - * - * @returns Location subject - */ -export function watchLocation(): Subject { - return new Subject() -} diff --git a/docs/src/assets/javascripts/browser/location/hash/index.ts b/docs/src/assets/javascripts/browser/location/hash/index.ts deleted file mode 100644 index 0118f243..00000000 --- a/docs/src/assets/javascripts/browser/location/hash/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent } from "rxjs" -import { - filter, - map, - shareReplay, - startWith -} from "rxjs/operators" - -import { getElement } from "~/browser" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve location hash - * - * @returns Location hash - */ -export function getLocationHash(): string { - return location.hash.substring(1) -} - -/** - * Set location hash - * - * Setting a new fragment identifier via `location.hash` will have no effect - * if the value doesn't change. When a new fragment identifier is set, we want - * the browser to target the respective element at all times, which is why we - * use this dirty little trick. - * - * @param hash - Location hash - */ -export function setLocationHash(hash: string): void { - const el = h("a", { href: hash }) - el.addEventListener("click", ev => ev.stopPropagation()) - el.click() -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch location hash - * - * @returns Location hash observable - */ -export function watchLocationHash(): Observable { - return fromEvent(window, "hashchange") - .pipe( - map(getLocationHash), - startWith(getLocationHash()), - filter(hash => hash.length > 0), - shareReplay(1) - ) -} - -/** - * Watch location target - * - * @returns Location target observable - */ -export function watchLocationTarget(): Observable { - return watchLocationHash() - .pipe( - map(id => getElement(`[id="${id}"]`)!), - filter(el => typeof el !== "undefined") - ) -} diff --git a/docs/src/assets/javascripts/browser/location/index.ts b/docs/src/assets/javascripts/browser/location/index.ts deleted file mode 100644 index 551a09ac..00000000 --- a/docs/src/assets/javascripts/browser/location/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./hash" diff --git a/docs/src/assets/javascripts/browser/media/index.ts b/docs/src/assets/javascripts/browser/media/index.ts deleted file mode 100644 index b6a9ae24..00000000 --- a/docs/src/assets/javascripts/browser/media/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - NEVER, - Observable, - fromEvent, - fromEventPattern -} from "rxjs" -import { - mapTo, - startWith, - switchMap -} from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch media query - * - * Note that although `MediaQueryList.addListener` is deprecated we have to - * use it, because it's the only way to ensure proper downward compatibility. - * - * @see https://bit.ly/3dUBH2m - GitHub issue - * - * @param query - Media query - * - * @returns Media observable - */ -export function watchMedia(query: string): Observable { - const media = matchMedia(query) - return fromEventPattern(next => ( - media.addListener(() => next(media.matches)) - )) - .pipe( - startWith(media.matches) - ) -} - -/** - * Watch print mode, cross-browser - * - * @returns Print mode observable - */ -export function watchPrint(): Observable { - return fromEvent(window, "beforeprint") - .pipe( - mapTo(undefined) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Toggle an observable with a media observable - * - * @template T - Data type - * - * @param query$ - Media observable - * @param factory - Observable factory - * - * @returns Toggled observable - */ -export function at( - query$: Observable, factory: () => Observable -): Observable { - return query$ - .pipe( - switchMap(active => active ? factory() : NEVER) - ) -} diff --git a/docs/src/assets/javascripts/browser/request/index.ts b/docs/src/assets/javascripts/browser/request/index.ts deleted file mode 100644 index c6f09a9f..00000000 --- a/docs/src/assets/javascripts/browser/request/index.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, from } from "rxjs" -import { - filter, - map, - shareReplay, - switchMap -} from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch the given URL - * - * @param url - Request URL - * @param options - Options - * - * @returns Response observable - */ -export function request( - url: URL | string, options: RequestInit = { credentials: "same-origin" } -): Observable { - return from(fetch(`${url}`, options)) - .pipe( - filter(res => res.status === 200), - ) -} - -/** - * Fetch JSON from the given URL - * - * @template T - Data type - * - * @param url - Request URL - * @param options - Options - * - * @returns Data observable - */ -export function requestJSON( - url: URL | string, options?: RequestInit -): Observable { - return request(url, options) - .pipe( - switchMap(res => res.json()), - shareReplay(1) - ) -} - -/** - * Fetch XML from the given URL - * - * @param url - Request URL - * @param options - Options - * - * @returns Data observable - */ -export function requestXML( - url: URL | string, options?: RequestInit -): Observable { - const dom = new DOMParser() - return request(url, options) - .pipe( - switchMap(res => res.text()), - map(res => dom.parseFromString(res, "text/xml")), - shareReplay(1) - ) -} diff --git a/docs/src/assets/javascripts/browser/toggle/index.ts b/docs/src/assets/javascripts/browser/toggle/index.ts deleted file mode 100644 index ae60577e..00000000 --- a/docs/src/assets/javascripts/browser/toggle/index.ts +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent } from "rxjs" -import { map, startWith } from "rxjs/operators" - -import { getElementOrThrow } from "../element" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Toggle - */ -export type Toggle = - | "drawer" /* Toggle for drawer */ - | "search" /* Toggle for search */ - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Toggle map - */ -const toggles: Record = { - drawer: getElementOrThrow("[data-md-toggle=drawer]"), - search: getElementOrThrow("[data-md-toggle=search]") -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the value of a toggle - * - * @param name - Toggle - * - * @returns Toggle value - */ -export function getToggle(name: Toggle): boolean { - return toggles[name].checked -} - -/** - * Set toggle - * - * Simulating a click event seems to be the most cross-browser compatible way - * of changing the value while also emitting a `change` event. Before, Material - * used `CustomEvent` to programmatically change the value of a toggle, but this - * is a much simpler and cleaner solution which doesn't require a polyfill. - * - * @param name - Toggle - * @param value - Toggle value - */ -export function setToggle(name: Toggle, value: boolean): void { - if (toggles[name].checked !== value) - toggles[name].click() -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch toggle - * - * @param name - Toggle - * - * @returns Toggle value observable - */ -export function watchToggle(name: Toggle): Observable { - const el = toggles[name] - return fromEvent(el, "change") - .pipe( - map(() => el.checked), - startWith(el.checked) - ) -} diff --git a/docs/src/assets/javascripts/browser/viewport/_/index.ts b/docs/src/assets/javascripts/browser/viewport/_/index.ts deleted file mode 100644 index 827d9716..00000000 --- a/docs/src/assets/javascripts/browser/viewport/_/index.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, combineLatest } from "rxjs" -import { - distinctUntilKeyChanged, - map, - shareReplay -} from "rxjs/operators" - -import { Header } from "~/components" - -import { - ViewportOffset, - watchViewportOffset -} from "../offset" -import { - ViewportSize, - watchViewportSize -} from "../size" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport - */ -export interface Viewport { - offset: ViewportOffset /* Viewport offset */ - size: ViewportSize /* Viewport size */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch at options - */ -interface WatchAtOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch viewport - * - * @returns Viewport observable - */ -export function watchViewport(): Observable { - return combineLatest([ - watchViewportOffset(), - watchViewportSize() - ]) - .pipe( - map(([offset, size]) => ({ offset, size })), - shareReplay(1) - ) -} - -/** - * Watch viewport relative to element - * - * @param el - Element - * @param options - Options - * - * @returns Viewport observable - */ -export function watchViewportAt( - el: HTMLElement, { viewport$, header$ }: WatchAtOptions -): Observable { - const size$ = viewport$ - .pipe( - distinctUntilKeyChanged("size") - ) - - /* Compute element offset */ - const offset$ = combineLatest([size$, header$]) - .pipe( - map((): ViewportOffset => ({ - x: el.offsetLeft, - y: el.offsetTop - })) - ) - - /* Compute relative viewport, return hot observable */ - return combineLatest([header$, viewport$, offset$]) - .pipe( - map(([{ height }, { offset, size }, { x, y }]) => ({ - offset: { - x: offset.x - x, - y: offset.y - y + height - }, - size - })) - ) -} diff --git a/docs/src/assets/javascripts/browser/viewport/index.ts b/docs/src/assets/javascripts/browser/viewport/index.ts deleted file mode 100644 index d43797f7..00000000 --- a/docs/src/assets/javascripts/browser/viewport/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./offset" -export * from "./size" diff --git a/docs/src/assets/javascripts/browser/viewport/offset/index.ts b/docs/src/assets/javascripts/browser/viewport/offset/index.ts deleted file mode 100644 index d9d81e82..00000000 --- a/docs/src/assets/javascripts/browser/viewport/offset/index.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, merge } from "rxjs" -import { map, startWith } from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport offset - */ -export interface ViewportOffset { - x: number /* Horizontal offset */ - y: number /* Vertical offset */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve viewport offset - * - * On iOS Safari, viewport offset can be negative due to overflow scrolling. - * As this may induce strange behaviors downstream, we'll just limit it to 0. - * - * @returns Viewport offset - */ -export function getViewportOffset(): ViewportOffset { - return { - x: Math.max(0, pageXOffset), - y: Math.max(0, pageYOffset) - } -} - -/** - * Set viewport offset - * - * @param offset - Viewport offset - */ -export function setViewportOffset( - { x, y }: Partial -): void { - window.scrollTo(x || 0, y || 0) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch viewport offset - * - * @returns Viewport offset observable - */ -export function watchViewportOffset(): Observable { - return merge( - fromEvent(window, "scroll", { passive: true }), - fromEvent(window, "resize", { passive: true }) - ) - .pipe( - map(getViewportOffset), - startWith(getViewportOffset()) - ) -} diff --git a/docs/src/assets/javascripts/browser/viewport/size/index.ts b/docs/src/assets/javascripts/browser/viewport/size/index.ts deleted file mode 100644 index 6bdfaaf8..00000000 --- a/docs/src/assets/javascripts/browser/viewport/size/index.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent } from "rxjs" -import { map, startWith } from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Viewport size - */ -export interface ViewportSize { - width: number /* Viewport width */ - height: number /* Viewport height */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve viewport size - * - * @returns Viewport size - */ -export function getViewportSize(): ViewportSize { - return { - width: innerWidth, - height: innerHeight - } -} - -/* ------------------------------------------------------------------------- */ - -/** - * Watch viewport size - * - * @returns Viewport size observable - */ -export function watchViewportSize(): Observable { - return fromEvent(window, "resize", { passive: true }) - .pipe( - map(getViewportSize), - startWith(getViewportSize()) - ) -} diff --git a/docs/src/assets/javascripts/browser/worker/index.ts b/docs/src/assets/javascripts/browser/worker/index.ts deleted file mode 100644 index aa30d139..00000000 --- a/docs/src/assets/javascripts/browser/worker/index.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, Subject, fromEvent } from "rxjs" -import { - map, - share, - switchMapTo, - tap, - throttle -} from "rxjs/operators" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Worker message - */ -export interface WorkerMessage { - type: unknown /* Message type */ - data?: unknown /* Message data */ -} - -/** - * Worker handler - * - * @template T - Message type - */ -export interface WorkerHandler< - T extends WorkerMessage -> { - tx$: Subject /* Message transmission subject */ - rx$: Observable /* Message receive observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - * - * @template T - Worker message type - */ -interface WatchOptions { - tx$: Observable /* Message transmission observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch a web worker - * - * This function returns an observable that sends all values emitted by the - * message observable to the web worker. Web worker communication is expected - * to be bidirectional (request-response) and synchronous. Messages that are - * emitted during a pending request are throttled, the last one is emitted. - * - * @param worker - Web worker - * @param options - Options - * - * @returns Worker message observable - */ -export function watchWorker( - worker: Worker, { tx$ }: WatchOptions -): Observable { - - /* Intercept messages from worker-like objects */ - const rx$ = fromEvent(worker, "message") - .pipe( - map(({ data }) => data as T) - ) - - /* Send and receive messages, return hot observable */ - return tx$ - .pipe( - throttle(() => rx$, { leading: true, trailing: true }), - tap(message => worker.postMessage(message)), - switchMapTo(rx$), - share() - ) -} diff --git a/docs/src/assets/javascripts/bundle.ts b/docs/src/assets/javascripts/bundle.ts deleted file mode 100644 index bd223041..00000000 --- a/docs/src/assets/javascripts/bundle.ts +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import "focus-visible" -import { NEVER, Subject, defer, merge } from "rxjs" -import { - delay, - filter, - map, - mergeWith, - shareReplay, - switchMap -} from "rxjs/operators" - -import { configuration, feature } from "./_" -import { - at, - getElement, - requestJSON, - setToggle, - watchDocument, - watchKeyboard, - watchLocation, - watchLocationTarget, - watchMedia, - watchPrint, - watchViewport -} from "./browser" -import { - getComponentElement, - getComponentElements, - mountBackToTop, - mountContent, - mountDialog, - mountHeader, - mountHeaderTitle, - mountPalette, - mountSearch, - mountSearchHiglight, - mountSidebar, - mountSource, - mountTableOfContents, - mountTabs, - watchHeader, - watchMain -} from "./components" -import { - SearchIndex, - setupClipboardJS, - setupInstantLoading, - setupVersionSelector -} from "./integrations" -import { - patchIndeterminate, - patchScrollfix, - patchScrolllock -} from "./patches" - -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ - -/* Yay, JavaScript is available */ -document.documentElement.classList.remove("no-js") -document.documentElement.classList.add("js") - -/* Set up navigation observables and subjects */ -const document$ = watchDocument() -const location$ = watchLocation() -const target$ = watchLocationTarget() -const keyboard$ = watchKeyboard() - -/* Set up media observables */ -const viewport$ = watchViewport() -const tablet$ = watchMedia("(min-width: 960px)") -const screen$ = watchMedia("(min-width: 1220px)") -const print$ = watchPrint() - -/* Retrieve search index, if search is enabled */ -const config = configuration() -const index$ = document.forms.namedItem("search") - ? __search?.index || requestJSON( - new URL("search/search_index.json", config.base) - ) - : NEVER - -/* Set up Clipboard.js integration */ -const alert$ = new Subject() -setupClipboardJS({ alert$ }) - -/* Set up instant loading, if enabled */ -if (feature("navigation.instant")) - setupInstantLoading({ document$, location$, viewport$ }) - -/* Set up version selector */ -if (config.version?.provider === "mike") - setupVersionSelector() - -/* Always close drawer and search on navigation */ -merge(location$, target$) - .pipe( - delay(125) - ) - .subscribe(() => { - setToggle("drawer", false) - setToggle("search", false) - }) - -/* Set up global keyboard handlers */ -keyboard$ - .pipe( - filter(({ mode }) => mode === "global") - ) - .subscribe(key => { - switch (key.type) { - - /* Go to previous page */ - case "p": - case ",": - const prev = getElement("[href][rel=prev]") - if (typeof prev !== "undefined") - prev.click() - break - - /* Go to next page */ - case "n": - case ".": - const next = getElement("[href][rel=next]") - if (typeof next !== "undefined") - next.click() - break - } - }) - -/* Set up patches */ -patchIndeterminate({ document$, tablet$ }) -patchScrollfix({ document$ }) -patchScrolllock({ viewport$, tablet$ }) - -/* Set up header and main area observable */ -const header$ = watchHeader(getComponentElement("header"), { viewport$ }) -const main$ = document$ - .pipe( - map(() => getComponentElement("main")), - switchMap(el => watchMain(el, { viewport$, header$ })), - shareReplay(1) - ) - -/* Set up control component observables */ -const control$ = merge( - - /* Dialog */ - ...getComponentElements("dialog") - .map(el => mountDialog(el, { alert$ })), - - /* Header */ - ...getComponentElements("header") - .map(el => mountHeader(el, { viewport$, header$, main$ })), - - /* Color palette */ - ...getComponentElements("palette") - .map(el => mountPalette(el)), - - /* Search */ - ...getComponentElements("search") - .map(el => mountSearch(el, { index$, keyboard$ })), - - /* Repository information */ - ...getComponentElements("source") - .map(el => mountSource(el)) -) - -/* Set up content component observables */ -const content$ = defer(() => merge( - - /* Content */ - ...getComponentElements("content") - .map(el => mountContent(el, { target$, viewport$, print$ })), - - /* Search highlighting */ - ...getComponentElements("content") - .map(el => feature("search.highlight") - ? mountSearchHiglight(el, { index$, location$ }) - : NEVER - ), - - /* Header title */ - ...getComponentElements("header-title") - .map(el => mountHeaderTitle(el, { viewport$, header$ })), - - /* Sidebar */ - ...getComponentElements("sidebar") - .map(el => el.getAttribute("data-md-type") === "navigation" - ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ })) - : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ })) - ), - - /* Navigation tabs */ - ...getComponentElements("tabs") - .map(el => mountTabs(el, { viewport$, header$ })), - - /* Table of contents */ - ...getComponentElements("toc") - .map(el => mountTableOfContents(el, { viewport$, header$ })), - - /* Back-to-top button */ - ...getComponentElements("top") - .map(el => mountBackToTop(el, { viewport$, header$, main$ })) -)) - -/* Set up component observables */ -const component$ = document$ - .pipe( - switchMap(() => content$), - mergeWith(control$), - shareReplay(1) - ) - -/* Subscribe to all components */ -component$.subscribe() - -/* ---------------------------------------------------------------------------- - * Exports - * ------------------------------------------------------------------------- */ - -window.document$ = document$ /* Document observable */ -window.location$ = location$ /* Location subject */ -window.target$ = target$ /* Location target observable */ -window.keyboard$ = keyboard$ /* Keyboard observable */ -window.viewport$ = viewport$ /* Viewport observable */ -window.tablet$ = tablet$ /* Tablet observable */ -window.screen$ = screen$ /* Screen observable */ -window.print$ = print$ /* Print mode observable */ -window.alert$ = alert$ /* Alert subject */ -window.component$ = component$ /* Component observable */ diff --git a/docs/src/assets/javascripts/components/_/index.ts b/docs/src/assets/javascripts/components/_/index.ts deleted file mode 100644 index 375372fc..00000000 --- a/docs/src/assets/javascripts/components/_/index.ts +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { getElementOrThrow, getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Component type - */ -export type ComponentType = - | "announce" /* Announcement bar */ - | "container" /* Container */ - | "content" /* Content */ - | "dialog" /* Dialog */ - | "header" /* Header */ - | "header-title" /* Header title */ - | "header-topic" /* Header topic */ - | "main" /* Main area */ - | "palette" /* Color palette */ - | "search" /* Search */ - | "search-query" /* Search input */ - | "search-result" /* Search results */ - | "search-share" /* Search sharing */ - | "search-suggest" /* Search suggestions */ - | "sidebar" /* Sidebar */ - | "skip" /* Skip link */ - | "source" /* Repository information */ - | "tabs" /* Navigation tabs */ - | "toc" /* Table of contents */ - | "top" /* Back-to-top button */ - -/** - * Component - * - * @template T - Component type - * @template U - Reference type - */ -export type Component< - T extends {} = {}, - U extends HTMLElement = HTMLElement -> = - T & { - ref: U /* Component reference */ - } - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Component type map - */ -interface ComponentTypeMap { - "announce": HTMLElement /* Announcement bar */ - "container": HTMLElement /* Container */ - "content": HTMLElement /* Content */ - "dialog": HTMLElement /* Dialog */ - "header": HTMLElement /* Header */ - "header-title": HTMLElement /* Header title */ - "header-topic": HTMLElement /* Header topic */ - "main": HTMLElement /* Main area */ - "palette": HTMLElement /* Color palette */ - "search": HTMLElement /* Search */ - "search-query": HTMLInputElement /* Search input */ - "search-result": HTMLElement /* Search results */ - "search-share": HTMLAnchorElement /* Search sharing */ - "search-suggest": HTMLElement /* Search suggestions */ - "sidebar": HTMLElement /* Sidebar */ - "skip": HTMLAnchorElement /* Skip link */ - "source": HTMLAnchorElement /* Repository information */ - "tabs": HTMLElement /* Navigation tabs */ - "toc": HTMLElement /* Table of contents */ - "top": HTMLAnchorElement /* Back-to-top button */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the element for a given component or throw a reference error - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Element - */ -export function getComponentElement( - type: T, node: ParentNode = document -): ComponentTypeMap[T] { - return getElementOrThrow(`[data-md-component=${type}]`, node) -} - -/** - * Retrieve all elements for a given component - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Elements - */ -export function getComponentElements( - type: T, node: ParentNode = document -): ComponentTypeMap[T][] { - return getElements(`[data-md-component=${type}]`, node) -} diff --git a/docs/src/assets/javascripts/components/content/_/index.ts b/docs/src/assets/javascripts/components/content/_/index.ts deleted file mode 100644 index ddd1504a..00000000 --- a/docs/src/assets/javascripts/components/content/_/index.ts +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, merge } from "rxjs" - -import { Viewport, getElements } from "~/browser" - -import { Component } from "../../_" -import { CodeBlock, mountCodeBlock } from "../code" -import { Details, mountDetails } from "../details" -import { DataTable, mountDataTable } from "../table" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Content - */ -export type Content = - | CodeBlock - | DataTable - | Details - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - target$: Observable /* Location target observable */ - viewport$: Observable /* Viewport observable */ - print$: Observable /* Print mode observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount content - * - * This function mounts all components that are found in the content of the - * actual article, including code blocks, data tables and details. - * - * @param el - Content element - * @param options - Options - * - * @returns Content component observable - */ -export function mountContent( - el: HTMLElement, { target$, viewport$, print$ }: MountOptions -): Observable> { - return merge( - - /* Code blocks */ - ...getElements("pre > code", el) - .map(child => mountCodeBlock(child, { viewport$ })), - - /* Data tables */ - ...getElements("table:not([class])", el) - .map(child => mountDataTable(child)), - - /* Details */ - ...getElements("details", el) - .map(child => mountDetails(child, { target$, print$ })) - ) -} diff --git a/docs/src/assets/javascripts/components/content/code/index.ts b/docs/src/assets/javascripts/components/content/code/index.ts deleted file mode 100644 index 142eb520..00000000 --- a/docs/src/assets/javascripts/components/content/code/index.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import ClipboardJS from "clipboard" -import { - NEVER, - Observable, - Subject, - fromEvent, - merge, - of -} from "rxjs" -import { - distinctUntilKeyChanged, - finalize, - map, - switchMap, - tap, - withLatestFrom -} from "rxjs/operators" - -import { resetFocusable, setFocusable } from "~/actions" -import { - Viewport, - getElementContentSize, - getElementSize, - getElements, - watchMedia -} from "~/browser" -import { renderClipboardButton } from "~/templates" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Code block - */ -export interface CodeBlock { - scroll: boolean /* Code block overflows */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable /* Viewport observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable /* Viewport observable */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Global index for Clipboard.js integration - */ -let index = 0 - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch code block - * - * This function monitors size changes of the viewport, as well as switches of - * content tabs with embedded code blocks, as both may trigger overflow. - * - * @param el - Code block element - * @param options - Options - * - * @returns Code block observable - */ -export function watchCodeBlock( - el: HTMLElement, { viewport$ }: WatchOptions -): Observable { - const container$ = of(el) - .pipe( - switchMap(child => { - const container = child.closest("[data-tabs]") - if (container instanceof HTMLElement) { - return merge( - ...getElements("input", container) - .map(input => fromEvent(input, "change")) - ) - } - return NEVER - }) - ) - - /* Check overflow on resize and tab change */ - return merge( - viewport$.pipe(distinctUntilKeyChanged("size")), - container$ - ) - .pipe( - map(() => { - const visible = getElementSize(el) - const content = getElementContentSize(el) - return { - scroll: content.width > visible.width - } - }), - distinctUntilKeyChanged("scroll") - ) -} - -/** - * Mount code block - * - * This function ensures that an overflowing code block is focusable through - * keyboard, so it can be scrolled without a mouse to improve on accessibility. - * - * @param el - Code block element - * @param options - Options - * - * @returns Code block component observable - */ -export function mountCodeBlock( - el: HTMLElement, options: MountOptions -): Observable> { - const internal$ = new Subject() - internal$ - .pipe( - withLatestFrom(watchMedia("(hover)")) - ) - .subscribe(([{ scroll }, hover]) => { - if (scroll && hover) - setFocusable(el) - else - resetFocusable(el) - }) - - /* Render button for Clipboard.js integration */ - if (ClipboardJS.isSupported()) { - const parent = el.closest("pre")! - parent.id = `__code_${index++}` - parent.insertBefore( - renderClipboardButton(parent.id), - el - ) - } - - /* Create and return component */ - return watchCodeBlock(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/content/details/index.ts b/docs/src/assets/javascripts/components/content/details/index.ts deleted file mode 100644 index 94fc6b02..00000000 --- a/docs/src/assets/javascripts/components/content/details/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, Subject } from "rxjs" -import { - filter, - finalize, - map, - mapTo, - mergeWith, - tap -} from "rxjs/operators" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Details - */ -export interface Details { - scroll?: boolean /* Scroll into view */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - target$: Observable /* Location target observable */ - print$: Observable /* Print mode observable */ -} - -/** - * Mount options - */ -interface MountOptions { - target$: Observable /* Location target observable */ - print$: Observable /* Print mode observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch details - * - * @param el - Details element - * @param options - Options - * - * @returns Details observable - */ -export function watchDetails( - el: HTMLDetailsElement, { target$, print$ }: WatchOptions -): Observable
{ - return target$ - .pipe( - map(target => target.closest("details:not([open])")!), - filter(details => el === details), - mapTo({ scroll: true }), - mergeWith(print$.pipe(mapTo({}))) - ) -} - -/** - * Mount details - * - * This function ensures that `details` tags are opened on anchor jumps and - * prior to printing, so the whole content of the page is visible. - * - * @param el - Details element - * @param options - Options - * - * @returns Details component observable - */ -export function mountDetails( - el: HTMLDetailsElement, options: MountOptions -): Observable> { - const internal$ = new Subject
() - internal$.subscribe(({ scroll }) => { - el.setAttribute("open", "") - if (scroll) - el.scrollIntoView() - }) - - /* Create and return component */ - return watchDetails(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - mapTo({ ref: el }) - ) -} diff --git a/docs/src/assets/javascripts/components/content/index.ts b/docs/src/assets/javascripts/components/content/index.ts deleted file mode 100644 index 5d1f2f32..00000000 --- a/docs/src/assets/javascripts/components/content/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./code" -export * from "./details" -export * from "./table" diff --git a/docs/src/assets/javascripts/components/content/table/index.ts b/docs/src/assets/javascripts/components/content/table/index.ts deleted file mode 100644 index 0066f338..00000000 --- a/docs/src/assets/javascripts/components/content/table/index.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, of } from "rxjs" - -import { replaceElement } from "~/browser" -import { renderTable } from "~/templates" -import { h } from "~/utilities" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Data table - */ -export interface DataTable {} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Sentinel for replacement - */ -const sentinel = h("table") - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount data table - * - * This function wraps a data table in another scrollable container, so it can - * be smoothly scrolled on smaller screen sizes and won't break the layout. - * - * @param el - Data table element - * - * @returns Data table component observable - */ -export function mountDataTable( - el: HTMLElement -): Observable> { - replaceElement(el, sentinel) - replaceElement(sentinel, renderTable(el)) - - /* Create and return component */ - return of({ ref: el }) -} diff --git a/docs/src/assets/javascripts/components/dialog/index.ts b/docs/src/assets/javascripts/components/dialog/index.ts deleted file mode 100644 index bad32614..00000000 --- a/docs/src/assets/javascripts/components/dialog/index.ts +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - merge, - of -} from "rxjs" -import { - delay, - finalize, - map, - observeOn, - switchMap, - tap -} from "rxjs/operators" - -import { - resetDialogState, - setDialogMessage, - setDialogState -} from "~/actions" - -import { Component } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Dialog - */ -export interface Dialog { - message: string /* Dialog message */ - open: boolean /* Dialog is visible */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - alert$: Subject /* Alert subject */ -} - -/** - * Mount options - */ -interface MountOptions { - alert$: Subject /* Alert subject */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch dialog - * - * @param _el - Dialog element - * @param options - Options - * - * @returns Dialog observable - */ -export function watchDialog( - _el: HTMLElement, { alert$ }: WatchOptions -): Observable { - return alert$ - .pipe( - switchMap(message => merge( - of(true), - of(false).pipe(delay(2000)) - ) - .pipe( - map(open => ({ message, open })) - ) - ) - ) -} - -/** - * Mount dialog - * - * This function reveals the dialog in the right cornerwhen a new alert is - * emitted through the subject that is passed as part of the options. - * - * @param el - Dialog element - * @param options - Options - * - * @returns Dialog component observable - */ -export function mountDialog( - el: HTMLElement, options: MountOptions -): Observable> { - const internal$ = new Subject() - internal$ - .pipe( - observeOn(animationFrameScheduler) - ) - .subscribe(({ message, open }) => { - setDialogMessage(el, message) - if (open) - setDialogState(el, "open") - else - resetDialogState(el) - }) - - /* Create and return component */ - return watchDialog(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/header/_/index.ts b/docs/src/assets/javascripts/components/header/_/index.ts deleted file mode 100644 index 4a5275ba..00000000 --- a/docs/src/assets/javascripts/components/header/_/index.ts +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest, - defer, - of -} from "rxjs" -import { - bufferCount, - combineLatestWith, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - map, - observeOn, - shareReplay, - startWith, - switchMap -} from "rxjs/operators" - -import { feature } from "~/_" -import { resetHeaderState, setHeaderState } from "~/actions" -import { - Viewport, - watchElementSize, - watchToggle -} from "~/browser" - -import { Component } from "../../_" -import { Main } from "../../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Header - */ -export interface Header { - height: number /* Header visible height */ - sticky: boolean /* Header stickyness */ - hidden: boolean /* User scrolled past threshold */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable /* Viewport observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ - main$: Observable
/* Main area observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Compute whether the header is hidden - * - * If the user scrolls past a certain threshold, the header can be hidden when - * scrolling down, and shown when scrolling up. - * - * @param options - Options - * - * @returns Toggle observable - */ -function isHidden({ viewport$ }: WatchOptions): Observable { - if (!feature("header.autohide")) - return of(false) - - /* Compute direction and turning point */ - const direction$ = viewport$ - .pipe( - map(({ offset: { y } }) => y), - bufferCount(2, 1), - map(([a, b]) => [a < b, b] as const), - distinctUntilKeyChanged(0) - ) - - /* Compute whether header should be hidden */ - const hidden$ = combineLatest([viewport$, direction$]) - .pipe( - filter(([{ offset }, [, y]]) => Math.abs(y - offset.y) > 100), - map(([, [direction]]) => direction), - distinctUntilChanged() - ) - - /* Compute threshold for hiding */ - const search$ = watchToggle("search") - return combineLatest([viewport$, search$]) - .pipe( - map(([{ offset }, search]) => offset.y > 400 && !search), - distinctUntilChanged(), - switchMap(active => active ? hidden$ : of(false)), - startWith(false) - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch header - * - * @param el - Header element - * @param options - Options - * - * @returns Header observable - */ -export function watchHeader( - el: HTMLElement, options: WatchOptions -): Observable
{ - return defer(() => { - const styles = getComputedStyle(el) - return of( - styles.position === "sticky" || - styles.position === "-webkit-sticky" - ) - }) - .pipe( - combineLatestWith(watchElementSize(el), isHidden(options)), - map(([sticky, { height }, hidden]) => ({ - height: sticky ? height : 0, - sticky, - hidden - })), - distinctUntilChanged((a, b) => ( - a.sticky === b.sticky && - a.height === b.height && - a.hidden === b.hidden - )), - shareReplay(1) - ) -} - -/** - * Mount header - * - * This function manages the different states of the header, i.e. whether it's - * hidden or rendered with a shadow. This depends heavily on the main area. - * - * @param el - Header element - * @param options - Options - * - * @returns Header component observable - */ -export function mountHeader( - el: HTMLElement, { header$, main$ }: MountOptions -): Observable> { - const internal$ = new Subject
() - internal$ - .pipe( - distinctUntilKeyChanged("active"), - combineLatestWith(header$), - observeOn(animationFrameScheduler) - ) - .subscribe(([{ active }, { hidden }]) => { - if (active) - setHeaderState(el, hidden ? "hidden" : "shadow") - else - resetHeaderState(el) - }) - - /* Connect to long-living subject and return component */ - main$.subscribe(main => internal$.next(main)) - return header$ - .pipe( - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/header/index.ts b/docs/src/assets/javascripts/components/header/index.ts deleted file mode 100644 index e98ef06a..00000000 --- a/docs/src/assets/javascripts/components/header/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./title" diff --git a/docs/src/assets/javascripts/components/header/title/index.ts b/docs/src/assets/javascripts/components/header/title/index.ts deleted file mode 100644 index 98283602..00000000 --- a/docs/src/assets/javascripts/components/header/title/index.ts +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - NEVER, - Observable, - Subject, - animationFrameScheduler -} from "rxjs" -import { - distinctUntilKeyChanged, - finalize, - map, - observeOn, - tap -} from "rxjs/operators" - -import { - resetHeaderTitleState, - setHeaderTitleState -} from "~/actions" -import { - Viewport, - getElement, - getElementSize, - watchViewportAt -} from "~/browser" - -import { Component } from "../../_" -import { Header } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Header - */ -export interface HeaderTitle { - active: boolean /* User scrolled past first headline */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch header title - * - * @param el - Heading element - * @param options - Options - * - * @returns Header title observable - */ -export function watchHeaderTitle( - el: HTMLHeadingElement, { viewport$, header$ }: WatchOptions -): Observable { - return watchViewportAt(el, { header$, viewport$ }) - .pipe( - map(({ offset: { y } }) => { - const { height } = getElementSize(el) - return { - active: y >= height - } - }), - distinctUntilKeyChanged("active") - ) -} - -/** - * Mount header title - * - * This function swaps the header title from the site title to the title of the - * current page when the user scrolls past the first headline. - * - * @param el - Header title element - * @param options - Options - * - * @returns Header title component observable - */ -export function mountHeaderTitle( - el: HTMLElement, options: MountOptions -): Observable> { - const internal$ = new Subject() - internal$ - .pipe( - observeOn(animationFrameScheduler) - ) - .subscribe(({ active }) => { - if (active) - setHeaderTitleState(el, "active") - else - resetHeaderTitleState(el) - }) - - /* Obtain headline, if any */ - const headline = getElement("article h1") - if (typeof headline === "undefined") - return NEVER - - /* Create and return component */ - return watchHeaderTitle(headline, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/index.ts b/docs/src/assets/javascripts/components/index.ts deleted file mode 100644 index 7f42bc38..00000000 --- a/docs/src/assets/javascripts/components/index.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./content" -export * from "./dialog" -export * from "./header" -export * from "./main" -export * from "./palette" -export * from "./search" -export * from "./sidebar" -export * from "./source" -export * from "./tabs" -export * from "./toc" -export * from "./top" diff --git a/docs/src/assets/javascripts/components/main/index.ts b/docs/src/assets/javascripts/components/main/index.ts deleted file mode 100644 index aac74e07..00000000 --- a/docs/src/assets/javascripts/components/main/index.ts +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - combineLatest -} from "rxjs" -import { - distinctUntilChanged, - distinctUntilKeyChanged, - map, - switchMap -} from "rxjs/operators" - -import { Viewport, watchElementSize } from "~/browser" - -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Main area - */ -export interface Main { - offset: number /* Main area top offset */ - height: number /* Main area visible height */ - active: boolean /* User scrolled past header */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch main area - * - * This function returns an observable that computes the visual parameters of - * the main area which depends on the viewport vertical offset and height, as - * well as the height of the header element, if the header is fixed. - * - * @param el - Main area element - * @param options - Options - * - * @returns Main area observable - */ -export function watchMain( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable
{ - - /* Compute necessary adjustment for header */ - const adjust$ = header$ - .pipe( - map(({ height }) => height), - distinctUntilChanged() - ) - - /* Compute the main area's top and bottom borders */ - const border$ = adjust$ - .pipe( - switchMap(() => watchElementSize(el) - .pipe( - map(({ height }) => ({ - top: el.offsetTop, - bottom: el.offsetTop + height - })), - distinctUntilKeyChanged("bottom") - ) - ) - ) - - /* Compute the main area's offset, visible height and if we scrolled past */ - return combineLatest([adjust$, border$, viewport$]) - .pipe( - map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => { - height = Math.max(0, height - - Math.max(0, top - y, header) - - Math.max(0, height + y - bottom) - ) - return { - offset: top - header, - height, - active: top - header <= y - } - }), - distinctUntilChanged((a, b) => ( - a.offset === b.offset && - a.height === b.height && - a.active === b.active - )) - ) -} diff --git a/docs/src/assets/javascripts/components/palette/index.ts b/docs/src/assets/javascripts/components/palette/index.ts deleted file mode 100644 index 100377f9..00000000 --- a/docs/src/assets/javascripts/components/palette/index.ts +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - fromEvent, - of -} from "rxjs" -import { - finalize, - map, - mapTo, - mergeMap, - shareReplay, - startWith, - tap -} from "rxjs/operators" - -import { getElements } from "~/browser" - -import { Component } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Palette colors - */ -export interface PaletteColor { - scheme?: string /* Color scheme */ - primary?: string /* Primary color */ - accent?: string /* Accent color */ -} - -/** - * Palette - */ -export interface Palette { - index: number /* Palette index */ - color: PaletteColor /* Palette colors */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch color palette - * - * @param inputs - Color palette element - * - * @returns Color palette observable - */ -export function watchPalette( - inputs: HTMLInputElement[] -): Observable { - const data = localStorage.getItem(__prefix("__palette"))! - const current = JSON.parse(data) || { - index: inputs.findIndex(input => ( - matchMedia(input.getAttribute("data-md-color-media")!).matches - )) - } - - /* Emit changes in color palette */ - const palette$ = of(...inputs) - .pipe( - mergeMap(input => fromEvent(input, "change") - .pipe( - mapTo(input) - ) - ), - startWith(inputs[Math.max(0, current.index)]), - map(input => ({ - index: inputs.indexOf(input), - color: { - scheme: input.getAttribute("data-md-color-scheme"), - primary: input.getAttribute("data-md-color-primary"), - accent: input.getAttribute("data-md-color-accent") - } - } as Palette)), - shareReplay(1) - ) - - /* Persist preference in local storage */ - palette$.subscribe(palette => { - localStorage.setItem(__prefix("__palette"), JSON.stringify(palette)) - }) - - /* Return palette */ - return palette$ -} - -/** - * Mount color palette - * - * @param el - Color palette element - * - * @returns Color palette component observable - */ -export function mountPalette( - el: HTMLElement -): Observable> { - const internal$ = new Subject() - - /* Set color palette */ - internal$.subscribe(palette => { - for (const [key, value] of Object.entries(palette.color)) - if (typeof value === "string") - document.body.setAttribute(`data-md-color-${key}`, value) - - /* Toggle visibility */ - for (let index = 0; index < inputs.length; index++) { - const label = inputs[index].nextElementSibling - if (label instanceof HTMLElement) - label.hidden = palette.index !== index - } - }) - - /* Create and return component */ - const inputs = getElements("input", el) - return watchPalette(inputs) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/search/_/index.ts b/docs/src/assets/javascripts/components/search/_/index.ts deleted file mode 100644 index 43d93836..00000000 --- a/docs/src/assets/javascripts/components/search/_/index.ts +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { NEVER, Observable, ObservableInput, merge } from "rxjs" -import { filter, mergeWith, sample, take } from "rxjs/operators" - -import { configuration } from "~/_" -import { - Keyboard, - getActiveElement, - getElements, - setElementFocus, - setElementSelection, - setToggle -} from "~/browser" -import { - SearchIndex, - SearchResult, - isSearchQueryMessage, - isSearchReadyMessage, - setupSearchWorker -} from "~/integrations" - -import { - Component, - getComponentElement, - getComponentElements -} from "../../_" -import { SearchQuery, mountSearchQuery } from "../query" -import { mountSearchResult } from "../result" -import { SearchShare, mountSearchShare } from "../share" -import { SearchSuggest, mountSearchSuggest } from "../suggest" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search - */ -export type Search = - | SearchQuery - | SearchResult - | SearchShare - | SearchSuggest - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - index$: ObservableInput /* Search index observable */ - keyboard$: Observable /* Keyboard observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search - * - * This function sets up the search functionality, including the underlying - * web worker and all keyboard bindings. - * - * @param el - Search element - * @param options - Options - * - * @returns Search component observable - */ -export function mountSearch( - el: HTMLElement, { index$, keyboard$ }: MountOptions -): Observable> { - const config = configuration() - try { - const url = __search?.worker || config.search - const worker = setupSearchWorker(url, index$) - - /* Retrieve query and result components */ - const query = getComponentElement("search-query", el) - const result = getComponentElement("search-result", el) - - /* Re-emit query when search is ready */ - const { tx$, rx$ } = worker - tx$ - .pipe( - filter(isSearchQueryMessage), - sample(rx$ - .pipe( - filter(isSearchReadyMessage), - take(1) - ) - ) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Set up search keyboard handlers */ - keyboard$ - .pipe( - filter(({ mode }) => mode === "search") - ) - .subscribe(key => { - const active = getActiveElement() - switch (key.type) { - - /* Enter: go to first (best) result */ - case "Enter": - if (active === query) { - const anchors = new Map() - for (const anchor of getElements( - ":first-child [href]", result - )) { - const article = anchor.firstElementChild! - anchors.set(anchor, parseFloat( - article.getAttribute("data-md-score")! - )) - } - - /* Go to result with highest score, if any */ - if (anchors.size) { - const [[best]] = [...anchors].sort(([, a], [, b]) => b - a) - best.click() - } - - /* Otherwise omit form submission */ - key.claim() - } - break - - /* Escape or Tab: close search */ - case "Escape": - case "Tab": - setToggle("search", false) - setElementFocus(query, false) - break - - /* Vertical arrows: select previous or next search result */ - case "ArrowUp": - case "ArrowDown": - if (typeof active === "undefined") { - setElementFocus(query) - } else { - const els = [query, ...getElements( - ":not(details) > [href], summary, details[open] [href]", - result - )] - const i = Math.max(0, ( - Math.max(0, els.indexOf(active)) + els.length + ( - key.type === "ArrowUp" ? -1 : +1 - ) - ) % els.length) - setElementFocus(els[i]) - } - - /* Prevent scrolling of page */ - key.claim() - break - - /* All other keys: hand to search query */ - default: - if (query !== getActiveElement()) - setElementFocus(query) - } - }) - - /* Set up global keyboard handlers */ - keyboard$ - .pipe( - filter(({ mode }) => mode === "global"), - ) - .subscribe(key => { - switch (key.type) { - - /* Open search and select query */ - case "f": - case "s": - case "/": - setElementFocus(query) - setElementSelection(query) - key.claim() - break - } - }) - - /* Create and return component */ - const query$ = mountSearchQuery(query, worker) - const result$ = mountSearchResult(result, worker, { query$ }) - return merge(query$, result$) - .pipe( - mergeWith( - - /* Search sharing */ - ...getComponentElements("search-share", el) - .map(child => mountSearchShare(child, { query$ })), - - /* Search suggestions */ - ...getComponentElements("search-suggest", el) - .map(child => mountSearchSuggest(child, worker, { keyboard$ })) - ) - ) - - /* Gracefully handle broken search */ - } catch (err) { - el.hidden = true - return NEVER - } -} diff --git a/docs/src/assets/javascripts/components/search/highlight/.eslintrc b/docs/src/assets/javascripts/components/search/highlight/.eslintrc deleted file mode 100644 index 38a5714d..00000000 --- a/docs/src/assets/javascripts/components/search/highlight/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "no-null/no-null": "off" - } -} diff --git a/docs/src/assets/javascripts/components/search/highlight/index.ts b/docs/src/assets/javascripts/components/search/highlight/index.ts deleted file mode 100644 index b54deea8..00000000 --- a/docs/src/assets/javascripts/components/search/highlight/index.ts +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - ObservableInput, - combineLatest -} from "rxjs" -import { filter, map, startWith } from "rxjs/operators" - -import { getLocation } from "~/browser" -import { - SearchIndex, - setupSearchHighlighter -} from "~/integrations" -import { h } from "~/utilities" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search highlighting - */ -export interface SearchHighlight { - nodes: Map /* Map of replacements */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - index$: ObservableInput /* Search index observable */ - location$: Observable /* Location observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search highlighting - * - * @param el - Content element - * @param options - Options - * - * @returns Search highlighting component observable - */ -export function mountSearchHiglight( - el: HTMLElement, { index$, location$ }: MountOptions -): Observable> { - return combineLatest([ - index$, - location$ - .pipe( - startWith(getLocation()), - filter(url => url.searchParams.has("h")) - ) - ]) - .pipe( - map(([index, url]) => setupSearchHighlighter(index.config, true)( - url.searchParams.get("h")! - )), - map(fn => { - const nodes = new Map() - - /* Traverse text nodes and collect matches */ - const it = document.createNodeIterator(el, NodeFilter.SHOW_TEXT) - for (let node = it.nextNode(); node; node = it.nextNode()) { - if (node.parentElement?.offsetHeight) { - const original = node.textContent! - const replaced = fn(original) - if (replaced.length > original.length) - nodes.set(node as ChildNode, replaced) - } - } - - /* Replace original nodes with matches */ - for (const [node, text] of nodes) { - const { childNodes } = h("span", null, text) - node.replaceWith(...Array.from(childNodes)) - } - - /* Return component */ - return { ref: el, nodes } - }) - ) -} diff --git a/docs/src/assets/javascripts/components/search/index.ts b/docs/src/assets/javascripts/components/search/index.ts deleted file mode 100644 index 074d324b..00000000 --- a/docs/src/assets/javascripts/components/search/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./highlight" -export * from "./query" -export * from "./result" -export * from "./share" -export * from "./suggest" diff --git a/docs/src/assets/javascripts/components/search/query/index.ts b/docs/src/assets/javascripts/components/search/query/index.ts deleted file mode 100644 index 0241983d..00000000 --- a/docs/src/assets/javascripts/components/search/query/index.ts +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - combineLatest, - fromEvent, - merge -} from "rxjs" -import { - delay, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - finalize, - map, - take, - takeLast, - takeUntil, - tap -} from "rxjs/operators" - -import { - resetSearchQueryPlaceholder, - setSearchQueryPlaceholder -} from "~/actions" -import { - getLocation, - setElementFocus, - setToggle, - watchElementFocus -} from "~/browser" -import { - SearchMessageType, - SearchQueryMessage, - SearchWorker, - defaultTransform, - isSearchReadyMessage -} from "~/integrations" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search query - */ -export interface SearchQuery { - value: string /* Query value */ - focus: boolean /* Query focus */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch search query - * - * Note that the focus event which triggers re-reading the current query value - * is delayed by `1ms` so the input's empty state is allowed to propagate. - * - * @param el - Search query element - * @param worker - Search worker - * - * @returns Search query observable - */ -export function watchSearchQuery( - el: HTMLInputElement, { rx$ }: SearchWorker -): Observable { - const fn = __search?.transform || defaultTransform - - /* Intercept focus and input events */ - const focus$ = watchElementFocus(el) - const value$ = merge( - fromEvent(el, "keyup"), - fromEvent(el, "focus").pipe(delay(1)) - ) - .pipe( - map(() => fn(el.value)), - distinctUntilChanged() - ) - - /* Intercept deep links */ - const location = getLocation() - if (location.searchParams.has("q")) { - setToggle("search", true) - rx$ - .pipe( - filter(isSearchReadyMessage), - take(1) - ) - .subscribe(() => { - el.value = location.searchParams.get("q")! - setElementFocus(el) - }) - } - - /* Combine into single observable */ - return combineLatest([value$, focus$]) - .pipe( - map(([value, focus]) => ({ value, focus })) - ) -} - -/** - * Mount search query - * - * @param el - Search query element - * @param worker - Search worker - * - * @returns Search query component observable - */ -export function mountSearchQuery( - el: HTMLInputElement, { tx$, rx$ }: SearchWorker -): Observable> { - const internal$ = new Subject() - - /* Handle value changes */ - internal$ - .pipe( - distinctUntilKeyChanged("value"), - map(({ value }): SearchQueryMessage => ({ - type: SearchMessageType.QUERY, - data: value - })) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Handle focus changes */ - internal$ - .pipe( - distinctUntilKeyChanged("focus") - ) - .subscribe(({ focus }) => { - if (focus) { - setToggle("search", focus) - setSearchQueryPlaceholder(el, "") - } else { - resetSearchQueryPlaceholder(el) - } - }) - - /* Handle reset */ - fromEvent(el.form!, "reset") - .pipe( - takeUntil(internal$.pipe(takeLast(1))) - ) - .subscribe(() => setElementFocus(el)) - - /* Create and return component */ - return watchSearchQuery(el, { tx$, rx$ }) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/search/result/index.ts b/docs/src/assets/javascripts/components/search/result/index.ts deleted file mode 100644 index 4b91e3aa..00000000 --- a/docs/src/assets/javascripts/components/search/result/index.ts +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - merge, - of -} from "rxjs" -import { - bufferCount, - filter, - finalize, - map, - observeOn, - switchMap, - take, - tap, - withLatestFrom, - zipWith -} from "rxjs/operators" - -import { - addToSearchResultList, - resetSearchResultList, - resetSearchResultMeta, - setSearchResultMeta -} from "~/actions" -import { - getElementOrThrow, - watchElementThreshold -} from "~/browser" -import { - SearchResult, - SearchWorker, - isSearchReadyMessage, - isSearchResultMessage -} from "~/integrations" -import { renderSearchResultItem } from "~/templates" - -import { Component } from "../../_" -import { SearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - query$: Observable /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search result list - * - * This function performs a lazy rendering of the search results, depending on - * the vertical offset of the search result container. - * - * @param el - Search result list element - * @param worker - Search worker - * @param options - Options - * - * @returns Search result list component observable - */ -export function mountSearchResult( - el: HTMLElement, { rx$ }: SearchWorker, { query$ }: MountOptions -): Observable> { - const internal$ = new Subject() - const boundary$ = watchElementThreshold(el.parentElement!) - .pipe( - filter(Boolean) - ) - - /* Retrieve nested components */ - const meta = getElementOrThrow(":scope > :first-child", el) - const list = getElementOrThrow(":scope > :last-child", el) - - /* Update search result metadata when ready */ - rx$ - .pipe( - filter(isSearchReadyMessage), - take(1) - ) - .subscribe(() => { - resetSearchResultMeta(meta) - }) - - /* Update search result metadata */ - internal$ - .pipe( - observeOn(animationFrameScheduler), - withLatestFrom(query$) - ) - .subscribe(([{ items }, { value }]) => { - if (value) - setSearchResultMeta(meta, items.length) - else - resetSearchResultMeta(meta) - }) - - /* Update search result list */ - internal$ - .pipe( - observeOn(animationFrameScheduler), - tap(() => resetSearchResultList(list)), - switchMap(({ items }) => merge( - of(...items.slice(0, 10)), - of(...items.slice(10)) - .pipe( - bufferCount(4), - zipWith(boundary$), - switchMap(([chunk]) => of(...chunk)) - ) - )) - ) - .subscribe(result => { - addToSearchResultList(list, renderSearchResultItem(result)) - }) - - /* Filter search result message */ - const result$ = rx$ - .pipe( - filter(isSearchResultMessage), - map(({ data }) => data) - ) - - /* Create and return component */ - return result$ - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/search/share/index.ts b/docs/src/assets/javascripts/components/search/share/index.ts deleted file mode 100644 index 67056b77..00000000 --- a/docs/src/assets/javascripts/components/search/share/index.ts +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - fromEvent -} from "rxjs" -import { - finalize, - map, - tap -} from "rxjs/operators" - -import { getLocation } from "~/browser" - -import { Component } from "../../_" -import { SearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search sharing - */ -export interface SearchShare { - url: URL /* Deep link for sharing */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - query$: Observable /* Search query observable */ -} - -/** - * Mount options - */ -interface MountOptions { - query$: Observable /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search sharing - * - * @param _el - Search sharing element - * @param options - Options - * - * @returns Search sharing observable - */ -export function watchSearchShare( - _el: HTMLElement, { query$ }: WatchOptions -): Observable { - return query$ - .pipe( - map(({ value }) => { - const url = getLocation() - url.hash = "" - url.searchParams.delete("h") - url.searchParams.set("q", value) - return { url } - }) - ) -} - -/** - * Mount search sharing - * - * @param el - Search sharing element - * @param options - Options - * - * @returns Search sharing component observable - */ -export function mountSearchShare( - el: HTMLAnchorElement, options: MountOptions -): Observable> { - const internal$ = new Subject() - internal$.subscribe(({ url }) => { - el.setAttribute("data-clipboard-text", el.href) - el.href = `${url}` - }) - - /* Prevent following of link */ - fromEvent(el, "click") - .subscribe(ev => ev.preventDefault()) - - /* Create and return component */ - return watchSearchShare(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/search/suggest/index.ts b/docs/src/assets/javascripts/components/search/suggest/index.ts deleted file mode 100644 index b743e547..00000000 --- a/docs/src/assets/javascripts/components/search/suggest/index.ts +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - asyncScheduler, - fromEvent -} from "rxjs" -import { - combineLatestWith, - distinctUntilChanged, - filter, - finalize, - map, - observeOn, - tap -} from "rxjs/operators" - -import { Keyboard } from "~/browser" -import { - SearchResult, - SearchWorker, - isSearchResultMessage -} from "~/integrations" - -import { Component, getComponentElement } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search suggestions - */ -export interface SearchSuggest {} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Mount options - */ -interface MountOptions { - keyboard$: Observable /* Keyboard observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount search suggestions - * - * This function will perform a lazy rendering of the search results, depending - * on the vertical offset of the search result container. - * - * @param el - Search result list element - * @param worker - Search worker - * @param options - Options - * - * @returns Search result list component observable - */ -export function mountSearchSuggest( - el: HTMLElement, { rx$ }: SearchWorker, { keyboard$ }: MountOptions -): Observable> { - const internal$ = new Subject() - - /* Retrieve query component and track all changes */ - const query = getComponentElement("search-query") - const query$ = fromEvent(query, "keydown") - .pipe( - observeOn(asyncScheduler), - map(() => query.value), - distinctUntilChanged(), - ) - - /* Update search suggestions */ - internal$ - .pipe( - combineLatestWith(query$), - map(([{ suggestions }, value]) => { - const words = value.split(/([\s-]+)/) - if (suggestions?.length && words[words.length - 1]) { - const last = suggestions[suggestions.length - 1] - if (last.startsWith(words[words.length - 1])) - words[words.length - 1] = last - } else { - words.length = 0 - } - return words - }) - ) - .subscribe(words => el.innerHTML = words - .join("") - .replace(/\s/g, " ") - ) - - /* Set up search keyboard handlers */ - keyboard$ - .pipe( - filter(({ mode }) => mode === "search") - ) - .subscribe(key => { - switch (key.type) { - - /* Right arrow: accept current suggestion */ - case "ArrowRight": - if ( - el.innerText.length && - query.selectionStart === query.value.length - ) - query.value = el.innerText - break - } - }) - - /* Filter search result message */ - const result$ = rx$ - .pipe( - filter(isSearchResultMessage), - map(({ data }) => data) - ) - - /* Create and return component */ - return result$ - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(() => ({ ref: el })) - ) -} diff --git a/docs/src/assets/javascripts/components/sidebar/index.ts b/docs/src/assets/javascripts/components/sidebar/index.ts deleted file mode 100644 index 5be71632..00000000 --- a/docs/src/assets/javascripts/components/sidebar/index.ts +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest -} from "rxjs" -import { - distinctUntilChanged, - finalize, - map, - observeOn, - tap, - withLatestFrom -} from "rxjs/operators" - -import { - resetSidebarHeight, - resetSidebarOffset, - setSidebarHeight, - setSidebarOffset -} from "~/actions" -import { Viewport } from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" -import { Main } from "../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Sidebar - */ -export interface Sidebar { - height: number /* Sidebar height */ - locked: boolean /* User scrolled past header */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable /* Viewport observable */ - main$: Observable
/* Main area observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ - main$: Observable
/* Main area observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch sidebar - * - * This function returns an observable that computes the visual parameters of - * the sidebar which depends on the vertical viewport offset, as well as the - * height of the main area. When the page is scrolled beyond the header, the - * sidebar is locked and fills the remaining space. - * - * @param el - Sidebar element - * @param options - Options - * - * @returns Sidebar observable - */ -export function watchSidebar( - el: HTMLElement, { viewport$, main$ }: WatchOptions -): Observable { - const adjust = - el.parentElement!.offsetTop - - el.parentElement!.parentElement!.offsetTop - - /* Compute the sidebar's available height and if it should be locked */ - return combineLatest([main$, viewport$]) - .pipe( - map(([{ offset, height }, { offset: { y } }]) => { - height = height - + Math.min(adjust, Math.max(0, y - offset)) - - adjust - return { - height, - locked: y >= offset + adjust - } - }), - distinctUntilChanged((a, b) => ( - a.height === b.height && - a.locked === b.locked - )) - ) -} - -/** - * Mount sidebar - * - * @param el - Sidebar element - * @param options - Options - * - * @returns Sidebar component observable - */ -export function mountSidebar( - el: HTMLElement, { header$, ...options }: MountOptions -): Observable> { - const internal$ = new Subject() - internal$ - .pipe( - observeOn(animationFrameScheduler), - withLatestFrom(header$) - ) - .subscribe({ - - /* Update height and offset */ - next([{ height }, { height: offset }]) { - setSidebarHeight(el, height) - setSidebarOffset(el, offset) - }, - - /* Reset on complete */ - complete() { - resetSidebarOffset(el) - resetSidebarHeight(el) - } - }) - - /* Create and return component */ - return watchSidebar(el, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/source/_/index.ts b/docs/src/assets/javascripts/components/source/_/index.ts deleted file mode 100644 index d99549f0..00000000 --- a/docs/src/assets/javascripts/components/source/_/index.ts +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { NEVER, Observable, Subject, defer, of } from "rxjs" -import { - catchError, - filter, - finalize, - map, - shareReplay, - tap -} from "rxjs/operators" - -import { setSourceFacts, setSourceState } from "~/actions" -import { renderSourceFacts } from "~/templates" - -import { Component } from "../../_" -import { SourceFacts, fetchSourceFacts } from "../facts" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Repository information - */ -export interface Source { - facts: SourceFacts /* Repository facts */ -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Repository information observable - */ -let fetch$: Observable - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch repository information - * - * This function tries to read the repository facts from session storage, and - * if unsuccessful, fetches them from the underlying provider. - * - * @param el - Repository information element - * - * @returns Repository information observable - */ -export function watchSource( - el: HTMLAnchorElement -): Observable { - return fetch$ ||= defer(() => { - const data = sessionStorage.getItem(__prefix("__source")) - if (data) { - return of(JSON.parse(data)) - } else { - const value$ = fetchSourceFacts(el.href) - value$.subscribe(value => { - try { - sessionStorage.setItem(__prefix("__source"), JSON.stringify(value)) - } catch (err) { - /* Uncritical, just swallow */ - } - }) - - /* Return value */ - return value$ - } - }) - .pipe( - catchError(() => NEVER), - filter(facts => Object.keys(facts).length > 0), - map(facts => ({ facts })), - shareReplay(1) - ) -} - -/** - * Mount repository information - * - * @param el - Repository information element - * - * @returns Repository information component observable - */ -export function mountSource( - el: HTMLAnchorElement -): Observable> { - const internal$ = new Subject() - internal$.subscribe(({ facts }) => { - setSourceFacts(el, renderSourceFacts(facts)) - setSourceState(el, "done") - }) - - /* Create and return component */ - return watchSource(el) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/source/facts/_/index.ts b/docs/src/assets/javascripts/components/source/facts/_/index.ts deleted file mode 100644 index 10ca37ba..00000000 --- a/docs/src/assets/javascripts/components/source/facts/_/index.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { NEVER, Observable } from "rxjs" - -import { fetchSourceFactsFromGitHub } from "../github" -import { fetchSourceFactsFromGitLab } from "../gitlab" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Repository facts for repositories - */ -export interface RepositoryFacts { - stars?: number /* Number of stars */ - forks?: number /* Number of forks */ - version?: string /* Latest version */ -} - -/** - * Repository facts for organizations - */ -export interface OrganizationFacts { - repositories?: number /* Number of repositories */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Repository facts - */ -export type SourceFacts = - | RepositoryFacts - | OrganizationFacts - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch repository facts - * - * @param url - Repository URL - * - * @returns Repository facts observable - */ -export function fetchSourceFacts( - url: string -): Observable { - const [type] = url.match(/(git(?:hub|lab))/i) || [] - switch (type.toLowerCase()) { - - /* GitHub repository */ - case "github": - const [, user, repo] = url.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i)! - return fetchSourceFactsFromGitHub(user, repo) - - /* GitLab repository */ - case "gitlab": - const [, base, slug] = url.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i)! - return fetchSourceFactsFromGitLab(base, slug) - - /* Everything else */ - default: - return NEVER - } -} diff --git a/docs/src/assets/javascripts/components/source/facts/github/index.ts b/docs/src/assets/javascripts/components/source/facts/github/index.ts deleted file mode 100644 index cdf325f4..00000000 --- a/docs/src/assets/javascripts/components/source/facts/github/index.ts +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Repo, User } from "github-types" -import { Observable, zip } from "rxjs" -import { defaultIfEmpty, map } from "rxjs/operators" - -import { requestJSON } from "~/browser" - -import { SourceFacts } from "../_" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * GitHub release (partial) - */ -interface Release { - tag_name: string /* Tag name */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch GitHub repository facts - * - * @param user - GitHub user - * @param repo - GitHub repository - * - * @returns Repository facts observable - */ -export function fetchSourceFactsFromGitHub( - user: string, repo?: string -): Observable { - if (typeof repo !== "undefined") { - const url = `https://api.github.com/repos/${user}/${repo}` - return zip( - - /* Fetch version */ - requestJSON(`${url}/releases/latest`) - .pipe( - map(release => ({ - version: release.tag_name - })), - defaultIfEmpty({}) - ), - - /* Fetch stars and forks */ - requestJSON(url) - .pipe( - map(info => ({ - stars: info.stargazers_count, - forks: info.forks_count - })), - defaultIfEmpty({}) - ) - ) - .pipe( - map(([release, info]) => ({ ...release, ...info })) - ) - - /* User or organization */ - } else { - const url = `https://api.github.com/repos/${user}` - return requestJSON(url) - .pipe( - map(info => ({ - repositories: info.public_repos - })), - defaultIfEmpty({}) - ) - } -} diff --git a/docs/src/assets/javascripts/components/source/facts/gitlab/index.ts b/docs/src/assets/javascripts/components/source/facts/gitlab/index.ts deleted file mode 100644 index 0d80e2fa..00000000 --- a/docs/src/assets/javascripts/components/source/facts/gitlab/index.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { ProjectSchema } from "gitlab" -import { Observable } from "rxjs" -import { defaultIfEmpty, map } from "rxjs/operators" - -import { requestJSON } from "~/browser" - -import { SourceFacts } from "../_" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch GitLab repository facts - * - * @param base - GitLab base - * @param project - GitLab project - * - * @returns Repository facts observable - */ -export function fetchSourceFactsFromGitLab( - base: string, project: string -): Observable { - const url = `https://${base}/api/v4/projects/${encodeURIComponent(project)}` - return requestJSON(url) - .pipe( - map(({ star_count, forks_count }) => ({ - stars: star_count, - forks: forks_count - })), - defaultIfEmpty({}) - ) -} diff --git a/docs/src/assets/javascripts/components/source/facts/index.ts b/docs/src/assets/javascripts/components/source/facts/index.ts deleted file mode 100644 index 9d88a9c6..00000000 --- a/docs/src/assets/javascripts/components/source/facts/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./github" -export * from "./gitlab" diff --git a/docs/src/assets/javascripts/components/source/index.ts b/docs/src/assets/javascripts/components/source/index.ts deleted file mode 100644 index 64468ace..00000000 --- a/docs/src/assets/javascripts/components/source/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./facts" diff --git a/docs/src/assets/javascripts/components/tabs/index.ts b/docs/src/assets/javascripts/components/tabs/index.ts deleted file mode 100644 index d925e12e..00000000 --- a/docs/src/assets/javascripts/components/tabs/index.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - of -} from "rxjs" -import { - distinctUntilKeyChanged, - finalize, - map, - observeOn, - switchMap, - tap -} from "rxjs/operators" - -import { feature } from "~/_" -import { resetTabsState, setTabsState } from "~/actions" -import { - Viewport, - watchElementSize, - watchViewportAt -} from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Navigation tabs - */ -export interface Tabs { - hidden: boolean /* User scrolled past tabs */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch navigation tabs - * - * @param el - Navigation tabs element - * @param options - Options - * - * @returns Navigation tabs observable - */ -export function watchTabs( - el: HTMLElement, { viewport$, header$ }: WatchOptions -): Observable { - return watchElementSize(document.body) - .pipe( - switchMap(() => watchViewportAt(el, { header$, viewport$ })), - map(({ offset: { y } }) => { - return { - hidden: y >= 10 - } - }), - distinctUntilKeyChanged("hidden") - ) -} - -/** - * Mount navigation tabs - * - * This function hides the navigation tabs when scrolling past the threshold - * and makes them reappear in a nice CSS animation when scrolling back up. - * - * @param el - Navigation tabs element - * @param options - Options - * - * @returns Navigation tabs component observable - */ -export function mountTabs( - el: HTMLElement, options: MountOptions -): Observable> { - const internal$ = new Subject() - internal$ - .pipe( - observeOn(animationFrameScheduler) - ) - .subscribe({ - - /* Update state */ - next({ hidden }) { - if (hidden) - setTabsState(el, "hidden") - else - resetTabsState(el) - }, - - /* Reset on complete */ - complete() { - resetTabsState(el) - } - }) - - /* Create and return component */ - return ( - feature("navigation.tabs.sticky") - ? of({ hidden: false }) - : watchTabs(el, options) - ) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/toc/index.ts b/docs/src/assets/javascripts/components/toc/index.ts deleted file mode 100644 index 6969d70e..00000000 --- a/docs/src/assets/javascripts/components/toc/index.ts +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest -} from "rxjs" -import { - bufferCount, - distinctUntilChanged, - distinctUntilKeyChanged, - finalize, - map, - observeOn, - scan, - startWith, - switchMap, - tap -} from "rxjs/operators" - -import { - resetAnchorActive, - resetAnchorState, - setAnchorActive, - setAnchorState -} from "~/actions" -import { - Viewport, - getElement, - getElements, - watchElementSize -} from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Table of contents - */ -export interface TableOfContents { - prev: HTMLAnchorElement[][] /* Anchors (previous) */ - next: HTMLAnchorElement[][] /* Anchors (next) */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch table of contents - * - * This is effectively a scroll spy implementation which will account for the - * fixed header and automatically re-calculate anchor offsets when the viewport - * is resized. The returned observable will only emit if the table of contents - * needs to be repainted. - * - * This implementation tracks an anchor element's entire path starting from its - * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the - * Material theme currently doesn't make use of this information, it enables - * the styling of the entire hierarchy through customization. - * - * Note that the current anchor is the last item of the `prev` anchor list. - * - * @param anchors - Anchor elements - * @param options - Options - * - * @returns Table of contents observable - */ -export function watchTableOfContents( - anchors: HTMLAnchorElement[], { viewport$, header$ }: WatchOptions -): Observable { - const table = new Map() - for (const anchor of anchors) { - const id = decodeURIComponent(anchor.hash.substring(1)) - const target = getElement(`[id="${id}"]`) - if (typeof target !== "undefined") - table.set(anchor, target) - } - - /* Compute necessary adjustment for header */ - const adjust$ = header$ - .pipe( - map(header => 24 + header.height) - ) - - /* Compute partition of previous and next anchors */ - const partition$ = watchElementSize(document.body) - .pipe( - distinctUntilKeyChanged("height"), - - /* Build index to map anchor paths to vertical offsets */ - map(() => { - let path: HTMLAnchorElement[] = [] - return [...table].reduce((index, [anchor, target]) => { - while (path.length) { - const last = table.get(path[path.length - 1])! - if (last.tagName >= target.tagName) { - path.pop() - } else { - break - } - } - - /* If the current anchor is hidden, continue with its parent */ - let offset = target.offsetTop - while (!offset && target.parentElement) { - target = target.parentElement - offset = target.offsetTop - } - - /* Map reversed anchor path to vertical offset */ - return index.set( - [...path = [...path, anchor]].reverse(), - offset - ) - }, new Map()) - }), - - /* Sort index by vertical offset (see https://bit.ly/30z6QSO) */ - map(index => new Map([...index].sort(([, a], [, b]) => a - b))), - - /* Re-compute partition when viewport offset changes */ - switchMap(index => combineLatest([adjust$, viewport$]) - .pipe( - scan(([prev, next], [adjust, { offset: { y } }]) => { - - /* Look forward */ - while (next.length) { - const [, offset] = next[0] - if (offset - adjust < y) { - prev = [...prev, next.shift()!] - } else { - break - } - } - - /* Look backward */ - while (prev.length) { - const [, offset] = prev[prev.length - 1] - if (offset - adjust >= y) { - next = [prev.pop()!, ...next] - } else { - break - } - } - - /* Return partition */ - return [prev, next] - }, [[], [...index]]), - distinctUntilChanged((a, b) => ( - a[0] === b[0] && - a[1] === b[1] - )) - ) - ) - ) - - /* Compute and return anchor list migrations */ - return partition$ - .pipe( - map(([prev, next]) => ({ - prev: prev.map(([path]) => path), - next: next.map(([path]) => path) - })), - - /* Extract anchor list migrations */ - startWith({ prev: [], next: [] }), - bufferCount(2, 1), - map(([a, b]) => { - - /* Moving down */ - if (a.prev.length < b.prev.length) { - return { - prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length), - next: [] - } - - /* Moving up */ - } else { - return { - prev: b.prev.slice(-1), - next: b.next.slice(0, b.next.length - a.next.length) - } - } - }) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Mount table of contents - * - * @param el - Anchor list element - * @param options - Options - * - * @returns Table of contents component observable - */ -export function mountTableOfContents( - el: HTMLElement, options: MountOptions -): Observable> { - const internal$ = new Subject() - internal$ - .pipe( - observeOn(animationFrameScheduler), - ) - .subscribe(({ prev, next }) => { - - /* Look forward */ - for (const [anchor] of next) { - resetAnchorActive(anchor) - resetAnchorState(anchor) - } - - /* Look backward */ - for (const [index, [anchor]] of prev.entries()) { - setAnchorActive(anchor, index === prev.length - 1) - setAnchorState(anchor, "blur") - } - }) - - /* Create and return component */ - const anchors = getElements("[href^=\\#]", el) - return watchTableOfContents(anchors, options) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/components/top/index.ts b/docs/src/assets/javascripts/components/top/index.ts deleted file mode 100644 index 9b317f04..00000000 --- a/docs/src/assets/javascripts/components/top/index.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest -} from "rxjs" -import { - bufferCount, - distinctUntilChanged, - distinctUntilKeyChanged, - finalize, - map, - observeOn, - tap, - withLatestFrom -} from "rxjs/operators" - -import { - resetBackToTopOffset, - resetBackToTopState, - resetFocusable, - setBackToTopOffset, - setBackToTopState, - setFocusable -} from "~/actions" -import { Viewport, setElementFocus } from "~/browser" - -import { Component } from "../_" -import { Header } from "../header" -import { Main } from "../main" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Back-to-top button - */ -export interface BackToTop { - hidden: boolean /* User scrolled up */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ - main$: Observable
/* Main area observable */ -} - -/** - * Mount options - */ -interface MountOptions { - viewport$: Observable /* Viewport observable */ - header$: Observable
/* Header observable */ - main$: Observable
/* Main area observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch back-to-top - * - * @param _el - Back-to-top element - * @param options - Options - * - * @returns Back-to-top observable - */ -export function watchBackToTop( - _el: HTMLElement, { viewport$, main$ }: WatchOptions -): Observable { - - /* Compute direction */ - const direction$ = viewport$ - .pipe( - map(({ offset: { y } }) => y), - bufferCount(2, 1), - map(([a, b]) => a > b && b), - distinctUntilChanged() - ) - - /* Compute whether button should be hidden */ - const hidden$ = main$ - .pipe( - distinctUntilKeyChanged("active") - ) - - /* Compute threshold for hiding */ - return combineLatest([hidden$, direction$]) - .pipe( - map(([{ active }, direction]) => ({ - hidden: !(active && direction) - })), - distinctUntilChanged((a, b) => ( - a.hidden === b.hidden - )) - ) -} - -/* ------------------------------------------------------------------------- */ - -/** - * Mount back-to-top - * - * @param el - Back-to-top element - * @param options - Options - * - * @returns Back-to-top component observable - */ -export function mountBackToTop( - el: HTMLElement, { viewport$, header$, main$ }: MountOptions -): Observable> { - const internal$ = new Subject() - internal$ - .pipe( - observeOn(animationFrameScheduler), - withLatestFrom(header$ - .pipe( - distinctUntilKeyChanged("height") - ) - ) - ) - .subscribe({ - - /* Update state */ - next([{ hidden }, { height }]) { - setBackToTopOffset(el, height + 16) - if (hidden) { - setBackToTopState(el, "hidden") - setElementFocus(el, false) - setFocusable(el, -1) - } else { - resetBackToTopState(el) - resetFocusable(el) - } - }, - - /* Reset on complete */ - complete() { - resetBackToTopOffset(el) - resetBackToTopState(el) - resetFocusable(el) - } - }) - - /* Create and return component */ - return watchBackToTop(el, { viewport$, header$, main$ }) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/assets/javascripts/integrations/clipboard/index.ts b/docs/src/assets/javascripts/integrations/clipboard/index.ts deleted file mode 100644 index e27c2601..00000000 --- a/docs/src/assets/javascripts/integrations/clipboard/index.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import ClipboardJS from "clipboard" -import { Observable, Subject } from "rxjs" - -import { translation } from "~/_" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Setup options - */ -interface SetupOptions { - alert$: Subject /* Alert subject */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up Clipboard.js integration - * - * @param options - Options - */ -export function setupClipboardJS( - { alert$ }: SetupOptions -): void { - if (ClipboardJS.isSupported()) { - new Observable(subscriber => { - new ClipboardJS("[data-clipboard-target], [data-clipboard-text]") - .on("success", ev => subscriber.next(ev)) - }) - .subscribe(() => alert$.next(translation("clipboard.copied"))) - } -} diff --git a/docs/src/assets/javascripts/integrations/index.ts b/docs/src/assets/javascripts/integrations/index.ts deleted file mode 100644 index 6a1e986b..00000000 --- a/docs/src/assets/javascripts/integrations/index.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./clipboard" -export * from "./instant" -export * from "./search" -export * from "./version" diff --git a/docs/src/assets/javascripts/integrations/instant/.eslintrc b/docs/src/assets/javascripts/integrations/instant/.eslintrc deleted file mode 100644 index 5adf108a..00000000 --- a/docs/src/assets/javascripts/integrations/instant/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "no-self-assign": "off", - "no-null/no-null": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/instant/index.ts b/docs/src/assets/javascripts/integrations/instant/index.ts deleted file mode 100644 index 63b81ee4..00000000 --- a/docs/src/assets/javascripts/integrations/instant/index.ts +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - EMPTY, - NEVER, - Observable, - Subject, - fromEvent, - merge, - of -} from "rxjs" -import { - bufferCount, - catchError, - concatMap, - debounceTime, - distinctUntilChanged, - distinctUntilKeyChanged, - filter, - map, - sample, - share, - skip, - skipUntil, - switchMap -} from "rxjs/operators" - -import { configuration, feature } from "~/_" -import { - Viewport, - ViewportOffset, - getElement, - getElements, - replaceElement, - request, - requestXML, - setLocation, - setLocationHash, - setViewportOffset -} from "~/browser" -import { getComponentElement } from "~/components" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * History state - */ -export interface HistoryState { - url: URL /* State URL */ - offset?: ViewportOffset /* State viewport offset */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Setup options - */ -interface SetupOptions { - document$: Subject /* Document subject */ - location$: Subject /* Location subject */ - viewport$: Observable /* Viewport observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Preprocess a list of URLs - * - * This function replaces the `site_url` in the sitemap with the actual base - * URL, to allow instant loading to work in occasions like Netlify previews. - * - * @param urls - URLs - * - * @returns Processed URLs - */ -function preprocess(urls: string[]): string[] { - if (urls.length < 2) - return urls - - /* Take the first two URLs and remove everything after the last slash */ - const [root, next] = urls - .sort((a, b) => a.length - b.length) - .map(url => url.replace(/[^/]+$/, "")) - - /* Compute common prefix */ - let index = 0 - if (root === next) - index = root.length - else - while (root.charCodeAt(index) === next.charCodeAt(index)) - index++ - - /* Replace common prefix (i.e. base) with effective base */ - const config = configuration() - return urls.map(url => ( - url.replace(root.slice(0, index), config.base) - )) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up instant loading - * - * When fetching, theoretically, we could use `responseType: "document"`, but - * since all MkDocs links are relative, we need to make sure that the current - * location matches the document we just loaded. Otherwise any relative links - * in the document could use the old location. - * - * This is the reason why we need to synchronize history events and the process - * of fetching the document for navigation changes (except `popstate` events): - * - * 1. Fetch document via `XMLHTTPRequest` - * 2. Set new location via `history.pushState` - * 3. Parse and emit fetched document - * - * For `popstate` events, we must not use `history.pushState`, or the forward - * history will be irreversibly overwritten. In case the request fails, the - * location change is dispatched regularly. - * - * @param options - Options - */ -export function setupInstantLoading( - { document$, location$, viewport$ }: SetupOptions -): void { - const config = configuration() - if (location.protocol === "file:") - return - - /* Disable automatic scroll restoration */ - if ("scrollRestoration" in history) { - history.scrollRestoration = "manual" - - /* Hack: ensure that reloads restore viewport offset */ - fromEvent(window, "beforeunload") - .subscribe(() => { - history.scrollRestoration = "auto" - }) - } - - /* Hack: ensure absolute favicon link to omit 404s when switching */ - const favicon = getElement("link[rel=icon]") - if (typeof favicon !== "undefined") - favicon.href = favicon.href - - /* Intercept internal navigation */ - const push$ = requestXML(new URL("sitemap.xml", config.base)) - .pipe( - map(sitemap => preprocess(getElements("loc", sitemap) - .map(node => node.textContent!) - )), - switchMap(urls => fromEvent(document.body, "click") - .pipe( - filter(ev => !ev.metaKey && !ev.ctrlKey), - switchMap(ev => { - - /* Handle HTML and SVG elements */ - if (ev.target instanceof Element) { - const el = ev.target.closest("a") - if (el && !el.target) { - const url = new URL(el.href) - - /* Canonicalize URL */ - url.search = "" - url.hash = "" - - /* Check if URL should be intercepted */ - if ( - url.pathname !== location.pathname && - urls.includes(url.toString()) - ) { - ev.preventDefault() - return of({ - url: new URL(el.href) - }) - } - } - } - return NEVER - }) - ) - ), - share() - ) - - /* Intercept history back and forward */ - const pop$ = fromEvent(window, "popstate") - .pipe( - filter(ev => ev.state !== null), - map(ev => ({ - url: new URL(location.href), - offset: ev.state - })), - share() - ) - - /* Emit location change */ - merge(push$, pop$) - .pipe( - distinctUntilChanged((a, b) => a.url.href === b.url.href), - map(({ url }) => url) - ) - .subscribe(location$) - - /* Fetch document via `XMLHTTPRequest` */ - const response$ = location$ - .pipe( - distinctUntilKeyChanged("pathname"), - switchMap(url => request(url.href) - .pipe( - catchError(() => { - setLocation(url) - return NEVER - }) - ) - ), - share() - ) - - /* Set new location via `history.pushState` */ - push$ - .pipe( - sample(response$) - ) - .subscribe(({ url }) => { - history.pushState({}, "", `${url}`) - }) - - /* Parse and emit fetched document */ - const dom = new DOMParser() - response$ - .pipe( - switchMap(res => res.text()), - map(res => dom.parseFromString(res, "text/html")) - ) - .subscribe(document$) - - /* Replace meta tags and components */ - document$ - .pipe( - skip(1) - ) - .subscribe(replacement => { - for (const selector of [ - - /* Meta tags */ - "title", - "link[rel=canonical]", - "meta[name=author]", - "meta[name=description]", - - /* Components */ - "[data-md-component=announce]", - "[data-md-component=container]", - "[data-md-component=header-topic]", - "[data-md-component=logo], .md-logo", // compat - "[data-md-component=skip]", - ...feature("navigation.tabs.sticky") - ? ["[data-md-component=tabs]"] - : [] - ]) { - const source = getElement(selector) - const target = getElement(selector, replacement) - if ( - typeof source !== "undefined" && - typeof target !== "undefined" - ) { - replaceElement(source, target) - } - } - }) - - /* Re-evaluate scripts */ - document$ - .pipe( - skip(1), - map(() => getComponentElement("container")), - switchMap(el => of(...getElements("script", el))), - concatMap(el => { - const script = h("script") - if (el.src) { - for (const name of el.getAttributeNames()) - script.setAttribute(name, el.getAttribute(name)!) - replaceElement(el, script) - - /* Complete when script is loaded */ - return new Observable(observer => { - script.onload = () => observer.complete() - }) - - /* Complete immediately */ - } else { - script.textContent = el.textContent - replaceElement(el, script) - return EMPTY - } - }) - ) - .subscribe() - - /* Emit history state change */ - merge(push$, pop$) - .pipe( - sample(document$), - ) - .subscribe(({ url, offset }) => { - if (url.hash && !offset) { - setLocationHash(url.hash) - } else { - setViewportOffset(offset || { y: 0 }) - } - }) - - /* Debounce update of viewport offset */ - viewport$ - .pipe( - skipUntil(push$), - debounceTime(250), - distinctUntilKeyChanged("offset") - ) - .subscribe(({ offset }) => { - history.replaceState(offset, "") - }) - - /* Set viewport offset from history */ - merge(push$, pop$) - .pipe( - bufferCount(2, 1), - filter(([a, b]) => a.url.pathname === b.url.pathname), - map(([, state]) => state) - ) - .subscribe(({ offset }) => { - setViewportOffset(offset || { y: 0 }) - }) -} diff --git a/docs/src/assets/javascripts/integrations/search/_/.eslintrc b/docs/src/assets/javascripts/integrations/search/_/.eslintrc deleted file mode 100644 index fd92bace..00000000 --- a/docs/src/assets/javascripts/integrations/search/_/.eslintrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off", - "no-console": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/search/_/index.ts b/docs/src/assets/javascripts/integrations/search/_/index.ts deleted file mode 100644 index d3ed2108..00000000 --- a/docs/src/assets/javascripts/integrations/search/_/index.ts +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - SearchDocument, - SearchDocumentMap, - setupSearchDocumentMap -} from "../document" -import { - SearchHighlightFactoryFn, - setupSearchHighlighter -} from "../highlighter" -import { SearchOptions } from "../options" -import { - SearchQueryTerms, - getSearchQueryTerms, - parseSearchQuery -} from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search index configuration - */ -export interface SearchIndexConfig { - lang: string[] /* Search languages */ - separator: string /* Search separator */ -} - -/** - * Search index document - */ -export interface SearchIndexDocument { - location: string /* Document location */ - title: string /* Document title */ - text: string /* Document text */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search index - * - * This interfaces describes the format of the `search_index.json` file which - * is automatically built by the MkDocs search plugin. - */ -export interface SearchIndex { - config: SearchIndexConfig /* Search index configuration */ - docs: SearchIndexDocument[] /* Search index documents */ - index?: object /* Prebuilt index */ - options: SearchOptions /* Search options */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search metadata - */ -export interface SearchMetadata { - score: number /* Score (relevance) */ - terms: SearchQueryTerms /* Search query terms */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search result document - */ -export type SearchResultDocument = SearchDocument & SearchMetadata - -/** - * Search result item - */ -export type SearchResultItem = SearchResultDocument[] - -/* ------------------------------------------------------------------------- */ - -/** - * Search result - */ -export interface SearchResult { - items: SearchResultItem[] /* Search result items */ - suggestions?: string[] /* Search suggestions */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Compute the difference of two lists of strings - * - * @param a - 1st list of strings - * @param b - 2nd list of strings - * - * @returns Difference - */ -function difference(a: string[], b: string[]): string[] { - const [x, y] = [new Set(a), new Set(b)] - return [ - ...new Set([...x].filter(value => !y.has(value))) - ] -} - -/* ---------------------------------------------------------------------------- - * Class - * ------------------------------------------------------------------------- */ - -/** - * Search index - */ -export class Search { - - /** - * Search document mapping - * - * A mapping of URLs (including hash fragments) to the actual articles and - * sections of the documentation. The search document mapping must be created - * regardless of whether the index was prebuilt or not, as Lunr.js itself - * only stores the actual index. - */ - protected documents: SearchDocumentMap - - /** - * Search highlight factory function - */ - protected highlight: SearchHighlightFactoryFn - - /** - * The underlying Lunr.js search index - */ - protected index: lunr.Index - - /** - * Search options - */ - protected options: SearchOptions - - /** - * Create the search integration - * - * @param data - Search index - */ - public constructor({ config, docs, index, options }: SearchIndex) { - this.options = options - - /* Set up document map and highlighter factory */ - this.documents = setupSearchDocumentMap(docs) - this.highlight = setupSearchHighlighter(config, false) - - /* Set separator for tokenizer */ - lunr.tokenizer.separator = new RegExp(config.separator) - - /* If no index was given, create it */ - if (typeof index === "undefined") { - this.index = lunr(function () { - - /* Set up multi-language support */ - if (config.lang.length === 1 && config.lang[0] !== "en") { - this.use((lunr as any)[config.lang[0]]) - } else if (config.lang.length > 1) { - this.use((lunr as any).multiLanguage(...config.lang)) - } - - /* Compute functions to be removed from the pipeline */ - const fns = difference([ - "trimmer", "stopWordFilter", "stemmer" - ], options.pipeline) - - /* Remove functions from the pipeline for registered languages */ - for (const lang of config.lang.map(language => ( - language === "en" ? lunr : (lunr as any)[language] - ))) { - for (const fn of fns) { - this.pipeline.remove(lang[fn]) - this.searchPipeline.remove(lang[fn]) - } - } - - /* Set up reference */ - this.ref("location") - - /* Set up fields */ - this.field("title", { boost: 1e3 }) - this.field("text") - - /* Index documents */ - for (const doc of docs) - this.add(doc) - }) - - /* Handle prebuilt index */ - } else { - this.index = lunr.Index.load(index) - } - } - - /** - * Search for matching documents - * - * The search index which MkDocs provides is divided up into articles, which - * contain the whole content of the individual pages, and sections, which only - * contain the contents of the subsections obtained by breaking the individual - * pages up at `h1` ... `h6`. As there may be many sections on different pages - * with identical titles (for example within this very project, e.g. "Usage" - * or "Installation"), they need to be put into the context of the containing - * page. For this reason, section results are grouped within their respective - * articles which are the top-level results that are returned. - * - * @param query - Query value - * - * @returns Search results - */ - public search(query: string): SearchResult { - if (query) { - try { - const highlight = this.highlight(query) - - /* Parse query to extract clauses for analysis */ - const clauses = parseSearchQuery(query) - .filter(clause => ( - clause.presence !== lunr.Query.presence.PROHIBITED - )) - - /* Perform search and post-process results */ - const groups = this.index.search(`${query}*`) - - /* Apply post-query boosts based on title and search query terms */ - .reduce((item, { ref, score, matchData }) => { - const document = this.documents.get(ref) - if (typeof document !== "undefined") { - const { location, title, text, parent } = document - - /* Compute and analyze search query terms */ - const terms = getSearchQueryTerms( - clauses, - Object.keys(matchData.metadata) - ) - - /* Highlight title and text and apply post-query boosts */ - const boost = +!parent + +Object.values(terms).every(t => t) - item.push({ - location, - title: highlight(title), - text: highlight(text), - score: score * (1 + boost), - terms - }) - } - return item - }, []) - - /* Sort search results again after applying boosts */ - .sort((a, b) => b.score - a.score) - - /* Group search results by page */ - .reduce((items, result) => { - const document = this.documents.get(result.location) - if (typeof document !== "undefined") { - const ref = "parent" in document - ? document.parent!.location - : document.location - items.set(ref, [...items.get(ref) || [], result]) - } - return items - }, new Map()) - - /* Generate search suggestions, if desired */ - let suggestions: string[] | undefined - if (this.options.suggestions) { - const titles = this.index.query(builder => { - for (const clause of clauses) - builder.term(clause.term, { - fields: ["title"], - presence: lunr.Query.presence.REQUIRED, - wildcard: lunr.Query.wildcard.TRAILING - }) - }) - - /* Retrieve suggestions for best match */ - suggestions = titles.length - ? Object.keys(titles[0].matchData.metadata) - : [] - } - - /* Return items and suggestions */ - return { - items: [...groups.values()], - ...typeof suggestions !== "undefined" && { suggestions } - } - - /* Log errors to console (for now) */ - } catch { - console.warn(`Invalid query: ${query} – see https://bit.ly/2s3ChXG`) - } - } - - /* Return nothing in case of error or empty query */ - return { items: [] } - } -} diff --git a/docs/src/assets/javascripts/integrations/search/document/index.ts b/docs/src/assets/javascripts/integrations/search/document/index.ts deleted file mode 100644 index 0bcd679a..00000000 --- a/docs/src/assets/javascripts/integrations/search/document/index.ts +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import escapeHTML from "escape-html" - -import { SearchIndexDocument } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search document - */ -export interface SearchDocument extends SearchIndexDocument { - parent?: SearchIndexDocument /* Parent article */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search document mapping - */ -export type SearchDocumentMap = Map - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Create a search document mapping - * - * @param docs - Search index documents - * - * @returns Search document map - */ -export function setupSearchDocumentMap( - docs: SearchIndexDocument[] -): SearchDocumentMap { - const documents = new Map() - const parents = new Set() - for (const doc of docs) { - const [path, hash] = doc.location.split("#") - - /* Extract location and title */ - const location = doc.location - const title = doc.title - - /* Escape and cleanup text */ - const text = escapeHTML(doc.text) - .replace(/\s+(?=[,.:;!?])/g, "") - .replace(/\s+/g, " ") - - /* Handle section */ - if (hash) { - const parent = documents.get(path)! - - /* Ignore first section, override article */ - if (!parents.has(parent)) { - parent.title = doc.title - parent.text = text - - /* Remember that we processed the article */ - parents.add(parent) - - /* Add subsequent section */ - } else { - documents.set(location, { - location, - title, - text, - parent - }) - } - - /* Add article */ - } else { - documents.set(location, { - location, - title, - text - }) - } - } - return documents -} diff --git a/docs/src/assets/javascripts/integrations/search/highlighter/index.ts b/docs/src/assets/javascripts/integrations/search/highlighter/index.ts deleted file mode 100644 index 5d13e198..00000000 --- a/docs/src/assets/javascripts/integrations/search/highlighter/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import escapeHTML from "escape-html" - -import { SearchIndexConfig } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search highlight function - * - * @param value - Value - * - * @returns Highlighted value - */ -export type SearchHighlightFn = (value: string) => string - -/** - * Search highlight factory function - * - * @param query - Query value - * - * @returns Search highlight function - */ -export type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Create a search highlighter - * - * @param config - Search index configuration - * @param escape - Whether to escape HTML - * - * @returns Search highlight factory function - */ -export function setupSearchHighlighter( - config: SearchIndexConfig, escape: boolean -): SearchHighlightFactoryFn { - const separator = new RegExp(config.separator, "img") - const highlight = (_: unknown, data: string, term: string) => { - return `${data}${term}` - } - - /* Return factory function */ - return (query: string) => { - query = query - .replace(/[\s*+\-:~^]+/g, " ") - .trim() - - /* Create search term match expression */ - const match = new RegExp(`(^|${config.separator})(${ - query - .replace(/[|\\{}()[\]^$+*?.-]/g, "\\$&") - .replace(separator, "|") - })`, "img") - - /* Highlight string value */ - return value => ( - escape - ? escapeHTML(value) - : value - ) - .replace(match, highlight) - .replace(/<\/mark>(\s+)]*>/img, "$1") - } -} diff --git a/docs/src/assets/javascripts/integrations/search/index.ts b/docs/src/assets/javascripts/integrations/search/index.ts deleted file mode 100644 index 1a5430e9..00000000 --- a/docs/src/assets/javascripts/integrations/search/index.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./document" -export * from "./highlighter" -export * from "./options" -export * from "./query" -export * from "./worker" diff --git a/docs/src/assets/javascripts/integrations/search/options/index.ts b/docs/src/assets/javascripts/integrations/search/options/index.ts deleted file mode 100644 index ad1015a5..00000000 --- a/docs/src/assets/javascripts/integrations/search/options/index.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search pipeline function - */ -export type SearchPipelineFn = - | "trimmer" /* Trimmer */ - | "stopWordFilter" /* Stop word filter */ - | "stemmer" /* Stemmer */ - -/** - * Search pipeline - */ -export type SearchPipeline = SearchPipelineFn[] - -/* ------------------------------------------------------------------------- */ - -/** - * Search options - */ -export interface SearchOptions { - pipeline: SearchPipeline /* Search pipeline */ - suggestions: boolean /* Search suggestions */ -} diff --git a/docs/src/assets/javascripts/integrations/search/query/_/.eslintrc b/docs/src/assets/javascripts/integrations/search/query/_/.eslintrc deleted file mode 100644 index 8b8e4250..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/_/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/search/query/_/index.ts b/docs/src/assets/javascripts/integrations/search/query/_/index.ts deleted file mode 100644 index e9679a05..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/_/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search query clause - */ -export interface SearchQueryClause { - presence: lunr.Query.presence /* Clause presence */ - term: string /* Clause term */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Search query terms - */ -export type SearchQueryTerms = Record - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Parse a search query for analysis - * - * @param value - Query value - * - * @returns Search query clauses - */ -export function parseSearchQuery( - value: string -): SearchQueryClause[] { - const query = new (lunr as any).Query(["title", "text"]) - const parser = new (lunr as any).QueryParser(value, query) - - /* Parse and return query clauses */ - parser.parse() - return query.clauses -} - -/** - * Analyze the search query clauses in regard to the search terms found - * - * @param query - Search query clauses - * @param terms - Search terms - * - * @returns Search query terms - */ -export function getSearchQueryTerms( - query: SearchQueryClause[], terms: string[] -): SearchQueryTerms { - const clauses = new Set(query) - - /* Match query clauses against terms */ - const result: SearchQueryTerms = {} - for (let t = 0; t < terms.length; t++) - for (const clause of clauses) - if (terms[t].startsWith(clause.term)) { - result[clause.term] = true - clauses.delete(clause) - } - - /* Annotate unmatched query clauses */ - for (const clause of clauses) - result[clause.term] = false - - /* Return query terms */ - return result -} diff --git a/docs/src/assets/javascripts/integrations/search/query/index.ts b/docs/src/assets/javascripts/integrations/search/query/index.ts deleted file mode 100644 index 98442a55..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./transform" diff --git a/docs/src/assets/javascripts/integrations/search/query/transform/.eslintrc b/docs/src/assets/javascripts/integrations/search/query/transform/.eslintrc deleted file mode 100644 index 5645b172..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/transform/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "no-control-regex": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/search/query/transform/index.ts b/docs/src/assets/javascripts/integrations/search/query/transform/index.ts deleted file mode 100644 index f498495c..00000000 --- a/docs/src/assets/javascripts/integrations/search/query/transform/index.ts +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search transformation function - * - * @param value - Query value - * - * @returns Transformed query value - */ -export type SearchTransformFn = (value: string) => string - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Default transformation function - * - * 1. Search for terms in quotation marks and prepend a `+` modifier to denote - * that the resulting document must contain all terms, converting the query - * to an `AND` query (as opposed to the default `OR` behavior). While users - * may expect terms enclosed in quotation marks to map to span queries, i.e. - * for which order is important, Lunr.js doesn't support them, so the best - * we can do is to convert the terms to an `AND` query. - * - * 2. Replace control characters which are not located at the beginning of the - * query or preceded by white space, or are not followed by a non-whitespace - * character or are at the end of the query string. Furthermore, filter - * unmatched quotation marks. - * - * 3. Trim excess whitespace from left and right. - * - * @param query - Query value - * - * @returns Transformed query value - */ -export function defaultTransform(query: string): string { - return query - .split(/"([^"]+)"/g) /* => 1 */ - .map((terms, index) => index & 1 - ? terms.replace(/^\b|^(?![^\x00-\x7F]|$)|\s+/g, " +") - : terms - ) - .join("") - .replace(/"|(?:^|\s+)[*+\-:^~]+(?=\s+|$)/g, "") /* => 2 */ - .trim() /* => 3 */ -} diff --git a/docs/src/assets/javascripts/integrations/search/worker/_/index.ts b/docs/src/assets/javascripts/integrations/search/worker/_/index.ts deleted file mode 100644 index 146f14a6..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/_/index.ts +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { ObservableInput, Subject, from } from "rxjs" -import { map, share } from "rxjs/operators" - -import { configuration, feature, translation } from "~/_" -import { WorkerHandler, watchWorker } from "~/browser" - -import { SearchIndex } from "../../_" -import { - SearchOptions, - SearchPipeline -} from "../../options" -import { - SearchMessage, - SearchMessageType, - SearchSetupMessage, - isSearchResultMessage -} from "../message" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search worker - */ -export type SearchWorker = WorkerHandler - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Set up search index - * - * @param data - Search index - * - * @returns Search index - */ -function setupSearchIndex( - { config, docs, index }: SearchIndex -): SearchIndex { - - /* Override default language with value from translation */ - if (config.lang.length === 1 && config.lang[0] === "en") - config.lang = [ - translation("search.config.lang") - ] - - /* Override default separator with value from translation */ - if (config.separator === "[\\s\\-]+") - config.separator = translation("search.config.separator") - - /* Set pipeline from translation */ - const pipeline = translation("search.config.pipeline") - .split(/\s*,\s*/) - .filter(Boolean) as SearchPipeline - - /* Determine search options */ - const options: SearchOptions = { - pipeline, - suggestions: feature("search.suggest") - } - - /* Return search index after defaulting */ - return { config, docs, index, options } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up search worker - * - * This function creates a web worker to set up and query the search index, - * which is done using Lunr.js. The index must be passed as an observable to - * enable hacks like _localsearch_ via search index embedding as JSON. - * - * @param url - Worker URL - * @param index - Search index observable input - * - * @returns Search worker - */ -export function setupSearchWorker( - url: string, index: ObservableInput -): SearchWorker { - const config = configuration() - const worker = new Worker(url) - - /* Create communication channels and resolve relative links */ - const tx$ = new Subject() - const rx$ = watchWorker(worker, { tx$ }) - .pipe( - map(message => { - if (isSearchResultMessage(message)) { - for (const result of message.data.items) - for (const document of result) - document.location = `${new URL(document.location, config.base)}` - } - return message - }), - share() - ) - - /* Set up search index */ - from(index) - .pipe( - map(data => ({ - type: SearchMessageType.SETUP, - data: setupSearchIndex(data) - })) - ) - .subscribe(tx$.next.bind(tx$)) - - /* Return search worker */ - return { tx$, rx$ } -} diff --git a/docs/src/assets/javascripts/integrations/search/worker/index.ts b/docs/src/assets/javascripts/integrations/search/worker/index.ts deleted file mode 100644 index 22d729a7..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./message" diff --git a/docs/src/assets/javascripts/integrations/search/worker/main/.eslintrc b/docs/src/assets/javascripts/integrations/search/worker/main/.eslintrc deleted file mode 100644 index 09c57919..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/main/.eslintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-misused-promises": "off" - } -} diff --git a/docs/src/assets/javascripts/integrations/search/worker/main/index.ts b/docs/src/assets/javascripts/integrations/search/worker/main/index.ts deleted file mode 100644 index 435e5373..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/main/index.ts +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import lunr from "lunr" - -import { Search, SearchIndexConfig } from "../../_" -import { - SearchMessage, - SearchMessageType -} from "../message" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Add support for usage with `iframe-worker` polyfill - * - * While `importScripts` is synchronous when executed inside of a web worker, - * it's not possible to provide a synchronous polyfilled implementation. The - * cool thing is that awaiting a non-Promise is a noop, so extending the type - * definition to return a `Promise` shouldn't break anything. - * - * @see https://bit.ly/2PjDnXi - GitHub comment - */ -declare global { - function importScripts(...urls: string[]): Promise | void -} - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Search index - */ -let index: Search - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Fetch (= import) multi-language support through `lunr-languages` - * - * This function automatically imports the stemmers necessary to process the - * languages, which are defined through the search index configuration. - * - * If the worker runs inside of an `iframe` (when using `iframe-worker` as - * a shim), the base URL for the stemmers to be loaded must be determined by - * searching for the first `script` element with a `src` attribute, which will - * contain the contents of this script. - * - * @param config - Search index configuration - * - * @returns Promise resolving with no result - */ -async function setupSearchLanguages( - config: SearchIndexConfig -): Promise { - let base = "../lunr" - - /* Detect `iframe-worker` and fix base URL */ - if (typeof parent !== "undefined" && "IFrameWorker" in parent) { - const worker = document.querySelector("script[src]")! - const [path] = worker.src.split("/worker") - - /* Prefix base with path */ - base = base.replace("..", path) - } - - /* Add scripts for languages */ - const scripts = [] - for (const lang of config.lang) { - switch (lang) { - - /* Add segmenter for Japanese */ - case "ja": - scripts.push(`${base}/tinyseg.js`) - break - - /* Add segmenter for Hindi and Thai */ - case "hi": - case "th": - scripts.push(`${base}/wordcut.js`) - break - } - - /* Add language support */ - if (lang !== "en") - scripts.push(`${base}/min/lunr.${lang}.min.js`) - } - - /* Add multi-language support */ - if (config.lang.length > 1) - scripts.push(`${base}/min/lunr.multi.min.js`) - - /* Load scripts synchronously */ - if (scripts.length) - await importScripts( - `${base}/min/lunr.stemmer.support.min.js`, - ...scripts - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Message handler - * - * @param message - Source message - * - * @returns Target message - */ -export async function handler( - message: SearchMessage -): Promise { - switch (message.type) { - - /* Search setup message */ - case SearchMessageType.SETUP: - await setupSearchLanguages(message.data.config) - index = new Search(message.data) - return { - type: SearchMessageType.READY - } - - /* Search query message */ - case SearchMessageType.QUERY: - return { - type: SearchMessageType.RESULT, - data: index ? index.search(message.data) : { items: [] } - } - - /* All other messages */ - default: - throw new TypeError("Invalid message type") - } -} - -/* ---------------------------------------------------------------------------- - * Worker - * ------------------------------------------------------------------------- */ - -/* @ts-ignore - expose Lunr.js in global scope, or stemmers will not work */ -self.lunr = lunr - -/* Handle messages */ -addEventListener("message", async ev => { - postMessage(await handler(ev.data)) -}) diff --git a/docs/src/assets/javascripts/integrations/search/worker/message/index.ts b/docs/src/assets/javascripts/integrations/search/worker/message/index.ts deleted file mode 100644 index 2f6a3866..00000000 --- a/docs/src/assets/javascripts/integrations/search/worker/message/index.ts +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { SearchIndex, SearchResult } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search message type - */ -export const enum SearchMessageType { - SETUP, /* Search index setup */ - READY, /* Search index ready */ - QUERY, /* Search query */ - RESULT /* Search results */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Message containing the data necessary to setup the search index - */ -export interface SearchSetupMessage { - type: SearchMessageType.SETUP /* Message type */ - data: SearchIndex /* Message data */ -} - -/** - * Message indicating the search index is ready - */ -export interface SearchReadyMessage { - type: SearchMessageType.READY /* Message type */ -} - -/** - * Message containing a search query - */ -export interface SearchQueryMessage { - type: SearchMessageType.QUERY /* Message type */ - data: string /* Message data */ -} - -/** - * Message containing results for a search query - */ -export interface SearchResultMessage { - type: SearchMessageType.RESULT /* Message type */ - data: SearchResult /* Message data */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Message exchanged with the search worker - */ -export type SearchMessage = - | SearchSetupMessage - | SearchReadyMessage - | SearchQueryMessage - | SearchResultMessage - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Type guard for search setup messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchSetupMessage( - message: SearchMessage -): message is SearchSetupMessage { - return message.type === SearchMessageType.SETUP -} - -/** - * Type guard for search ready messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchReadyMessage( - message: SearchMessage -): message is SearchReadyMessage { - return message.type === SearchMessageType.READY -} - -/** - * Type guard for search query messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchQueryMessage( - message: SearchMessage -): message is SearchQueryMessage { - return message.type === SearchMessageType.QUERY -} - -/** - * Type guard for search result messages - * - * @param message - Search worker message - * - * @returns Test result - */ -export function isSearchResultMessage( - message: SearchMessage -): message is SearchResultMessage { - return message.type === SearchMessageType.RESULT -} diff --git a/docs/src/assets/javascripts/integrations/version/index.ts b/docs/src/assets/javascripts/integrations/version/index.ts deleted file mode 100644 index 4be76ee8..00000000 --- a/docs/src/assets/javascripts/integrations/version/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { configuration } from "~/_" -import { getElementOrThrow, requestJSON } from "~/browser" -import { Version, renderVersionSelector } from "~/templates" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up version selector - */ -export function setupVersionSelector(): void { - const config = configuration() - requestJSON(new URL("../versions.json", config.base)) - .subscribe(versions => { - const topic = getElementOrThrow(".md-header__topic") - topic.appendChild(renderVersionSelector(versions)) - }) -} diff --git a/docs/src/assets/javascripts/patches/indeterminate/index.ts b/docs/src/assets/javascripts/patches/indeterminate/index.ts deleted file mode 100644 index 0397edc4..00000000 --- a/docs/src/assets/javascripts/patches/indeterminate/index.ts +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, of } from "rxjs" -import { - mapTo, - mergeMap, - switchMap, - takeWhile, - tap, - withLatestFrom -} from "rxjs/operators" - -import { getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - document$: Observable /* Document observable */ - tablet$: Observable /* Tablet breakpoint observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch indeterminate checkboxes - * - * This function replaces the indeterminate "pseudo state" with the actual - * indeterminate state, which is used to keep navigation always expanded. - * - * @param options - Options - */ -export function patchIndeterminate( - { document$, tablet$ }: PatchOptions -): void { - document$ - .pipe( - switchMap(() => of(...getElements( - "[data-md-state=indeterminate]" - ))), - tap(el => { - el.indeterminate = true - el.checked = false - }), - mergeMap(el => fromEvent(el, "change") - .pipe( - takeWhile(() => el.hasAttribute("data-md-state")), - mapTo(el) - ) - ), - withLatestFrom(tablet$) - ) - .subscribe(([el, tablet]) => { - el.removeAttribute("data-md-state") - if (tablet) - el.checked = false - }) -} diff --git a/docs/src/assets/javascripts/patches/index.ts b/docs/src/assets/javascripts/patches/index.ts deleted file mode 100644 index 3195e6e5..00000000 --- a/docs/src/assets/javascripts/patches/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./indeterminate" -export * from "./scrollfix" -export * from "./scrolllock" diff --git a/docs/src/assets/javascripts/patches/scrollfix/index.ts b/docs/src/assets/javascripts/patches/scrollfix/index.ts deleted file mode 100644 index 941464ca..00000000 --- a/docs/src/assets/javascripts/patches/scrollfix/index.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, fromEvent, of } from "rxjs" -import { - filter, - mapTo, - mergeMap, - switchMap, - tap -} from "rxjs/operators" - -import { getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - document$: Observable /* Document observable */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Check whether the given device is an Apple device - * - * @returns Test result - */ -function isAppleDevice(): boolean { - return /(iPad|iPhone|iPod)/.test(navigator.userAgent) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch all elements with `data-md-scrollfix` attributes - * - * This is a year-old patch which ensures that overflow scrolling works at the - * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon - * the start of a touch event. - * - * @see https://bit.ly/2SCtAOO - Original source - * - * @param options - Options - */ -export function patchScrollfix( - { document$ }: PatchOptions -): void { - document$ - .pipe( - switchMap(() => of(...getElements("[data-md-scrollfix]"))), - tap(el => el.removeAttribute("data-md-scrollfix")), - filter(isAppleDevice), - mergeMap(el => fromEvent(el, "touchstart") - .pipe( - mapTo(el) - ) - ) - ) - .subscribe(el => { - const top = el.scrollTop - - /* We're at the top of the container */ - if (top === 0) { - el.scrollTop = 1 - - /* We're at the bottom of the container */ - } else if (top + el.offsetHeight === el.scrollHeight) { - el.scrollTop = top - 1 - } - }) -} diff --git a/docs/src/assets/javascripts/patches/scrolllock/index.ts b/docs/src/assets/javascripts/patches/scrolllock/index.ts deleted file mode 100644 index 884c7612..00000000 --- a/docs/src/assets/javascripts/patches/scrolllock/index.ts +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - animationFrameScheduler, - combineLatest, - of -} from "rxjs" -import { - delay, - map, - observeOn, - switchMap, - withLatestFrom -} from "rxjs/operators" - -import { resetScrollLock, setScrollLock } from "~/actions" -import { Viewport, watchToggle } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Patch options - */ -interface PatchOptions { - viewport$: Observable /* Viewport observable */ - tablet$: Observable /* Tablet breakpoint observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Patch the document body to lock when search is open - * - * For mobile and tablet viewports, the search is rendered full screen, which - * leads to scroll leaking when at the top or bottom of the search result. This - * function locks the body when the search is in full screen mode, and restores - * the scroll position when leaving. - * - * @param options - Options - */ -export function patchScrolllock( - { viewport$, tablet$ }: PatchOptions -): void { - combineLatest([watchToggle("search"), tablet$]) - .pipe( - map(([active, tablet]) => active && !tablet), - switchMap(active => of(active) - .pipe( - delay(active ? 400 : 100), - observeOn(animationFrameScheduler) - ) - ), - withLatestFrom(viewport$) - ) - .subscribe(([active, { offset: { y }}]) => { - if (active) - setScrollLock(document.body, y) - else - resetScrollLock(document.body) - }) -} diff --git a/docs/src/assets/javascripts/templates/clipboard/index.tsx b/docs/src/assets/javascripts/templates/clipboard/index.tsx deleted file mode 100644 index fd54c316..00000000 --- a/docs/src/assets/javascripts/templates/clipboard/index.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a 'copy-to-clipboard' button - * - * @param id - Unique identifier - * - * @returns Element - */ -export function renderClipboardButton(id: string): HTMLElement { - return ( - - ) -} diff --git a/docs/src/assets/javascripts/templates/index.ts b/docs/src/assets/javascripts/templates/index.ts deleted file mode 100644 index 416f29fb..00000000 --- a/docs/src/assets/javascripts/templates/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./clipboard" -export * from "./search" -export * from "./source" -export * from "./table" -export * from "./version" diff --git a/docs/src/assets/javascripts/templates/search/index.tsx b/docs/src/assets/javascripts/templates/search/index.tsx deleted file mode 100644 index d9e777b3..00000000 --- a/docs/src/assets/javascripts/templates/search/index.tsx +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { feature, translation } from "~/_" -import { - SearchDocument, - SearchMetadata, - SearchResultItem -} from "~/integrations/search" -import { h, truncate } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Render flag - */ -const enum Flag { - TEASER = 1, /* Render teaser */ - PARENT = 2 /* Render as parent */ -} - -/* ---------------------------------------------------------------------------- - * Helper function - * ------------------------------------------------------------------------- */ - -/** - * Render a search document - * - * @param document - Search document - * @param flag - Render flags - * - * @returns Element - */ -function renderSearchDocument( - document: SearchDocument & SearchMetadata, flag: Flag -): HTMLElement { - const parent = flag & Flag.PARENT - const teaser = flag & Flag.TEASER - - /* Render missing query terms */ - const missing = Object.keys(document.terms) - .filter(key => !document.terms[key]) - .map(key => [{key}, " "]) - .flat() - .slice(0, -1) - - /* Assemble query string for highlighting */ - const url = new URL(document.location) - if (feature("search.highlight")) - url.searchParams.set("h", Object.entries(document.terms) - .filter(([, match]) => match) - .reduce((highlight, [value]) => `${highlight} ${value}`.trim(), "") - ) - - /* Render article or section, depending on flags */ - return ( - -
- {parent > 0 &&
} -

{document.title}

- {teaser > 0 && document.text.length > 0 && -

- {truncate(document.text, 320)} -

- } - {teaser > 0 && missing.length > 0 && -

- {translation("search.result.term.missing")}: {...missing} -

- } -
-
- ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a search result - * - * @param result - Search result - * - * @returns Element - */ -export function renderSearchResultItem( - result: SearchResultItem -): HTMLElement { - const threshold = result[0].score - const docs = [...result] - - /* Find and extract parent article */ - const parent = docs.findIndex(doc => !doc.location.includes("#")) - const [article] = docs.splice(parent, 1) - - /* Determine last index above threshold */ - let index = docs.findIndex(doc => doc.score < threshold) - if (index === -1) - index = docs.length - - /* Partition sections */ - const best = docs.slice(0, index) - const more = docs.slice(index) - - /* Render children */ - const children = [ - renderSearchDocument(article, Flag.PARENT | +(!parent && index === 0)), - ...best.map(section => renderSearchDocument(section, Flag.TEASER)), - ...more.length ? [ -
- - {more.length > 0 && more.length === 1 - ? translation("search.result.more.one") - : translation("search.result.more.other", more.length) - } - - {...more.map(section => renderSearchDocument(section, Flag.TEASER))} -
- ] : [] - ] - - /* Render search result */ - return ( -
  • - {children} -
  • - ) -} diff --git a/docs/src/assets/javascripts/templates/source/index.tsx b/docs/src/assets/javascripts/templates/source/index.tsx deleted file mode 100644 index f124188d..00000000 --- a/docs/src/assets/javascripts/templates/source/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { SourceFacts } from "~/components" -import { h, round } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render repository facts - * - * @param facts - Repository facts - * - * @returns Element - */ -export function renderSourceFacts(facts: SourceFacts): HTMLElement { - return ( -
      - {Object.entries(facts).map(([key, value]) => ( -
    • - {typeof value === "number" ? round(value) : value} -
    • - ))} -
    - ) -} diff --git a/docs/src/assets/javascripts/templates/table/index.tsx b/docs/src/assets/javascripts/templates/table/index.tsx deleted file mode 100644 index 012450d7..00000000 --- a/docs/src/assets/javascripts/templates/table/index.tsx +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a table inside a wrapper to improve scrolling on mobile - * - * @param table - Table element - * - * @returns Element - */ -export function renderTable(table: HTMLElement): HTMLElement { - return ( -
    -
    - {table} -
    -
    - ) -} diff --git a/docs/src/assets/javascripts/templates/version/index.tsx b/docs/src/assets/javascripts/templates/version/index.tsx deleted file mode 100644 index 484f72dd..00000000 --- a/docs/src/assets/javascripts/templates/version/index.tsx +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { configuration, translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Version - */ -export interface Version { - version: string /* Version identifier */ - title: string /* Version title */ - aliases: string[] /* Version aliases */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Render a version - * - * @param version - Version - * - * @returns Element - */ -function renderVersion(version: Version): HTMLElement { - const config = configuration() - - /* Ensure trailing slash, see https://bit.ly/3rL5u3f */ - const url = new URL(`../${version.version}/`, config.base) - return ( -
  • - - {version.title} - -
  • - ) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render a version selector - * - * @param versions - Versions - * - * @returns Element - */ -export function renderVersionSelector(versions: Version[]): HTMLElement { - const config = configuration() - - /* Determine active version */ - const [, current] = config.base.match(/([^/]+)\/?$/)! - const active = - versions.find(({ version, aliases }) => ( - version === current || aliases.includes(current) - )) || versions[0] - - /* Render version selector */ - return ( -
    - -
      - {versions.map(renderVersion)} -
    -
    - ) -} diff --git a/docs/src/assets/javascripts/utilities/h/.eslintrc b/docs/src/assets/javascripts/utilities/h/.eslintrc deleted file mode 100644 index d79b45b0..00000000 --- a/docs/src/assets/javascripts/utilities/h/.eslintrc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "rules": { - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-namespace": "off", - "jsdoc/require-jsdoc": "off" - } -} diff --git a/docs/src/assets/javascripts/utilities/h/index.ts b/docs/src/assets/javascripts/utilities/h/index.ts deleted file mode 100644 index 3c6dbabc..00000000 --- a/docs/src/assets/javascripts/utilities/h/index.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { JSX as JSXInternal } from "preact" - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * HTML attributes - */ -type Attributes = - & JSXInternal.HTMLAttributes - & JSXInternal.SVGAttributes - & Record - -/** - * Child element - */ -type Child = - | HTMLElement - | Text - | string - | number - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Append a child node to an element - * - * @param el - Element - * @param child - Child node(s) - */ -function appendChild(el: HTMLElement, child: Child | Child[]): void { - - /* Handle primitive types (including raw HTML) */ - if (typeof child === "string" || typeof child === "number") { - el.innerHTML += child.toString() - - /* Handle nodes */ - } else if (child instanceof Node) { - el.appendChild(child) - - /* Handle nested children */ - } else if (Array.isArray(child)) { - for (const node of child) - appendChild(el, node) - } -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * JSX factory - * - * @template T - Element type - * - * @param tag - HTML tag - * @param attributes - HTML attributes - * @param children - Child elements - * - * @returns Element - */ -export function h( - tag: T, attributes?: Attributes | null, ...children: Child[] -): HTMLElementTagNameMap[T] - -export function h( - tag: string, attributes?: Attributes | null, ...children: Child[] -): T - -export function h( - tag: string, attributes?: Attributes | null, ...children: Child[] -): T { - const el = document.createElement(tag) - - /* Set attributes, if any */ - if (attributes) - for (const attr of Object.keys(attributes)) - if (typeof attributes[attr] !== "boolean") - el.setAttribute(attr, attributes[attr]) - else if (attributes[attr]) - el.setAttribute(attr, "") - - /* Append child nodes */ - for (const child of children) - appendChild(el, child) - - /* Return element */ - return el as T -} - -/* ---------------------------------------------------------------------------- - * Namespace - * ------------------------------------------------------------------------- */ - -export declare namespace h { - namespace JSX { - type Element = HTMLElement - type IntrinsicElements = JSXInternal.IntrinsicElements - } -} diff --git a/docs/src/assets/javascripts/utilities/index.ts b/docs/src/assets/javascripts/utilities/index.ts deleted file mode 100644 index 7718f927..00000000 --- a/docs/src/assets/javascripts/utilities/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./h" -export * from "./string" diff --git a/docs/src/assets/javascripts/utilities/string/index.ts b/docs/src/assets/javascripts/utilities/string/index.ts deleted file mode 100644 index 7dc43461..00000000 --- a/docs/src/assets/javascripts/utilities/string/index.ts +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Truncate a string after the given number of characters - * - * This is not a very reasonable approach, since the summaries kind of suck. - * It would be better to create something more intelligent, highlighting the - * search occurrences and making a better summary out of it, but this note was - * written three years ago, so who knows if we'll ever fix it. - * - * @param value - Value to be truncated - * @param n - Number of characters - * - * @returns Truncated value - */ -export function truncate(value: string, n: number): string { - let i = n - if (value.length > i) { - while (value[i] !== " " && --i > 0) { /* keep eating */ } - return `${value.substring(0, i)}...` - } - return value -} - -/** - * Round a number for display with repository facts - * - * This is a reverse-engineered version of GitHub's weird rounding algorithm - * for stars, forks and all other numbers. While all numbers below `1,000` are - * returned as-is, bigger numbers are converted to fixed numbers: - * - * - `1,049` => `1k` - * - `1,050` => `1.1k` - * - `1,949` => `1.9k` - * - `1,950` => `2k` - * - * @param value - Original value - * - * @returns Rounded value - */ -export function round(value: number): string { - if (value > 999) { - const digits = +((value - 950) % 1000 > 99) - return `${((value + 0.000001) / 1000).toFixed(digits)}k` - } else { - return value.toString() - } -} - -/** - * Simple hash function - * - * @see https://bit.ly/2wsVjJ4 - Original source - * - * @param value - Value to be hashed - * - * @returns Hash as 32bit integer - */ -export function hash(value: string): number { - let h = 0 - for (let i = 0, len = value.length; i < len; i++) { - h = ((h << 5) - h) + value.charCodeAt(i) - h |= 0 // Convert to 32bit integer - } - return h -} diff --git a/docs/src/assets/javascripts/workers/search.ts b/docs/src/assets/javascripts/workers/search.ts deleted file mode 100644 index db409938..00000000 --- a/docs/src/assets/javascripts/workers/search.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import "~/integrations/search/worker/main" diff --git a/docs/src/assets/stylesheets/_config.scss b/docs/src/assets/stylesheets/_config.scss deleted file mode 100644 index 4ab8cddb..00000000 --- a/docs/src/assets/stylesheets/_config.scss +++ /dev/null @@ -1,42 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Variables: breakpoints -// ---------------------------------------------------------------------------- - -// Device-specific breakpoints -$break-devices: ( - mobile: ( - portrait: px2em(220px) px2em(479px), - landscape: px2em(480px) px2em(719px) - ), - tablet: ( - portrait: px2em(720px) px2em(959px), - landscape: px2em(960px) px2em(1219px) - ), - screen: ( - small: px2em(1220px) px2em(1599px), - medium: px2em(1600px) px2em(1999px), - large: px2em(2000px) - ) -); diff --git a/docs/src/assets/stylesheets/main.scss b/docs/src/assets/stylesheets/main.scss deleted file mode 100644 index c8aa7610..00000000 --- a/docs/src/assets/stylesheets/main.scss +++ /dev/null @@ -1,75 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; -@import "material-shadows"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "main/reset"; -@import "main/colors"; -@import "main/icons"; -@import "main/typeset"; - -@import "main/layout/base"; -@import "main/layout/announce"; -@import "main/layout/clipboard"; -@import "main/layout/content"; -@import "main/layout/dialog"; -@import "main/layout/form"; -@import "main/layout/header"; -@import "main/layout/footer"; -@import "main/layout/nav"; -@import "main/layout/search"; -@import "main/layout/select"; -@import "main/layout/sidebar"; -@import "main/layout/source"; -@import "main/layout/tabs"; -@import "main/layout/top"; -@import "main/layout/version"; - -@import "main/extensions/markdown/admonition"; -@import "main/extensions/markdown/footnotes"; -@import "main/extensions/markdown/toc"; - -@import "main/extensions/pymdownx/arithmatex"; -@import "main/extensions/pymdownx/critic"; -@import "main/extensions/pymdownx/details"; -@import "main/extensions/pymdownx/emoji"; -@import "main/extensions/pymdownx/highlight"; -@import "main/extensions/pymdownx/keys"; -@import "main/extensions/pymdownx/tabbed"; -@import "main/extensions/pymdownx/tasklist"; - -@import "main/modifiers"; -@import "main/shame"; diff --git a/docs/src/assets/stylesheets/main/_colors.scss b/docs/src/assets/stylesheets/main/_colors.scss deleted file mode 100644 index 4513216e..00000000 --- a/docs/src/assets/stylesheets/main/_colors.scss +++ /dev/null @@ -1,107 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Color definitions -:root { - - // Default color shades - --md-default-fg-color: hsla(0, 0%, 0%, 0.87); - --md-default-fg-color--light: hsla(0, 0%, 0%, 0.54); - --md-default-fg-color--lighter: hsla(0, 0%, 0%, 0.32); - --md-default-fg-color--lightest: hsla(0, 0%, 0%, 0.07); - --md-default-bg-color: hsla(0, 0%, 100%, 1); - --md-default-bg-color--light: hsla(0, 0%, 100%, 0.7); - --md-default-bg-color--lighter: hsla(0, 0%, 100%, 0.3); - --md-default-bg-color--lightest: hsla(0, 0%, 100%, 0.12); - - // Primary color shades - --md-primary-fg-color: hsla(#{hex2hsl($clr-indigo-500)}, 1); - --md-primary-fg-color--light: hsla(#{hex2hsl($clr-indigo-400)}, 1); - --md-primary-fg-color--dark: hsla(#{hex2hsl($clr-indigo-700)}, 1); - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Accent color shades - --md-accent-fg-color: hsla(#{hex2hsl($clr-indigo-a200)}, 1); - --md-accent-fg-color--transparent: hsla(#{hex2hsl($clr-indigo-a200)}, 0.1); - --md-accent-bg-color: hsla(0, 0%, 100%, 1); - --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Light theme (default) - > * { - - // Code color shades - --md-code-fg-color: hsla(200, 18%, 26%, 1); - --md-code-bg-color: hsla(0, 0%, 96%, 1); - - // Code highlighting color shades - --md-code-hl-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5); - --md-code-hl-number-color: hsla(0, 67%, 50%, 1); - --md-code-hl-special-color: hsla(340, 83%, 47%, 1); - --md-code-hl-function-color: hsla(291, 45%, 50%, 1); - --md-code-hl-constant-color: hsla(250, 63%, 60%, 1); - --md-code-hl-keyword-color: hsla(219, 54%, 51%, 1); - --md-code-hl-string-color: hsla(150, 63%, 30%, 1); - --md-code-hl-name-color: var(--md-code-fg-color); - --md-code-hl-operator-color: var(--md-default-fg-color--light); - --md-code-hl-punctuation-color: var(--md-default-fg-color--light); - --md-code-hl-comment-color: var(--md-default-fg-color--light); - --md-code-hl-generic-color: var(--md-default-fg-color--light); - --md-code-hl-variable-color: var(--md-default-fg-color--light); - - // Typeset color shades - --md-typeset-color: var(--md-default-fg-color); - - // Typeset `a` color shades - --md-typeset-a-color: var(--md-primary-fg-color); - - // Typeset `mark` color shades - --md-typeset-mark-color: hsla(#{hex2hsl($clr-yellow-a200)}, 0.5); - - // Typeset `del` and `ins` color shades - --md-typeset-del-color: hsla(6, 90%, 60%, 0.15); - --md-typeset-ins-color: hsla(150, 90%, 44%, 0.15); - - // Typeset `kbd` color shades - --md-typeset-kbd-color: hsla(0, 0%, 98%, 1); - --md-typeset-kbd-accent-color: hsla(0, 100%, 100%, 1); - --md-typeset-kbd-border-color: hsla(0, 0%, 72%, 1); - - // Typeset `table` color shades - --md-typeset-table-color: hsla(0, 0%, 0%, 0.12); - - // Admonition color shades - --md-admonition-fg-color: var(--md-default-fg-color); - --md-admonition-bg-color: var(--md-default-bg-color); - - // Footer color shades - --md-footer-fg-color: hsla(0, 0%, 100%, 1); - --md-footer-fg-color--light: hsla(0, 0%, 100%, 0.7); - --md-footer-fg-color--lighter: hsla(0, 0%, 100%, 0.3); - --md-footer-bg-color: hsla(0, 0%, 0%, 0.87); - --md-footer-bg-color--dark: hsla(0, 0%, 0%, 0.32); - } -} diff --git a/docs/src/assets/stylesheets/main/_icons.scss b/docs/src/assets/stylesheets/main/_icons.scss deleted file mode 100644 index 977804ac..00000000 --- a/docs/src/assets/stylesheets/main/_icons.scss +++ /dev/null @@ -1,37 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon -.md-icon { - - // SVG defaults - svg { - display: block; - width: px2rem(24px); - height: px2rem(24px); - fill: currentColor; - } -} diff --git a/docs/src/assets/stylesheets/main/_modifiers.scss b/docs/src/assets/stylesheets/main/_modifiers.scss deleted file mode 100644 index 69e64f45..00000000 --- a/docs/src/assets/stylesheets/main/_modifiers.scss +++ /dev/null @@ -1,63 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // [tablet +]: Allow for rendering content as sidebars - @include break-from-device(tablet) { - - // Modifier to float block elements - .inline { - float: left; - width: px2rem(234px); - margin-top: 0; - margin-right: px2rem(16px); - margin-bottom: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: right; - margin-right: 0; - margin-left: px2rem(16px); - } - - // Modifier to move to end (ltr: right, rtl: left) - &.end { - float: right; - margin-right: 0; - margin-left: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - margin-right: px2rem(16px); - margin-left: 0; - } - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/_reset.scss b/docs/src/assets/stylesheets/main/_reset.scss deleted file mode 100644 index de854ad2..00000000 --- a/docs/src/assets/stylesheets/main/_reset.scss +++ /dev/null @@ -1,113 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Enforce correct box model and prevent adjustments of font size after -// orientation changes in IE and iOS -html { - box-sizing: border-box; - text-size-adjust: none; -} - -// All elements shall inherit the document default -*, -*::before, -*::after { - box-sizing: inherit; -} - -// Remove margin in all browsers -body { - margin: 0; -} - -// Reset tap outlines on iOS and Android -a, -button, -label, -input { - -webkit-tap-highlight-color: transparent; -} - -// Reset link styles -a { - color: inherit; - text-decoration: none; -} - -// Normalize horizontal separator styles -hr { - display: block; - box-sizing: content-box; - height: px2rem(1px); - padding: 0; - overflow: visible; - border: 0; -} - -// Normalize font-size in all browsers -small { - font-size: 80%; -} - -// Prevent subscript and superscript from affecting line-height -sub, -sup { - line-height: 1em; -} - -// Remove border on image -img { - border-style: none; -} - -// Reset table styles -table { - border-collapse: separate; - border-spacing: 0; -} - -// Reset table cell styles -td, -th { - font-weight: 400; - vertical-align: top; -} - -// Reset button styles -button { - margin: 0; - padding: 0; - font-size: inherit; - font-family: inherit; - background: transparent; - border: 0; -} - -// Reset input styles -input { - border: 0; - outline: none; -} diff --git a/docs/src/assets/stylesheets/main/_shame.scss b/docs/src/assets/stylesheets/main/_shame.scss deleted file mode 100644 index a6acadab..00000000 --- a/docs/src/assets/stylesheets/main/_shame.scss +++ /dev/null @@ -1,25 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Nothing to see here, move along -// ---------------------------------------------------------------------------- diff --git a/docs/src/assets/stylesheets/main/_typeset.scss b/docs/src/assets/stylesheets/main/_typeset.scss deleted file mode 100644 index 5ee204a6..00000000 --- a/docs/src/assets/stylesheets/main/_typeset.scss +++ /dev/null @@ -1,640 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules: font definitions -// ---------------------------------------------------------------------------- - -// Enable font-smoothing in Webkit and FF -body { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -// Define default fonts -body, -input { - color: var(--md-typeset-color); - font-feature-settings: "kern", "liga"; - font-family: - var(--md-text-font-family, _), - -apple-system, BlinkMacSystemFont, Helvetica, Arial, sans-serif; -} - -// Define monospaced fonts -code, -pre, -kbd { - color: var(--md-typeset-color); - font-feature-settings: "kern"; - font-family: - var(--md-code-font-family, _), - SFMono-Regular, Consolas, Menlo, monospace; -} - -// ---------------------------------------------------------------------------- -// Rules: typesetted content -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-typeset-table-sort-icon: svg-load("material/sort.svg"); - --md-typeset-table-sort-icon--asc: svg-load("material/sort-ascending.svg"); - --md-typeset-table-sort-icon--desc: svg-load("material/sort-descending.svg"); -} - -// ---------------------------------------------------------------------------- - -// Content that is typeset - if possible, all margins, paddings and font sizes -// should be set in ems, so nested blocks (e.g. admonitions) render correctly. -.md-typeset { - font-size: px2rem(16px); - line-height: 1.6; - color-adjust: exact; - - // [print]: We'll use a smaller `font-size` for printing, so code examples - // don't break too early, and `16px` looks too big anyway. - @media print { - font-size: px2rem(13.6px); - } - - // Default spacing - ul, - ol, - dl, - figure, - blockquote, - pre { - margin: 1em 0; - } - - // Headline on level 1 - h1 { - margin: 0 0 px2em(40px, 32px); - color: var(--md-default-fg-color--light); - font-weight: 300; - font-size: px2em(32px); - line-height: 1.3; - letter-spacing: -0.01em; - } - - // Headline on level 2 - h2 { - margin: px2em(40px, 25px) 0 px2em(16px, 25px); - font-weight: 300; - font-size: px2em(25px); - line-height: 1.4; - letter-spacing: -0.01em; - } - - // Headline on level 3 - h3 { - margin: px2em(32px, 20px) 0 px2em(16px, 20px); - font-weight: 400; - font-size: px2em(20px); - line-height: 1.5; - letter-spacing: -0.01em; - } - - // Headline on level 3 following level 2 - h2 + h3 { - margin-top: px2em(16px, 20px); - } - - // Headline on level 4 - h4 { - margin: px2em(16px) 0; - font-weight: 700; - letter-spacing: -0.01em; - } - - // Headline on level 5-6 - h5, - h6 { - margin: px2em(16px, 12.8px) 0; - color: var(--md-default-fg-color--light); - font-weight: 700; - font-size: px2em(12.8px); - letter-spacing: -0.01em; - } - - // Headline on level 5 - h5 { - text-transform: uppercase; - } - - // Horizontal separator - hr { - display: flow-root; - margin: 1.5em 0; - border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest); - } - - // Text link - a { - color: var(--md-typeset-a-color); - word-break: break-word; - - // Also enable color transition on pseudo elements - &, - &::before { - transition: color 125ms; - } - - // Text link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - } - - // Code block - code, - pre, - kbd { - color: var(--md-code-fg-color); - direction: ltr; - - // [print]: Wrap text and hide scollbars - @media print { - white-space: pre-wrap; - } - } - - // Inline code block - code { - padding: 0 px2em(4px, 13.6px); - font-size: px2em(13.6px); - word-break: break-word; - background-color: var(--md-code-bg-color); - border-radius: px2rem(2px); - box-decoration-break: clone; - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - } - - // Code block in headline - h1 code, - h2 code, - h3 code, - h4 code, - h5 code, - h6 code { - margin: initial; - padding: initial; - background-color: transparent; - box-shadow: none; - } - - // Ensure link color in code blocks - a code { - color: currentColor; - } - - // Unformatted content - pre { - position: relative; - display: flow-root; - line-height: 1.4; - - // Code block - > code { - display: block; - margin: 0; - padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px); - overflow: auto; - word-break: normal; - box-shadow: none; - box-decoration-break: slice; - touch-action: auto; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Code block on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } - } - - // [mobile -]: Align with body copy - @include break-to-device(mobile) { - - // Unformatted text - > pre { - margin: 1em px2rem(-16px); - - // Code block - code { - border-radius: 0; - } - } - } - - // Keyboard key - kbd { - display: inline-block; - padding: 0 px2em(8px, 12px); - color: var(--md-default-fg-color); - font-size: px2em(12px); - vertical-align: text-top; - word-break: break-word; - background-color: var(--md-typeset-kbd-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(2px) 0 px2rem(1px) var(--md-typeset-kbd-border-color), - 0 px2rem(2px) 0 var(--md-typeset-kbd-border-color), - 0 px2rem(-2px) px2rem(4px) var(--md-typeset-kbd-accent-color) inset; - } - - // Text highlighting marker - mark { - color: inherit; - word-break: break-word; - background-color: var(--md-typeset-mark-color); - box-decoration-break: clone; - } - - // Abbreviation - abbr { - text-decoration: none; - border-bottom: px2rem(1px) dotted var(--md-default-fg-color--light); - cursor: help; - - // Show tooltip for touch devices - @media (hover: none) { - position: relative; - - // Tooltip - &[title]:focus::after, - &[title]:hover::after { - @include z-depth(2); - - position: absolute; - left: 0; - display: inline-block; - width: auto; - min-width: max-content; - max-width: 80%; - margin-top: 2em; - padding: px2rem(4px) px2rem(6px); - color: var(--md-default-bg-color); - font-size: px2rem(14px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - content: attr(title); - } - } - } - - // Small text - small { - opacity: 0.75; - } - - // Superscript and subscript - sup, - sub { - margin-left: px2em(1px, 12.8px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(1px, 12.8px); - margin-left: initial; - } - } - - // Blockquotes, possibly nested - blockquote { - padding-left: px2rem(12px); - color: var(--md-default-fg-color--light); - border-left: px2rem(4px) solid var(--md-default-fg-color--lighter); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(12px); - padding-left: initial; - border-right: px2rem(4px) solid var(--md-default-fg-color--lighter); - border-left: initial; - } - } - - // Unordered list - ul { - list-style-type: disc; - } - - // Unordered and ordered list - ul, - ol { - display: flow-root; - margin-left: px2em(10px); - padding: 0; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(10px); - margin-left: initial; - } - - // Nested ordered list - ol { - list-style-type: lower-alpha; - - // Triply nested ordered list - ol { - list-style-type: lower-roman; - } - } - - // List element - li { - margin-bottom: 0.5em; - margin-left: px2em(20px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(20px); - margin-left: initial; - } - - // Adjust spacing - p, - blockquote { - margin: 0.5em 0; - } - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - - // Nested list - ul, - ol { - margin: 0.5em 0 0.5em px2em(10px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(10px); - margin-left: initial; - } - } - } - } - - // Definition list - dd { - margin: 1em 0 1.5em px2em(30px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2em(30px); - margin-left: initial; - } - } - - // Image or icon - img, - svg { - max-width: 100%; - height: auto; - - // Adjust spacing when left-aligned - &[align="left"] { - margin: 1em; - margin-left: 0; - } - - // Adjust spacing when right-aligned - &[align="right"] { - margin: 1em; - margin-right: 0; - } - - // Adjust spacing when sole children - &[align]:only-child { - margin-top: 0; - } - } - - // Figure - figure { - display: flow-root; - width: fit-content; - max-width: 100%; - margin: 0 auto; - text-align: center; - - // Figure images - img { - display: block; - } - } - - // Figure caption - figcaption { - max-width: px2rem(480px); - margin: 1em auto 2em; - font-style: italic; - } - - // Limit width to container - iframe { - max-width: 100%; - } - - // Data table - table:not([class]) { - display: inline-block; - max-width: 100%; - overflow: auto; - font-size: px2rem(12.8px); - background-color: var(--md-default-bg-color); - border: px2rem(1px) solid var(--md-typeset-table-color); - border-radius: px2rem(2px); - touch-action: auto; - - // [print]: Reset display mode so table header wraps when printing - @media print { - display: table; - } - - // Due to margin collapse because of the necessary inline-block hack, we - // cannot increase the bottom margin on the table, so we just increase the - // top margin on the following element - + * { - margin-top: 1.5em; - } - - // Elements in table heading and cell - th > *, - td > * { - - // Adjust spacing on first child - &:first-child { - margin-top: 0; - } - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - } - - // Table heading and cell - th:not([align]), - td:not([align]) { - text-align: left; - - // Adjust for right-to-left languages - [dir="rtl"] & { - text-align: right; - } - } - - // Table heading - th { - min-width: px2rem(100px); - padding: px2em(12px, 12.8px) px2em(16px, 12.8px); - font-weight: 700; - vertical-align: top; - - // Links in table headings - a { - color: inherit; - } - } - - // Table cell - td { - padding: px2em(12px, 12.8px) px2em(16px, 12.8px); - vertical-align: top; - border-top: px2rem(1px) solid var(--md-typeset-table-color); - } - - // Table body row - tbody tr { - transition: background-color 125ms; - - // Table row on hover - &:hover { - background-color: rgba(0, 0, 0, 0.035); - box-shadow: 0 px2rem(1px) 0 var(--md-default-bg-color) inset; - } - } - - // Text link in table - a { - word-break: normal; - } - } - - // Sortable table - table th[role="columnheader"] { - cursor: pointer; - - // Sort icon - &::after { - display: inline-block; - width: 1.2em; - height: 1.2em; - margin-left: 0.5em; - vertical-align: text-bottom; - mask-image: var(--md-typeset-table-sort-icon); - mask-repeat: no-repeat; - mask-size: contain; - transition: background-color 125ms; - content: ""; - } - - // Show sort icon on hover - &:hover::after { - background-color: var(--md-default-fg-color--lighter); - } - - // Sort ascending icon - &[aria-sort="ascending"]::after { - background-color: var(--md-default-fg-color--light); - mask-image: var(--md-typeset-table-sort-icon--asc); - } - - // Sort descending icon - &[aria-sort="descending"]::after { - background-color: var(--md-default-fg-color--light); - mask-image: var(--md-typeset-table-sort-icon--desc); - } - } - - // Data table scroll wrapper - &__scrollwrap { - margin: 1em px2rem(-16px); - overflow-x: auto; - touch-action: auto; - } - - // Data table wrapper - &__table { - display: inline-block; - margin-bottom: 0.5em; - padding: 0 px2rem(16px); - - // [print]: Reset display mode so table header wraps when printing - @media print { - display: block; - } - - // Data table - html & table { - display: table; - width: 100%; - margin: 0; - overflow: hidden; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/markdown/_admonition.scss b/docs/src/assets/stylesheets/main/extensions/markdown/_admonition.scss deleted file mode 100644 index b707db33..00000000 --- a/docs/src/assets/stylesheets/main/extensions/markdown/_admonition.scss +++ /dev/null @@ -1,197 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Variables -// ---------------------------------------------------------------------------- - -/// Admonition flavours -$admonitions: ( - note: pencil $clr-blue-a200, - abstract summary tldr: clipboard-text $clr-light-blue-a400, - info todo: information $clr-cyan-a700, - tip hint important: fire $clr-teal-a700, - success check done: check-bold $clr-green-a700, - question help faq: help-circle $clr-light-green-a700, - warning caution attention: alert $clr-orange-a400, - failure fail missing: close-thick $clr-red-a200, - danger error: lightning-bolt $clr-red-a400, - bug: bug $clr-pink-a400, - example: format-list-numbered $clr-deep-purple-a200, - quote cite: format-quote-close $clr-grey -) !default; - -// ---------------------------------------------------------------------------- -// Rules: layout -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - @each $names, $props in $admonitions { - --md-admonition-icon--#{nth($names, 1)}: - svg-load("material/#{nth($props, 1)}.svg"); - } -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Admonition - .admonition { - margin: px2em(20px, 12.8px) 0; - padding: 0 px2rem(12px); - overflow: hidden; - color: var(--md-admonition-fg-color); - font-size: px2rem(12.8px); - page-break-inside: avoid; - background-color: var(--md-admonition-bg-color); - border-left: px2rem(4px) solid $clr-blue-a200; - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.05), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.05); - - // [print]: Omit shadow as it may lead to rendering errors - @media print { - box-shadow: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - border-right: px2rem(4px) solid $clr-blue-a200; - border-left: none; - } - - // Adjust vertical spacing for nested admonitions - .admonition { - margin-top: 1em; - margin-bottom: 1em; - } - - // Adjust spacing for contained table wrappers - .md-typeset__scrollwrap { - margin: 1em px2rem(-12px); - } - - // Adjust spacing for contained tables - .md-typeset__table { - padding: 0 px2rem(12px); - } - - // Adjust spacing for single-child tabbed block container - > .tabbed-set:only-child { - margin-top: 0; - } - - // Adjust spacing on last child - html & > :last-child { - margin-bottom: px2rem(12px); - } - } - - // Admonition title - .admonition-title { - position: relative; - margin: 0 px2rem(-12px) 0 px2rem(-16px); - padding: px2rem(8px) px2rem(12px) px2rem(8px) px2rem(40px); - font-weight: 700; - background-color: transparentize($clr-blue-a200, 0.9); - border-left: px2rem(4px) solid $clr-blue-a200; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin: 0 px2rem(-16px) 0 px2rem(-12px); - padding: px2rem(8px) px2rem(40px) px2rem(8px) px2rem(12px); - border-right: px2rem(4px) solid $clr-blue-a200; - border-left: none; - } - - // Adjust spacing for title-only admonitions - html &:last-child { - margin-bottom: 0; - } - - // Admonition icon - &::before { - position: absolute; - left: px2rem(12px); - width: px2rem(20px); - height: px2rem(20px); - background-color: $clr-blue-a200; - mask-image: var(--md-admonition-icon--note); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(12px); - left: initial; - } - } - - // Adjust spacing on last tabbed block container child - if the tabbed - // block container is the sole child, it looks better to omit the margin - + .tabbed-set:last-child { - margin-top: 0; - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: flavours -// ---------------------------------------------------------------------------- - -@each $names, $props in $admonitions { - $name: nth($names, 1); - $tint: nth($props, 2); - - // Admonition flavour - .md-typeset .admonition.#{$name} { - border-color: $tint; - } - - // Admonition flavour title - .md-typeset .#{$name} > .admonition-title { - background-color: transparentize($tint, 0.9); - border-color: $tint; - - // Admonition icon - &::before { - background-color: $tint; - mask-image: var(--md-admonition-icon--#{$name}); - mask-repeat: no-repeat; - mask-size: contain; - } - } - - // Define synonyms for flavours - @if length($names) > 1 { - @for $n from 2 through length($names) { - .#{nth($names, $n)} { - @extend .#{$name}; - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss b/docs/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss deleted file mode 100644 index b69dcf6e..00000000 --- a/docs/src/assets/stylesheets/main/extensions/markdown/_footnotes.scss +++ /dev/null @@ -1,153 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-footnotes-icon: svg-load("material/keyboard-return.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Footnote container - .footnote { - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - - // Footnote list - omit left indentation - > ol { - margin-left: 0; - - // Footnote item - footnote items can contain lists, so we need to scope - // the spacing adjustments to the top-level footnote item. - > li { - transition: color 125ms; - - // Darken color on target - &:target { - color: var(--md-default-fg-color); - } - - // Show backreferences on footnote hover - &:hover .footnote-backref, - &:target .footnote-backref { - transform: translateX(0); - opacity: 1; - } - - // Adjust spacing on first child - > :first-child { - margin-top: 0; - } - } - } - } - - // Footnote reference - .footnote-ref { - font-weight: 700; - font-size: px2em(12px, 16px); - - // Hack: increase specificity to override default - html & { - outline-offset: px2rem(2px); - } - } - - // Footnote backreference - .footnote-backref { - display: inline-block; - color: var(--md-typeset-a-color); - // Hack: omit Unicode arrow for replacement with icon - font-size: 0; - vertical-align: text-bottom; - transform: translateX(px2rem(5px)); - opacity: 0; - transition: - color 250ms, - transform 250ms 250ms, - opacity 125ms 250ms; - - // [print]: Show footnote backreferences - @media print { - color: var(--md-typeset-a-color); - transform: translateX(0); - opacity: 1; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-5px)); - } - - // Adjust color on hover - &:hover { - color: var(--md-accent-fg-color); - } - - // Footnote backreference icon - &::before { - display: inline-block; - width: px2rem(16px); - height: px2rem(16px); - background-color: currentColor; - mask-image: var(--md-footnotes-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - } - - // Footnote reference wrapper - [id^="fnref:"]:target { - scroll-margin-top: initial; - margin-top: -1 * px2rem(48px + 24px - 4px); - padding-top: px2rem(48px + 24px - 4px); - - // Show outline for all devices - > .footnote-ref { - outline: auto; - } - } - - // Footnote wrapper - [id^="fn:"]:target { - scroll-margin-top: initial; - margin-top: -1 * px2rem(48px + 24px - 3px); - padding-top: px2rem(48px + 24px - 3px); - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/markdown/_toc.scss b/docs/src/assets/stylesheets/main/extensions/markdown/_toc.scss deleted file mode 100644 index 78db25c3..00000000 --- a/docs/src/assets/stylesheets/main/extensions/markdown/_toc.scss +++ /dev/null @@ -1,172 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Headerlink - .headerlink { - display: inline-block; - margin-left: px2rem(10px); - color: var(--md-default-fg-color--lighter); - opacity: 0; - transition: - color 250ms, - opacity 125ms; - - // [print]: Hide headerlinks - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(10px); - margin-left: initial; - } - } - - // Show headerlinks on parent hover - :hover > .headerlink, - :target > .headerlink, - .headerlink:focus { - opacity: 1; - transition: - color 250ms, - opacity 125ms; - } - - // Adjust color on parent target or focus/hover - :target > .headerlink, - .headerlink:focus, - .headerlink:hover { - color: var(--md-accent-fg-color); - } - - // Adjust scroll offset for all elements with `id` attributes - general scroll - // margin offset for anything that can be targeted. Browser support is pretty - // decent by now, but Edge <79 and Safari (iOS and macOS) still don't support - // it properly, so we settle with a cross-browser anchor correction solution. - :target { - scroll-margin-top: px2rem(48px + 24px); - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll offset for sticky navigation tabs - .md-header--lifted ~ .md-container & { - scroll-margin-top: px2rem(96px + 24px); - } - } - } - - // Adjust scroll offset for headlines of level 1-3 - h1:target, - h2:target, - h3:target { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - display: block; - margin-top: -1 * px2rem(48px + 24px - 4px); - padding-top: px2rem(48px + 24px - 4px); - content: ""; - } - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll offset for sticky navigation tabs - .md-header--lifted ~ .md-container & { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - margin-top: -1 * px2rem(96px + 24px - 4px); - padding-top: px2rem(96px + 24px - 4px); - } - } - } - } - - // Adjust scroll offset for headlines of level 4 - h4:target { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - display: block; - margin-top: -1 * px2rem(48px + 24px - 3px); - padding-top: px2rem(48px + 24px - 3px); - content: ""; - } - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll offset for sticky navigation tabs - .md-header--lifted ~ .md-container & { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - margin-top: -1 * px2rem(96px + 24px - 3px); - padding-top: px2rem(96px + 24px - 3px); - } - } - } - } - - // Adjust scroll offset for headlines of level 5-6 - h5:target, - h6:target { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - display: block; - margin-top: -1 * px2rem(48px + 24px); - padding-top: px2rem(48px + 24px); - content: ""; - } - - // [screen +]: Sticky navigation tabs - @include break-from-device(screen) { - - // Adjust scroll offset for sticky navigation tabs - .md-header--lifted ~ .md-container & { - scroll-margin-top: initial; - - // Anchor correction hack - &::before { - margin-top: -1 * px2rem(96px + 24px); - padding-top: px2rem(96px + 24px); - } - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss deleted file mode 100644 index a96c9d44..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_arithmatex.scss +++ /dev/null @@ -1,48 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Arithmatex container - div.arithmatex { - overflow: auto; - - // [mobile -]: Align with body copy - @include break-to-device(mobile) { - margin: 0 px2rem(-16px); - } - - // Arithmatex content - > * { - width: min-content; - // stylelint-disable-next-line declaration-no-important - margin: 1em auto !important; - padding: 0 px2rem(16px); - touch-action: auto; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss deleted file mode 100644 index 08424723..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_critic.scss +++ /dev/null @@ -1,81 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Deletion, addition or comment - del.critic, - ins.critic, - .critic.comment { - box-decoration-break: clone; - } - - // Deletion - del.critic { - background-color: var(--md-typeset-del-color); - } - - // Addition - ins.critic { - background-color: var(--md-typeset-ins-color); - } - - // Comment - .critic.comment { - color: var(--md-code-hl-comment-color); - - // Comment opening mark - &::before { - content: "/* "; - } - - // Comment closing mark - &::after { - content: " */"; - } - } - - // Critic block - .critic.block { - display: block; - margin: 1em 0; - padding-right: px2rem(16px); - padding-left: px2rem(16px); - overflow: auto; - box-shadow: none; - - // Adjust spacing on first child - > :first-child { - margin-top: 0.5em; - } - - // Adjust spacing on last child - > :last-child { - margin-bottom: 0.5em; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_details.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_details.scss deleted file mode 100644 index c26e08b4..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_details.scss +++ /dev/null @@ -1,128 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-details-icon: svg-load("material/chevron-right.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Details - details { - @extend .admonition; - - display: flow-root; - padding-top: 0; - overflow: visible; - - // Details title icon - rotate icon on transition to open state - &[open] > summary::after { - transform: rotate(90deg); - } - - // Adjust spacing for details in closed state - &:not([open]) { - padding-bottom: 0; - box-shadow: none; - - // Hack: we cannot set `overflow: hidden` on the `details` element (which - // is why we set it to `overflow: visible`, as the outline would not be - // visible when focusing. Therefore, we must set the border radius on the - // summary explicitly. - > summary { - border-radius: px2rem(2px); - } - } - - // Hack: omit margin collapse - &::after { - display: table; - content: ""; - } - } - - // Details title - summary { - @extend .admonition-title; - - display: block; - min-height: px2rem(20px); - padding: px2rem(8px) px2rem(36px) px2rem(8px) px2rem(40px); - border-top-left-radius: px2rem(2px); - border-top-right-radius: px2rem(2px); - cursor: pointer; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding: px2rem(8px) px2rem(44px) px2rem(8px) px2rem(36px); - } - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Details marker - &::after { - position: absolute; - top: px2rem(8px); - right: px2rem(8px); - width: px2rem(20px); - height: px2rem(20px); - background-color: currentColor; - mask-image: var(--md-details-icon); - mask-repeat: no-repeat; - mask-size: contain; - transform: rotate(0deg); - transition: transform 250ms; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(8px); - transform: rotate(180deg); - } - } - - // Hide native details marker - &::marker, - &::-webkit-details-marker { - display: none; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss deleted file mode 100644 index 693fb7ce..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_emoji.scss +++ /dev/null @@ -1,45 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Emoji and icon container - .emojione, - .twemoji, - .gemoji { - display: inline-flex; - height: px2em(18px); - vertical-align: text-top; - - // Icon - inlined via mkdocs-material-extensions - svg { - width: px2em(18px); - max-height: 100%; - fill: currentColor; - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss deleted file mode 100644 index 38289576..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_highlight.scss +++ /dev/null @@ -1,275 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules: syntax highlighting -// ---------------------------------------------------------------------------- - -// Code block -.highlight { - .o, // Operator - .ow { // Operator, word - color: var(--md-code-hl-operator-color); - } - - .p { // Punctuation - color: var(--md-code-hl-punctuation-color); - } - - .cpf, // Comment, preprocessor file - .l, // Literal - .s, // Literal, string - .sb, // Literal, string backticks - .sc, // Literal, string char - .s2, // Literal, string double - .si, // Literal, string interpol - .s1, // Literal, string single - .ss { // Literal, string symbol - color: var(--md-code-hl-string-color); - } - - .cp, // Comment, pre-processor - .se, // Literal, string escape - .sh, // Literal, string heredoc - .sr, // Literal, string regex - .sx { // Literal, string other - color: var(--md-code-hl-special-color); - } - - .m, // Number - .mb, // Number, binary - .mf, // Number, float - .mh, // Number, hex - .mi, // Number, integer - .il, // Number, integer long - .mo { // Number, octal - color: var(--md-code-hl-number-color); - } - - .k, // Keyword, - .kd, // Keyword, declaration - .kn, // Keyword, namespace - .kp, // Keyword, pseudo - .kr, // Keyword, reserved - .kt { // Keyword, type - color: var(--md-code-hl-keyword-color); - } - - .kc, // Keyword, constant - .n { // Name - color: var(--md-code-hl-name-color); - } - - .no, // Name, constant - .nb, // Name, builtin - .bp { // Name, builtin pseudo - color: var(--md-code-hl-constant-color); - } - - .nc, // Name, class - .ne, // Name, exception - .nf, // Name, function - .nn { // Name, namespace - color: var(--md-code-hl-function-color); - } - - .nd, // Name, decorator - .ni, // Name, entity - .nl, // Name, label - .nt { // Name, tag - color: var(--md-code-hl-keyword-color); - } - - .c, // Comment - .cm, // Comment, multiline - .c1, // Comment, single - .ch, // Comment, shebang - .cs, // Comment, special - .sd { // Literal, string doc - color: var(--md-code-hl-comment-color); - } - - .na, // Name, attribute - .nv, // Variable, - .vc, // Variable, class - .vg, // Variable, global - .vi { // Variable, instance - color: var(--md-code-hl-variable-color); - } - - .ge, // Generic, emph - .gr, // Generic, error - .gh, // Generic, heading - .go, // Generic, output - .gp, // Generic, prompt - .gs, // Generic, strong - .gu, // Generic, subheading - .gt { // Generic, traceback - color: var(--md-code-hl-generic-color); - } - - .gd, // Diff, delete - .gi { // Diff, insert - margin: 0 px2em(-2px); - padding: 0 px2em(2px); - border-radius: px2rem(2px); - } - - .gd { // Diff, delete - background-color: var(--md-typeset-del-color); - } - - .gi { // Diff, insert - background-color: var(--md-typeset-ins-color); - } - - // Highlighted line - .hll { - display: block; - margin: 0 px2em(-16px, 13.6px); - padding: 0 px2em(16px, 13.6px); - background-color: var(--md-code-hl-color); - } - - // Code block line numbers (inline) - [data-linenos]::before { - position: sticky; - left: px2em(-16px, 13.6px); - float: left; - margin-right: px2em(16px, 13.6px); - margin-left: px2em(-16px, 13.6px); - padding-left: px2em(16px, 13.6px); - color: var(--md-default-fg-color--light); - background-color: var(--md-code-bg-color); - box-shadow: px2rem(-1px) 0 var(--md-default-fg-color--lightest) inset; - content: attr(data-linenos); - user-select: none; - } -} - -// ---------------------------------------------------------------------------- -// Rules: layout -// ---------------------------------------------------------------------------- - -// Code block with line numbers -.highlighttable { - display: flow-root; - overflow: hidden; - - // Set table elements to block layout, because otherwise the whole flexbox - // hacking won't work correctly - tbody, - td { - display: block; - padding: 0; - } - - // We need to use flexbox layout, because otherwise it's not possible to - // make the code container scroll while keeping the line numbers static - tr { - display: flex; - } - - // The pre tags are nested inside a table, so we need to omit the margin - // because it collapses below all the overflows - pre { - margin: 0; - } - - // Code block line numbers - disable user selection, so code can be easily - // copied without accidentally also copying the line numbers - .linenos { - padding: px2em(10.5px, 13.6px) px2em(16px, 13.6px); - padding-right: 0; - font-size: px2em(13.6px); - background-color: var(--md-code-bg-color); - user-select: none; - } - - // Code block line numbers container - .linenodiv { - padding-right: px2em(8px, 13.6px); - box-shadow: px2rem(-1px) 0 var(--md-default-fg-color--lightest) inset; - - // Adjust colors and alignment - pre { - color: var(--md-default-fg-color--light); - text-align: right; - } - } - - // Code block container - stretch to remaining space - .code { - flex: 1; - overflow: hidden; - } -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Code block with line numbers - .highlighttable { - margin: 1em 0; - direction: ltr; - border-radius: px2rem(2px); - - // Omit rounded borders on contained code block - code { - border-radius: 0; - } - } - - // [mobile -]: Align with body copy - @include break-to-device(mobile) { - - // Top-level code block - > .highlight { - margin: 1em px2rem(-16px); - - // Highlighted line - .hll { - margin: 0 px2rem(-16px); - padding: 0 px2rem(16px); - } - - // Omit rounded borders - code { - border-radius: 0; - } - } - - // Top-level code block with line numbers - > .highlighttable { - margin: 1em px2rem(-16px); - border-radius: 0; - - // Highlighted line - .hll { - margin: 0 px2rem(-16px); - padding: 0 px2rem(16px); - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss deleted file mode 100644 index 75785945..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_keys.scss +++ /dev/null @@ -1,120 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Keyboard key - .keys { - - // Keyboard key icon - kbd::before, - kbd::after { - position: relative; - margin: 0; - color: inherit; - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - } - - // Surrounding text - span { - padding: 0 px2em(3.2px); - color: var(--md-default-fg-color--light); - } - - // Define keyboard keys with left icon - @each $name, $code in ( - - // Modifiers - "alt": "\2387", - "left-alt": "\2387", - "right-alt": "\2387", - "command": "\2318", - "left-command": "\2318", - "right-command": "\2318", - "control": "\2303", - "left-control": "\2303", - "right-control": "\2303", - "meta": "\25C6", - "left-meta": "\25C6", - "right-meta": "\25C6", - "option": "\2325", - "left-option": "\2325", - "right-option": "\2325", - "shift": "\21E7", - "left-shift": "\21E7", - "right-shift": "\21E7", - "super": "\2756", - "left-super": "\2756", - "right-super": "\2756", - "windows": "\229E", - "left-windows": "\229E", - "right-windows": "\229E", - - // Other keys - "arrow-down": "\2193", - "arrow-left": "\2190", - "arrow-right": "\2192", - "arrow-up": "\2191", - "backspace": "\232B", - "backtab": "\21E4", - "caps-lock": "\21EA", - "clear": "\2327", - "context-menu": "\2630", - "delete": "\2326", - "eject": "\23CF", - "end": "\2913", - "escape": "\238B", - "home": "\2912", - "insert": "\2380", - "page-down": "\21DF", - "page-up": "\21DE", - "print-screen": "\2399" - ) { - .key-#{$name} { - &::before { - padding-right: px2em(6.4px); - content: $code; - } - } - } - - // Define keyboard keys with right icon - @each $name, $code in ( - "tab": "\21E5", - "num-enter": "\2324", - "enter": "\23CE" - ) { - .key-#{$name} { - &::after { - padding-left: px2em(6.4px); - content: $code; - } - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss deleted file mode 100644 index 1727d15d..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_tabbed.scss +++ /dev/null @@ -1,123 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Tabbed block content - .tabbed-content { - display: none; - order: 99; - width: 100%; - box-shadow: 0 px2rem(-1px) var(--md-default-fg-color--lightest); - - // [print]: Show all tabs (even hidden ones) when printing - @media print { - display: block; - order: initial; - } - - // Code block is the only child of a tab - remove margin and mirror - // previous (now deprecated) SuperFences code block grouping behavior - > pre:only-child, - > .highlight:only-child pre, - > .highlighttable:only-child { - margin: 0; - - // Omit rounded borders - > code { - border-top-left-radius: 0; - border-top-right-radius: 0; - } - } - - // Adjust spacing for nested tab - > .tabbed-set { - margin: 0; - } - } - - // Tabbed block container - .tabbed-set { - position: relative; - display: flex; - flex-wrap: wrap; - margin: 1em 0; - border-radius: px2rem(2px); - - // Tab radio button - the Tabbed extension will generate radio buttons with - // labels, so tabs can be triggered without the necessity for JavaScript. - // This is pretty cool, as it has great accessibility out-of-the box, so - // we just hide the radio button and toggle the label color for indication. - > input { - position: absolute; - width: 0; - height: 0; - opacity: 0; - - // Tab label for checked radio button - &:checked + label { - color: var(--md-accent-fg-color); - border-color: var(--md-accent-fg-color); - - // Show tabbed block content - + .tabbed-content { - display: block; - } - } - - // Tab label on focus - &:focus + label { - outline-style: auto; - outline-color: var(--md-accent-fg-color); - } - - // Hide outline for pointer devices - &:not(.focus-visible) + label { - outline: none; - -webkit-tap-highlight-color: transparent; - } - } - - // Tab label - > label { - z-index: 1; - width: auto; - padding: px2em(12px, 12.8px) 1.25em px2em(10px, 12.8px); - color: var(--md-default-fg-color--light); - font-weight: 700; - font-size: px2rem(12.8px); - border-bottom: px2rem(2px) solid transparent; - cursor: pointer; - transition: color 250ms; - - // Tab label on hover - &:hover { - color: var(--md-accent-fg-color); - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss b/docs/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss deleted file mode 100644 index 6ee10486..00000000 --- a/docs/src/assets/stylesheets/main/extensions/pymdownx/_tasklist.scss +++ /dev/null @@ -1,91 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-tasklist-icon: - svg-load("octicons/check-circle-fill-24.svg"); - --md-tasklist-icon--checked: - svg-load("octicons/check-circle-fill-24.svg"); -} - -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Tasklist item - .task-list-item { - position: relative; - list-style-type: none; - - // Make checkbox items align with normal list items, but position - // everything in ems for correct layout at smaller font sizes - [type="checkbox"] { - position: absolute; - top: 0.45em; - left: -2em; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: -2em; - left: initial; - } - } - } - - // Hide native checkbox, when custom classes are enabled - .task-list-control [type="checkbox"] { - z-index: -1; - opacity: 0; - } - - // Tasklist indicator in unchecked state - .task-list-indicator::before { - position: absolute; - top: 0.15em; - left: px2em(-24px); - width: px2em(20px); - height: px2em(20px); - background-color: var(--md-default-fg-color--lightest); - mask-image: var(--md-tasklist-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2em(-24px); - left: initial; - } - } - - // Tasklist indicator in checked state - [type="checkbox"]:checked + .task-list-indicator::before { - background-color: $clr-green-a400; - mask-image: var(--md-tasklist-icon--checked); - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_announce.scss b/docs/src/assets/stylesheets/main/layout/_announce.scss deleted file mode 100644 index 4f2a13b9..00000000 --- a/docs/src/assets/stylesheets/main/layout/_announce.scss +++ /dev/null @@ -1,44 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Announcement bar -.md-announce { - overflow: auto; - background-color: var(--md-footer-bg-color); - - // [print]: Hide announcement bar - @media print { - display: none; - } - - // Announcement wrapper - &__inner { - margin: px2rem(12px) auto; - padding: 0 px2rem(16px); - color: var(--md-footer-fg-color); - font-size: px2rem(14px); - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_base.scss b/docs/src/assets/stylesheets/main/layout/_base.scss deleted file mode 100644 index 7863fec2..00000000 --- a/docs/src/assets/stylesheets/main/layout/_base.scss +++ /dev/null @@ -1,184 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules: base grid and containers -// ---------------------------------------------------------------------------- - -// Stretch container to viewport and set base `font-size` -html { - height: 100%; - overflow-x: hidden; - // Hack: normally, we would set the base `font-size` to `62.5%`, so we can - // base all calculations on `10px`, but Chromium and Chrome define a minimal - // `font-size` of `12px` if the system language is set to Chinese. For this - // reason we just double the `font-size` and set it to `20px`. - // - // See https://github.com/squidfunk/mkdocs-material/issues/911 - font-size: 125%; - - // [screen medium +]: Set base `font-size` to `11px` - @include break-from-device(screen medium) { - font-size: 137.5%; - } - - // [screen large +]: Set base `font-size` to `12px` - @include break-from-device(screen large) { - font-size: 150%; - } -} - -// Stretch body to container - flexbox is used, so the footer will always be -// aligned to the bottom of the viewport -body { - position: relative; - display: flex; - flex-direction: column; - width: 100%; - min-height: 100%; - // Hack: reset `font-size` to `10px`, so the spacing for all inline elements - // is correct again. Otherwise the spacing would be based on `20px`. - font-size: px2rem(10px); - background-color: var(--md-default-bg-color); - - // [print]: Omit flexbox layout due to a Firefox bug (https://mzl.la/39DgR3m) - @media print { - display: block; - } - - // Body in locked state - &[data-md-state="lock"] { - - // [tablet portrait -]: Omit scroll bubbling - @include break-to-device(tablet portrait) { - position: fixed; - } - } -} - -// ---------------------------------------------------------------------------- - -// Grid container - this class is applied to wrapper elements within the -// header, content area and footer, and makes sure that their width is limited -// to `1220px`, and they are rendered centered if the screen is larger. -.md-grid { - max-width: px2rem(1220px); - margin-right: auto; - margin-left: auto; -} - -// Main container -.md-container { - display: flex; - flex-direction: column; - flex-grow: 1; - - // [print]: Omit flexbox layout due to a Firefox bug (https://mzl.la/39DgR3m) - @media print { - display: block; - } -} - -// Main area - stretch to remaining space of container -.md-main { - flex-grow: 1; - - // Main area wrapper - &__inner { - display: flex; - height: 100%; - margin-top: px2rem(24px + 6px); - } -} - -// Add ellipsis in case of overflowing text -.md-ellipsis { - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} - -// ---------------------------------------------------------------------------- -// Rules: navigational elements -// ---------------------------------------------------------------------------- - -// Toggle - this class is applied to checkbox elements, which are used to -// implement the CSS-only drawer and navigation, as well as the search -.md-toggle { - display: none; -} - -// Option - this class is applied to radio elements, which are used to -// implement the color palette toggle -.md-option { - position: absolute; - width: 0; - height: 0; - opacity: 0; - - // Option label for checked radio button - &:checked + label:not([hidden]) { - display: block; - } - - // Show outline for keyboard devices - &.focus-visible + label { - outline-style: auto; - outline-color: var(--md-accent-fg-color); - } -} - -// Skip link -.md-skip { - position: fixed; - // Hack: if we don't set the negative `z-index`, the skip link will force the - // creation of new layers when code blocks are near the header on scrolling - z-index: -1; - margin: px2rem(10px); - padding: px2rem(6px) px2rem(10px); - color: var(--md-default-bg-color); - font-size: px2rem(12.8px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - outline-color: var(--md-accent-fg-color); - transform: translateY(px2rem(8px)); - opacity: 0; - - // Show skip link on focus - &:focus { - z-index: 10; - transform: translateY(0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 175ms 75ms; - } -} - -// ---------------------------------------------------------------------------- -// Rules: print styles -// ---------------------------------------------------------------------------- - -// Add margins to page -@page { - margin: 25mm; -} diff --git a/docs/src/assets/stylesheets/main/layout/_clipboard.scss b/docs/src/assets/stylesheets/main/layout/_clipboard.scss deleted file mode 100644 index eff2c719..00000000 --- a/docs/src/assets/stylesheets/main/layout/_clipboard.scss +++ /dev/null @@ -1,103 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-clipboard-icon: svg-load("material/content-copy.svg"); -} - -// ---------------------------------------------------------------------------- - -// Button to copy to clipboard -.md-clipboard { - position: absolute; - top: px2em(8px); - right: px2em(8px); - z-index: 1; - width: px2em(24px); - height: px2em(24px); - color: var(--md-default-fg-color--lightest); - border-radius: px2rem(2px); - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(2px); - cursor: pointer; - transition: color 250ms; - - // [print]: Hide button - @media print { - display: none; - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Darken color on code block hover - :hover > & { - color: var(--md-default-fg-color--light); - } - - // Button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Button icon - the width and height are defined in `em`, so the size is - // automatically adjusted for nested code blocks (e.g. in admonitions) - &::after { - display: block; - width: px2em(18px); - height: px2em(18px); - margin: 0 auto; - background-color: currentColor; - mask-image: var(--md-clipboard-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Inline button - &--inline { - cursor: pointer; - - // Code block - code { - transition: - color 250ms, - background-color 250ms; - } - - // Code block on focus/hover - &:focus code, - &:hover code { - color: var(--md-accent-fg-color); - background-color: var(--md-accent-fg-color--transparent); - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_content.scss b/docs/src/assets/stylesheets/main/layout/_content.scss deleted file mode 100644 index e53f76cc..00000000 --- a/docs/src/assets/stylesheets/main/layout/_content.scss +++ /dev/null @@ -1,119 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Content area -.md-content { - flex-grow: 1; - // Hack: we must use `overflow: hidden`, so the content area is capped by - // the dimensions of its parent. Otherwise, long code blocks might lead to - // a wider content area which will break everything. This, however, induces - // margin collapse, which will break scroll margins. Adding a large enough - // scroll padding seems to do the trick, at least in Chrome and Firefox. - overflow: hidden; - scroll-padding-top: px2rem(1024px); - - // Content wrapper - &__inner { - margin: 0 px2rem(16px) px2rem(24px); - padding-top: px2rem(12px); - - // [screen +]: Adjust spacing between content area and sidebars - @include break-from-device(screen) { - - // Sidebar with navigation is visible - .md-sidebar--primary:not([hidden]) ~ .md-content > & { - margin-left: px2rem(24px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(24px); - margin-left: px2rem(16px); - } - } - - // Sidebar with table of contents is visible - .md-sidebar--secondary:not([hidden]) ~ .md-content > & { - margin-right: px2rem(24px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(16px); - margin-left: px2rem(24px); - } - } - } - - // Hack: add pseudo element for spacing, as the overflow of the content - // container may not be hidden due to an imminent offset error on targets - &::before { - display: block; - height: px2rem(8px); - content: ""; - } - - // Adjust spacing on last child - > :last-child { - margin-bottom: 0; - } - } - - // Button inside of the content area - these buttons are meant for actions on - // a document-level, i.e. linking to related source code files, printing etc. - &__button { - float: right; - margin: px2rem(8px) 0; - margin-left: px2rem(8px); - padding: 0; - - // [print]: Hide buttons - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - margin-right: px2rem(8px); - margin-left: initial; - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - - // Adjust default link color for icons - .md-typeset & { - color: var(--md-default-fg-color--lighter); - } - - // Align with body copy located next to icon - svg { - display: inline; - vertical-align: top; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_dialog.scss b/docs/src/assets/stylesheets/main/layout/_dialog.scss deleted file mode 100644 index e522aba3..00000000 --- a/docs/src/assets/stylesheets/main/layout/_dialog.scss +++ /dev/null @@ -1,73 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Dialog -.md-dialog { - @include z-depth(2); - - position: fixed; - right: px2rem(16px); - bottom: px2rem(16px); - left: initial; - z-index: 3; - min-width: px2rem(222px); - padding: px2rem(8px) px2rem(12px); - background-color: var(--md-default-fg-color); - border-radius: px2rem(2px); - transform: translateY(100%); - opacity: 0; - transition: - transform 0ms 400ms, - opacity 400ms; - pointer-events: none; - - // [print]: Hide dialog - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(16px); - } - - // Dialog in open state - &[data-md-state="open"] { - transform: translateY(0); - opacity: 1; - transition: - transform 400ms cubic-bezier(0.075, 0.85, 0.175, 1), - opacity 400ms; - pointer-events: initial; - } - - // Dialog wrapper - &__inner { - color: var(--md-default-bg-color); - font-size: px2rem(14px); - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_footer.scss b/docs/src/assets/stylesheets/main/layout/_footer.scss deleted file mode 100644 index 97a53b7e..00000000 --- a/docs/src/assets/stylesheets/main/layout/_footer.scss +++ /dev/null @@ -1,211 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Footer -.md-footer { - color: var(--md-footer-fg-color); - background-color: var(--md-footer-bg-color); - - // [print]: Hide footer - @media print { - display: none; - } - - // Footer wrapper - &__inner { - padding: px2rem(4px); - overflow: auto; - } - - // Footer link to previous and next page - &__link { - display: flex; - padding-top: px2rem(28px); - padding-bottom: px2rem(8px); - outline-color: var(--md-accent-fg-color); - transition: opacity 250ms; - - // [tablet +]: Adjust width to 50/50 - @include break-from-device(tablet) { - width: 50%; - } - - // Footer link on focus/hover - &:focus, - &:hover { - opacity: 0.7; - } - - // Footer link to previous page - &--prev { - float: left; - - // [mobile -]: Adjust width to 25/75 and hide title - @include break-to-device(mobile) { - width: 25%; - - // Hide footer title - .md-footer__title { - display: none; - } - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: right; - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - - // Footer link to next page - &--next { - float: right; - text-align: right; - - // [mobile -]: Adjust width to 25/75 - @include break-to-device(mobile) { - width: 75%; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - text-align: left; - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - } - - // Footer title - &__title { - position: relative; - flex-grow: 1; - max-width: calc(100% - #{px2rem(48px)}); - padding: 0 px2rem(20px); - font-size: px2rem(18px); - line-height: px2rem(48px); - } - - // Footer link button - &__button { - margin: px2rem(4px); - padding: px2rem(8px); - } - - // Footer link direction (i.e. prev and next) - &__direction { - position: absolute; - right: 0; - left: 0; - margin-top: px2rem(-20px); - padding: 0 px2rem(20px); - font-size: px2rem(12.8px); - opacity: 0.7; - } -} - -// Footer metadata -.md-footer-meta { - background-color: var(--md-footer-bg-color--dark); - - // Footer metadata wrapper - &__inner { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - padding: px2rem(4px); - } - - // Lighten color for non-hovered text links - html &.md-typeset a { - color: var(--md-footer-fg-color--light); - - // Text link on focus/hover - &:focus, - &:hover { - color: var(--md-footer-fg-color); - } - } -} - -// Footer copyright and theme information -.md-footer-copyright { - width: 100%; - margin: auto px2rem(12px); - padding: px2rem(8px) 0; - color: var(--md-footer-fg-color--lighter); - font-size: px2rem(12.8px); - - // [tablet portrait +]: Show copyright and social links in one line - @include break-from-device(tablet portrait) { - width: auto; - } - - // Footer copyright highlight - this is the upper part of the copyright and - // theme information, which will include a darker color than the theme link - &__highlight { - color: var(--md-footer-fg-color--light); - } -} - -// Footer social links -.md-footer-social { - margin: 0 px2rem(8px); - padding: px2rem(4px) 0 px2rem(12px); - - // [tablet portrait +]: Show copyright and social links in one line - @include break-from-device(tablet portrait) { - padding: px2rem(12px) 0; - } - - // Footer social link - &__link { - display: inline-block; - width: px2rem(32px); - height: px2rem(32px); - text-align: center; - - // Adjust line-height to match height for correct alignment - &::before { - line-height: 1.9; - } - - // Fill icon with current color - svg { - max-height: px2rem(16px); - vertical-align: -25%; - fill: currentColor; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_form.scss b/docs/src/assets/stylesheets/main/layout/_form.scss deleted file mode 100644 index e525fa7a..00000000 --- a/docs/src/assets/stylesheets/main/layout/_form.scss +++ /dev/null @@ -1,84 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Form button - .md-button { - display: inline-block; - padding: px2em(10px) px2em(32px); - color: var(--md-primary-fg-color); - font-weight: 700; - border: px2rem(2px) solid currentColor; - border-radius: px2rem(2px); - cursor: pointer; - transition: - color 125ms, - background-color 125ms, - border-color 125ms; - - // Primary button - &--primary { - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - border-color: var(--md-primary-fg-color); - } - - // Button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - border-color: var(--md-accent-fg-color); - } - } - - // Form input - .md-input { - height: px2rem(36px); - padding: 0 px2rem(12px); - font-size: px2rem(16px); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.1); - transition: box-shadow 250ms; - - // Input on focus/hover - &:focus, - &:hover { - box-shadow: - 0 px2rem(8px) px2rem(20px) hsla(0, 0%, 0%, 0.15), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.15); - } - - // Stretch to full width - &--stretch { - width: 100%; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_header.scss b/docs/src/assets/stylesheets/main/layout/_header.scss deleted file mode 100644 index c189d437..00000000 --- a/docs/src/assets/stylesheets/main/layout/_header.scss +++ /dev/null @@ -1,272 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Header - by default, the header will be sticky and stay always on top of the -// viewport. If this behavior is not desired, just set `position: static`. -.md-header { - position: sticky; - top: 0; - right: 0; - left: 0; - z-index: 3; - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - // Hack: reduce jitter by adding a transparent box shadow of the same size - // so the size of the layer doesn't change during animation - box-shadow: - 0 0 px2rem(4px) rgba(0, 0, 0, 0), - 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0); - - // [print]: Hide header - @media print { - display: none; - } - - // Header in shadow state, i.e. shadow is visible - &[data-md-state="shadow"] { - box-shadow: - 0 0 px2rem(4px) rgba(0, 0, 0, 0.1), - 0 px2rem(4px) px2rem(8px) rgba(0, 0, 0, 0.2); - transition: - transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1), - box-shadow 250ms; - } - - // Header in hidden state, i.e. moved out of sight - &[data-md-state="hidden"] { - transform: translateY(-100%); - transition: - transform 250ms cubic-bezier(0.8, 0, 0.6, 1), - box-shadow 250ms; - } - - // Header wrapper - &__inner { - display: flex; - align-items: center; - padding: 0 px2rem(4px); - } - - // Header button - &__button { - position: relative; - z-index: 1; - margin: px2rem(4px); - padding: px2rem(8px); - color: currentColor; - vertical-align: middle; - outline-color: var(--md-accent-fg-color); - cursor: pointer; - transition: opacity 250ms; - - // Button on hover - &:hover { - opacity: 0.7; - } - - // Header button is visible - &:not([hidden]) { - display: inline-block; - } - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Button with logo, pointing to `config.site_url` - &.md-logo { - margin: px2rem(4px); - padding: px2rem(8px); - - // [tablet -]: Hide button - @include break-to-device(tablet) { - display: none; - } - - // Image or icon - img, - svg { - display: block; - width: px2rem(24px); - height: px2rem(24px); - fill: currentColor; - } - } - - // Button for search - &[for="__search"] { - - // [tablet landscape +]: Hide button - @include break-from-device(tablet landscape) { - display: none; - } - - // [no-js]: Hide button - .no-js & { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - } - - // Button for drawer - &[for="__drawer"] { - - // [screen +]: Hide button - @include break-from-device(screen) { - display: none; - } - } - } - - // Header topic - &__topic { - position: absolute; - display: flex; - max-width: 100%; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - - // Second header topic - title of the current page - & + & { - z-index: -1; - transform: translateX(px2rem(25px)); - opacity: 0; - transition: - transform 400ms cubic-bezier(1, 0.7, 0.1, 0.1), - opacity 150ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-25px)); - } - } - } - - // Header title - &__title { - flex-grow: 1; - height: px2rem(48px); - margin-right: px2rem(8px); - margin-left: px2rem(20px); - font-size: px2rem(18px); - line-height: px2rem(48px); - - // Header title in active state, i.e. page title is visible - &[data-md-state="active"] .md-header__topic { - z-index: -1; - transform: translateX(px2rem(-25px)); - opacity: 0; - transition: - transform 400ms cubic-bezier(1, 0.7, 0.1, 0.1), - opacity 150ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(25px)); - } - - // Second header topic - title of the current page - + .md-header__topic { - z-index: 0; - transform: translateX(0); - opacity: 1; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - pointer-events: initial; - } - } - - // Add ellipsis in case of overflowing text - > .md-header__ellipsis { - position: relative; - width: 100%; - height: 100%; - } - } - - // Header option - &__option { - display: flex; - flex-shrink: 0; - max-width: 100%; - white-space: nowrap; - transition: - max-width 0ms 250ms, - opacity 250ms 250ms; - - // Hide toggle when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - max-width: 0; - opacity: 0; - transition: - max-width 0ms, - opacity 0ms; - } - } - - // Repository information container - &__source { - display: none; - - // [tablet landscape +]: Show repository information - @include break-from-device(tablet landscape) { - display: block; - width: px2rem(234px); - max-width: px2rem(234px); - margin-left: px2rem(20px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(20px); - margin-left: initial; - } - } - - // [screen +]: Adjust spacing of search bar - @include break-from-device(screen) { - margin-left: px2rem(28px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(28px); - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_nav.scss b/docs/src/assets/stylesheets/main/layout/_nav.scss deleted file mode 100644 index 6a8886a9..00000000 --- a/docs/src/assets/stylesheets/main/layout/_nav.scss +++ /dev/null @@ -1,687 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-nav-icon--prev: svg-load("material/arrow-left.svg"); - --md-nav-icon--next: svg-load("material/chevron-right.svg"); - --md-toc-icon: svg-load("material/table-of-contents.svg"); -} - -// ---------------------------------------------------------------------------- - -// Navigation -.md-nav { - font-size: px2rem(14px); - line-height: 1.3; - - // Navigation title - &__title { - display: block; - padding: 0 px2rem(12px); - overflow: hidden; - font-weight: 700; - text-overflow: ellipsis; - - // Navigaton button - .md-nav__button { - display: none; - - // Stretch images based on height, as it's the smaller dimension - img { - width: auto; - height: 100%; - } - - // Button with logo, pointing to `config.site_url` - &.md-logo { - - // Image or icon - img, - svg { - display: block; - width: px2rem(48px); - height: px2rem(48px); - fill: currentColor; - } - } - } - } - - // Navigation list - &__list { - margin: 0; - padding: 0; - list-style: none; - } - - // Navigation item - &__item { - padding: 0 px2rem(12px); - - // Navigation item on level 2 - & & { - padding-right: 0; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(12px); - padding-left: 0; - } - } - } - - // Navigation link - &__link { - display: block; - margin-top: 0.625em; - overflow: hidden; - text-overflow: ellipsis; - cursor: pointer; - transition: color 125ms; - scroll-snap-align: start; - - // Link in blurred state - &[data-md-state="blur"] { - color: var(--md-default-fg-color--light); - } - - // Active link - .md-nav__item &--active { - color: var(--md-typeset-a-color); - } - - // Navigation link in nested list - .md-nav__item--nested > & { - color: inherit; - } - - // Navigation link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Show outline for keyboard devices - &.focus-visible { - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - } - - // Navigation link to table of contents - .md-nav--primary &[for="__toc"] { - display: none; - - // Table of contents icon - .md-icon::after { - display: block; - width: 100%; - height: 100%; - mask-image: var(--md-toc-icon); - background-color: currentColor; - } - - // Hide table of contents - ~ .md-nav { - display: none; - } - } - } - - // Repository information container - &__source { - display: none; - } - - // [tablet -]: Layered navigation - @include break-to-device(tablet) { - - // Primary and nested navigation - &--primary, - &--primary & { - position: absolute; - top: 0; - right: 0; - left: 0; - z-index: 1; - display: flex; - flex-direction: column; - height: 100%; - background-color: var(--md-default-bg-color); - } - - // Primary navigation - &--primary { - - // Navigation title and item - .md-nav__title, - .md-nav__item { - font-size: px2rem(16px); - line-height: 1.5; - } - - // Navigation title - .md-nav__title { - position: relative; - height: px2rem(112px); - padding: px2rem(60px) px2rem(16px) px2rem(4px); - color: var(--md-default-fg-color--light); - font-weight: 400; - line-height: px2rem(48px); - white-space: nowrap; - background-color: var(--md-default-fg-color--lightest); - cursor: pointer; - - // Navigation icon - .md-nav__icon { - position: absolute; - top: px2rem(8px); - left: px2rem(8px); - display: block; - width: px2rem(24px); - height: px2rem(24px); - margin: px2rem(4px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(8px); - left: initial; - } - - // Navigation icon in link to previous level - &::after { - display: block; - width: 100%; - height: 100%; - background-color: currentColor; - mask-image: var(--md-nav-icon--prev); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - } - - // Navigation list - ~ .md-nav__list { - overflow-y: auto; - background-color: var(--md-default-bg-color); - box-shadow: - 0 px2rem(1px) 0 var(--md-default-fg-color--lightest) inset; - scroll-snap-type: y mandatory; - touch-action: pan-y; - - // Omit border on first child - > :first-child { - border-top: 0; - } - } - - // Top-level navigation title - &[for="__drawer"] { - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - } - - // Button with logo, pointing to `config.site_url` - .md-logo { - position: absolute; - top: px2rem(4px); - left: px2rem(4px); - display: block; - margin: px2rem(4px); - padding: px2rem(8px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(4px); - left: initial; - } - } - } - - // Navigation list - .md-nav__list { - flex: 1; - } - - // Navigation item - .md-nav__item { - padding: 0; - border-top: px2rem(1px) solid var(--md-default-fg-color--lightest); - - // Navigation link in nested navigation - &--nested > .md-nav__link { - padding-right: px2rem(48px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(16px); - padding-left: px2rem(48px); - } - } - - // Navigation link in active navigation - &--active > .md-nav__link { - color: var(--md-typeset-a-color); - - // Navigation link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - } - } - - // Navigation link - .md-nav__link { - position: relative; - margin-top: 0; - padding: px2rem(12px) px2rem(16px); - - // Navigation icon - .md-nav__icon { - position: absolute; - top: 50%; - right: px2rem(12px); - width: px2rem(24px); - height: px2rem(24px); - margin-top: px2rem(-12px); - color: inherit; - font-size: px2rem(24px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(12px); - } - - // Navigation icon in link to next level - &::after { - display: block; - width: 100%; - height: 100%; - background-color: currentColor; - mask-image: var(--md-nav-icon--next); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - } - } - - // Flip icon vertically - .md-nav__icon { - - // Adjust for right-to-left languages - [dir="rtl"] &::after { - transform: scale(-1); - } - } - - // Table of contents contained in primary navigation - .md-nav--secondary { - - // Navigation link - omit unnecessary layering - .md-nav__link { - position: static; - } - - // Navigation on level 2-6 - .md-nav { - position: static; - background-color: transparent; - - // Navigation link on level 3 - .md-nav__link { - padding-left: px2rem(28px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(28px); - padding-left: initial; - } - } - - // Navigation link on level 4 - .md-nav .md-nav__link { - padding-left: px2rem(40px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(40px); - padding-left: initial; - } - } - - // Navigation link on level 5 - .md-nav .md-nav .md-nav__link { - padding-left: px2rem(52px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(52px); - padding-left: initial; - } - } - - // Navigation link on level 6 - .md-nav .md-nav .md-nav .md-nav__link { - padding-left: px2rem(64px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(64px); - padding-left: initial; - } - } - } - } - } - - // Table of contents - &--secondary { - background-color: transparent; - } - - // Toggle for nested navigation - &__toggle ~ & { - display: flex; - transform: translateX(100%); - opacity: 0; - transition: - transform 250ms cubic-bezier(0.8, 0, 0.6, 1), - opacity 125ms 50ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(-100%); - } - } - - // Show nested navigation when toggle is active - &__toggle:checked ~ & { - transform: translateX(0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 125ms 125ms; - - // Navigation list - > .md-nav__list { - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - } - } - } - - // [tablet portrait -]: Layered navigation with table of contents - @include break-to-device(tablet portrait) { - - // Show link to table of contents - &--primary &__link[for="__toc"] { - display: block; - padding-right: px2rem(48px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(16px); - padding-left: px2rem(48px); - } - - // Show table of contents icon - .md-icon::after { - content: ""; - } - - // Hide navigation link to current page - + .md-nav__link { - display: none; - } - - // Show table of contents - ~ .md-nav { - display: flex; - } - } - - // Repository information container - &__source { - display: block; - padding: 0 px2rem(4px); - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color--dark); - } - } - - // [tablet landscape]: Layered navigation with table of contents - @include break-at-device(tablet landscape) { - - // Show link to integrated table of contents - &--integrated &__link[for="__toc"] { - display: block; - padding-right: px2rem(48px); - scroll-snap-align: initial; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(16px); - padding-left: px2rem(48px); - } - - // Show table of contents icon - .md-icon::after { - content: ""; - } - - // Hide navigation link to current page - + .md-nav__link { - display: none; - } - - // Show table of contents - ~ .md-nav { - display: flex; - } - } - } - - // [tablet landscape +]: Tree-like table of contents - @include break-from-device(tablet landscape) { - - // Navigation title - &--secondary &__title { - - // Adjust snapping behavior - &[for="__toc"] { - scroll-snap-align: start; - } - - // Hide navigation icon - .md-nav__icon { - display: none; - } - } - } - - // [screen +]: Tree-like navigation - @include break-from-device(screen) { - transition: max-height 250ms cubic-bezier(0.86, 0, 0.07, 1); - - // Navigation title - &--primary &__title { - - // Adjust snapping behavior - &[for="__drawer"] { - scroll-snap-align: start; - } - - // Hide navigation icon - .md-nav__icon { - display: none; - } - } - - // Hide toggle for nested navigation - &__toggle ~ & { - display: none; - } - - // Show nested navigation when toggle is active or indeterminate - &__toggle:checked ~ &, - &__toggle:indeterminate ~ & { - display: block; - } - - // Hide navigation title in nested navigation - &__item--nested > & > &__title { - display: none; - } - - // Navigation section - &__item--section { - display: block; - margin: 1.25em 0; - - // Adjust spacing on last child - &:last-child { - margin-bottom: 0; - } - - // Hide navigation link, as sections are always expanded - > .md-nav__link { - display: none; - } - - // Navigation - > .md-nav { - display: block; - - // Navigation title - > .md-nav__title { - display: block; - padding: 0; - pointer-events: none; - scroll-snap-align: start; - } - - // Adjust spacing on next level item - > .md-nav__list > .md-nav__item { - padding: 0; - } - } - } - - // Navigation icon - &__icon { - float: right; - width: px2rem(18px); - height: px2rem(18px); - transition: transform 250ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - transform: rotate(180deg); - } - - // Navigation icon content - &::after { - display: inline-block; - width: 100%; - height: 100%; - vertical-align: px2rem(-2px); - background-color: currentColor; - mask-image: var(--md-nav-icon--next); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Navigation icon - rotate icon when toggle is active or indeterminate - .md-nav__item--nested .md-nav__toggle:checked ~ .md-nav__link &, - .md-nav__item--nested .md-nav__toggle:indeterminate ~ .md-nav__link & { - transform: rotate(90deg); - } - } - - // Modifier for when navigation tabs are rendered - &--lifted { - - // Hide nested level 0 items and site title - > .md-nav__list > .md-nav__item--nested, - > .md-nav__title { - display: none; - } - - // Hide level 0 items - > .md-nav__list > .md-nav__item { - display: none; - - // Active parent navigation item - &--active { - display: block; - padding: 0; - - // Hide nested links - > .md-nav__link { - display: none; - } - - // Show title and adjust spacing - > .md-nav > .md-nav__title { - display: block; - padding: 0 px2rem(12px); - pointer-events: none; - scroll-snap-align: start; - } - } - } - - // Hack: Always show active navigation tab on breakpoint screen, despite - // of checkbox being checked or not. Fixes #1655. - .md-nav[data-md-level="1"] { - display: block; - - // Adjust spacing for level 1 items - > .md-nav__list > .md-nav__item { - padding-right: px2rem(12px); - } - } - } - - // Modifier for when table of contents is rendered in primary navigation - &--integrated &__link[for="__toc"] ~ .md-nav { - display: block; - margin-bottom: 1.25em; - border-left: px2rem(1px) solid var(--md-primary-fg-color); - - // Hide navigation title - > .md-nav__title { - display: none; - } - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_search.scss b/docs/src/assets/stylesheets/main/layout/_search.scss deleted file mode 100644 index cf35874a..00000000 --- a/docs/src/assets/stylesheets/main/layout/_search.scss +++ /dev/null @@ -1,790 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-search-result-icon: svg-load("material/file-search-outline.svg"); -} - -// ---------------------------------------------------------------------------- - -// Search -.md-search { - position: relative; - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding: px2rem(4px) 0; - } - - // [no-js]: Hide search - .no-js & { - display: none; - } - - // Search overlay - &__overlay { - z-index: 1; - opacity: 0; - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - position: absolute; - top: px2rem(-20px); - left: px2rem(-44px); - width: px2rem(40px); - height: px2rem(40px); - overflow: hidden; - background-color: var(--md-default-bg-color); - border-radius: px2rem(20px); - transform-origin: center; - transition: - transform 300ms 100ms, - opacity 200ms 200ms; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(-44px); - left: initial; - } - - // Show overlay when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - opacity: 1; - transition: - transform 400ms, - opacity 100ms; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - position: fixed; - top: 0; - left: 0; - width: 0; - height: 0; - background-color: hsla(0, 0%, 0%, 0.54); - cursor: pointer; - transition: - width 0ms 250ms, - height 0ms 250ms, - opacity 250ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: 0; - left: initial; - } - - // Show overlay when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - width: 100%; - // Hack: when the header is translated upon scrolling, a new layer is - // induced, which means that the height will now refer to the height of - // the header, albeit positioning is fixed. This should be mitigated - // in all cases when setting the height to 2x the viewport. - height: 200vh; - opacity: 1; - transition: - width 0ms, - height 0ms, - opacity 250ms; - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - - // [mobile portrait -]: Scale up 45 times - @include break-to-device(mobile portrait) { - transform: scale(45); - } - - // [mobile landscape]: Scale up 60 times - @include break-at-device(mobile landscape) { - transform: scale(60); - } - - // [tablet portrait]: Scale up 75 times - @include break-at-device(tablet portrait) { - transform: scale(75); - } - } - } - - // Search wrapper - &__inner { - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - position: fixed; - top: 0; - left: 0; - z-index: 2; - width: 0; - height: 0; - overflow: hidden; - transform: translateX(5%); - opacity: 0; - transition: - width 0ms 300ms, - height 0ms 300ms, - transform 150ms 150ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 150ms 150ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: 0; - left: initial; - transform: translateX(-5%); - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - width: 100%; - height: 100%; - transform: translateX(0); - opacity: 1; - transition: - width 0ms 0ms, - height 0ms 0ms, - transform 150ms 150ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms 150ms; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - position: relative; - float: right; - width: px2rem(234px); - padding: px2rem(2px) 0; - transition: width 250ms cubic-bezier(0.1, 0.7, 0.1, 1); - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - - // [tablet landscape]: Omit overlaying header title - @include break-at-device(tablet landscape) { - width: px2rem(468px); - } - - // [screen +]: Match width of content area - @include break-from-device(screen) { - width: px2rem(688px); - } - } - } - - // Search form - &__form { - position: relative; - z-index: 2; - height: px2rem(48px); - background-color: var(--md-default-bg-color); - box-shadow: 0 0 px2rem(12px) transparent; - transition: - color 250ms, - background-color 250ms; - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - height: px2rem(36px); - background-color: hsla(0, 0%, 0%, 0.26); - border-radius: px2rem(2px); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 100%, 0.12); - } - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - color: var(--md-default-fg-color); - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px) px2rem(2px) 0 0; - box-shadow: 0 0 px2rem(12px) hsla(0, 0%, 0%, 0.07); - } - } - - // Search input - &__input { - position: relative; - z-index: 2; - width: 100%; - height: 100%; - padding: 0 px2rem(44px) 0 px2rem(72px); - font-size: px2rem(18px); - text-overflow: ellipsis; - background: transparent; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding: 0 px2rem(72px) 0 px2rem(44px); - } - - // Search placeholder - &::placeholder { - transition: color 250ms; - } - - // Search icon and placeholder - ~ .md-search__icon, - &::placeholder { - color: var(--md-default-fg-color--light); - } - - // Remove the "x" rendered by Internet Explorer - &::-ms-clear { - display: none; - } - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - width: 100%; - height: px2rem(48px); - font-size: px2rem(18px); - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - color: inherit; - font-size: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - } - - // Search placeholder - &::placeholder { - color: var(--md-primary-bg-color--light); - } - - // Search icon - + .md-search__icon { - color: var(--md-primary-bg-color); - } - - // Adjust appearance when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - text-overflow: clip; - - // Search icon and placeholder - + .md-search__icon, - &::placeholder { - color: var(--md-default-fg-color--light); - } - } - } - } - - // Search icon - &__icon { - display: inline-block; - width: px2rem(24px); - height: px2rem(24px); - cursor: pointer; - transition: - color 250ms, - opacity 250ms; - - // Search icon on hover - &:hover { - opacity: 0.7; - } - - // Search focus button - &[for="__search"] { - position: absolute; - top: px2rem(6px); - left: px2rem(10px); - z-index: 2; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(10px); - left: initial; - - // Flip icon vertically - svg { - transform: scaleX(-1); - } - } - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(12px); - left: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(16px); - left: initial; - } - - // Hide the magnifying glass - svg:first-child { - display: none; - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - pointer-events: none; - - // Hide the back arrow - svg:last-child { - display: none; - } - } - } - } - - // Search options - &__options { - position: absolute; - top: px2rem(6px); - right: px2rem(10px); - z-index: 2; - pointer-events: none; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(10px); - } - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(12px); - right: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: initial; - left: px2rem(16px); - } - } - - // Search option buttons - > * { - margin-left: px2rem(4px); - color: var(--md-default-fg-color--light); - transform: scale(0.75); - opacity: 0; - transition: - transform 150ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 150ms; - - // Hide outline for pointer devices - &:not(.focus-visible) { - outline: none; - -webkit-tap-highlight-color: transparent; - } - - // Show reset button when search is active and input non-empty - [data-md-toggle="search"]:checked ~ .md-header - .md-search__input:valid ~ & { - transform: scale(1); - opacity: 1; - pointer-events: initial; - - // Search focus icon - &:hover { - opacity: 0.7; - } - } - } - } - - // Search suggestions - &__suggest { - position: absolute; - top: 0; - display: flex; - align-items: center; - width: 100%; - height: 100%; - padding: 0 px2rem(44px) 0 px2rem(72px); - color: var(--md-default-fg-color--lighter); - font-size: px2rem(18px); - white-space: nowrap; - opacity: 0; - transition: opacity 50ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding: 0 px2rem(72px) 0 px2rem(44px); - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - font-size: px2rem(16px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - } - } - - // Show suggestions when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - opacity: 1; - transition: opacity 300ms 100ms; - } - } - - // Search output - &__output { - position: absolute; - z-index: 1; - width: 100%; - overflow: hidden; - border-radius: 0 0 px2rem(2px) px2rem(2px); - - // [tablet portrait -]: Search modal - @include break-to-device(tablet portrait) { - top: px2rem(48px); - bottom: 0; - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - top: px2rem(38px); - opacity: 0; - transition: opacity 400ms; - - // Show output when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - @include z-depth(6); - - opacity: 1; - } - } - } - - // Search scroll wrapper - &__scrollwrap { - height: 100%; - overflow-y: auto; - background-color: var(--md-default-bg-color); - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - // Hack: Chrome 88+ has weird overscroll behavior. Overall, scroll snapping - // seems to be something that is not ready for prime time on some browsers. - // scroll-snap-type: y mandatory; - touch-action: pan-y; - - // Mitigiate excessive repaints on non-retina devices - @media (max-resolution: 1dppx) { - transform: translateZ(0); - } - - // [tablet landscape]: Set fixed width to omit unnecessary reflow - @include break-at-device(tablet landscape) { - width: px2rem(468px); - } - - // [screen +]: Set fixed width to omit unnecessary reflow - @include break-from-device(screen) { - width: px2rem(688px); - } - - // [tablet landscape +]: Limit height to viewport - @include break-from-device(tablet landscape) { - max-height: 0; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Show scroll wrapper when search is active - [data-md-toggle="search"]:checked ~ .md-header & { - max-height: 75vh; - } - - // Search scroll wrapper on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } - } -} - -// Search result -.md-search-result { - color: var(--md-default-fg-color); - word-break: break-word; - - // Search result metadata - &__meta { - padding: 0 px2rem(16px); - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - line-height: px2rem(36px); - background-color: var(--md-default-fg-color--lightest); - scroll-snap-align: start; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - padding-left: initial; - } - } - } - - // Search result list - &__list { - margin: 0; - padding: 0; - list-style: none; - } - - // Search result item - &__item { - box-shadow: 0 px2rem(-1px) 0 var(--md-default-fg-color--lightest); - - // Omit border on first child - &:first-child { - box-shadow: none; - } - } - - // Search result link - &__link { - display: block; - outline: none; - transition: background-color 250ms; - scroll-snap-align: start; - - // Search result link on focus/hover - &:focus, - &:hover { - background-color: var(--md-accent-fg-color--transparent); - } - - // Adjust spacing on last child of last link - &:last-child p:last-child { - margin-bottom: px2rem(12px); - } - } - - // Search result more link - &__more summary { - display: block; - padding: px2em(12px) px2rem(16px); - color: var(--md-typeset-a-color); - font-size: px2rem(12.8px); - outline: none; - cursor: pointer; - transition: - color 250ms, - background-color 250ms; - scroll-snap-align: start; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - padding-left: px2rem(16px); - } - } - - // Search result more link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - background-color: var(--md-accent-fg-color--transparent); - } - - // Hide native details marker - &::marker, - &::-webkit-details-marker { - display: none; - } - - // Adjust transparency of less relevant results - ~ * > * { - opacity: 0.65; - } - } - - // Search result article - &__article { - position: relative; - padding: 0 px2rem(16px); - overflow: hidden; - - // [tablet landscape +]: Adjust spacing - @include break-from-device(tablet landscape) { - padding-left: px2rem(44px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(44px); - padding-left: px2rem(16px); - } - } - - // Search result article document - &--document { - - // Search result title - .md-search-result__title { - margin: px2rem(11px) 0; - font-weight: 400; - font-size: px2rem(16px); - line-height: 1.4; - } - } - } - - // Search result icon - &__icon { - position: absolute; - left: 0; - width: px2rem(24px); - height: px2rem(24px); - margin: px2rem(10px); - color: var(--md-default-fg-color--light); - - // [tablet portrait -]: Hide icon - @include break-to-device(tablet portrait) { - display: none; - } - - // Search result icon content - &::after { - display: inline-block; - width: 100%; - height: 100%; - background-color: currentColor; - mask-image: var(--md-search-result-icon); - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: 0; - left: initial; - - // Flip icon vertically - &::after { - transform: scaleX(-1); - } - } - } - - // Search result title - &__title { - margin: 0.5em 0; - font-weight: 700; - font-size: px2rem(12.8px); - line-height: 1.6; - } - - // Search result teaser - &__teaser { - display: -webkit-box; - max-height: px2rem(40px); - margin: 0.5em 0; - overflow: hidden; - color: var(--md-default-fg-color--light); - font-size: px2rem(12.8px); - line-height: 1.6; - text-overflow: ellipsis; - -webkit-box-orient: vertical; - -webkit-line-clamp: 2; - - // [mobile -]: Adjust number of lines - @include break-to-device(mobile) { - max-height: px2rem(60px); - -webkit-line-clamp: 3; - } - - // [tablet landscape]: Adjust number of lines - @include break-at-device(tablet landscape) { - max-height: px2rem(60px); - -webkit-line-clamp: 3; - } - - // Search term highlighting - mark { - text-decoration: underline; - background-color: transparent; - } - } - - // Search result terms - &__terms { - margin: 0.5em 0; - font-size: px2rem(12.8px); - font-style: italic; - } - - // Search term highlighting - mark { - color: var(--md-accent-fg-color); - background-color: transparent; - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_select.scss b/docs/src/assets/stylesheets/main/layout/_select.scss deleted file mode 100644 index 1ca64102..00000000 --- a/docs/src/assets/stylesheets/main/layout/_select.scss +++ /dev/null @@ -1,126 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Selection -.md-select { - position: relative; - z-index: 1; - - // Selection bubble - &__inner { - position: absolute; - top: calc(100% - #{px2rem(4px)}); - left: 50%; - max-height: 0; - margin-top: px2rem(4px); - color: var(--md-default-fg-color); - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 0 px2rem(1px) hsla(0, 0%, 0%, 0.25); - transform: translate3d(-50%, px2rem(6px), 0); - opacity: 0; - transition: - transform 250ms 375ms, - opacity 250ms 250ms, - max-height 0ms 500ms; - - // Selection bubble on parent focus/hover - .md-select:focus-within &, - .md-select:hover & { - max-height: px2rem(200px); - transform: translate3d(-50%, 0, 0); - opacity: 1; - transition: - transform 250ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 250ms, - max-height 0ms; - } - - // Selection bubble handle - &::after { - position: absolute; - top: 0; - left: 50%; - width: 0; - height: 0; - margin-top: px2rem(-4px); - margin-left: px2rem(-4px); - border: px2rem(4px) solid transparent; - border-top: 0; - border-bottom-color: var(--md-default-bg-color); - content: ""; - } - } - - // Selection list - &__list { - max-height: inherit; - margin: 0; - padding: 0; - overflow: auto; - font-size: px2rem(16px); - list-style-type: none; - border-radius: px2rem(2px); - } - - // Selection item - &__item { - line-height: px2rem(36px); - } - - // Selection link - &__link { - display: block; - width: 100%; - padding-right: px2rem(24px); - padding-left: px2rem(12px); - outline: none; - cursor: pointer; - transition: - background-color 250ms, - color 250ms; - scroll-snap-align: start; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(12px); - padding-left: px2rem(24px); - } - - // Link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Link on focus - &:focus { - background-color: var(--md-default-fg-color--lightest); - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_sidebar.scss b/docs/src/assets/stylesheets/main/layout/_sidebar.scss deleted file mode 100644 index a8cff6eb..00000000 --- a/docs/src/assets/stylesheets/main/layout/_sidebar.scss +++ /dev/null @@ -1,191 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Sidebar -.md-sidebar { - position: sticky; - top: px2rem(48px); - flex-shrink: 0; - align-self: flex-start; - width: px2rem(242px); - padding: px2rem(24px) 0; - - // [print]: Hide sidebar - @media print { - display: none; - } - - // [tablet -]: Show navigation as drawer - @include break-to-device(tablet) { - - // Primary sidebar with navigation - &--primary { - position: fixed; - top: 0; - left: px2rem(-242px); - z-index: 4; - display: block; - width: px2rem(242px); - height: 100%; - background-color: var(--md-default-bg-color); - transform: translateX(0); - transition: - transform 250ms cubic-bezier(0.4, 0, 0.2, 1), - box-shadow 250ms; - - // Adjust for right-to-left languages - [dir="rtl"] & { - right: px2rem(-242px); - left: initial; - } - - // Show sidebar when drawer is active - [data-md-toggle="drawer"]:checked ~ .md-container & { - @include z-depth(8); - - transform: translateX(px2rem(242px)); - - // Adjust for right-to-left languages - [dir="rtl"] & { - transform: translateX(px2rem(-242px)); - } - } - - // Stretch scroll wrapper for primary sidebar - .md-sidebar__scrollwrap { - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 0; - margin: 0; - scroll-snap-type: none; - overflow: hidden; - } - } - } - - // [screen +]: Show navigation as sidebar - @include break-from-device(screen) { - height: 0; - - // [no-js]: Switch to native sticky behavior - .no-js & { - height: auto; - } - } - - // Secondary sidebar with table of contents - &--secondary { - display: none; - order: 2; - - // [tablet landscape +]: Show table of contents as sidebar - @include break-from-device(tablet landscape) { - height: 0; - - // [no-js]: Switch to native sticky behavior - .no-js & { - height: auto; - } - - // Sidebar is visible - &:not([hidden]) { - display: block; - } - - // Ensure smooth scrolling on iOS - .md-sidebar__scrollwrap { - touch-action: pan-y; - } - } - } - - // Sidebar scroll wrapper - &__scrollwrap { - margin: 0 px2rem(4px); - overflow-y: auto; - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - // Hack: Chrome 81+ exhibits a strange bug, where it scrolls the container - // to the bottom if `scroll-snap-type` is set on the initial render. For - // this reason, we disable scroll snapping until this is resolved (#1667). - // scroll-snap-type: y mandatory; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Sidebar scroll wrapper on hover - &:hover { - scrollbar-color: var(--md-accent-fg-color) transparent; - } - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - } -} - -// [tablet -]: Show overlay on active drawer -@include break-to-device(tablet) { - - // Sidebar overlay - .md-overlay { - position: fixed; - top: 0; - z-index: 4; - width: 0; - height: 0; - background-color: hsla(0, 0%, 0%, 0.54); - opacity: 0; - transition: - width 0ms 250ms, - height 0ms 250ms, - opacity 250ms; - - // Show overlay when drawer is active - [data-md-toggle="drawer"]:checked ~ & { - width: 100%; - height: 100%; - opacity: 1; - transition: - width 0ms, - height 0ms, - opacity 250ms; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_source.scss b/docs/src/assets/stylesheets/main/layout/_source.scss deleted file mode 100644 index 7dfd5023..00000000 --- a/docs/src/assets/stylesheets/main/layout/_source.scss +++ /dev/null @@ -1,203 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// Show repository facts -@keyframes facts { - 0% { - height: 0; - } - - 100% { - height: px2rem(13px); - } -} - -// Show repository fact -@keyframes fact { - 0% { - transform: translateY(100%); - opacity: 0; - } - - 50% { - opacity: 0; - } - - 100% { - transform: translateY(0%); - opacity: 1; - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-source-forks-icon: svg-load("octicons/repo-forked-16.svg"); - --md-source-repositories-icon: svg-load("octicons/repo-16.svg"); - --md-source-stars-icon: svg-load("octicons/star-16.svg"); - --md-source-version-icon: svg-load("octicons/tag-16.svg"); -} - -// ---------------------------------------------------------------------------- - -// Repository information -.md-source { - display: block; - font-size: px2rem(13px); - line-height: 1.2; - white-space: nowrap; - outline-color: var(--md-accent-fg-color); - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - transition: opacity 250ms; - - // Repository information on hover - &:hover { - opacity: 0.7; - } - - // Repository icon - &__icon { - display: inline-block; - width: px2rem(40px); - height: px2rem(48px); - vertical-align: middle; - - // Align with margin only (as opposed to normal button alignment) - svg { - margin-top: px2rem(12px); - margin-left: px2rem(12px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(12px); - margin-left: initial; - } - } - - // Adjust spacing if icon is present - + .md-source__repository { - margin-left: px2rem(-40px); - padding-left: px2rem(40px); - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(-40px); - margin-left: initial; - padding-right: px2rem(40px); - padding-left: initial; - } - } - } - - // Repository name - &__repository { - display: inline-block; - max-width: calc(100% - #{px2rem(24px)}); - margin-left: px2rem(12px); - overflow: hidden; - text-overflow: ellipsis; - vertical-align: middle; - } - - // Repository facts - &__facts { - margin: px2rem(2px) 0 0; - padding: 0; - overflow: hidden; - font-size: px2rem(11px); - list-style-type: none; - opacity: 0.75; - - // Show after the data was loaded - [data-md-state="done"] & { - animation: facts 250ms ease-in; - } - } - - // Repository fact - &__fact { - display: inline-block; - - // Show after the data was loaded - [data-md-state="done"] & { - animation: fact 400ms ease-out; - } - - // Repository fact icon - &::before { - display: inline-block; - width: px2rem(12px); - height: px2rem(12px); - margin-right: px2rem(2px); - vertical-align: text-top; - background-color: currentColor; - mask-repeat: no-repeat; - mask-size: contain; - content: ""; - } - - // Adjust spacing for repository fact icon - &:nth-child(1n+2)::before { - margin-left: px2rem(8px); - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: initial; - margin-left: px2rem(2px); - - // Adjust spacing for repository fact icon - &:nth-child(1n+2)::before { - margin-right: px2rem(8px); - margin-left: initial; - } - } - - // Repository fact: version - &--version::before { - mask-image: var(--md-source-version-icon); - } - - // Repository fact: stars - &--stars::before { - mask-image: var(--md-source-stars-icon); - } - - // Repository fact: forks - &--forks::before { - mask-image: var(--md-source-forks-icon); - } - - // Repository fact: repositories - &--repositories::before { - mask-image: var(--md-source-repositories-icon); - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_tabs.scss b/docs/src/assets/stylesheets/main/layout/_tabs.scss deleted file mode 100644 index 2567e09c..00000000 --- a/docs/src/assets/stylesheets/main/layout/_tabs.scss +++ /dev/null @@ -1,113 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Navigation tabs -.md-tabs { - width: 100%; - overflow: auto; - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - - // [print]: Hide tabs - @media print { - display: none; - } - - // [tablet -]: Hide tabs - @include break-to-device(tablet) { - display: none; - } - - // Tabs in hidden state, i.e. when scrolling down - &[data-md-state="hidden"] { - pointer-events: none; - } - - // Navigation tabs list - &__list { - margin: 0; - margin-left: px2rem(4px); - padding: 0; - white-space: nowrap; - list-style: none; - contain: content; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(4px); - margin-left: initial; - } - } - - // Navigation tabs item - &__item { - display: inline-block; - height: px2rem(48px); - padding-right: px2rem(12px); - padding-left: px2rem(12px); - } - - // Navigation tabs link - could be defined as block elements and aligned via - // line height, but this would imply more repaints when scrolling - &__link { - display: block; - margin-top: px2rem(16px); - font-size: px2rem(14px); - outline-color: var(--md-accent-fg-color); - outline-offset: px2rem(4px); - // Hack: save a repaint when tabs are appearing on scrolling up - backface-visibility: hidden; - opacity: 0.7; - transition: - transform 400ms cubic-bezier(0.1, 0.7, 0.1, 1), - opacity 250ms; - - // Active link and link on focus/hover - &--active, - &:focus, - &:hover { - color: inherit; - opacity: 1; - } - - // Delay transitions by a small amount - @for $i from 2 through 16 { - .md-tabs__item:nth-child(#{$i}) & { - transition-delay: 20ms * ($i - 1); - } - } - - // Hide tabs upon scrolling - disable transition to minimizes repaints - // while scrolling down, while scrolling up seems to be okay - .md-tabs[data-md-state="hidden"] & { - transform: translateY(50%); - opacity: 0; - transition: - transform 0ms 100ms, - opacity 100ms; - } - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_top.scss b/docs/src/assets/stylesheets/main/layout/_top.scss deleted file mode 100644 index 51ce4954..00000000 --- a/docs/src/assets/stylesheets/main/layout/_top.scss +++ /dev/null @@ -1,79 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Back-to-top button -.md-top { - position: fixed; - top: px2rem(48px + 16px); - z-index: 2; - margin-left: 50%; - padding: px2rem(8px) px2rem(16px); - color: var(--md-default-fg-color--light); - font-size: px2rem(14px); - background-color: var(--md-default-bg-color); - border-radius: px2rem(32px); - outline: none; - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 0 px2rem(1px) hsla(0, 0%, 0%, 0.25); - transform: translate(-50%, 0); - transition: - color 125ms, - background-color 125ms, - transform 125ms cubic-bezier(0.4, 0, 0.2, 1), - opacity 125ms; - - // [print]: Hide back-to-top button - @media print { - display: none; - } - - // Adjust for right-to-left languages - [dir="rtl"] & { - float: left; - } - - // Back-to-top button in hidden state - &[data-md-state="hidden"] { - transform: translate(-50%, px2rem(4px)); - opacity: 0; - transition-duration: 0ms; - pointer-events: none; - } - - // Back-to-top button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - } - - // Inline icon - svg { - display: inline-block; - vertical-align: -0.5em; - } -} diff --git a/docs/src/assets/stylesheets/main/layout/_version.scss b/docs/src/assets/stylesheets/main/layout/_version.scss deleted file mode 100644 index 5f813bc5..00000000 --- a/docs/src/assets/stylesheets/main/layout/_version.scss +++ /dev/null @@ -1,173 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// See https://github.com/squidfunk/mkdocs-material/issues/2429 -@keyframes hoverfix { - 0% { - pointer-events: none; - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Icon definitions -:root { - --md-version-icon: svg-load("fontawesome/solid/caret-down.svg"); -} - -// ---------------------------------------------------------------------------- - -// Version selection -.md-version { - flex-shrink: 0; - height: px2rem(48px); - font-size: px2rem(16px); - - // Current selection - &__current { - position: relative; - // Hack: in general, we would use `vertical-align` to align the version at - // the bottom with the title, but since the list uses absolute positioning, - // this won't work consistently. Furthermore, we would need to use inline - // positioning to align the links, which looks jagged. - top: px2rem(1px); - margin-right: px2rem(8px); - margin-left: px2rem(28px); - color: inherit; - outline: none; - cursor: pointer; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(28px); - margin-left: px2rem(8px); - } - - // Version selection icon - &::after { - display: inline-block; - width: px2rem(8px); - height: px2rem(12px); - margin-left: px2rem(8px); - background-color: currentColor; - mask-image: var(--md-version-icon); - mask-repeat: no-repeat; - content: ""; - - // Adjust for right-to-left languages - [dir="rtl"] & { - margin-right: px2rem(8px); - margin-left: initial; - } - } - } - - // Version selection list - &__list { - position: absolute; - top: px2rem(3px); - z-index: 1; - max-height: 0; - margin: px2rem(4px) px2rem(16px); - padding: 0; - overflow: auto; - color: var(--md-default-fg-color); - list-style-type: none; - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 0 px2rem(1px) hsla(0, 0%, 0%, 0.25); - opacity: 0; - transition: - max-height 0ms 500ms, - opacity 250ms 250ms; - scroll-snap-type: y mandatory; - - // Version selection list on parent focus/hover - .md-version:focus-within &, - .md-version:hover & { - max-height: px2rem(200px); - opacity: 1; - transition: - max-height 0ms, - opacity 250ms; - } - - // Fix hover on touch devices - @media (pointer: coarse) { - - // Switch off on hover - .md-version:hover & { - animation: hoverfix 250ms forwards; - } - - // Enable on focus - .md-version:focus-within & { - animation: none; - } - } - } - - // Version selection item - &__item { - line-height: px2rem(36px); - } - - // Version selection link - &__link { - display: block; - width: 100%; - padding-right: px2rem(24px); - padding-left: px2rem(12px); - white-space: nowrap; - outline: none; - cursor: pointer; - transition: - color 250ms, - background-color 250ms; - scroll-snap-align: start; - - // Adjust for right-to-left languages - [dir="rtl"] & { - padding-right: px2rem(12px); - padding-left: px2rem(24px); - } - - // Link on focus/hover - &:focus, - &:hover { - color: var(--md-accent-fg-color); - } - - // Link on focus - &:focus { - background-color: var(--md-default-fg-color--lightest); - } - } -} diff --git a/docs/src/assets/stylesheets/palette.scss b/docs/src/assets/stylesheets/palette.scss deleted file mode 100644 index 6da9d2c6..00000000 --- a/docs/src/assets/stylesheets/palette.scss +++ /dev/null @@ -1,40 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "palette/accent"; -@import "palette/primary"; -@import "palette/scheme"; diff --git a/docs/src/assets/stylesheets/palette/_accent.scss b/docs/src/assets/stylesheets/palette/_accent.scss deleted file mode 100644 index e8c21403..00000000 --- a/docs/src/assets/stylesheets/palette/_accent.scss +++ /dev/null @@ -1,60 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -@each $name, $color in ( - "red": $clr-red-a400, - "pink": $clr-pink-a400, - "purple": $clr-purple-a200, - "deep-purple": $clr-deep-purple-a200, - "indigo": $clr-indigo-a200, - "blue": $clr-blue-a200, - "light-blue": $clr-light-blue-a700, - "cyan": $clr-cyan-a700, - "teal": $clr-teal-a700, - "green": $clr-green-a700, - "light-green": $clr-light-green-a700, - "lime": $clr-lime-a700, - "yellow": $clr-yellow-a700, - "amber": $clr-amber-a700, - "orange": $clr-orange-a400, - "deep-orange": $clr-deep-orange-a200 -) { - - // Color palette - [data-md-color-accent="#{$name}"] { - --md-accent-fg-color: hsla(#{hex2hsl($color)}, 1); - --md-accent-fg-color--transparent: hsla(#{hex2hsl($color)}, 0.1); - - // Inverted text for lighter shades - @if index("lime" "yellow" "amber" "orange", $name) { - --md-accent-bg-color: hsla(0, 0%, 0%, 0.87); - --md-accent-bg-color--light: hsla(0, 0%, 0%, 0.54); - } @else { - --md-accent-bg-color: hsla(0, 0%, 100%, 1); - --md-accent-bg-color--light: hsla(0, 0%, 100%, 0.7); - } - } -} diff --git a/docs/src/assets/stylesheets/palette/_primary.scss b/docs/src/assets/stylesheets/palette/_primary.scss deleted file mode 100644 index 2ddccdbd..00000000 --- a/docs/src/assets/stylesheets/palette/_primary.scss +++ /dev/null @@ -1,170 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -@each $name, $colors in ( - "red": $clr-red-400 $clr-red-300 $clr-red-600, - "pink": $clr-pink-500 $clr-pink-400 $clr-pink-700, - "purple": $clr-purple-400 $clr-purple-300 $clr-purple-600, - "deep-purple": $clr-deep-purple-400 $clr-deep-purple-300 $clr-deep-purple-500, - "indigo": $clr-indigo-500 $clr-indigo-400 $clr-indigo-700, - "blue": $clr-blue-500 $clr-blue-400 $clr-blue-700, - "light-blue": $clr-light-blue-500 $clr-light-blue-400 $clr-light-blue-700, - "cyan": $clr-cyan-500 $clr-cyan-400 $clr-cyan-700, - "teal": $clr-teal-500 $clr-teal-400 $clr-teal-700, - "green": $clr-green-500 $clr-green-400 $clr-green-700, - "light-green": $clr-light-green-500 $clr-light-green-400 $clr-light-green-700, - "lime": $clr-lime-500 $clr-lime-400 $clr-lime-700, - "yellow": $clr-yellow-500 $clr-yellow-400 $clr-yellow-700, - "amber": $clr-amber-500 $clr-amber-400 $clr-amber-700, - "orange": $clr-orange-400 $clr-orange-400 $clr-orange-600, - "deep-orange": $clr-deep-orange-400 $clr-deep-orange-300 $clr-deep-orange-600, - "brown": $clr-brown-500 $clr-brown-400 $clr-brown-700, - "grey": $clr-grey-600 $clr-grey-500 $clr-grey-700, - "blue-grey": $clr-blue-grey-600 $clr-blue-grey-500 $clr-blue-grey-700 -) { - - // Color palette - [data-md-color-primary="#{$name}"] { - --md-primary-fg-color: hsla(#{hex2hsl(nth($colors, 1))}, 1); - --md-primary-fg-color--light: hsla(#{hex2hsl(nth($colors, 2))}, 1); - --md-primary-fg-color--dark: hsla(#{hex2hsl(nth($colors, 3))}, 1); - - // Inverted text for lighter shades - @if index("lime" "yellow" "amber" "orange", $name) { - --md-primary-bg-color: hsla(0, 0%, 0%, 0.87); - --md-primary-bg-color--light: hsla(0, 0%, 0%, 0.54); - } @else { - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: white -// ---------------------------------------------------------------------------- - -// Color palette -[data-md-color-primary="white"] { - --md-primary-fg-color: hsla(0, 0%, 100%, 1); - --md-primary-fg-color--light: hsla(0, 0%, 100%, 0.7); - --md-primary-fg-color--dark: hsla(0, 0%, 0%, 0.07); - --md-primary-bg-color: hsla(0, 0%, 0%, 0.87); - --md-primary-bg-color--light: hsla(0, 0%, 0%, 0.54); - - // Typeset color shades - --md-typeset-a-color: hsla(#{hex2hsl($clr-indigo-500)}, 1); - - // [tablet portrait +]: Header-embedded search - @include break-from-device(tablet landscape) { - - // Search form - .md-search__form { - background-color: hsla(0, 0%, 0%, 0.07); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 0%, 0.32); - } - } - - // Search icon - .md-search__input + .md-search__icon { - color: hsla(0, 0%, 0%, 0.87); - } - } - - // [screen +]: Add bottom border for tabs - @include break-from-device(screen) { - - // Navigation tabs - .md-tabs { - border-bottom: px2rem(1px) solid hsla(0, 0%, 0%, 0.07); - } - } -} - -// ---------------------------------------------------------------------------- -// Rules: black -// ---------------------------------------------------------------------------- - -// Color palette -[data-md-color-primary="black"] { - --md-primary-fg-color: hsla(0, 0%, 0%, 1); - --md-primary-fg-color--light: hsla(0, 0%, 0%, 0.54); - --md-primary-fg-color--dark: hsla(0, 0%, 0%, 1); - --md-primary-bg-color: hsla(0, 0%, 100%, 1); - --md-primary-bg-color--light: hsla(0, 0%, 100%, 0.7); - - // Text color shades - --md-typeset-a-color: hsla(#{hex2hsl($clr-indigo-500)}, 1); - - // Header - .md-header { - background-color: hsla(0, 0%, 0%, 1); - } - - // [tablet portrait -]: Layered navigation - @include break-to-device(tablet portrait) { - - // Repository information container - .md-nav__source { - background-color: hsla(0, 0%, 0%, 0.87); - } - } - - // [tablet landscape +]: Header-embedded search - @include break-from-device(tablet landscape) { - - // Search form - .md-search__form { - background-color: hsla(0, 0%, 100%, 0.12); - - // Search form on hover - &:hover { - background-color: hsla(0, 0%, 100%, 0.3); - } - } - } - - // [tablet -]: Layered navigation - @include break-to-device(tablet) { - - // Site title in main navigation - html & .md-nav--primary .md-nav__title[for="__drawer"] { - background-color: hsla(0, 0%, 0%, 1); - } - } - - // [screen +]: Set background color for tabs - @include break-from-device(screen) { - - // Navigation tabs - .md-tabs { - background-color: hsla(0, 0%, 0%, 1); - } - } -} diff --git a/docs/src/assets/stylesheets/palette/_scheme.scss b/docs/src/assets/stylesheets/palette/_scheme.scss deleted file mode 100644 index 5ef7dc18..00000000 --- a/docs/src/assets/stylesheets/palette/_scheme.scss +++ /dev/null @@ -1,99 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Only use dark mode on screens -@media screen { - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] { - - // Slate's hue in the range [0,360] - change this variable to alter the tone - // of the theme, e.g. to make it more redish or greenish. This is a slate- - // specific variable, but the same approach may be adapted to custom themes. - --md-hue: 232; - - // Default color shades - --md-default-fg-color: hsla(var(--md-hue), 75%, 95%, 1); - --md-default-fg-color--light: hsla(var(--md-hue), 75%, 90%, 0.62); - --md-default-fg-color--lighter: hsla(var(--md-hue), 75%, 90%, 0.32); - --md-default-fg-color--lightest: hsla(var(--md-hue), 75%, 90%, 0.12); - --md-default-bg-color: hsla(var(--md-hue), 15%, 21%, 1); - --md-default-bg-color--light: hsla(var(--md-hue), 15%, 21%, 0.54); - --md-default-bg-color--lighter: hsla(var(--md-hue), 15%, 21%, 0.26); - --md-default-bg-color--lightest: hsla(var(--md-hue), 15%, 21%, 0.07); - - // Code color shades - --md-code-fg-color: hsla(var(--md-hue), 18%, 86%, 1); - --md-code-bg-color: hsla(var(--md-hue), 15%, 15%, 1); - - // Code highlighting color shades - --md-code-hl-color: hsla(#{hex2hsl($clr-blue-a200)}, 0.15); - --md-code-hl-number-color: hsla(6, 74%, 63%, 1); - --md-code-hl-special-color: hsla(340, 83%, 66%, 1); - --md-code-hl-function-color: hsla(291, 57%, 65%, 1); - --md-code-hl-constant-color: hsla(250, 62%, 70%, 1); - --md-code-hl-keyword-color: hsla(219, 66%, 64%, 1); - --md-code-hl-string-color: hsla(150, 58%, 44%, 1); - --md-code-hl-name-color: var(--md-code-fg-color); - --md-code-hl-operator-color: var(--md-default-fg-color--light); - --md-code-hl-punctuation-color: var(--md-default-fg-color--light); - --md-code-hl-comment-color: var(--md-default-fg-color--light); - --md-code-hl-generic-color: var(--md-default-fg-color--light); - --md-code-hl-variable-color: var(--md-default-fg-color--light); - - // Typeset color shades - --md-typeset-color: var(--md-default-fg-color); - - // Typeset `a` color shades - --md-typeset-a-color: var(--md-primary-fg-color); - - // Typeset `mark` color shades - --md-typeset-mark-color: hsla(#{hex2hsl($clr-blue-a200)}, 0.3); - - // Typeset `kbd` color shades - --md-typeset-kbd-color: hsla(var(--md-hue), 15%, 94%, 0.12); - --md-typeset-kbd-accent-color: hsla(var(--md-hue), 15%, 94%, 0.2); - --md-typeset-kbd-border-color: hsla(var(--md-hue), 15%, 14%, 1); - - // Typeset `table` color shades - --md-typeset-table-color: hsla(var(--md-hue), 75%, 95%, 0.12); - - // Admonition color shades - --md-admonition-bg-color: hsla(var(--md-hue), 0%, 100%, 0.025); - - // Footer color shades - --md-footer-bg-color: hsla(var(--md-hue), 15%, 12%, 0.87); - --md-footer-bg-color--dark: hsla(var(--md-hue), 15%, 10%, 1); - - // Black and white primary colors - &[data-md-color-primary="black"], - &[data-md-color-primary="white"] { - - // Typeset color shades - --md-typeset-a-color: hsla(#{hex2hsl($clr-indigo-400)}, 1); - } - } -} diff --git a/docs/src/assets/stylesheets/utilities/_break.scss b/docs/src/assets/stylesheets/utilities/_break.scss deleted file mode 100644 index 0bf63c79..00000000 --- a/docs/src/assets/stylesheets/utilities/_break.scss +++ /dev/null @@ -1,215 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Variables -// ---------------------------------------------------------------------------- - -/// -/// Device-specific breakpoints -/// -/// @example -/// $break-devices: ( -/// mobile: ( -/// portrait: 220px 479px, -/// landscape: 480px 719px -/// ), -/// tablet: ( -/// portrait: 720px 959px, -/// landscape: 960px 1219px -/// ), -/// screen: ( -/// small: 1220px 1599px, -/// medium: 1600px 1999px, -/// large: 2000px -/// ) -/// ); -/// -$break-devices: () !default; - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -/// -/// Choose minimum and maximum device widths -/// -@function break-select-min-max($devices) { - $min: 1000000; - $max: 0; - @each $key, $value in $devices { - @while type-of($value) == map { - $value: break-select-min-max($value); - } - @if type-of($value) == list { - @each $number in $value { - @if type-of($number) == number { - $min: min($number, $min); - @if $max { - $max: max($number, $max); - } - } @else { - @error "Invalid number: #{$number}"; - } - } - } @else if type-of($value) == number { - $min: min($value, $min); - $max: null; - } @else { - @error "Invalid value: #{$value}"; - } - } - @return $min, $max; -} - -/// -/// Select minimum and maximum widths for a device breakpoint -/// -@function break-select-device($device) { - $current: $break-devices; - @for $n from 1 through length($device) { - @if type-of($current) == map { - $current: map-get($current, nth($device, $n)); - } @else { - @error "Invalid device map: #{$devices}"; - } - } - @if type-of($current) == list or type-of($current) == number { - $current: (default: $current); - } - @return break-select-min-max($current); -} - -// ---------------------------------------------------------------------------- -// Mixins -// ---------------------------------------------------------------------------- - -/// -/// A minimum-maximum media query breakpoint -/// -@mixin break-at($breakpoint) { - @if type-of($breakpoint) == number { - @media screen and (min-width: $breakpoint) { - @content; - } - } @else if type-of($breakpoint) == list { - $min: nth($breakpoint, 1); - $max: nth($breakpoint, 2); - @if type-of($min) == number and type-of($max) == number { - @media screen and (min-width: $min) and (max-width: $max) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// An orientation media query breakpoint -/// -@mixin break-at-orientation($breakpoint) { - @if type-of($breakpoint) == string { - @media screen and (orientation: $breakpoint) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// A maximum-aspect-ratio media query breakpoint -/// -@mixin break-at-ratio($breakpoint) { - @if type-of($breakpoint) == number { - @media screen and (max-aspect-ratio: $breakpoint) { - @content; - } - } @else { - @error "Invalid breakpoint: #{$breakpoint}"; - } -} - -/// -/// A minimum-maximum media query device breakpoint -/// -@mixin break-at-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - @if nth($breakpoint, 2) { - $min: nth($breakpoint, 1); - $max: nth($breakpoint, 2); - - @media screen and (min-width: $min) and (max-width: $max) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } - } @else { - @error "Invalid device: #{$device}"; - } -} - -/// -/// A minimum media query device breakpoint -/// -@mixin break-from-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - $min: nth($breakpoint, 1); - - @media screen and (min-width: $min) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } -} - -/// -/// A maximum media query device breakpoint -/// -@mixin break-to-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - $max: nth($breakpoint, 2); - - @media screen and (max-width: $max) { - @content; - } - } @else { - @error "Invalid device: #{$device}"; - } -} diff --git a/docs/src/assets/stylesheets/utilities/_convert.scss b/docs/src/assets/stylesheets/utilities/_convert.scss deleted file mode 100644 index a95fcbc7..00000000 --- a/docs/src/assets/stylesheets/utilities/_convert.scss +++ /dev/null @@ -1,79 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -@use "sass:math"; - -// ---------------------------------------------------------------------------- -// Helpers -// ---------------------------------------------------------------------------- - -/// -/// Strip units from a number -/// -@function strip-units($number) { - @return math.div($number, ($number * 0 + 1)); -} - -/// -/// Convert color in HEX to HSL -/// -/// Note, that we need to strip the `deg` units from the `hue` value, as they -/// were added in Color Level 4, which not all browsers support. -/// -@function hex2hsl($color) { - @return - round(strip-units(hue($color))), - round(saturation($color)), - round(lightness($color)); -} - -// ---------------------------------------------------------------------------- - -/// -/// Convert font size in px to em -/// -@function px2em($size, $base: 16px) { - @if unit($size) == px { - @if unit($base) == px { - @return math.div($size, $base) * 1em; - } @else { - @error "Invalid base: #{$base} - unit must be 'px'"; - } - } @else { - @error "Invalid size: #{$size} - unit must be 'px'"; - } -} - -/// -/// Convert font size in px to rem -/// -@function px2rem($size, $base: 20px) { - @if unit($size) == px { - @if unit($base) == px { - @return math.div($size, $base) * 1rem; - } @else { - @error "Invalid base: #{$base} - unit must be 'px'"; - } - } @else { - @error "Invalid size: #{$size} - unit must be 'px'"; - } -} diff --git a/docs/src/base.html b/docs/src/base.html deleted file mode 100644 index c68ed07b..00000000 --- a/docs/src/base.html +++ /dev/null @@ -1,411 +0,0 @@ - - -{% import "partials/language.html" as lang with context %} - - - - - - - {% block site_meta %} - - - - - {% if page and page.meta and page.meta.description %} - - {% elif config.site_description %} - - {% endif %} - - - {% if page and page.meta and page.meta.keywords %} - - {% elif config.site_keywords %} - - {% endif %} - - - {% if page and page.meta and page.meta.author %} - - {% elif config.site_author %} - - {% endif %} - - - {% if page.canonical_url %} - - {% endif %} - - - - - - - {% endblock %} - - - {% block htmltitle %} - {% if page and page.meta and page.meta.title %} - {{ page.meta.title }} - {{ config.site_name }} - {% elif page and page.title and not page.is_homepage %} - {{ page.title | striptags }} - {{ config.site_name }} - {% else %} - {{ config.site_name }} - {% endif %} - {% endblock %} - - - {% block styles %} - - - - {% if config.theme.palette %} - {% set palette = config.theme.palette %} - - - - {% if palette.primary %} - {% import "partials/palette.html" as map %} - {% set primary = map.primary( - palette.primary | replace(" ", "-") | lower - ) %} - - {% endif %} - {% endif %} - {% endblock %} - - - {% block libs %}{% endblock %} - - - {% block fonts %} - - - {% if config.theme.font != false %} - {% set font = config.theme.font %} - - - - {% endif %} - {% endblock %} - - - {% if config.extra.manifest %} - - {% endif %} - - - {% for path in config["extra_css"] %} - - {% endfor %} - - - {% block analytics %} - {% include "partials/integrations/analytics.html" %} - {% endblock %} - - - {% block extrahead %}{% endblock %} - - - - {% set direction = config.theme.direction or lang.t('direction') %} - {% if config.theme.palette %} - {% set palette = config.theme.palette %} - {% if not palette is mapping %} - {% set palette = palette | first %} - {% endif %} - {% set scheme = palette.scheme | replace(" ", "-") | lower %} - {% set primary = palette.primary | replace(" ", "-") | lower %} - {% set accent = palette.accent | replace(" ", "-") | lower %} - - {% else %} - - {% endif %} - - - {% set features = config.theme.features or [] %} - {% include "partials/javascripts/base.html" %} - - - {% if not config.theme.palette is mapping %} - {% include "partials/javascripts/palette.html" %} - {% endif %} - - - - - - - - - -
    - - -
    - {% if self.announce() %} - - {% endif %} -
    - - - {% block header %} - {% include "partials/header.html" %} - {% endblock %} - - -
    - - - {% block hero %}{% endblock %} - - - {% block tabs %} - {% if not "navigation.tabs.sticky" in features %} - {% if "navigation.tabs" in features %} - {% include "partials/tabs.html" %} - {% endif %} - {% endif %} - {% endblock %} - - -
    -
    - - - {% block site_nav %} - - - {% if nav %} - {% if page and page.meta and page.meta.hide %} - {% set hidden = "hidden" if "navigation" in page.meta.hide %} - {% endif %} - - {% endif %} - - - {% if page.toc and not "toc.integrate" in features %} - {% if page and page.meta and page.meta.hide %} - {% set hidden = "hidden" if "toc" in page.meta.hide %} - {% endif %} - - {% endif %} - {% endblock %} - - -
    -
    - - - {% block content %} - - - {% if page.edit_url %} - - {% include ".icons/material/pencil.svg" %} - - {% endif %} - - - {% if not "\x3ch1" in page.content %} -

    {{ page.title | d(config.site_name, true)}}

    - {% endif %} - - - {{ page.content }} - - - {% if page and page.meta %} - {% if page.meta.git_revision_date_localized or - page.meta.revision_date - %} - {% include "partials/source-file.html" %} - {% endif %} - {% endif %} - {% endblock %} - - - {% block disqus %} - {% include "partials/integrations/disqus.html" %} - {% endblock %} -
    -
    -
    - - - {% if "navigation.top" in features %} - - {% include ".icons/material/arrow-up.svg" %} - {{ lang.t('top.title') }} - - {% endif %} -
    - - - {% block footer %} - {% include "partials/footer.html" %} - {% endblock %} -
    - - -
    -
    -
    - - - {% block config %} - {%- set app = { - "base": base_url, - "features": features, - "translations": {}, - "search": "assets/javascripts/workers/search.js" | url, - "version": config.extra.version or None - } -%} - - - {%- set translations = app.translations -%} - {%- for key in [ - "clipboard.copy", - "clipboard.copied", - "search.config.lang", - "search.config.pipeline", - "search.config.separator", - "search.placeholder", - "search.result.placeholder", - "search.result.none", - "search.result.one", - "search.result.other", - "search.result.more.one", - "search.result.more.other", - "search.result.term.missing", - "select.version.title" - ] -%} - {%- set _ = translations.update({ key: lang.t(key) }) -%} - {%- endfor -%} - - - - {% endblock %} - - - {% block scripts %} - - - - {% for path in config["extra_javascript"] %} - - {% endfor %} - {% endblock %} - - diff --git a/docs/src/main.html b/docs/src/main.html deleted file mode 100644 index 37d79e55..00000000 --- a/docs/src/main.html +++ /dev/null @@ -1,23 +0,0 @@ - - -{% extends "base.html" %} diff --git a/docs/src/mkdocs_theme.yml b/docs/src/mkdocs_theme.yml deleted file mode 100644 index ab57f819..00000000 --- a/docs/src/mkdocs_theme.yml +++ /dev/null @@ -1,68 +0,0 @@ -# Copyright (c) 2016-2021 Martin Donath - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -# IN THE SOFTWARE. - -# Language for theme localization -language: en - -# Text direction (can be ltr or rtl), default: ltr -direction: - -# Feature flags for functionality that alters behavior significantly, and thus -# may be a matter of taste -features: [] - -# Sets the primary and accent color palettes as defined in the Material Design -# documentation - possible values can be looked up in the getting started guide -palette: - - # Primary color used for header, sidebar and links, default: indigo - primary: - - # Accent color for highlighting user interaction, default: indigo - accent: - -# Fonts used by Material, automatically loaded from Google Fonts - see the site -# for a list of available fonts -font: - - # Default font for text - text: Roboto - - # Fixed-width font for code listings - code: Roboto Mono - -# From Material 5.x on, icons are inlined into the HTML and CSS as SVGs. Some -# icons that are part of the HTML can be configured and replaced -icon: - -# Favicon to be rendered -favicon: assets/images/favicon.png - -# Material includes the search in the header as a partial, not as a separate -# template, so it's correct that search.html is missing -include_search_page: false - -# Material doesn't use MkDocs search functionality but provides its own. For -# this reason, only the search index needs to be built -search_index_only: true - -# Static pages to build -static_templates: - - 404.html diff --git a/docs/src/overrides/assets/javascripts/bundle.ts b/docs/src/overrides/assets/javascripts/bundle.ts deleted file mode 100644 index 45f918b2..00000000 --- a/docs/src/overrides/assets/javascripts/bundle.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { merge } from "rxjs" -import { switchMap } from "rxjs/operators" - -import { - getComponentElements, - mountIconSearch, - mountSponsorship -} from "./components" -import { setupAnalytics } from "./integrations" - -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ - -/* Set up extra analytics events */ -setupAnalytics() - -/* Set up extra component observables */ -const component$ = document$ - .pipe( - switchMap(() => merge( - - /* Icon search */ - ...getComponentElements("iconsearch") - .map(el => mountIconSearch(el)), - - /* Sponsorship */ - ...getComponentElements("sponsorship") - .map(el => mountSponsorship(el)) - )) - ) - -/* Subscribe to all components */ -component$.subscribe() diff --git a/docs/src/overrides/assets/javascripts/components/_/index.ts b/docs/src/overrides/assets/javascripts/components/_/index.ts deleted file mode 100644 index 4060302a..00000000 --- a/docs/src/overrides/assets/javascripts/components/_/index.ts +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { getElementOrThrow, getElements } from "~/browser" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Component type - */ -export type ComponentType = - | "iconsearch" /* Icon search */ - | "iconsearch-query" /* Icon search input */ - | "iconsearch-result" /* Icon search results */ - | "sponsorship" /* Sponsorship */ - | "sponsorship-count" /* Sponsorship count */ - | "sponsorship-total" /* Sponsorship total */ - -/** - * Component - * - * @template T - Component type - * @template U - Reference type - */ -export type Component< - T extends {} = {}, - U extends HTMLElement = HTMLElement -> = - T & { - ref: U /* Component reference */ - } - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Component type map - */ -interface ComponentTypeMap { - "iconsearch": HTMLElement /* Icon search */ - "iconsearch-query": HTMLInputElement /* Icon search input */ - "iconsearch-result": HTMLElement /* Icon search results */ - "sponsorship": HTMLElement /* Sponsorship */ - "sponsorship-count": HTMLElement /* Sponsorship count */ - "sponsorship-total": HTMLElement /* Sponsorship total */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Retrieve the element for a given component or throw a reference error - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Element - */ -export function getComponentElement( - type: T, node: ParentNode = document -): ComponentTypeMap[T] { - return getElementOrThrow(`[data-mdx-component=${type}]`, node) -} - -/** - * Retrieve all elements for a given component - * - * @template T - Component type - * - * @param type - Component type - * @param node - Node of reference - * - * @returns Elements - */ -export function getComponentElements( - type: T, node: ParentNode = document -): ComponentTypeMap[T][] { - return getElements(`[data-mdx-component=${type}]`, node) -} diff --git a/docs/src/overrides/assets/javascripts/components/iconsearch/_/index.ts b/docs/src/overrides/assets/javascripts/components/iconsearch/_/index.ts deleted file mode 100644 index 38b88e37..00000000 --- a/docs/src/overrides/assets/javascripts/components/iconsearch/_/index.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable, merge } from "rxjs" - -import { configuration } from "~/_" -import { requestJSON } from "~/browser" - -import { Component, getComponentElement } from "../../_" -import { - IconSearchQuery, - mountIconSearchQuery -} from "../query" -import { - IconSearchResult, - mountIconSearchResult -} from "../result" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon category - */ -export interface IconCategory { - base: string /* Category base URL */ - data: Record /* Category data */ -} - -/** - * Icon search index - */ -export interface IconSearchIndex { - icons: IconCategory /* Icons */ - emojis: IconCategory /* Emojis */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Icon search - */ -export type IconSearch = - | IconSearchQuery - | IconSearchResult - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount icon search - * - * @param el - Icon search element - * - * @returns Icon search component observable - */ -export function mountIconSearch( - el: HTMLElement -): Observable> { - const config = configuration() - const index$ = requestJSON( - new URL("overrides/assets/javascripts/iconsearch_index.json", config.base) - ) - - /* Retrieve query and result components */ - const query = getComponentElement("iconsearch-query", el) - const result = getComponentElement("iconsearch-result", el) - - /* Create and return component */ - const query$ = mountIconSearchQuery(query) - const result$ = mountIconSearchResult(result, { index$, query$ }) - return merge(query$, result$) -} diff --git a/docs/src/overrides/assets/javascripts/components/iconsearch/index.ts b/docs/src/overrides/assets/javascripts/components/iconsearch/index.ts deleted file mode 100644 index ad7fe77b..00000000 --- a/docs/src/overrides/assets/javascripts/components/iconsearch/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./query" -export * from "./result" diff --git a/docs/src/overrides/assets/javascripts/components/iconsearch/query/index.ts b/docs/src/overrides/assets/javascripts/components/iconsearch/query/index.ts deleted file mode 100644 index 0e1f6c66..00000000 --- a/docs/src/overrides/assets/javascripts/components/iconsearch/query/index.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { - Observable, - combineLatest, - fromEvent, - merge -} from "rxjs" -import { - delay, - distinctUntilChanged, - filter, - map, - withLatestFrom -} from "rxjs/operators" - -import { watchElementFocus } from "~/browser" - -import { Component } from "../../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon search query - */ -export interface IconSearchQuery { - value: string /* Query value */ - focus: boolean /* Query focus */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount icon search query - * - * @param el - Icon search query element - * - * @returns Icon search query component observable - */ -export function mountIconSearchQuery( - el: HTMLInputElement -): Observable> { - - /* Intercept focus and input events */ - const focus$ = watchElementFocus(el) - const value$ = merge( - fromEvent(el, "keyup"), - fromEvent(el, "focus").pipe(delay(1)) - ) - .pipe( - map(() => el.value), - distinctUntilChanged() - ) - - /* Log search on blur */ - focus$ - .pipe( - filter(active => !active), - withLatestFrom(value$) - ) - .subscribe(([, value]) => { - const path = document.location.pathname - if (value.length) - ga("send", "pageview", `${path}?q=[icon]+${value}`) - }) - - /* Combine into single observable */ - return combineLatest([value$, focus$]) - .pipe( - map(([value, focus]) => ({ ref: el, value, focus })), - ) -} diff --git a/docs/src/overrides/assets/javascripts/components/iconsearch/result/index.ts b/docs/src/overrides/assets/javascripts/components/iconsearch/result/index.ts deleted file mode 100644 index 91e0ca3c..00000000 --- a/docs/src/overrides/assets/javascripts/components/iconsearch/result/index.ts +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { filter as search } from "fuzzaldrin-plus" -import { - Observable, - Subject, - animationFrameScheduler, - combineLatest, - merge, - of -} from "rxjs" -import { - bufferCount, - distinctUntilKeyChanged, - filter, - finalize, - map, - observeOn, - switchMap, - tap, - withLatestFrom, - zipWith -} from "rxjs/operators" - -import { - addToSearchResultList, - resetSearchResultList, - resetSearchResultMeta, - setSearchResultMeta -} from "~/actions" -import { - getElementOrThrow, - watchElementThreshold -} from "~/browser" - -import { Icon, renderIconSearchResult } from "_/templates" - -import { Component } from "../../_" -import { IconSearchIndex } from "../_" -import { IconSearchQuery } from "../query" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon search result - */ -export interface IconSearchResult { - data: Icon[] /* Search result data */ -} - -/* ---------------------------------------------------------------------------- - * Helper types - * ------------------------------------------------------------------------- */ - -/** - * Watch options - */ -interface WatchOptions { - index$: Observable /* Search index observable */ - query$: Observable /* Search query observable */ -} - -/** - * Mount options - */ -interface MountOptions { - index$: Observable /* Search index observable */ - query$: Observable /* Search query observable */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Watch icon search result - * - * @param _el - Icon search result element - * @param options - Options - * - * @returns Icon search result observable - */ -export function watchIconSearchResult( - _el: HTMLElement, { index$, query$ }: WatchOptions -): Observable { - return combineLatest([ - query$.pipe(distinctUntilKeyChanged("value")), - index$ - .pipe( - map(({ icons, emojis }) => [ - ...Object.keys(icons.data), - ...Object.keys(emojis.data) - ]) - ) - ]) - .pipe( - map(([{ value }, data]) => search(data, value)), - switchMap(shortcodes => index$.pipe( - map(({ icons, emojis }) => ({ - data: shortcodes.map(shortcode => { - const category = - shortcode in icons.data - ? icons - : emojis - return { - shortcode, - url: [ - category.base, - category.data[shortcode] - ].join("") - } - }) - })) - )) - ) -} - -/** - * Mount icon search result - * - * @param el - Icon search result element - * @param options - Options - * - * @returns Icon search result component observable - */ -export function mountIconSearchResult( - el: HTMLElement, { index$, query$ }: MountOptions -): Observable> { - const internal$ = new Subject() - const boundary$ = watchElementThreshold(el) - .pipe( - filter(Boolean) - ) - - /* Update search result metadata */ - const meta = getElementOrThrow(":scope > :first-child", el) - internal$ - .pipe( - observeOn(animationFrameScheduler), - withLatestFrom(query$) - ) - .subscribe(([{ data }, { value }]) => { - if (value) - setSearchResultMeta(meta, data.length) - else - resetSearchResultMeta(meta) - }) - - /* Update icon search result list */ - const list = getElementOrThrow(":scope > :last-child", el) - internal$ - .pipe( - observeOn(animationFrameScheduler), - tap(() => resetSearchResultList(list)), - switchMap(({ data }) => merge( - of(...data.slice(0, 10)), - of(...data.slice(10)) - .pipe( - bufferCount(10), - zipWith(boundary$), - switchMap(([chunk]) => of(...chunk)) - ) - )), - withLatestFrom(query$) - ) - .subscribe(([result, { value }]) => { - addToSearchResultList(list, renderIconSearchResult(result, value)) - }) - - /* Create and return component */ - return watchIconSearchResult(el, { query$, index$ }) - .pipe( - tap(state => internal$.next(state)), - finalize(() => internal$.complete()), - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/overrides/assets/javascripts/components/index.ts b/docs/src/overrides/assets/javascripts/components/index.ts deleted file mode 100644 index fdeed26c..00000000 --- a/docs/src/overrides/assets/javascripts/components/index.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./_" -export * from "./iconsearch" -export * from "./sponsorship" diff --git a/docs/src/overrides/assets/javascripts/components/sponsorship/index.ts b/docs/src/overrides/assets/javascripts/components/sponsorship/index.ts deleted file mode 100644 index 171e3369..00000000 --- a/docs/src/overrides/assets/javascripts/components/sponsorship/index.ts +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { Observable } from "rxjs" -import { map } from "rxjs/operators" - -import { getElementOrThrow, requestJSON } from "~/browser" - -import { renderPrivateSponsor, renderPublicSponsor } from "_/templates" - -import { Component, getComponentElement } from "../_" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Sponsor type - */ -export type SponsorType = - | "user" /* Sponsor is a user */ - | "organization" /* Sponsor is an organization */ - -/** - * Sponsor visibility - */ -export type SponsorVisibility = - | "public" /* Sponsor is a user */ - | "private" /* Sponsor is an organization */ - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsor user - */ -export interface SponsorUser { - type: SponsorType /* Sponsor type */ - name: string /* Sponsor login name */ - image: string /* Sponsor image URL */ - url: string /* Sponsor URL */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Public sponsor - */ -export interface PublicSponsor { - type: "public" /* Sponsor visibility */ - user: SponsorUser /* Sponsor user */ -} - -/** - * Private sponsor - */ -export interface PrivateSponsor { - type: "private" /* Sponsor visibility */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsor - */ -export type Sponsor = - | PublicSponsor - | PrivateSponsor - -/* ------------------------------------------------------------------------- */ - -/** - * Sponsorship - */ -export interface Sponsorship { - sponsors: Sponsor[] /* Sponsors */ - total: number /* Total amount */ -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Mount sponsorship - * - * @param el - Sponsorship element - * - * @returns Sponsorship component observable - */ -export function mountSponsorship( - el: HTMLElement -): Observable> { - const sponsorship$ = requestJSON( - "https://3if8u9o552.execute-api.us-east-1.amazonaws.com/_/" - ) - - /* Retrieve adjacent components */ - const count = getComponentElement("sponsorship-count") - const total = getComponentElement("sponsorship-total") - - /* Render sponsorship */ - sponsorship$.subscribe(sponsorship => { - el.removeAttribute("hidden") - - /* Render public sponsors with avatar and links */ - const list = getElementOrThrow(":scope > :first-child", el) - for (const sponsor of sponsorship.sponsors) - if (sponsor.type === "public") - list.appendChild(renderPublicSponsor(sponsor.user)) - - /* Render combined private sponsors */ - list.appendChild(renderPrivateSponsor( - sponsorship.sponsors.filter(({ type }) => ( - type === "private" - )).length - )) - - /* Render sponsorship count and total */ - count.innerText = `${sponsorship.sponsors.length}` - total.innerText = `$ ${sponsorship.total - .toString() - .replace(/\B(?=(\d{3})+(?!\d))/g, ",") - }` - }) - - // /* Create and return component */ - return sponsorship$ - .pipe( - map(state => ({ ref: el, ...state })) - ) -} diff --git a/docs/src/overrides/assets/javascripts/integrations/analytics/index.ts b/docs/src/overrides/assets/javascripts/integrations/analytics/index.ts deleted file mode 100644 index f7efd853..00000000 --- a/docs/src/overrides/assets/javascripts/integrations/analytics/index.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { fromEvent } from "rxjs" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Set up extra analytics events - */ -export function setupAnalytics(): void { - const { origin } = new URL(location.href) - fromEvent(document.body, "click") - .subscribe(ev => { - if (ev.target instanceof HTMLElement) { - const el = ev.target.closest("a") - if (el && el.origin !== origin) - ga("send", "event", "outbound", "click", el.href) - } - }) -} diff --git a/docs/src/overrides/assets/javascripts/integrations/index.ts b/docs/src/overrides/assets/javascripts/integrations/index.ts deleted file mode 100644 index 3093cb03..00000000 --- a/docs/src/overrides/assets/javascripts/integrations/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./analytics" diff --git a/docs/src/overrides/assets/javascripts/templates/iconsearch/index.tsx b/docs/src/overrides/assets/javascripts/templates/iconsearch/index.tsx deleted file mode 100644 index 5dac49b4..00000000 --- a/docs/src/overrides/assets/javascripts/templates/iconsearch/index.tsx +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { wrap } from "fuzzaldrin-plus" - -import { translation } from "~/_" -import { h } from "~/utilities" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Icon - */ -export interface Icon { - shortcode: string /* Icon shortcode */ - url: string /* Icon URL */ -} - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/** - * Highlight an icon search result - * - * @param icon - Icon - * @param query - Search query - * - * @returns Highlighted result - */ -function highlight(icon: Icon, query: string): string { - return wrap(icon.shortcode, query, { - wrap: { - tagOpen: "", - tagClose: "" - } - }) -} - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render an icon search result - * - * @param icon - Icon - * @param query - Search query - * - * @returns Element - */ -export function renderIconSearchResult( - icon: Icon, query: string -): HTMLElement { - return ( -
  • - - - - -
  • - ) -} diff --git a/docs/src/overrides/assets/javascripts/templates/index.ts b/docs/src/overrides/assets/javascripts/templates/index.ts deleted file mode 100644 index 8bd18b91..00000000 --- a/docs/src/overrides/assets/javascripts/templates/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -export * from "./iconsearch" -export * from "./sponsorship" diff --git a/docs/src/overrides/assets/javascripts/templates/sponsorship/index.tsx b/docs/src/overrides/assets/javascripts/templates/sponsorship/index.tsx deleted file mode 100644 index 7e61433e..00000000 --- a/docs/src/overrides/assets/javascripts/templates/sponsorship/index.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2016-2021 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -import { h } from "~/utilities" - -import { SponsorUser } from "_/components" - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Render public sponsor - * - * @param user - Sponsor user - * - * @returns Element - */ -export function renderPublicSponsor( - user: SponsorUser -): HTMLElement { - const title = `@${user.name}` - return ( - - - - ) -} - -/** - * Render private sponsor - * - * @param count - Number of private sponsors - * - * @returns Element - */ -export function renderPrivateSponsor( - count: number -): HTMLElement { - return ( - - +{count} - - ) -} diff --git a/docs/src/overrides/assets/stylesheets/main.scss b/docs/src/overrides/assets/stylesheets/main.scss deleted file mode 100644 index b30bbe0f..00000000 --- a/docs/src/overrides/assets/stylesheets/main.scss +++ /dev/null @@ -1,46 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Dependencies -// ---------------------------------------------------------------------------- - -@import "material-color"; -@import "material-shadows"; - -// ---------------------------------------------------------------------------- -// Local imports -// ---------------------------------------------------------------------------- - -@import "utilities/break"; -@import "utilities/convert"; - -@import "config"; - -@import "main/typeset"; - -@import "main/layout/announce"; -@import "main/layout/hero"; -@import "main/layout/iconsearch"; -@import "main/layout/sponsorship"; - -@import "main/shame"; diff --git a/docs/src/overrides/assets/stylesheets/main/_shame.scss b/docs/src/overrides/assets/stylesheets/main/_shame.scss deleted file mode 100644 index a6acadab..00000000 --- a/docs/src/overrides/assets/stylesheets/main/_shame.scss +++ /dev/null @@ -1,25 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Nothing to see here, move along -// ---------------------------------------------------------------------------- diff --git a/docs/src/overrides/assets/stylesheets/main/_typeset.scss b/docs/src/overrides/assets/stylesheets/main/_typeset.scss deleted file mode 100644 index 6dec25f0..00000000 --- a/docs/src/overrides/assets/stylesheets/main/_typeset.scss +++ /dev/null @@ -1,148 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Keyframes -// ---------------------------------------------------------------------------- - -// Pumping heart animation -@keyframes mdx-heart { - 0%, - 40%, - 80%, - 100% { - transform: scale(1); - } - - 20%, - 60% { - transform: scale(1.15); - } -} - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Twitter icon - .twitter { - color: #00acee; - } - - // Insiders video - .mdx-video { - width: auto; - - // Insiders video container - &__inner { - position: relative; - width: 100%; - height: 0; - padding-bottom: 56.138%; - } - - // Insiders video iframe - iframe { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - overflow: hidden; - border: none; - } - } - - // Pumping heart - .mdx-heart { - animation: mdx-heart 1000ms infinite; - } - - // Insiders color (for links, etc.) - .mdx-insiders { - color: $clr-pink-500; - } - - // Switch buttons - .mdx-switch button { - cursor: pointer; - transition: opacity 250ms; - - // Button on focus/hover - &:focus, - &:hover { - opacity: 0.75; - } - - // Code block - > code { - display: block; - color: var(--md-primary-bg-color); - background-color: var(--md-primary-fg-color); - } - } - - // Two-column layout - .mdx-columns { - - // Column - ol, - ul { - columns: 2; - - // [mobile portrait -]: Reset columns on mobile - @include break-to-device(mobile portrait) { - columns: initial; - } - } - - // Column item - li { - break-inside: avoid; - } - } - - // Blog author - .mdx-author { - display: flex; - font-size: px2rem(13.6px); - - // Blog author image - img { - height: px2rem(40px); - border-radius: 100%; - } - - // Blog author content - p { - margin-right: px2rem(16px); - - // Blog metadata - > span { - display: block; - } - } - } -} diff --git a/docs/src/overrides/assets/stylesheets/main/layout/_announce.scss b/docs/src/overrides/assets/stylesheets/main/layout/_announce.scss deleted file mode 100644 index a4d6831c..00000000 --- a/docs/src/overrides/assets/stylesheets/main/layout/_announce.scss +++ /dev/null @@ -1,46 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Announcement bar -.md-announce { - - // Text link, also on focus/hover - a, - a:focus, - a:hover { - color: currentColor; - } - - // Don't wrap name of blog article - strong { - white-space: nowrap; - } - - // Twitter icon - .twitter { - margin-left: 0.2em; - } -} diff --git a/docs/src/overrides/assets/stylesheets/main/layout/_hero.scss b/docs/src/overrides/assets/stylesheets/main/layout/_hero.scss deleted file mode 100644 index c0af9120..00000000 --- a/docs/src/overrides/assets/stylesheets/main/layout/_hero.scss +++ /dev/null @@ -1,124 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Landing page container -.mdx-container { - padding-top: px2rem(20px); - background: - url("data:image/svg+xml;utf8,") no-repeat bottom, - linear-gradient( - to bottom, - var(--md-primary-fg-color), - hsla(280, 67%, 55%, 1) 99%, - var(--md-default-bg-color) 99% - ); - - // Adjust background for slate theme - [data-md-color-scheme="slate"] & { - background: - url("data:image/svg+xml;utf8,") no-repeat bottom, - linear-gradient( - to bottom, - var(--md-primary-fg-color), - hsla(280, 67%, 55%, 1) 99%, - var(--md-default-bg-color) 99% - ); - } -} - -// Landing page hero -.mdx-hero { - margin: 0 px2rem(16px); - color: var(--md-primary-bg-color); - - // Hero headline - h1 { - margin-bottom: px2rem(20px); - color: currentColor; - font-weight: 700; - - // [mobile portrait -]: Larger hero headline - @include break-to-device(mobile portrait) { - font-size: px2rem(28px); - } - } - - // Hero content - &__content { - padding-bottom: px2rem(120px); - } - - // [tablet landscape +]: Columnar display - @include break-from-device(tablet landscape) { - display: flex; - align-items: stretch; - - // Adjust spacing and set dimensions - &__content { - max-width: px2rem(380px); - margin-top: px2rem(70px); - padding-bottom: 14vw; - } - - // Hero image - &__image { - order: 1; - width: px2rem(760px); - transform: translateX(#{px2rem(80px)}); - } - } - - // [screen +]: Columnar display and adjusted spacing - @include break-from-device(screen) { - - // Hero image - &__image { - transform: translateX(#{px2rem(160px)}); - } - } - - // Button - .md-button { - margin-top: px2rem(10px); - margin-right: px2rem(10px); - color: var(--md-primary-bg-color); - - // Button on focus/hover - &:focus, - &:hover { - color: var(--md-accent-bg-color); - background-color: var(--md-accent-fg-color); - border-color: var(--md-accent-fg-color); - } - - // Primary button - &--primary { - color: hsla(280deg, 37%, 48%, 1); - background-color: var(--md-primary-bg-color); - border-color: var(--md-primary-bg-color); - } - } -} diff --git a/docs/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss b/docs/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss deleted file mode 100644 index 910130bf..00000000 --- a/docs/src/overrides/assets/stylesheets/main/layout/_iconsearch.scss +++ /dev/null @@ -1,130 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Icon search - .mdx-iconsearch { - position: relative; - background-color: var(--md-default-bg-color); - border-radius: px2rem(2px); - box-shadow: - 0 px2rem(4px) px2rem(10px) hsla(0, 0%, 0%, 0.1), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.1); - transition: box-shadow 125ms; - - // Icon search on focus/hover - &:focus-within, - &:hover { - box-shadow: - 0 px2rem(8px) px2rem(20px) hsla(0, 0%, 0%, 0.15), - 0 px2rem(0.5px) px2rem(1px) hsla(0, 0%, 0%, 0.15); - } - - // Icon search input - .md-input { - background: var(--md-default-bg-color); - box-shadow: 0 0 px2rem(12px) hsla(0, 0%, 0%, 0.07); - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] & { - background: var(--md-code-bg-color); - } - } - } - - // Icon search result - .mdx-iconsearch-result { - max-height: 50vh; - overflow-y: auto; - // Hack: promote to own layer to reduce jitter - backface-visibility: hidden; - touch-action: pan-y; - scrollbar-width: thin; - scrollbar-color: var(--md-default-fg-color--lighter) transparent; - - // Webkit scrollbar - &::-webkit-scrollbar { - width: px2rem(4px); - height: px2rem(4px); - } - - // Webkit scrollbar thumb - &::-webkit-scrollbar-thumb { - background-color: var(--md-default-fg-color--lighter); - - // Webkit scrollbar thumb on hover - &:hover { - background-color: var(--md-accent-fg-color); - } - } - - // Icon search result metadata - &__meta { - position: absolute; - top: px2rem(8px); - right: px2rem(12px); - color: var(--md-default-fg-color--lighter); - font-size: px2rem(12.8px); - } - - // Icon search result list - &__list { - margin: 0; - padding: 0; - list-style: none; - } - - // Icon search result item - &__item { - margin: 0; - padding: px2rem(4px) px2rem(12px); - border-bottom: px2rem(1px) solid var(--md-default-fg-color--lightest); - - // Omit border on last child - &:last-child { - border-bottom: none; - } - - // Item content - > * { - margin-right: px2rem(12px); - } - - // Set icon dimensions to fit - img { - width: px2rem(18px); - height: px2rem(18px); - - // Slate theme, i.e. dark mode - [data-md-color-scheme="slate"] &[src*=squidfunk] { - filter: invert(1); - } - } - } - } -} diff --git a/docs/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss b/docs/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss deleted file mode 100644 index 54a75f8c..00000000 --- a/docs/src/overrides/assets/stylesheets/main/layout/_sponsorship.scss +++ /dev/null @@ -1,110 +0,0 @@ -//// -/// Copyright (c) 2016-2021 Martin Donath -/// -/// Permission is hereby granted, free of charge, to any person obtaining a -/// copy of this software and associated documentation files (the "Software"), -/// to deal in the Software without restriction, including without limitation -/// the rights to use, copy, modify, merge, publish, distribute, sublicense, -/// and/or sell copies of the Software, and to permit persons to whom the -/// Software is furnished to do so, subject to the following conditions: -/// -/// The above copyright notice and this permission notice shall be included in -/// all copies or substantial portions of the Software. -/// -/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL -/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -/// DEALINGS -//// - -// ---------------------------------------------------------------------------- -// Rules -// ---------------------------------------------------------------------------- - -// Scoped in typesetted content to match specificity of regular content -.md-typeset { - - // Premium sponsors - .mdx-premium { - - // Paragraphs - p { - margin: 2em 0; - text-align: center; - } - - // Images - img { - height: px2rem(40px); - } - } - - // Sponsorship - .mdx-sponsorship { - - // Sponsorship list - &__list { - margin: 2em 0; - overflow: auto; - } - - // Sponsorship item - &__item { - display: block; - float: left; - width: px2rem(60px); - height: px2rem(60px); - margin: px2rem(4px); - overflow: hidden; - border-radius: 100%; - transform: scale(1); - transition: - color 125ms, - transform 125ms; - - // Sponsor item on focus/hover - &:focus, - &:hover { - transform: scale(1.1); - - // Sponsor avatar - img { - filter: grayscale(0%); - } - } - - // Private sponsor - &--private { - color: var(--md-default-fg-color--lighter); - font-weight: 700; - font-size: px2rem(24px); - line-height: px2rem(60px); - text-align: center; - background: var(--md-default-fg-color--lightest); - } - - // Sponsor avatar - img { - display: block; - width: 100%; - height: auto; - filter: grayscale(100%); - transition: filter 125ms; - } - } - } - - // Sponsorship button - .mdx-sponsorship-button { - font-weight: 400; - } - - // Sponsorship count and total - .mdx-sponsorship-count, - .mdx-sponsorship-total { - font-weight: 700; - } -} diff --git a/docs/src/overrides/home.html b/docs/src/overrides/home.html deleted file mode 100644 index 95c6b94c..00000000 --- a/docs/src/overrides/home.html +++ /dev/null @@ -1,106 +0,0 @@ - - -{% extends "overrides/main.html" %} - - -{% block tabs %} - {{ super() }} - - - - - -
    -
    -
    - - -
    - -
    - - -
    -

    Technical documentation that just works

    -

    {{ config.site_description }}. Set up in 5 minutes.

    - - Quick start - - - Get Insiders - -
    -
    -
    -
    -{% endblock %} - - -{% block content %}{% endblock %} - - -{% block footer %}{% endblock %} diff --git a/docs/src/overrides/main.html b/docs/src/overrides/main.html deleted file mode 100644 index 9f715940..00000000 --- a/docs/src/overrides/main.html +++ /dev/null @@ -1,53 +0,0 @@ - - -{% extends "base.html" %} - - -{% block extrahead %} - - - -{% endblock %} - - -{% block announce %} - - For updates follow @squidfunk on - - Twitter - -{% endblock %} - - -{% block scripts %} - {{ super() }} - - - -{% endblock %} - diff --git a/docs/src/partials/footer.html b/docs/src/partials/footer.html deleted file mode 100644 index 4b0a16a5..00000000 --- a/docs/src/partials/footer.html +++ /dev/null @@ -1,110 +0,0 @@ - - -{% import "partials/language.html" as lang with context %} - - - diff --git a/docs/src/partials/header.html b/docs/src/partials/header.html deleted file mode 100644 index f5cf2060..00000000 --- a/docs/src/partials/header.html +++ /dev/null @@ -1,161 +0,0 @@ - - - -{% set class = "md-header" %} -{% if "navigation.tabs.sticky" in features %} - {% set class = class ~ " md-header--lifted" %} -{% endif %} - - -
    - - - - {% if "navigation.tabs.sticky" in features %} - {% if "navigation.tabs" in features %} - {% include "partials/tabs.html" %} - {% endif %} - {% endif %} -
    diff --git a/docs/src/partials/integrations/analytics.html b/docs/src/partials/integrations/analytics.html deleted file mode 100644 index dfc367cf..00000000 --- a/docs/src/partials/integrations/analytics.html +++ /dev/null @@ -1,36 +0,0 @@ - - - -{% if config.google_analytics %} - {% set provider = "google" %} -{% endif %} - - -{% if config.extra.analytics %} - {% set provider = config.extra.analytics.provider %} -{% endif %} - - -{% if provider %} - {% include "partials/integrations/analytics/" ~ provider ~ ".html" %} -{% endif %} diff --git a/docs/src/partials/integrations/analytics/google.html b/docs/src/partials/integrations/analytics/google.html deleted file mode 100644 index 632558e4..00000000 --- a/docs/src/partials/integrations/analytics/google.html +++ /dev/null @@ -1,93 +0,0 @@ - - - -{% if config.google_analytics %} - {% set property = config.google_analytics[0] %} -{% endif %} - - -{% if config.extra.analytics %} - {% set property = config.extra.analytics.property | d("", true) %} -{% endif %} - - -{% if property.startswith("G-") %} - - - - -{% elif property.startswith("UA-") %} - - -{% endif %} - - diff --git a/docs/src/partials/integrations/disqus.html b/docs/src/partials/integrations/disqus.html deleted file mode 100644 index 0eaeb9a1..00000000 --- a/docs/src/partials/integrations/disqus.html +++ /dev/null @@ -1,46 +0,0 @@ - - - -{% set disqus = config.extra.disqus %} -{% if page and page.meta and page.meta.disqus is string %} - {% set disqus = page.meta.disqus %} -{% endif %} - - -{% if not page.is_homepage and disqus %} -

    {{ lang.t("meta.comments") }}

    -
    - -{% endif %} diff --git a/docs/src/partials/javascripts/base.html b/docs/src/partials/javascripts/base.html deleted file mode 100644 index db6d4a24..00000000 --- a/docs/src/partials/javascripts/base.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - diff --git a/docs/src/partials/javascripts/palette.html b/docs/src/partials/javascripts/palette.html deleted file mode 100644 index 99479329..00000000 --- a/docs/src/partials/javascripts/palette.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - diff --git a/docs/src/partials/language.html b/docs/src/partials/language.html deleted file mode 100644 index c91bc43e..00000000 --- a/docs/src/partials/language.html +++ /dev/null @@ -1,28 +0,0 @@ - - - -{% import "partials/languages/" ~ config.theme.language ~ ".html" as lang %} -{% import "partials/languages/en.html" as fallback %} - - -{% macro t(key) %}{{ lang.t(key) or fallback.t(key) }}{% endmacro %} diff --git a/docs/src/partials/languages/af.html b/docs/src/partials/languages/af.html deleted file mode 100644 index abae5296..00000000 --- a/docs/src/partials/languages/af.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "af", - "clipboard.copy": "Kopieer na knipbord", - "clipboard.copied": "gekopieer na knipbord", - "edit.link.title": "Wysig hierdie bladsy", - "footer.previous": "Vorige", - "footer.next": "Volgende", - "meta.comments": "Kommentaar", - "meta.source": "Bron", - "search.config.lang": "nl", - "search.placeholder": "Soek", - "search.result.placeholder": "Tik om te begin soek", - "search.result.none": "Geen ooreenstemmende dokumente", - "search.result.one": "1 ooreenstemmende dokument", - "search.result.other": "# ooreenstemmende dokumente", - "skip.link.title": "Slaan oor na inhoud", - "source.link.title": "Slaan oor na inhoud", - "source.revision.date": "Laaste opdatering", - "source.file.date.updated": "Laaste opdatering", - "source.file.date.created": "Geskep", - "toc.title": "Inhoudsopgawe" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ar.html b/docs/src/partials/languages/ar.html deleted file mode 100644 index 254f6f21..00000000 --- a/docs/src/partials/languages/ar.html +++ /dev/null @@ -1,46 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "ar", - "direction": "rtl", - "clipboard.copy": "نسخ إلى الحافظة", - "clipboard.copied": "تم النسخ الى الحافظة", - "edit.link.title": "عدل الصفحة", - "footer.previous": "السابقة", - "footer.next": "التالية", - "meta.comments": "التعليقات", - "meta.source": "المصدر", - "search.config.pipeline": " ", - "search.placeholder": "بحث", - "search.result.placeholder": "اكتب لبدء البحث", - "search.result.none": "لا توجد نتائج", - "search.result.one": "نتائج البحث مستند واحد", - "search.result.other": "نتائج البحث # مستندات", - "skip.link.title": "انتقل إلى المحتوى", - "source.link.title": "اذهب إلى المصدر", - "source.revision.date": "اخر تحديث", - "source.file.date.updated": "اخر تحديث", - "source.file.date.created": "خلقت", - "toc.title": "جدول المحتويات" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/bg.html b/docs/src/partials/languages/bg.html deleted file mode 100644 index 2204b625..00000000 --- a/docs/src/partials/languages/bg.html +++ /dev/null @@ -1,52 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "bg", - "clipboard.copy": "Копирай", - "clipboard.copied": "Копирано", - "edit.link.title": "Редактирай тази страница", - "footer.previous": "Предишна", - "footer.next": "Следваща", - "footer.title": "Долен колонтитул", - "header.title": "Горен колонтитул", - "meta.comments": "Коментари", - "meta.source": "Код", - "nav.title": "Навигация", - "search.config.lang": "ru", - "search.placeholder": "Търси", - "search.reset": "Изчисти", - "search.result.placeholder": "Започнете да пишете, за да търсите", - "search.result.none": "Няма резултати", - "search.result.one": "1 резултат", - "search.result.other": "# резултата", - "search.result.more.one": "още 1 на тази страница", - "search.result.more.other": "още # на тази страница", - "skip.link.title": "Към съдържанието", - "source.link.title": "Към хранилището", - "source.revision.date": "Последна промяна", - "source.file.date.updated": "Последна промяна", - "source.file.date.created": "Създаден", - "tabs.title": "Табове", - "toc.title": "Съдържание" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/bn.html b/docs/src/partials/languages/bn.html deleted file mode 100644 index 9acec3c1..00000000 --- a/docs/src/partials/languages/bn.html +++ /dev/null @@ -1,50 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "bn", - "clipboard.copy": "ক্লিপবোর্ডে কপি করুন", - "clipboard.copied": "ক্লিপবোর্ডে কপি হয়েছে", - "edit.link.title": "এই পেজ এডিট করুন", - "footer.previous": "পূর্ববর্তী", - "footer.next": "পরে", - "footer.title": "ফুটার", - "header.title": "হেডার", - "meta.comments": "কমেন্ট", - "meta.source": "সোর্স", - "nav.title": "ন্যাভিগেশন", - "search.config.pipeline": " ", - "search.placeholder": "সার্চ", - "search.reset": "মুছে ফেলুন", - "search.result.placeholder": "সার্চ টাইপ করুন", - "search.result.none": "কিছু পাওয়া যায়নি", - "search.result.one": "১ টা ডকুমেন্ট", - "search.result.other": "# টা ডকুমেন্ট", - "skip.link.title": "কনটেন্টে যান", - "source.link.title": "রিপোজিটরিতে যান", - "source.revision.date": "শেষ আপডেট", - "source.file.date.updated": "শেষ আপডেট", - "source.file.date.created": "তৈরি হয়েছে", - "tabs.title": "ট্যাব", - "toc.title": "টেবিল অফ কনটেন্ট" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ca.html b/docs/src/partials/languages/ca.html deleted file mode 100644 index 898072ee..00000000 --- a/docs/src/partials/languages/ca.html +++ /dev/null @@ -1,44 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "ca", - "clipboard.copy": "Còpia al porta-retalls", - "clipboard.copied": "Copiat al porta-retalls", - "edit.link.title": "Edita aquesta pàgina", - "footer.previous": "Anterior", - "footer.next": "Següent", - "meta.comments": "Comentaris", - "meta.source": "Codi font", - "search.placeholder": "Cerca", - "search.result.placeholder": "Escriu per a començar a cercar", - "search.result.none": "Cap document coincideix", - "search.result.one": "1 document coincident", - "search.result.other": "# documents coincidents", - "skip.link.title": "Salta el contingut", - "source.link.title": "Ves al repositori", - "source.revision.date": "Darrera actualització", - "source.file.date.updated": "Darrera actualització", - "source.file.date.created": "Creada", - "toc.title": "Taula de continguts" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/cs.html b/docs/src/partials/languages/cs.html deleted file mode 100644 index e5d555a8..00000000 --- a/docs/src/partials/languages/cs.html +++ /dev/null @@ -1,44 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "cs", - "clipboard.copy": "Kopírovat do schránky", - "clipboard.copied": "Zkopírováno do schránky", - "edit.link.title": "Upravit tuto stránku", - "footer.previous": "Předchozí", - "footer.next": "Další", - "meta.comments": "Komentáře", - "meta.source": "Zdroj", - "search.placeholder": "Hledat", - "search.result.placeholder": "Pište co se má vyhledat", - "search.result.none": "Nenalezeny žádné dokumenty", - "search.result.one": "Nalezený dokument: 1", - "search.result.other": "Nalezené dokumenty: #", - "skip.link.title": "Přeskočit obsah", - "source.link.title": "Přejít do repozitáře", - "source.revision.date": "Poslední aktualizace", - "source.file.date.updated": "Poslední aktualizace", - "source.file.date.created": "Vytvořeno", - "toc.title": "Obsah" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/da.html b/docs/src/partials/languages/da.html deleted file mode 100644 index 3b161a6a..00000000 --- a/docs/src/partials/languages/da.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "da", - "clipboard.copy": "Kopiér til udklipsholderen", - "clipboard.copied": "Kopieret til udklipsholderen", - "edit.link.title": "Redigér denne side", - "footer.previous": "Forrige", - "footer.next": "Næste", - "meta.comments": "Kommentarer", - "meta.source": "Kilde", - "search.config.lang": "da", - "search.placeholder": "Søg", - "search.result.placeholder": "Indtast søgeord", - "search.result.none": "Ingen resultater fundet", - "search.result.one": "1 resultat", - "search.result.other": "# resultater", - "skip.link.title": "Gå til indholdet", - "source.link.title": "Åbn arkiv", - "source.revision.date": "Sidste ændring", - "source.file.date.updated": "Sidste ændring", - "source.file.date.created": "Oprettet", - "toc.title": "Indholdsfortegnelse" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/de.html b/docs/src/partials/languages/de.html deleted file mode 100644 index e7891678..00000000 --- a/docs/src/partials/languages/de.html +++ /dev/null @@ -1,55 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "de", - "clipboard.copy": "In Zwischenablage kopieren", - "clipboard.copied": "In Zwischenablage kopiert", - "edit.link.title": "Seite editieren", - "footer.previous": "Zurück", - "footer.next": "Weiter", - "meta.comments": "Kommentare", - "meta.source": "Quellcode", - "search.config.lang": "de", - "search.placeholder": "Suche", - "search.share": "Teilen", - "search.reset": "Zurücksetzen", - "search.result.initializer": "Suche wird initialisiert", - "search.result.placeholder": "Suchbegriff eingeben", - "search.result.none": "Keine Suchergebnisse", - "search.result.one": "1 Suchergebnis", - "search.result.other": "# Suchergebnisse", - "search.result.more.one": "1 weiteres Suchergebnis auf dieser Seite", - "search.result.more.other": "# weitere Suchergebnisse auf dieser Seite", - "search.result.term.missing": "Es fehlt", - "search.title": "Suche", - "select.language.title": "Sprache wechseln", - "select.version.title": "Version auswählen", - "skip.link.title": "Zum Inhalt", - "source.link.title": "Quellcode", - "source.revision.date": "Letztes Update", - "source.file.date.updated": "Letztes Update", - "source.file.date.created": "Erstellt", - "toc.title": "Inhaltsverzeichnis", - "top.title": "Zurück zum Seitenanfang" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/en.html b/docs/src/partials/languages/en.html deleted file mode 100644 index 2fc412b2..00000000 --- a/docs/src/partials/languages/en.html +++ /dev/null @@ -1,62 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "en", - "direction": "ltr", - "clipboard.copy": "Copy to clipboard", - "clipboard.copied": "Copied to clipboard", - "edit.link.title": "Edit this page", - "footer.previous": "Previous", - "footer.next": "Next", - "footer.title": "Footer", - "header.title": "Header", - "meta.comments": "Comments", - "meta.source": "Source", - "nav.title": "Navigation", - "search.config.lang": "en", - "search.config.pipeline": "trimmer, stopWordFilter", - "search.config.separator": "[\s\-]+", - "search.placeholder": "Search", - "search.share": "Share", - "search.reset": "Clear", - "search.result.initializer": "Initializing search", - "search.result.placeholder": "Type to start searching", - "search.result.none": "No matching documents", - "search.result.one": "1 matching document", - "search.result.other": "# matching documents", - "search.result.more.one": "1 more on this page", - "search.result.more.other": "# more on this page", - "search.result.term.missing": "Missing", - "search.title": "Search", - "select.language.title": "Select language", - "select.version.title": "Select version", - "skip.link.title": "Skip to content", - "source.link.title": "Go to repository", - "source.revision.date": "Last update", - "source.file.date.updated": "Last update", - "source.file.date.created": "Created", - "tabs.title": "Tabs", - "toc.title": "Table of contents", - "top.title": "Back to top" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/eo.html b/docs/src/partials/languages/eo.html deleted file mode 100644 index 07af949a..00000000 --- a/docs/src/partials/languages/eo.html +++ /dev/null @@ -1,50 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "eo", - "clipboard.copy": "Kopii al tondujo", - "clipboard.copied": "Kopiado al klipo", - "edit.link.title": "Redakti ĉi tiun paĝon", - "footer.previous": "Antaŭa", - "footer.next": "Sekva", - "footer.title": "Piedlinio", - "header.title": "Kaplinio", - "meta.comments": "Komentoj", - "meta.source": "Fontkodo", - "nav.title": "Navigado", - "search.config.lang": "es", - "search.placeholder": "Serĉo", - "search.reset": "Klara", - "search.result.placeholder": "Tajpu por komenci serĉadon", - "search.result.none": "Neniuj kongruaj dokumentoj", - "search.result.one": "1 kongrua dokumento", - "search.result.other": "# kongruaj dokumentoj", - "skip.link.title": "Saltu al enhavo", - "source.link.title": "Iru al deponejo", - "source.revision.date": "Lasta ĝisdatigo", - "source.file.date.updated": "Lasta ĝisdatigo", - "source.file.date.created": "Kreita", - "tabs.title": "Langetoj", - "toc.title": "Enhavtabelo" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/es.html b/docs/src/partials/languages/es.html deleted file mode 100644 index caede33d..00000000 --- a/docs/src/partials/languages/es.html +++ /dev/null @@ -1,57 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "es", - "clipboard.copy": "Copiar al portapapeles", - "clipboard.copied": "Copiado al portapapeles", - "edit.link.title": "Editar esta página", - "footer.previous": "Anterior", - "footer.next": "Siguiente", - "footer.title": "Pie", - "header.title": "Cabecera", - "meta.comments": "Comentarios", - "meta.source": "Fuente", - "nav.title": "Navegación", - "search.config.lang": "es", - "search.placeholder": "Búsqueda", - "search.reset": "Limpiar", - "search.result.initializer": "Inicializando búsqueda", - "search.result.placeholder": "Teclee para comenzar búsqueda", - "search.result.none": "No se encontraron documentos", - "search.result.one": "1 documento encontrado", - "search.result.other": "# documentos encontrados", - "search.result.more.one": "1 más en esta página", - "search.result.more.other": "# más en esta página", - "search.result.term.missing": "Falta", - "select.language.title": "Seleccionar idioma", - "select.version.title": "Seleccionar versión", - "skip.link.title": "Saltar a contenido", - "source.link.title": "Ir al repositorio", - "source.revision.date": "Última actualización", - "source.file.date.updated": "Última actualización", - "source.file.date.created": "Creado", - "tabs.title": "Pestañas", - "toc.title": "Tabla de contenidos", - "top.title": "Volver al principio" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/et.html b/docs/src/partials/languages/et.html deleted file mode 100644 index eac90dcb..00000000 --- a/docs/src/partials/languages/et.html +++ /dev/null @@ -1,44 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "et", - "clipboard.copy": "Kopeeri lõikelauale", - "clipboard.copied": "Kopeeritud", - "edit.link.title": "Muuda seda lehte", - "footer.previous": "Eelmine", - "footer.next": "Järgmine", - "meta.comments": "Kommentaarid", - "meta.source": "Lähtekood", - "search.placeholder": "Otsi", - "search.result.placeholder": "Otsimiseks kirjuta siia", - "search.result.none": "Otsingule ei leitud ühtegi vastet", - "search.result.one": "Leiti üks tulemus", - "search.result.other": "Leiti # tulemust", - "skip.link.title": "Keri sisuni", - "source.link.title": "Ava repositooriumis", - "source.revision.date": "Viimane uuendus", - "source.file.date.updated": "Viimane uuendus", - "source.file.date.created": "Loodud", - "toc.title": "Sisukord" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/fa.html b/docs/src/partials/languages/fa.html deleted file mode 100644 index 77fc6fb2..00000000 --- a/docs/src/partials/languages/fa.html +++ /dev/null @@ -1,46 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "fa", - "direction": "rtl", - "clipboard.copy": "کپی کردن", - "clipboard.copied": "کپی شد", - "edit.link.title": "این صفحه را ویرایش کنید", - "footer.previous": "قبلی", - "footer.next": "بعدی", - "meta.comments": "نظرات", - "meta.source": "منبع", - "search.config.pipeline": " ", - "search.placeholder": "جستجو", - "search.result.placeholder": "برای شروع جستجو تایپ کنید", - "search.result.none": "سندی یافت نشد", - "search.result.one": "1 سند یافت شد", - "search.result.other": "# سند یافت شد", - "skip.link.title": "پرش به محتویات", - "source.link.title": "رفتن به مخزن", - "source.revision.date": "اخرین بروزرسانی", - "source.file.date.updated": "اخرین بروزرسانی", - "source.file.date.created": "ایجاد شده", - "toc.title": "فهرست موضوعات" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/fi.html b/docs/src/partials/languages/fi.html deleted file mode 100644 index 9ad2e3c8..00000000 --- a/docs/src/partials/languages/fi.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "fi", - "clipboard.copy": "Kopioi leikepöydälle", - "clipboard.copied": "Kopioitu leikepöydälle", - "edit.link.title": "Muokkaa tätä sivua", - "footer.previous": "Edellinen", - "footer.next": "Seuraava", - "meta.comments": "Kommentit", - "meta.source": "Lähdekodi", - "search.config.lang": "fi", - "search.placeholder": "Hae", - "search.result.placeholder": "Kirjoita aloittaaksesi haun", - "search.result.none": "Ei täsmääviä dokumentteja", - "search.result.one": "1 täsmäävä dokumentti", - "search.result.other": "# täsmäävää dokumenttia", - "skip.link.title": "Hyppää sisältöön", - "source.link.title": "Mene repositoryyn", - "source.revision.date": "Viimeisin päivitys", - "source.file.date.updated": "Viimeisin päivitys", - "source.file.date.created": "Luotu", - "toc.title": "Sisällysluettelo" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/fr.html b/docs/src/partials/languages/fr.html deleted file mode 100644 index a9b7f3ef..00000000 --- a/docs/src/partials/languages/fr.html +++ /dev/null @@ -1,57 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "fr", - "clipboard.copy": "Copier dans le presse-papier", - "clipboard.copied": "Copié dans le presse-papier", - "edit.link.title": "Editer cette page", - "footer.previous": "Précédent", - "footer.next": "Suivant", - "footer.title": "Pied de page", - "header.title": "En-tête", - "meta.comments": "Commentaires", - "meta.source": "Source", - "nav.title": "Navigation", - "search.config.lang": "fr", - "search.placeholder": "Rechercher", - "search.reset": "Effacer", - "search.result.initializer": "Initialisation de la recherche", - "search.result.placeholder": "Taper pour démarrer la recherche", - "search.result.none": "Aucun document trouvé", - "search.result.one": "1 document trouvé", - "search.result.other": "# documents trouvés", - "search.result.more.one": "1 de plus sur cette page", - "search.result.more.other": "# de plus sur cette page", - "search.result.term.missing": "Non trouvé", - "select.language.title": "Sélectionner la langue", - "select.version.title": "Sélectionner la version", - "skip.link.title": "Aller au contenu", - "source.link.title": "Aller au dépôt", - "source.revision.date": "Dernière mise à jour", - "source.file.date.updated": "Dernière mise à jour", - "source.file.date.created": "Créé", - "tabs.title": "Onglets", - "toc.title": "Table des matières", - "top.title": "Retour en haut de la page" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/gl.html b/docs/src/partials/languages/gl.html deleted file mode 100644 index 7d4d9ab6..00000000 --- a/docs/src/partials/languages/gl.html +++ /dev/null @@ -1,57 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "gl", - "clipboard.copy": "Copiar no cortapapeis", - "clipboard.copied": "Copiado no cortapapeis", - "edit.link.title": "Editar esta páxina", - "footer.previous": "Anterior", - "footer.next": "Seguinte", - "footer.title": "Pé", - "header.title": "Cabeceira", - "meta.comments": "Comentarios", - "meta.source": "Fonte", - "nav.title": "Navegación", - "search.config.lang": "es", - "search.placeholder": "Procura", - "search.reset": "Limpar", - "search.result.initializer": "Inicializando procura", - "search.result.placeholder": "Insira un termo", - "search.result.none": "Sen resultados", - "search.result.one": "1 resultado atopado", - "search.result.other": "# resultados atopados", - "search.result.more.one": "1 máis nesta páxina", - "search.result.more.other": "# máis nesta páxina", - "search.result.term.missing": "Falta", - "select.language.title": "Seleccionar idioma", - "select.version.title": "Seleccionar version", - "skip.link.title": "Ir ao contido", - "source.link.title": "Ir ao repositorio", - "source.revision.date": "Última actualización", - "source.file.date.updated": "Última actualización", - "source.file.date.created": "Creada", - "tabs.title": "Pestanas", - "toc.title": "Táboa de contidos", - "top.title": "Volver ao principio" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/gr.html b/docs/src/partials/languages/gr.html deleted file mode 100644 index 0edc3e4d..00000000 --- a/docs/src/partials/languages/gr.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "gr", - "clipboard.copy": "Αντιγραφή", - "clipboard.copied": "Αντιγράφηκε", - "edit.link.title": "Επεξεργασία αυτής της σελίδας", - "footer.previous": "Επόμενη", - "footer.next": "Προηγούμενη", - "meta.comments": "Σχόλια", - "meta.source": "Πηγή", - "search.config.pipeline": " ", - "search.placeholder": "Αναζήτηση", - "search.result.placeholder": "Πληκτρολογήστε για να αρχίσει η αναζήτηση", - "search.result.none": "Δε βρέθηκαν αντίστοιχα αρχεία", - "search.result.one": "1 αντίστοιχο αρχείο", - "search.result.other": "# αντίστοιχα αρχεία", - "skip.link.title": "Μετάβαση στο περιεχόμενο", - "source.link.title": "Μετάβαση στο αποθετήριο", - "source.revision.date": "τελευταία ενημέρωση", - "source.file.date.updated": "τελευταία ενημέρωση", - "source.file.date.created": "Δημιουργήθηκε", - "toc.title": "Πίνακας περιεχομένων" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/he.html b/docs/src/partials/languages/he.html deleted file mode 100644 index 79bbf3ea..00000000 --- a/docs/src/partials/languages/he.html +++ /dev/null @@ -1,46 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "he", - "direction": "rtl", - "clipboard.copy": "העתק ללוח", - "clipboard.copied": "הועתק ללוח", - "edit.link.title": "ערוך דף זה", - "footer.previous": "קודם", - "footer.next": "הַבָּא", - "meta.comments": "הערות", - "meta.source": "מָקוֹר", - "search.config.pipeline": " ", - "search.placeholder": "לחפש", - "search.result.placeholder": "הקלד כדי להתחיל לחפש", - "search.result.none": "אין מסמכים תואמים", - "search.result.one": "1 מסמך תואם", - "search.result.other": "# מסמך תואם", - "skip.link.title": "דלג לתוכן", - "source.link.title": "עבור אל מאגר", - "source.revision.date": "העדכון אחרון", - "source.file.date.updated": "העדכון אחרון", - "source.file.date.created": "נוצר", - "toc.title": "תוכן העניינים" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/hi.html b/docs/src/partials/languages/hi.html deleted file mode 100644 index fca93740..00000000 --- a/docs/src/partials/languages/hi.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "hi", - "clipboard.copy": "क्लिपबोर्ड पर कॉपी करें", - "clipboard.copied": "क्लिपबोर्ड पर कॉपी कर दिया गया", - "edit.link.title": "इस पृष्ठ को संपादित करें", - "footer.previous": "पिछला", - "footer.next": "आगामी", - "meta.comments": "टिप्पणियाँ", - "meta.source": "स्रोत", - "search.config.lang": "hi", - "search.placeholder": "खोज", - "search.result.placeholder": "खोज शुरू करने के लिए टाइप करें", - "search.result.none": "कोई मिलान डॉक्यूमेंट नहीं", - "search.result.one": "1 मिलान डॉक्यूमेंट", - "search.result.other": "# मिलान डाक्यूमेंट्स", - "skip.link.title": "विषय पर बढ़ें", - "source.link.title": "रिपॉजिटरी पर जाएं", - "source.revision.date": "आखिरी अपडेट", - "source.file.date.updated": "आखिरी अपडेट", - "source.file.date.created": "बनाया था", - "toc.title": "विषय - सूची" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/hr.html b/docs/src/partials/languages/hr.html deleted file mode 100644 index 6fa4118c..00000000 --- a/docs/src/partials/languages/hr.html +++ /dev/null @@ -1,44 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "hr", - "clipboard.copy": "Kopirajte u međuspremnik", - "clipboard.copied": "Kopirano u međuspremnik", - "edit.link.title": "Uredi stranicu", - "footer.previous": "Prethodno", - "footer.next": "Sljedeće", - "meta.comments": "Komentari", - "meta.source": "Izvor", - "search.placeholder": "Pretraživanje", - "search.result.placeholder": "Unesite pojam pretraživanja", - "search.result.none": "Ništa nije pronađeno", - "search.result.one": "1 rezultat pretraživanja", - "search.result.other": "# rezultata pretraživanja", - "skip.link.title": "Preskočite na sadržaj", - "source.link.title": "Idite u repozitorij", - "source.revision.date": "Zadnje ažuriranje", - "source.file.date.updated": "Zadnje ažuriranje", - "source.file.date.created": "Stvoreno", - "toc.title": "Sadržaj" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/hu.html b/docs/src/partials/languages/hu.html deleted file mode 100644 index 2eeb3112..00000000 --- a/docs/src/partials/languages/hu.html +++ /dev/null @@ -1,54 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "hu", - "clipboard.copy": "Másolás vágólapra", - "clipboard.copied": "Vágólapra másolva", - "edit.link.title": "Oldal szerkesztése", - "footer.previous": "Előző", - "footer.next": "Következő", - "footer.title": "Élőláb", - "header.title": "Élőfej", - "meta.comments": "Hozzászólások", - "meta.source": "Forrás", - "nav.title": "Navigáció", - "search.config.lang": "hu", - "search.placeholder": "Keresés", - "search.reset": "Törlés", - "search.result.initializer": "Keresés inicializálása", - "search.result.placeholder": "Kereséshez írj ide valamit", - "search.result.none": "Nincs találat", - "search.result.one": "1 egyező dokumentum", - "search.result.other": "# egyező dokumentum", - "search.result.more.one": "1 további találat az oldalon", - "search.result.more.other": "# további találat az oldalon", - "search.result.term.missing": "Üres", - "skip.link.title": "Kihagyás", - "source.link.title": "Főoldalra ugrás", - "source.revision.date": "Utolsó frissítés", - "source.file.date.updated": "Utolsó frissítés", - "source.file.date.created": "Létrehozva", - "tabs.title": "Lapok", - "toc.title": "Tartalomjegyzék" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/id.html b/docs/src/partials/languages/id.html deleted file mode 100644 index 2d68bd5f..00000000 --- a/docs/src/partials/languages/id.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "id", - "clipboard.copy": "Salin ke memori", - "clipboard.copied": "Tersalin ke memori", - "edit.link.title": "Ubah halaman ini", - "footer.previous": "Sebelumnya", - "footer.next": "Selanjutnya", - "meta.comments": "Komentar", - "meta.source": "Sumber", - "search.config.pipeline": " ", - "search.placeholder": "Cari", - "search.result.placeholder": "Ketik untuk mulai pencarian", - "search.result.none": "Tidak ada dokumen yang sesuai", - "search.result.one": "1 dokumen ditemukan", - "search.result.other": "# dokumen ditemukan", - "skip.link.title": "Lewati ke isi", - "source.link.title": "Menuju repositori", - "source.revision.date": "Pembaharuan Terakhir", - "source.revision.date": "Pembaharuan Terakhir", - "source.file.date.created": "Dibuat", - "toc.title": "Daftar isi" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/is.html b/docs/src/partials/languages/is.html deleted file mode 100644 index b3943e42..00000000 --- a/docs/src/partials/languages/is.html +++ /dev/null @@ -1,51 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "is", - "clipboard.copy": "Afrita í klemmuspjald", - "clipboard.copied": "Afritað í klemmuspjald", - "edit.link.title": "Ritvinna þessa síðu", - "footer.previous": "Fyrra", - "footer.next": "Næsta", - "footer.title": "Síðufótur", - "header.title": "Haus", - "meta.comments": "Athugasemdir", - "meta.source": "Grunnur", - "nav.title": "Valmynd", - "search.placeholder": "Leit", - "search.reset": "Hreinsa", - "search.result.placeholder": "Sláðu inn til að hefja leit", - "search.result.none": "Engin skjöl fundust", - "search.result.one": "1 skjal fannst", - "search.result.other": "# skjöl fundust", - "search.result.more.one": "1 til viðbótar á þessari síðu", - "search.result.more.other": "# til viðbótar á þessari síðu", - "skip.link.title": "Hoppa yfir í efni", - "source.link.title": "Fara í gagnahirslu (e. repository)", - "source.revision.date": "Síðasta uppfærsla", - "source.file.date.updated": "Síðasta uppfærsla", - "source.file.date.created": "Búið til", - "tabs.title": "Flipar", - "toc.title": "Efnisyfirlit" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/it.html b/docs/src/partials/languages/it.html deleted file mode 100644 index 6be33aac..00000000 --- a/docs/src/partials/languages/it.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "it", - "clipboard.copy": "Copia", - "clipboard.copied": "Copiato", - "edit.link.title": "Modifica", - "footer.previous": "Precedente", - "footer.next": "Prossimo", - "meta.comments": "Commenti", - "meta.source": "Sorgente", - "search.config.lang": "it", - "search.placeholder": "Cerca", - "search.result.placeholder": "Scrivi per iniziare a cercare", - "search.result.none": "Nessun documento trovato", - "search.result.one": "1 documento trovato", - "search.result.other": "# documenti trovati", - "skip.link.title": "Vai al contenuto", - "source.link.title": "Apri repository", - "source.revision.date": "Ultimo aggiornamento", - "source.file.date.updated": "Ultimo aggiornamento", - "source.file.date.created": "Creata", - "toc.title": "Indice" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ja.html b/docs/src/partials/languages/ja.html deleted file mode 100644 index 6710293b..00000000 --- a/docs/src/partials/languages/ja.html +++ /dev/null @@ -1,56 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "ja", - "clipboard.copy": "クリップボードへコピー", - "clipboard.copied": "コピーしました", - "edit.link.title": "編集", - "footer.previous": "前", - "footer.next": "次", - "footer.title": "フッター", - "header.title": "ヘッダー", - "meta.comments": "コメント", - "meta.source": "ソース", - "nav.title": "ナビゲーション", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\s\- 、。,.]+", - "search.placeholder": "検索", - "search.reset": "クリア", - "search.result.initializer": "検索を初期化", - "search.result.placeholder": "検索キーワードを入力してください", - "search.result.none": "何も見つかりませんでした", - "search.result.one": "1件見つかりました", - "search.result.other": "#件見つかりました", - "search.result.more.one": "このページ内にもう1件見つかりました", - "search.result.more.other": "このページ内にあと#件見つかりました", - "search.result.term.missing": "検索に含まれない", - "skip.link.title": "コンテンツにスキップ", - "source.link.title": "リポジトリへ", - "source.revision.date": "最終更新日", - "source.file.date.updated": "最終更新日", - "source.file.date.created": "作成した", - "tabs.title": "タブ", - "toc.title": "目次" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ka.html b/docs/src/partials/languages/ka.html deleted file mode 100644 index c3711a48..00000000 --- a/docs/src/partials/languages/ka.html +++ /dev/null @@ -1,50 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "ka", - "clipboard.copy": "კოპირება", - "clipboard.copied": "კოპირებულია", - "edit.link.title": "გვერდის რედარქირება", - "footer.previous": "წინა", - "footer.next": "შემდეგი", - "meta.comments": "კომენტარები", - "meta.source": "წყარო", - "nav.title": "ნავიგაცია", - "search.config.pipeline": " ", - "search.placeholder": "ძებნა", - "search.reset": "გასუფთავება", - "search.result.placeholder": "ჩაწერე ძებნის დასაწყებად", - "search.result.none": "დოკუმენტი ვერ მოიძებნა", - "search.result.one": "მოიძებნა 1 დოკუმენტი", - "search.result.other": "მოიძებნა # დოკუმენტი", - "search.result.more.one": "კიდევ 1 ამ გვერდზე", - "search.result.more.other": "კიდევ # ამ გვერდზე", - "skip.link.title": "კონტენტზე გადასვლა", - "source.link.title": "საცავში გადასვლა", - "source.revision.date": "ბოლო განახლება", - "source.file.date.updated": "ბოლო განახლება", - "source.file.date.created": "შეიქმნა", - "tabs.title": "ტაბები", - "toc.title": "სარჩევი" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/kr.html b/docs/src/partials/languages/kr.html deleted file mode 100644 index 17aa91b5..00000000 --- a/docs/src/partials/languages/kr.html +++ /dev/null @@ -1,55 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "kr", - "clipboard.copy": "클립보드로 복사", - "clipboard.copied": "클립보드에 복사됨", - "edit.link.title": "이 페이지를 편집", - "footer.previous": "이전", - "footer.next": "다음", - "meta.comments": "댓글", - "meta.source": "출처", - "search.config.pipeline": " ", - "search.placeholder": "검색", - "search.share": "공유", - "search.reset": "지우기", - "search.result.initializer": "검색 초기화", - "search.result.placeholder": "검색어를 입력하세요", - "search.result.none": "검색어와 일치하는 문서가 없습니다", - "search.result.one": "1개의 일치하는 문서", - "search.result.other": "#개의 일치하는 문서", - "search.result.more.one": "이 문서에서 1개의 검색 결과 더 보기", - "search.result.more.other": "이 문서에서 #개의 검색 결과 더 보기", - "search.result.term.missing": "포함되지 않은 검색어", - "search.title": "검색", - "select.language.title": "언어설정", - "select.version.title": "버전 선택", - "skip.link.title": "콘텐츠로 이동", - "source.link.title": "저장소로 이동", - "source.revision.date": "마지막 업데이트", - "source.file.date.updated": "마지막 업데이트", - "source.file.date.created": "작성일", - "toc.title": "목차", - "top.title": "맨위로" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/mn.html b/docs/src/partials/languages/mn.html deleted file mode 100644 index 498c8e70..00000000 --- a/docs/src/partials/languages/mn.html +++ /dev/null @@ -1,51 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "mn", - "clipboard.copy": "Хуулах", - "clipboard.copied": "Санах ойд хуулах", - "edit.link.title": "Хуудас засварлах", - "footer.previous": "Өмнөх", - "footer.next": "Дараах", - "footer.title": "Хөл", - "header.title": "Толгой", - "meta.comments": "Сэтгэгдэл", - "meta.source": "Эх үүсвэр", - "nav.title": "Чиглүүлэгч", - "search.config.lang": "ru", - "search.placeholder": "Хайлт", - "search.reset": "Цэвэрлэх", - "search.result.placeholder": "Хайлтын үгээ бичнэ үү", - "search.result.none": "Таарц илэрсэнгүй", - "search.result.one": "1 таарц илэрлээ", - "search.result.other": "# Тохирох баримт бичиг", - "search.result.more.one": "1 илүү хуудас байна", - "search.result.more.other": "# илүү хуудас байна", - "skip.link.title": "Агуулгыг алгасах", - "source.link.title": "Хадгалах сан руу очих", - "source.file.date.updated": "Сүүлийн шинэчлэлт", - "source.file.date.created": "Үүсгэсэн", - "tabs.title": "Табууд", - "toc.title": "Агуулга" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/my.html b/docs/src/partials/languages/my.html deleted file mode 100644 index aa52360d..00000000 --- a/docs/src/partials/languages/my.html +++ /dev/null @@ -1,50 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "my", - "clipboard.copy": "ကလစ်ဘုတ် သို့ ကူးယူရန်", - "clipboard.copied": "ကလစ်ဘုတ် သို့ ကူယူပြီး", - "edit.link.title": "ဤ စာမျက်နှာကို ပြင်ရန်", - "footer.previous": "နောက်သို့", - "footer.next": "ရှေ့သို့", - "footer.title": "အောက်ခြေ", - "header.title": "ခေါင်းပိုင်း", - "meta.comments": "မှတ်ချက်များ", - "meta.source": "ရင်းမြစ်", - "nav.title": "လမ်းညွှန်", - "search.config.pipeline": " ", - "search.placeholder": "ရှာရန်", - "search.reset": "ရှင်းလင်း", - "search.result.placeholder": "ရှာဖွေခြင်းစရန် စာရိုက်ပါ", - "search.result.none": "တူညီသော စာရွက်စာတမ်းများ မရှိပါ", - "search.result.one": "စာရွက်စာတမ်း ၁ ခု တူညီသည်", - "search.result.other": "စာရွက်စာတမ်း # ခု တူညီသည်", - "skip.link.title": "မာတိကာ သို့ သွားရန်", - "source.link.title": "repository သို့ သွားရန်", - "source.revision.date": "နောက်ဆုံး ထုတ်ပြန်ချက်", - "source.file.date.updated": "နောက်ဆုံး ထုတ်ပြန်ချက်", - "source.file.date.created": "နေပြည်တော်", - "tabs.title": "တက်များ", - "toc.title": "ပါဝင်အကြောင်းအရာများ" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/nl.html b/docs/src/partials/languages/nl.html deleted file mode 100644 index 2b392043..00000000 --- a/docs/src/partials/languages/nl.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "nl", - "clipboard.copy": "Kopiëren naar klembord", - "clipboard.copied": "Gekopieerd naar klembord", - "edit.link.title": "Wijzig deze pagina", - "footer.previous": "Vorige", - "footer.next": "Volgende", - "meta.comments": "Reacties", - "meta.source": "Bron", - "search.config.lang": "nl", - "search.placeholder": "Zoeken", - "search.result.placeholder": "Typ om te beginnen met zoeken", - "search.result.none": "Geen overeenkomende documenten", - "search.result.one": "1 overeenkomende document", - "search.result.other": "# overeenkomende documenten", - "skip.link.title": "Ga naar inhoud", - "source.link.title": "Ga naar repository", - "source.revision.date": "Laatst geüpdatet", - "source.file.date.updated": "Laatst geüpdatet", - "source.file.date.created": "Gecreëerd", - "toc.title": "Inhoudsopgave" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/nn.html b/docs/src/partials/languages/nn.html deleted file mode 100644 index b7f83b3c..00000000 --- a/docs/src/partials/languages/nn.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "nn", - "clipboard.copy": "Kopier til utklippstavla", - "clipboard.copied": "Kopiert til utklippstavla", - "edit.link.title": "Rediger denne sida", - "footer.previous": "Førre", - "footer.next": "Neste", - "meta.comments": "Kommentarar", - "meta.source": "Kjelde", - "search.config.lang": "no", - "search.placeholder": "Søk", - "search.result.placeholder": "Skriv søkeord", - "search.result.none": "Ingen treff", - "search.result.one": "1 treff", - "search.result.other": "# treff", - "skip.link.title": "Gå til innhald", - "source.link.title": "Gå til kjelde", - "source.revision.date": "Siste oppdatering", - "source.file.date.updated": "Siste oppdatering", - "source.file.date.created": "Laget", - "toc.title": "Innhaldsliste" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/no.html b/docs/src/partials/languages/no.html deleted file mode 100644 index b034679f..00000000 --- a/docs/src/partials/languages/no.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "no", - "clipboard.copy": "Kopier til utklippstavlen", - "clipboard.copied": "Kopiert til utklippstavlen", - "edit.link.title": "Rediger denne siden", - "footer.previous": "Forrige", - "footer.next": "Neste", - "meta.comments": "Kommentarer", - "meta.source": "Kilde", - "search.config.lang": "no", - "search.placeholder": "Søk", - "search.result.placeholder": "Skriv søkeord", - "search.result.none": "Ingen treff", - "search.result.one": "1 treff", - "search.result.other": "# treff", - "skip.link.title": "Gå til innhold", - "source.link.title": "Gå til kilde", - "source.revision.date": "Siste oppdatering", - "source.file.date.updated": "Siste oppdatering", - "source.file.date.created": "Created", - "toc.title": "Innholdsfortegnelse" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/pl.html b/docs/src/partials/languages/pl.html deleted file mode 100755 index cdb7ba3a..00000000 --- a/docs/src/partials/languages/pl.html +++ /dev/null @@ -1,54 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "pl", - "clipboard.copy": "Kopiuj do schowka", - "clipboard.copied": "Skopiowane", - "edit.link.title": "Edytuj tę stronę", - "footer.previous": "Poprzednia strona", - "footer.next": "Następna strona", - "footer.title": "Stopka", - "header.title": "Nagłówek", - "meta.comments": "Komentarze", - "meta.source": "Kod źródłowy", - "search.config.pipeline": " ", - "nav.title": "Nawigacja", - "search.placeholder": "Szukaj", - "search.reset": "Wyczyść", - "search.result.initializer": "Inicjowanie wyszukiwania", - "search.result.placeholder": "Zacznij pisać, aby szukać", - "search.result.none": "Brak wyników wyszukiwania", - "search.result.one": "Wyniki wyszukiwania: 1", - "search.result.other": "Wyniki wyszukiwania: #", - "search.result.more.one": "1 więcej na tej stronie", - "search.result.more.other": "# więcej na tej stronie", - "search.result.term.missing": "Brak", - "skip.link.title": "Przejdź do treści", - "source.link.title": "Idź do repozytorium", - "source.revision.date": "Ostatnia aktualizacja", - "source.file.date.updated": "Ostatnia aktualizacja", - "source.file.date.created": "Utworzony", - "tabs.title": "Zakładki", - "toc.title": "Spis treści" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/pt.html b/docs/src/partials/languages/pt.html deleted file mode 100644 index 9aca375c..00000000 --- a/docs/src/partials/languages/pt.html +++ /dev/null @@ -1,59 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "pt", - "clipboard.copy": "Copiar para área de transferência", - "clipboard.copied": "Copiado para área de transferência", - "edit.link.title": "Editar esta página", - "footer.previous": "Anterior", - "footer.next": "Próximo", - "footer.title": "Rodapé", - "header.title": "Cabeçalho", - "meta.comments": "Comentários", - "meta.source": "Fonte", - "nav.title": "Navegação", - "search.config.lang": "pt", - "search.placeholder": "Buscar", - "search.share": "Compartilhar", - "search.reset": "Limpar", - "search.result.initializer": "Inicializando a pesquisa", - "search.result.placeholder": "Digite para iniciar a busca", - "search.result.none": "Nenhum resultado encontrado", - "search.result.one": "1 resultado encontrado", - "search.result.other": "# resultados encontrados", - "search.result.more.one": "Mais 1 nesta página", - "search.result.more.other": "Mais # nesta página", - "search.result.term.missing": "Ausente", - "search.title": "Pesquisar", - "select.language.title": "Selecione o idioma", - "select.version.title": "Selecione a versão", - "skip.link.title": "Ir para o conteúdo", - "source.link.title": "Ir ao repositório", - "source.revision.date": "Última atualização", - "source.file.date.updated": "Última atualização", - "source.file.date.created": "Criada", - "tabs.title": "Abas", - "toc.title": "Índice", - "top.title": "Voltar ao topo" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ro.html b/docs/src/partials/languages/ro.html deleted file mode 100644 index caac19f2..00000000 --- a/docs/src/partials/languages/ro.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "ro", - "clipboard.copy": "Copiază în clipboard", - "clipboard.copied": "Copiat în clipboard", - "edit.link.title": "Editeaza această pagină", - "footer.previous": "Anterior", - "footer.next": "Următor", - "meta.comments": "Comentarii", - "meta.source": "Sursă", - "search.config.lang": "ro", - "search.placeholder": "Căutare", - "search.result.placeholder": "Tastează pentru a începe căutarea", - "search.result.none": "Nu a fost găsit niciun document", - "search.result.one": "1 document găsit", - "search.result.other": "# documente găsite", - "skip.link.title": "Sari la conținut", - "source.link.title": "Accesează repository-ul", - "source.revision.date": "Ultima actualizare", - "source.file.date.updated": "Ultima actualizare", - "source.file.date.created": "Creată", - "toc.title": "Cuprins" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/ru.html b/docs/src/partials/languages/ru.html deleted file mode 100644 index 69dd7ce2..00000000 --- a/docs/src/partials/languages/ru.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "ru", - "clipboard.copy": "Копировать в буфер", - "clipboard.copied": "Скопировано в буфер", - "edit.link.title": "Редактировать страницу", - "footer.previous": "Назад", - "footer.next": "Вперед", - "meta.comments": "Комментарии", - "meta.source": "Исходный код", - "search.config.lang": "ru", - "search.placeholder": "Поиск", - "search.result.placeholder": "Начните печатать для поиска", - "search.result.none": "Совпадений не найдено", - "search.result.one": "Найдено 1 совпадение", - "search.result.other": "Найдено # совпадений", - "skip.link.title": "Перейти к содержанию", - "source.link.title": "Перейти к репозиторию", - "source.revision.date": "Последнее обновление", - "source.file.date.updated": "Последнее обновление", - "source.file.date.created": "Созданный", - "toc.title": "Содержание" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sh.html b/docs/src/partials/languages/sh.html deleted file mode 100644 index f0f7efa8..00000000 --- a/docs/src/partials/languages/sh.html +++ /dev/null @@ -1,58 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "sh", - "clipboard.copy": "Kopiraj u klipbord", - "clipboard.copied": "Iskopirano u klipbord", - "edit.link.title": "Ažuriraj stranicu", - "footer.previous": "Prethodno", - "footer.next": "Sledeće", - "footer.title": "Podnožje", - "header.title": "Zaglavlje", - "meta.comments": "Komentari", - "meta.source": "Izvor", - "nav.title": "Navigacija", - "search.placeholder": "Pretraga", - "search.share": "Deljenje", - "search.reset": "Očisti", - "search.result.initializer": "Inicijalizujem pretragu", - "search.result.placeholder": "Unesite pojam pretrage", - "search.result.none": "Ništa nije pronađeno", - "search.result.one": "1 rezultat pretrage", - "search.result.other": "# rezultata pretrage", - "search.result.more.one": "još 1 na ovoj strani", - "search.result.more.other": "još # na ovoj strani", - "search.result.term.missing": "Nedostaje", - "search.title": "Pretraga", - "select.language.title": "Izaberi jezik", - "select.version.title": "Izaberi verziju", - "skip.link.title": "Idi na tekst", - "source.link.title": "Idi u repozitorijum", - "source.revision.date": "Ažuriran", - "source.file.date.updated": "Ažuriran", - "source.file.date.created": "Kreiran", - "tabs.title": "Tabovi", - "toc.title": "Sadržaj" - "top.title": "Nazad na vrh" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/si.html b/docs/src/partials/languages/si.html deleted file mode 100644 index 2dc89dcd..00000000 --- a/docs/src/partials/languages/si.html +++ /dev/null @@ -1,52 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "si", - "clipboard.copy": "කොපි කරන්න", - "clipboard.copied": "කොපි කළා", - "edit.link.title": "පිටුව සංස්කරණය", - "footer.previous": "පසුගිය", - "footer.next": "මීළඟ", - "footer.title": "පාදම", - "header.title": "ශීර්ෂය", - "meta.comments": "ප්‍රතිචාර", - "meta.source": "මූලාශ්‍රය", - "nav.title": "යාත්‍රණය", - "search.config.pipeline": " ", - "search.placeholder": "සොයන්න", - "search.reset": "මකන්න", - "search.result.placeholder": "සෙවීමට ටයිප් කරන්න", - "search.result.none": "කිසිවක් හමු නොවුණි", - "search.result.one": "1 ගැලපෙන ගොනුවක්", - "search.result.other": "ගැලපෙන ගොනු # ක්", - "search.result.more.one": "තව 1 ප්‍රතිඵලයක්", - "search.result.more.other": "තව ප්‍රතිඵල # ක්", - "skip.link.title": "අන්තර්ගතය වෙත යන්න", - "source.link.title": "රිපොසිටරියට යන්න", - "source.revision.date": "අවසන් යාවත්කාලීන වීම", - "source.file.date.updated": "අවසන් යාවත්කාලීන වීම", - "source.file.date.created": "ٺاھيو ويو", - "tabs.title": "ටැබ්ස්", - "toc.title": "පටුන" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sk.html b/docs/src/partials/languages/sk.html deleted file mode 100644 index 21d4870d..00000000 --- a/docs/src/partials/languages/sk.html +++ /dev/null @@ -1,44 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "sk", - "clipboard.copy": "Kopírovať do schránky", - "clipboard.copied": "Skopírované do schránky", - "edit.link.title": "Upraviť túto stránku", - "footer.previous": "Späť", - "footer.next": "Ďalej", - "meta.comments": "Komentáre", - "meta.source": "Zdroj", - "search.placeholder": "Hľadať", - "search.result.placeholder": "Pre vyhľadávanie začni písať", - "search.result.none": "Žiadne vyhovujúce dokumenty", - "search.result.one": "Vyhovujúci dokument: 1", - "search.result.other": "Vyhovujúce dokumenty: #", - "skip.link.title": "Preskočiť na obsah", - "source.link.title": "Zobraziť repozitár", - "source.revision.date": "Posledná aktualizácia", - "source.file.date.updated": "Posledná aktualizácia", - "source.file.date.created": "Vytvorené", - "toc.title": "Obsah" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sl.html b/docs/src/partials/languages/sl.html deleted file mode 100644 index 312bcb85..00000000 --- a/docs/src/partials/languages/sl.html +++ /dev/null @@ -1,44 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "sl", - "clipboard.copy": "Kopiraj v odložišče", - "clipboard.copied": "Kopirano v odložišče", - "edit.link.title": "Uredi stran", - "footer.previous": "Prejšnja stran", - "footer.next": "Naslednja stran", - "meta.comments": "Komentarji", - "meta.source": "Izvorna koda", - "search.placeholder": "Išči", - "search.result.placeholder": "Vpiši iskalni niz", - "search.result.none": "Ni zadetkov", - "search.result.one": "1 zadetek", - "search.result.other": "# zadetkov", - "skip.link.title": "Skoči na vsebino", - "source.link.title": "Pojdi na repozitorij", - "source.revision.date": "Zadnja posodobitev", - "source.file.date.updated": "Zadnja posodobitev", - "source.file.date.created": "Ustvarjeno", - "toc.title": "Kazalo" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sr.html b/docs/src/partials/languages/sr.html deleted file mode 100644 index 877b7bff..00000000 --- a/docs/src/partials/languages/sr.html +++ /dev/null @@ -1,57 +0,0 @@ - - -% macro t(key) %}{{ { - "language": "sh", - "clipboard.copy": "Копирај у клипборд", - "clipboard.copied": "Ископирано у клипборд", - "edit.link.title": "Ажурирај страницу", - "footer.previous": "Претходно", - "footer.next": "Следеће", - "footer.title": "Подножје", - "header.title": "Заглавље", - "meta.comments": "Коментари", - "meta.source": "Извор", - "nav.title": "Навигација", - "search.placeholder": "Претрага", - "search.share": "Дељење", - "search.reset": "Очисти", - "search.result.initializer": "Иницијализујем претрагу", - "search.result.placeholder": "Унесите појам претраге", - "search.result.none": "Ништа није пронађено", - "search.result.one": "1 резултат претраге", - "search.result.other": "# резултата претраге", - "search.result.more.one": "још 1 на овој страни", - "search.result.more.other": "још # на овој страни", - "search.result.term.missing": "Недостаје", - "search.title": "Претрага", - "select.language.title": "Изабери језик", - "select.version.title": "Изабери верзију", - "skip.link.title": "Иди на текст", - "source.link.title": "Иди у репозиторијум", - "source.revision.date": "Ажуриран", - "source.file.date.updated": "Ажуриран", - "source.file.date.created": "Креиран", - "tabs.title": "Табови", - "toc.title": "Садржај" - "top.title": "Назад на врх" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/sv.html b/docs/src/partials/languages/sv.html deleted file mode 100644 index d2f09d87..00000000 --- a/docs/src/partials/languages/sv.html +++ /dev/null @@ -1,54 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "sv", - "clipboard.copy": "Kopiera till urklipp", - "clipboard.copied": "Kopierat till urklipp", - "edit.link.title": "Redigera sidan", - "footer.previous": "Föregående", - "footer.next": "Nästa", - "footer.title": "Sidfot", - "header.title": "Sidhuvud", - "meta.comments": "Kommentarer", - "meta.source": "Källa", - "nav.title": "Navigation", - "search.config.lang": "sv", - "search.placeholder": "Sök", - "search.reset": "Rensa", - "search.result.initializer": "Initialiserar sök", - "search.result.placeholder": "Skriv sökord", - "search.result.none": "Inga sökresultat", - "search.result.one": "1 sökresultat", - "search.result.other": "# sökresultat", - "search.result.more.one": "1 till på denna sidan", - "search.result.more.other": "# till på denna sidan", - "search.result.term.missing": "Saknas", - "skip.link.title": "Gå till innehållet", - "source.link.title": "Gå till datakatalog", - "source.revision.date": "Senaste uppdateringen", - "source.file.date.updated": "Senaste uppdateringen", - "source.file.date.created": "Skapad", - "tabs.title": "Flikar", - "toc.title": "Innehållsförteckning" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/th.html b/docs/src/partials/languages/th.html deleted file mode 100644 index 6c7831cb..00000000 --- a/docs/src/partials/languages/th.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "th", - "clipboard.copy": "คัดลอก", - "clipboard.copied": "คัดลอกแล้ว", - "edit.link.title": "แก้ไขหน้านี้", - "footer.previous": "ก่อนหน้า", - "footer.next": "ต่อไป", - "meta.comments": "ความคิดเห็น", - "meta.source": "แหล่งที่มา", - "search.config.lang": "th", - "search.placeholder": "ค้นหา", - "search.result.placeholder": "พิมพ์เพื่อเริ่มค้นหา", - "search.result.none": "ไม่พบเอกสารที่ตรงกัน", - "search.result.one": "พบเอกสารที่ตรงกัน", - "search.result.other": "พบ # เอกสารที่ตรงกัน", - "skip.link.title": "ข้ามไปที่เนื้อหา", - "source.link.title": "ไปที่ Repository", - "source.revision.date": "สร้าง", - "source.file.date.updated": "สร้าง", - "source.file.date.created": "สร้าง", - "toc.title": "สารบัญ" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/tr.html b/docs/src/partials/languages/tr.html deleted file mode 100644 index 28645b88..00000000 --- a/docs/src/partials/languages/tr.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "tr", - "clipboard.copy": "Kopyala", - "clipboard.copied": "Kopyalandı", - "edit.link.title": "Düzenle", - "footer.previous": "Önceki", - "footer.next": "Sonraki", - "meta.comments": "Yorumlar", - "meta.source": "Kaynak", - "search.config.lang": "tr", - "search.placeholder": "Ara", - "search.result.placeholder": "Aramaya başlamak için yazın", - "search.result.none": "Eşleşen doküman bulunamadı", - "search.result.one": "1 doküman bulundu", - "search.result.other": "# doküman bulundu", - "skip.link.title": "Ana içeriğe geç", - "source.link.title": "Depoya git", - "source.revision.date": "Son Güncelleme", - "source.file.date.updated": "Son Güncelleme", - "source.file.date.created": "Oluşturuldu", - "toc.title": "İçindekiler" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/uk.html b/docs/src/partials/languages/uk.html deleted file mode 100644 index 266b0c93..00000000 --- a/docs/src/partials/languages/uk.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "uk", - "clipboard.copy": "Скопіювати в буфер", - "clipboard.copied": "Скопійовано в буфер", - "edit.link.title": "Редагувати сторінку", - "footer.previous": "Назад", - "footer.next": "Вперед", - "meta.comments": "Коментарі", - "meta.source": "Вихідний код", - "search.config.lang": "ru", - "search.placeholder": "Пошук", - "search.result.placeholder": "Розпочніть писати для пошуку", - "search.result.none": "Збігів не знайдено", - "search.result.one": "Знайдено 1 збіг", - "search.result.other": "Знайдено # збігів", - "skip.link.title": "Перейти до змісту", - "source.link.title": "Перейти до репозиторію", - "source.revision.date": "Останнє оновлення", - "source.file.date.updated": "Останнє оновлення", - "source.file.date.created": "Створено", - "toc.title": "Зміст" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/vi.html b/docs/src/partials/languages/vi.html deleted file mode 100644 index 006eb6c5..00000000 --- a/docs/src/partials/languages/vi.html +++ /dev/null @@ -1,45 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "vi", - "clipboard.copy": "Sao chép vào bộ nhớ", - "clipboard.copied": "Sao chép xong", - "edit.link.title": "Chỉnh sửa", - "footer.previous": "Trước", - "footer.next": "Sau", - "meta.comments": "Bình luận", - "meta.source": "Mã nguồn", - "search.config.lang": "vi", - "search.placeholder": "Tìm kiếm", - "search.result.placeholder": "Nhập để bắt đầu tìm kiếm", - "search.result.none": "Không tìm thấy tài liệu liên quan", - "search.result.one": "1 tài liệu liên quan", - "search.result.other": "# tài liệu liên quan", - "skip.link.title": "Vào thẳng nội dung", - "source.link.title": "Đến kho lưu trữ mã nguồn", - "source.revision.date": "Cập nhật cuối cùng", - "source.file.date.updated": "Cập nhật cuối cùng", - "source.file.date.created": "Tạo", - "toc.title": "Mục lục" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/zh-Hant.html b/docs/src/partials/languages/zh-Hant.html deleted file mode 100644 index 0efe77d4..00000000 --- a/docs/src/partials/languages/zh-Hant.html +++ /dev/null @@ -1,48 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "zh-Hant", - "clipboard.copy": "拷貝", - "clipboard.copied": "已拷貝", - "edit.link.title": "編輯此頁", - "footer.previous": "上一頁", - "footer.next": "下一頁", - "meta.comments": "評論", - "meta.source": "來源", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\,\。]+", - "search.placeholder": "搜尋", - "search.result.initializer": "正在初始化搜尋引擎", - "search.result.placeholder": "鍵入以開始檢索", - "search.result.none": "沒有找到符合條件的結果", - "search.result.one": "找到 1 个符合條件的結果", - "search.result.other": "# 個符合條件的結果", - "skip.link.title": "跳轉至", - "source.link.title": "前往倉庫", - "source.revision.date": "最後更新", - "source.file.date.updated": "最後更新", - "source.file.date.created": "建立日期", - "toc.title": "目錄" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/zh-TW.html b/docs/src/partials/languages/zh-TW.html deleted file mode 100644 index 18503d74..00000000 --- a/docs/src/partials/languages/zh-TW.html +++ /dev/null @@ -1,48 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "zh-Hant", - "clipboard.copy": "複製", - "clipboard.copied": "已複製", - "edit.link.title": "編輯此頁", - "footer.previous": "上一頁", - "footer.next": "下一頁", - "meta.comments": "留言", - "meta.source": "來源", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\s\- 、。,.?;]+", - "search.placeholder": "搜尋", - "search.result.initializer": "正在初始化搜尋引擎", - "search.result.placeholder": "打字進行搜尋", - "search.result.none": "沒有符合的項目", - "search.result.one": "找到 1 個符合的項目", - "search.result.other": "找到 # 個符合的項目", - "skip.link.title": "跳轉到", - "source.link.title": "前往倉庫", - "source.revision.date": "最後更新", - "source.file.date.updated": "最後更新", - "source.file.date.created": "建立日期", - "toc.title": "目錄" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/languages/zh.html b/docs/src/partials/languages/zh.html deleted file mode 100644 index eeebacf6..00000000 --- a/docs/src/partials/languages/zh.html +++ /dev/null @@ -1,48 +0,0 @@ - - - -{% macro t(key) %}{{ { - "language": "zh", - "clipboard.copy": "复制", - "clipboard.copied": "已复制", - "edit.link.title": "编辑此页", - "footer.previous": "上一页", - "footer.next": "下一页", - "meta.comments": "评论", - "meta.source": "来源", - "search.config.lang": "ja", - "search.config.pipeline": "trimmer, stemmer", - "search.config.separator": "[\,\。]+", - "search.placeholder": "搜索", - "search.result.initializer": "正在初始化搜索引擎", - "search.result.placeholder": "键入以开始搜索", - "search.result.none": "没有找到符合条件的结果", - "search.result.one": "找到 1 个符合条件的结果", - "search.result.other": "# 个符合条件的结果", - "skip.link.title": "跳转至", - "source.link.title": "前往仓库", - "source.revision.date": "最后更新", - "source.file.date.updated": "最后更新", - "source.file.date.created": "创建日期", - "toc.title": "目录" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/logo.html b/docs/src/partials/logo.html deleted file mode 100644 index 9cb0d0a3..00000000 --- a/docs/src/partials/logo.html +++ /dev/null @@ -1,29 +0,0 @@ - - - -{% if config.theme.logo %} - logo -{% else %} - {% set icon = config.theme.icon.logo or "material/library" %} - {% include ".icons/" ~ icon ~ ".svg" %} -{% endif %} diff --git a/docs/src/partials/nav-item.html b/docs/src/partials/nav-item.html deleted file mode 100644 index a96d7855..00000000 --- a/docs/src/partials/nav-item.html +++ /dev/null @@ -1,169 +0,0 @@ - - - -{% macro render(nav_item, path, level) %} - - - {% set class = "md-nav__item" %} - {% if nav_item.active %} - {% set class = class ~ " md-nav__item--active" %} - {% endif %} - - - {% if nav_item.children %} - - - {% if "navigation.sections" in features and level == 1 + ( - "navigation.tabs" in features - ) %} - {% set class = class ~ " md-nav__item--section" %} - {% endif %} - - -
  • - - - {% set checked = "checked" if nav_item.active %} - {% if "navigation.expand" in features and not checked %} - - {% else %} - - {% endif %} - - - {% set indexes = [] %} - {% if "navigation.indexes" in features %} - {% for item in nav_item.children %} - {% if item.is_index and not index is defined %} - {% set _ = indexes.append(item) %} - {% endif %} - {% endfor %} - {% endif %} - - - {% if not indexes %} - - - - {% else %} - {% set index = indexes | first %} - {% set class = "md-nav__link--active" if index == page %} - - {% endif %} - - - -
  • - - - {% elif nav_item == page %} -
  • - {% set toc = page.toc %} - - - - - - {% set first = toc | first %} - {% if first and first.level == 1 %} - {% set toc = first.children %} - {% endif %} - - - {% if toc %} - - {% endif %} - - {{ nav_item.title }} - - - - {% if toc %} - {% include "partials/toc.html" %} - {% endif %} -
  • - - - {% else %} -
  • - - {{ nav_item.title }} - -
  • - {% endif %} -{% endmacro %} - - -{{ render(nav_item, path, level) }} diff --git a/docs/src/partials/nav.html b/docs/src/partials/nav.html deleted file mode 100644 index d64112ff..00000000 --- a/docs/src/partials/nav.html +++ /dev/null @@ -1,68 +0,0 @@ - - - -{% set class = "md-nav md-nav--primary" %} -{% if "navigation.tabs" in features %} - {% set class = class ~ " md-nav--lifted" %} -{% endif %} -{% if "toc.integrate" in features %} - {% set class = class ~ " md-nav--integrated" %} -{% endif %} - - - diff --git a/docs/src/partials/palette.html b/docs/src/partials/palette.html deleted file mode 100644 index 5ee428b0..00000000 --- a/docs/src/partials/palette.html +++ /dev/null @@ -1,66 +0,0 @@ - - - -{% macro primary(key) %}{{ { - "red": "#ef5552", - "pink": "#e92063", - "purple": "#ab47bd", - "deep-purple": "#7e56c2", - "indigo": "#4051b5", - "blue": "#2094f3", - "light-blue": "#02a6f2", - "cyan": "#00bdd6", - "teal": "#009485", - "green": "#4cae4f", - "light-green": "#8bc34b", - "lime": "#cbdc38", - "yellow": "#ffec3d", - "amber": "#ffc105", - "orange": "#ffa724", - "deep-orange": "#ff6e42", - "brown": "#795649", - "grey": "#757575", - "blue-grey": "#546d78", - "black": "#000000", - "white": "#ffffff" -}[key] }}{% endmacro %} - - -{% macro accent(key) %}{{ { - "red": "#ff1a47", - "pink": "#f50056", - "purple": "#df41fb", - "deep-purple": "#7c4dff", - "indigo": "#526cfe", - "blue": "#4287ff", - "light-blue": "#0091eb", - "cyan": "#00bad6", - "teal": "#00bda4", - "green": "#00c753", - "light-green": "#63de17", - "lime": "#b0eb00", - "yellow": "#ffd500", - "amber": "#ffaa00", - "orange": "#ff9100", - "deep-orange": "#ff6e42" -}[key] }}{% endmacro %} diff --git a/docs/src/partials/search.html b/docs/src/partials/search.html deleted file mode 100644 index 40c1a075..00000000 --- a/docs/src/partials/search.html +++ /dev/null @@ -1,105 +0,0 @@ - - -{% import "partials/language.html" as lang with context %} - - - diff --git a/docs/src/partials/social.html b/docs/src/partials/social.html deleted file mode 100644 index 1dddddcf..00000000 --- a/docs/src/partials/social.html +++ /dev/null @@ -1,42 +0,0 @@ - - - -{% if config.extra.social %} - -{% endif %} diff --git a/docs/src/partials/source-date.html b/docs/src/partials/source-date.html deleted file mode 100644 index 5b1a197a..00000000 --- a/docs/src/partials/source-date.html +++ /dev/null @@ -1,24 +0,0 @@ - - - -{% include "partials/source-file.html" %} diff --git a/docs/src/partials/source-file.html b/docs/src/partials/source-file.html deleted file mode 100644 index d1ce0b66..00000000 --- a/docs/src/partials/source-file.html +++ /dev/null @@ -1,44 +0,0 @@ - - -{% import "partials/language.html" as lang with context %} - - -{% set label = lang.t("source.file.date.updated") %} -
    -
    - - - - {% if page.meta.git_revision_date_localized %} - {{ label }}: {{ page.meta.git_revision_date_localized }} - - {% if page.meta.git_creation_date_localized %} -
    {{ lang.t("source.file.date.created") }}: {{ page.meta.git_creation_date_localized }} - {% endif %} - - - {% elif page.meta.revision_date %} - {{ label }}: {{ page.meta.revision_date }} - {% endif %} -
    -
    diff --git a/docs/src/partials/source.html b/docs/src/partials/source.html deleted file mode 100644 index a69244a0..00000000 --- a/docs/src/partials/source.html +++ /dev/null @@ -1,39 +0,0 @@ - - -{% import "partials/language.html" as lang with context %} - - - -
    - {% set icon = config.theme.icon.repo or "fontawesome/brands/git-alt" %} - {% include ".icons/" ~ icon ~ ".svg" %} -
    -
    - {{ config.repo_name }} -
    -
    diff --git a/docs/src/partials/tabs-item.html b/docs/src/partials/tabs-item.html deleted file mode 100644 index 248af88b..00000000 --- a/docs/src/partials/tabs-item.html +++ /dev/null @@ -1,56 +0,0 @@ - - - -{% if not class %} - {% set class = "md-tabs__link" %} - {% if nav_item.active %} - {% set class = class ~ " md-tabs__link--active" %} - {% endif %} -{% endif %} - - -{% if nav_item.children %} - {% set title = title | d(nav_item.title) %} - {% set nav_item = nav_item.children | first %} - - - {% if nav_item.children %} - {% include "partials/tabs-item.html" %} - - - {% else %} -
  • - - {{ title }} - -
  • - {% endif %} - - -{% else %} -
  • - - {{ nav_item.title }} - -
  • -{% endif %} diff --git a/docs/src/partials/tabs.html b/docs/src/partials/tabs.html deleted file mode 100644 index 325a1459..00000000 --- a/docs/src/partials/tabs.html +++ /dev/null @@ -1,39 +0,0 @@ - - - -{% set class = "" %} - - - diff --git a/docs/src/partials/toc-item.html b/docs/src/partials/toc-item.html deleted file mode 100644 index f90ca7c8..00000000 --- a/docs/src/partials/toc-item.html +++ /dev/null @@ -1,39 +0,0 @@ - - - -
  • - - {{ toc_item.title }} - - - - {% if toc_item.children %} - - {% endif %} -
  • diff --git a/docs/src/partials/toc.html b/docs/src/partials/toc.html deleted file mode 100644 index c4c6d735..00000000 --- a/docs/src/partials/toc.html +++ /dev/null @@ -1,52 +0,0 @@ - - -{% import "partials/language.html" as lang with context %} - - - diff --git a/electron-builder.yml b/electron-builder.yml index fc5ee175..f32eb3a9 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -10,36 +10,39 @@ releaseInfo: --- - - SSH login is supported #40 - - Support query ClickHouse to dynamically add configuration - - Support metadata management to filter the database - - Support automatic prompt function of code editor + - Support metadata management to filter the table + - Support trino and presto for query + - Support trino and presto for monitor --> processors + - Support trino and presto for monitor --> connection + - Support trino and presto for monitor --> slow query #### Docs --- - - Fix Monitor --> Processor document image pointing error + - Refactoring software homepage + - Add clickhouse datasource docs + - Add presto & trino datasource docs #### Optimize ---- - - Optimize error reporting pop-up window #148 + - Optimize project description and introduction + - Optimize the homepage is not available & does not support data source charts #### Bug --- - - Fix the release error that the new version of the CI tool was not merged with the code release error + - Fix the exception that the data source is not selected in the track, the Track list can be selected #### UI --- - - Optimize query history display list - - Migrate the software update function to the system menu - - Support editor bracket matching + - Add multiple editor themes + - Query the list of data sources on the page, support the display of logo directories: output: ./release diff --git a/package.json b/package.json index d7b90e67..3006ea58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dbm", - "version": "1.16.0", + "version": "1.17.0", "author": "qianmoQ ", "description": "ClickHouse DataBase GUI", "github": "https://github.com/EdurtIO/dbm.git", @@ -14,7 +14,9 @@ "mac", "linux", "dbm", - "clickhouse" + "clickhouse", + "trino", + "presto" ], "publish": [ { @@ -46,7 +48,9 @@ "@angular/platform-browser": "12.1.2", "@angular/platform-browser-dynamic": "12.1.2", "@angular/router": "12.1.2", + "@ant-design/icons-angular": "^13.1.0", "@ctrl/ngx-codemirror": "^5.1.1", + "@dalongrong/presto-client": "^0.6.5", "@ngx-translate/core": "^14.0.0", "@ngx-translate/http-loader": "^7.0.0", "angular-highcharts": "^13.0.1", @@ -68,6 +72,8 @@ "ngx-markdown": "^13.1.0", "ngx-moment": "^6.0.2", "node-sql-parser": "^4.1.1", + "presto-stream-client": "^1.0.15", + "promise-timeout": "^1.3.0", "rxjs": "~6.6.0", "sass-loader": "^12.3.0", "sql-formatter": "^4.0.2", diff --git a/src/renderer/app/layout/header/header.component.ts b/src/renderer/app/layout/header/header.component.ts index df365a0c..bb246d67 100644 --- a/src/renderer/app/layout/header/header.component.ts +++ b/src/renderer/app/layout/header/header.component.ts @@ -74,7 +74,6 @@ export class HeaderComponent extends BaseComponent implements OnInit { handlerUpdateState() { ipcRenderer.on('updater', (event, arg) => { - console.log('update status ', arg); this.loading.button = false; this.ref.markForCheck(); this.ref.detectChanges(); @@ -86,7 +85,6 @@ export class HeaderComponent extends BaseComponent implements OnInit { this.releaseNotes = arg?.message?.releaseNotes; break; case UpdateEnum.downloading: - console.log(arg) this.disabled.button = false; this.percentage = arg.message.percent.toFixed(2); break; @@ -105,7 +103,6 @@ export class HeaderComponent extends BaseComponent implements OnInit { this.disabled.button = true; break; default: - console.log('default', arg) this.updateResponse = arg; this.disabled.button = true; break; diff --git a/src/renderer/app/layout/layout.module.ts b/src/renderer/app/layout/layout.module.ts index fbf94618..466c0194 100644 --- a/src/renderer/app/layout/layout.module.ts +++ b/src/renderer/app/layout/layout.module.ts @@ -1,18 +1,20 @@ -import { FormsModule } from '@angular/forms'; -import { NgModule } from '@angular/core'; -import { LayoutRouting } from './layout.routing'; -import { LayoutComponent } from './layout.component'; -import { HeaderComponent } from './header/header.component'; -import { CommonModule } from '@angular/common'; -import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; -import { HttpClient } from '@angular/common/http'; -import { TranslateHttpLoader } from '@ngx-translate/http-loader'; -import { NgZorroAntdModule } from '@renderer/app/ng-zorro-antd.module'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { MarkdownModule } from 'ngx-markdown'; -import { DatasourceService } from '@renderer/services/management/datasource.service'; -import { HttpService } from '@renderer/services/http.service'; -import { SshService } from '@renderer/services/ssh.service'; +import {FormsModule} from '@angular/forms'; +import {NgModule} from '@angular/core'; +import {LayoutRouting} from './layout.routing'; +import {LayoutComponent} from './layout.component'; +import {HeaderComponent} from './header/header.component'; +import {CommonModule} from '@angular/common'; +import {TranslateLoader, TranslateModule} from '@ngx-translate/core'; +import {HttpClient} from '@angular/common/http'; +import {TranslateHttpLoader} from '@ngx-translate/http-loader'; +import {NgZorroAntdModule} from '@renderer/app/ng-zorro-antd.module'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {MarkdownModule} from 'ngx-markdown'; +import {DatasourceService} from '@renderer/services/management/datasource.service'; +import {HttpService} from '@renderer/services/http.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {PrestoService} from "@renderer/services/presto.service"; +import {FactoryService} from "@renderer/services/factory.service"; const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => new TranslateHttpLoader(http, './renderer/assets/i18n/', '.json'); @@ -40,7 +42,9 @@ const httpLoaderFactory = (http: HttpClient): TranslateHttpLoader => BasicService, DatasourceService, HttpService, - SshService + SshService, + PrestoService, + FactoryService ] }) export class LayoutModule { diff --git a/src/renderer/app/ng-zorro-antd.module.ts b/src/renderer/app/ng-zorro-antd.module.ts index cc962f07..cc63dac1 100644 --- a/src/renderer/app/ng-zorro-antd.module.ts +++ b/src/renderer/app/ng-zorro-antd.module.ts @@ -37,6 +37,7 @@ import { NzBadgeModule } from 'ng-zorro-antd/badge'; import { NzPaginationModule } from 'ng-zorro-antd/pagination'; import { NzDrawerModule } from 'ng-zorro-antd/drawer'; import { NzTypographyModule } from 'ng-zorro-antd/typography'; +import { NzIconModule } from "ng-zorro-antd/icon"; @NgModule({ declarations: [], @@ -78,7 +79,8 @@ import { NzTypographyModule } from 'ng-zorro-antd/typography'; NzBadgeModule, NzPaginationModule, NzDrawerModule, - NzTypographyModule + NzTypographyModule, + NzIconModule ] }) export class NgZorroAntdModule { diff --git a/src/renderer/app/pages/home/home.component.html b/src/renderer/app/pages/home/home.component.html index 4afb6bd3..05cdc495 100644 --- a/src/renderer/app/pages/home/home.component.html +++ b/src/renderer/app/pages/home/home.component.html @@ -5,10 +5,19 @@
    - - - - + + + + + + + + + + + +
    diff --git a/src/renderer/app/pages/home/home.component.ts b/src/renderer/app/pages/home/home.component.ts index 9dd11624..974ea4c5 100644 --- a/src/renderer/app/pages/home/home.component.ts +++ b/src/renderer/app/pages/home/home.component.ts @@ -6,6 +6,7 @@ import { QueryService } from '@renderer/services/query/query.service'; import { RequestModel } from '@renderer/model/request.model'; import { ClickhousePluginService } from '@renderer/services/plugin/clickhouse.plugin.service'; import { DatasourceModel } from '@renderer/model/datasource.model'; +import {DatabaseEnum} from "@renderer/enum/database.enum"; @Component({ selector: 'app-home', @@ -16,6 +17,7 @@ export class HomeComponent implements OnInit { dataSources: DatasourceModel[] = new Array(); chartsConfig: ChartsModel[] = new Array(); chartsSkeleton: boolean[] = new Array(); + dataSourceType = DatabaseEnum; constructor(private datasourceService: DatasourceService, private queryService: QueryService, @@ -34,21 +36,23 @@ export class HomeComponent implements OnInit { handlerInitChart() { this.dataSources.forEach((value, index) => { - const request = new RequestModel(); - request.config = value; - this.clickhousePluginService.getQueryCount(request).then(response => { - if (response.status) { - const config = new ChartsModel(); - config.type = 'area'; - const series = new ChartsSeriesModel(); - config.xAxis.categories = response.data.columns.map(v => v.categories); - series.data = response.data.columns.map(v => v.value); - series.name = 'Count'; - config.series.push(series); - this.chartsConfig[index] = config; - } - this.chartsSkeleton[index] = false; - }); + if (value.type === DatabaseEnum.clickhosue) { + const request = new RequestModel(); + request.config = value; + this.clickhousePluginService.getQueryCount(request).then(response => { + if (response.status) { + const config = new ChartsModel(); + config.type = 'area'; + const series = new ChartsSeriesModel(); + config.xAxis.categories = response.data.columns.map(v => v.categories); + series.data = response.data.columns.map(v => v.value); + series.name = 'Count'; + config.series.push(series); + this.chartsConfig[index] = config; + } + this.chartsSkeleton[index] = false; + }); + } }); } } diff --git a/src/renderer/app/pages/home/home.module.ts b/src/renderer/app/pages/home/home.module.ts index 5f214c5a..a8cd7422 100644 --- a/src/renderer/app/pages/home/home.module.ts +++ b/src/renderer/app/pages/home/home.module.ts @@ -10,6 +10,7 @@ import { NgZorroAntdModule } from '@renderer/app/ng-zorro-antd.module'; import { QueryService } from '@renderer/services/query/query.service'; import { ClickhousePluginService } from '@renderer/services/plugin/clickhouse.plugin.service'; import { CommonShareModule } from '@renderer/app/common-share.module'; +import { TranslateModule } from "@ngx-translate/core"; const HOME_ROUTES: Routes = [ {path: '', component: HomeComponent} @@ -23,10 +24,10 @@ const HOME_ROUTES: Routes = [ ServiceModule, NgZorroAntdModule, CommonShareModule, - RouterModule.forChild(HOME_ROUTES) - ], - exports: [ + RouterModule.forChild(HOME_ROUTES), + TranslateModule ], + exports: [], declarations: [ HomeComponent ], diff --git a/src/renderer/app/pages/management/datasource/datasource.component.html b/src/renderer/app/pages/management/datasource/datasource.component.html index df27e505..7ea6ca1a 100644 --- a/src/renderer/app/pages/management/datasource/datasource.component.html +++ b/src/renderer/app/pages/management/datasource/datasource.component.html @@ -18,6 +18,7 @@ {{'common.name' | translate}} {{'common.host' | translate}} {{'common.protocol' | translate}} + {{'common.type' | translate}} {{'common.username' | translate}} {{'common.version' | translate}} {{'common.action' | translate}} @@ -29,6 +30,7 @@ {{data.name ? data.name : '-'}} {{data.host}} {{data.protocol}} + {{data.type}} {{data.username ? data.username : '-'}} {{data.version ? data.version : '-'}} @@ -99,10 +101,17 @@
    @@ -140,7 +149,7 @@ - + diff --git a/src/renderer/app/pages/management/datasource/datasource.component.ts b/src/renderer/app/pages/management/datasource/datasource.component.ts index c0e70a7f..53979af0 100644 --- a/src/renderer/app/pages/management/datasource/datasource.component.ts +++ b/src/renderer/app/pages/management/datasource/datasource.component.ts @@ -12,6 +12,7 @@ import { NzModalService } from 'ng-zorro-antd/modal'; import { TranslateService } from '@ngx-translate/core'; import { StringUtils } from '@renderer/utils/string.utils'; import { RequestModel } from '@renderer/model/request.model'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-management-datasource', @@ -41,6 +42,7 @@ export class DatasourceComponent extends BaseComponent implements OnInit { next: false }; sourceTypes: DatabaseModel[]; + dataSourceType = DatabaseEnum; constructor(private service: DatasourceService, private messageService: NzMessageService, diff --git a/src/renderer/app/pages/management/datasource/datasource.module.ts b/src/renderer/app/pages/management/datasource/datasource.module.ts index 4758c003..7ebde5c6 100644 --- a/src/renderer/app/pages/management/datasource/datasource.module.ts +++ b/src/renderer/app/pages/management/datasource/datasource.module.ts @@ -11,6 +11,7 @@ import { ServiceModule } from '@renderer/app/service.module'; import { CommonShareModule } from '@renderer/app/common-share.module'; import { NzModalService } from 'ng-zorro-antd/modal'; import { SshService } from '@renderer/services/ssh.service'; +import {PrestoService} from "@renderer/services/presto.service"; const DATASOURCE_ROUTES: Routes = [ {path: '', component: DatasourceComponent} @@ -35,7 +36,8 @@ const DATASOURCE_ROUTES: Routes = [ DatasourceService, DatasourceJob, NzModalService, - SshService + SshService, + PrestoService ] }) export class DatasourceModule { diff --git a/src/renderer/app/pages/management/metadata/metadata.component.ts b/src/renderer/app/pages/management/metadata/metadata.component.ts index 793641f7..f74fb1dd 100644 --- a/src/renderer/app/pages/management/metadata/metadata.component.ts +++ b/src/renderer/app/pages/management/metadata/metadata.component.ts @@ -12,6 +12,7 @@ import { TreeUtils } from '@renderer/utils/tree.utils'; import { NzContextMenuService, NzDropdownMenuComponent } from 'ng-zorro-antd/dropdown'; import { NzMessageService } from 'ng-zorro-antd/message'; import { NzFormatEmitEvent } from 'ng-zorro-antd/tree'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-management-metadata', @@ -54,6 +55,9 @@ export class MetadataComponent extends BaseComponent implements OnInit { configModel.title = k.alias; configModel.type = TypeEnum.disk; configModel.disabled = k.status ? false : true; + if (k.type === DatabaseEnum.presto || k.type === DatabaseEnum.trino) { + configModel.disabled = true; + } if (configModel.disabled) { configModel.isLeaf = true; } @@ -61,9 +65,9 @@ export class MetadataComponent extends BaseComponent implements OnInit { }); this.nodes = datasourceConfigs; }) - .catch(error => { - this.messageService.error(error.message); - }); + .catch(error => { + this.messageService.error(error.message); + }); this.outerHeight = window.outerHeight; } diff --git a/src/renderer/app/pages/management/metadata/metadata.module.ts b/src/renderer/app/pages/management/metadata/metadata.module.ts index 9e0586da..37bcd8bc 100644 --- a/src/renderer/app/pages/management/metadata/metadata.module.ts +++ b/src/renderer/app/pages/management/metadata/metadata.module.ts @@ -41,6 +41,7 @@ import { DatabaseRenameComponent } from '@renderer/components/database/rename/da import { ColumnCreateComponent } from '@renderer/components/column/create/column.create.component'; import { CommentColumnComponent } from '@renderer/components/column/comment/column.comment.component'; import { DatabaseFilterComponent } from '@renderer/components/database/filter/database.filter.component'; +import { TableFilterComponent } from '@renderer/components/table/filter/table.filter.component'; const MANAGEMENT_METADATA_ROUTES: Routes = [ {path: '', component: MetadataComponent} @@ -85,7 +86,8 @@ const MANAGEMENT_METADATA_ROUTES: Routes = [ DatabaseRenameComponent, ColumnCreateComponent, CommentColumnComponent, - DatabaseFilterComponent + DatabaseFilterComponent, + TableFilterComponent ], providers: [ DatasourceService, diff --git a/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts b/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts index 2120eb7d..51cf156e 100644 --- a/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts +++ b/src/renderer/app/pages/monitor/connection/monitor.connection.component.ts @@ -7,6 +7,7 @@ import { RequestModel } from '@renderer/model/request.model'; import { NzMessageService } from 'ng-zorro-antd/message'; import { ResponseDataModel } from '@renderer/model/response.model'; import { ChartsModel, ChartsSeriesModel } from '@renderer/model/charts.model'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-monitor-connection', diff --git a/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts b/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts index 8c04e347..24e8f04b 100644 --- a/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts +++ b/src/renderer/app/pages/monitor/mutations/monitor.mutations.component.ts @@ -8,6 +8,7 @@ import { NzMessageService } from 'ng-zorro-antd/message'; import { ResponseDataModel } from '@renderer/model/response.model'; import { BaseModel } from '@renderer/model/base.model'; import { ChartsModel, ChartsSeriesModel } from '@renderer/model/charts.model'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-monitor-mutations', @@ -30,7 +31,12 @@ export class MonitorMutationsComponent extends BaseComponent implements OnDestro private messageService: NzMessageService) { super(); this.datasourceService.getAll().then(response => { - this.dataSources = response; + this.dataSources = response.map(item => { + if (item.type === DatabaseEnum.trino || item.type === DatabaseEnum.presto) { + item.status = false; + } + return item; + }); }); } diff --git a/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts b/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts index f11c1ef3..6563bc50 100644 --- a/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts +++ b/src/renderer/app/pages/monitor/processor/monitor.processor.component.ts @@ -8,6 +8,7 @@ import { NzMessageService } from 'ng-zorro-antd/message'; import { ResponseDataModel } from '@renderer/model/response.model'; import { BaseModel } from '@renderer/model/base.model'; import { ChartsModel, ChartsSeriesModel } from '@renderer/model/charts.model'; +import { DatabaseEnum } from "@renderer/enum/database.enum"; @Component({ selector: 'app-monitor-processor', diff --git a/src/renderer/app/pages/query/query/query.component.html b/src/renderer/app/pages/query/query/query.component.html index 29418f83..2f9d9d47 100644 --- a/src/renderer/app/pages/query/query/query.component.html +++ b/src/renderer/app/pages/query/query/query.component.html @@ -20,11 +20,17 @@
    + nzCustomContent + nzValue="{{detail.alias}}" nzLabel="{{detail.alias}}"> + + + {{detail.alias}} +
    diff --git a/src/renderer/components/table/filter/table.filter.component.html b/src/renderer/components/table/filter/table.filter.component.html new file mode 100644 index 00000000..94aae9ba --- /dev/null +++ b/src/renderer/components/table/filter/table.filter.component.html @@ -0,0 +1,33 @@ +
    +
    + + {{'common.database'|translate}} + + {{database}} + + + + {{'common.name'|translate}} + + + + + + {{'common.precise'|translate}} + + + + + +
    +
    + diff --git a/src/renderer/components/table/filter/table.filter.component.ts b/src/renderer/components/table/filter/table.filter.component.ts new file mode 100644 index 00000000..fb801387 --- /dev/null +++ b/src/renderer/components/table/filter/table.filter.component.ts @@ -0,0 +1,37 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { BaseComponent } from '@renderer/app/base.component'; +import { ConfigModel } from '@renderer/model/config.model'; +import { StringUtils } from '@renderer/utils/string.utils'; +import { FilterModel } from '@renderer/model/filter.model'; + +@Component({ + selector: 'app-component-filter-table', + templateUrl: './table.filter.component.html' +}) +export class TableFilterComponent extends BaseComponent { + @Input() + config: ConfigModel; + @Input() + database: string; + @Output() + emitter = new EventEmitter(); + filter: FilterModel = new FilterModel(); + + constructor() { + super(); + } + + handlerValidate() { + if (StringUtils.isNotEmpty(this.filter.value)) { + this.disabled.button = false; + } else { + this.disabled.button = true; + } + } + + async handlerFilter() { + this.config.status = true; + this.config.filter = this.filter; + this.emitter.emit(this.config); + } +} diff --git a/src/renderer/config/base.config.ts b/src/renderer/config/base.config.ts index fecf0960..2cb99609 100644 --- a/src/renderer/config/base.config.ts +++ b/src/renderer/config/base.config.ts @@ -1,4 +1,8 @@ export interface BaseConfig { + version: string; + processesFetchAll: string; + connectionFetchAll: string; + slowQueryFetchAll: string; diskUsedRatio: string; databaseDiskUsedRatio: string; tableDiskUsedRatio: string; @@ -7,5 +11,7 @@ export interface BaseConfig { databaseItemsFilterPrecise: string; databaseItemsFilterFuzzy: string; tableItems: string; + tableItemsFilterPrecise: string; + tableItemsFilterFuzzy: string; columnItems: string; } diff --git a/src/renderer/config/clickhouse.config.ts b/src/renderer/config/clickhouse.config.ts index ca8dc6a2..dee2912f 100644 --- a/src/renderer/config/clickhouse.config.ts +++ b/src/renderer/config/clickhouse.config.ts @@ -1,6 +1,51 @@ -import { BaseConfig } from '@renderer/config/base.config'; +import {BaseConfig} from '@renderer/config/base.config'; export class ClickhouseConfig implements BaseConfig { + version = ` +SELECT version() AS version +`; + processesFetchAll = ` +SELECT + query_id AS id, + now() AS time, + query AS query, + toUInt64(toUInt64(read_rows) + toUInt64(written_rows)) AS rows, + round(elapsed, 1) AS elapsed, + formatReadableSize(toUInt64(read_bytes) + toUInt64(written_bytes)) AS bytes, + formatReadableSize(memory_usage) AS memoryUsage, + formatReadableSize(read_bytes) AS bytesRead, + formatReadableSize(written_bytes) AS bytesWritten, + cityHash64(query) AS hash, + hostName() AS host +FROM + system.processes +WHERE + round(elapsed, 1) > 0 + `; + slowQueryFetchAll = ` +SELECT + user, client_hostname AS host, + client_name AS hash, query AS query, + query_start_time AS time, query_duration_ms AS elapsed, + round(memory_usage / 1048576) AS memoryUsage, + result_rows AS rows, result_bytes / 1048576 AS bytes, + read_rows AS readRows, round(read_bytes / 1048576) AS bytesRead, + written_rows AS writtenRows, round(written_bytes / 1048576) AS bytesWritten +FROM system.query_log +WHERE type = 2 +AND query_duration_ms >= {0} +ORDER BY query_duration_ms DESC +LIMIT 100 + `; + connectionFetchAll = ` +SELECT + metric AS categories, + toUInt32(SUM(value)) AS value +FROM system.metrics +WHERE metric LIKE '%Connection' +GROUP BY metric +ORDER BY metric DESC + `; diskUsedRatio = ` SELECT name, path, formatReadableSize(free_space) AS freeSize, formatReadableSize(total_space) AS totalSize, @@ -88,6 +133,18 @@ WHERE name LIKE '%{0}%' SELECT uuid, name, engine AS value, partition_key, sorting_key, total_rows, total_bytes, database FROM system.tables WHERE database = '{0}' + `; + tableItemsFilterPrecise = ` +SELECT uuid, name, engine AS value, partition_key, sorting_key, total_rows, total_bytes, database +FROM system.tables +WHERE database = '{0}' +AND name = '{1}' + `; + tableItemsFilterFuzzy = ` +SELECT uuid, name, engine AS value, partition_key, sorting_key, total_rows, total_bytes, database +FROM system.tables +WHERE database = '{0}' +AND name LIKE '%{1}%' `; columnItems = ` DESC {0}.{1} diff --git a/src/renderer/config/operation.config.ts b/src/renderer/config/operation.config.ts index 0851842e..9f3ab452 100644 --- a/src/renderer/config/operation.config.ts +++ b/src/renderer/config/operation.config.ts @@ -19,6 +19,7 @@ export class OperationConfig { database.type = TypeEnum.database; database.operations = [ {type: TypeEnum.table, actions: [OperationEnum.create]}, + {type: TypeEnum.table, actions: [OperationEnum.filter]}, {type: TypeEnum.database, actions: [OperationEnum.delete]}, {type: TypeEnum.database, actions: [OperationEnum.structure]}, {type: TypeEnum.database, actions: [OperationEnum.rename]} diff --git a/src/renderer/config/presto.config.ts b/src/renderer/config/presto.config.ts new file mode 100644 index 00000000..9d108a95 --- /dev/null +++ b/src/renderer/config/presto.config.ts @@ -0,0 +1,59 @@ +import {BaseConfig} from "@renderer/config/base.config"; + +export class PrestoConfig implements BaseConfig { + version = ` +SELECT node_version AS version +FROM system.runtime.nodes +LIMIT 1 + `; + processesFetchAll = ` +SELECT + query_id AS id, + now() AS time, + query AS query, + '0' AS rows, + analysis_time_ms + planning_time_ms + queued_time_ms AS elapsed, + '0' AS bytes, + '0' AS memoryUsage, + '0' AS bytesRead, + '0' AS bytesWritten, + '' AS hash, + '' AS host +FROM + system.runtime.queries +WHERE + state = 'RUNNING' +`; + connectionFetchAll = ` +SELECT + source AS categories, + COUNT(1) AS value +FROM system.runtime.queries +WHERE state = 'RUNNING' +GROUP BY source +ORDER BY source DESC +`; + slowQueryFetchAll = ` +SELECT + query_id AS id, now() AS time, query AS query, '0' AS rows, + (analysis_time_ms + planning_time_ms + queued_time_ms) AS elapsed, + '0' AS bytes, '0' AS memoryUsage, + '0' AS bytesRead, '0' AS bytesWritten, + '' AS hash, '' AS host +FROM system.runtime.queries +WHERE (analysis_time_ms + planning_time_ms + queued_time_ms) >= {0} +ORDER BY (analysis_time_ms + planning_time_ms + queued_time_ms) DESC +LIMIT 100 + `; + columnDiskUsedRatio: string; + columnItems: string; + databaseDiskUsedRatio: string; + databaseItems: string; + databaseItemsFilterFuzzy: string; + databaseItemsFilterPrecise: string; + diskUsedRatio: string; + tableDiskUsedRatio: string; + tableItems: string; + tableItemsFilterFuzzy: string; + tableItemsFilterPrecise: string; +} diff --git a/src/renderer/config/source.type.config.ts b/src/renderer/config/source.type.config.ts index caa715f8..fdbd2fcc 100644 --- a/src/renderer/config/source.type.config.ts +++ b/src/renderer/config/source.type.config.ts @@ -1,17 +1,17 @@ -import { Injectable } from '@angular/core'; -import { DatabaseEnum } from '@renderer/enum/database.enum'; -import { DatabaseModel } from '@renderer/model/database.model'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { TranslateUtils } from '@renderer/utils/translate.utils'; +import {Injectable} from '@angular/core'; +import {DatabaseEnum} from '@renderer/enum/database.enum'; +import {DatabaseModel} from '@renderer/model/database.model'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {TranslateUtils} from '@renderer/utils/translate.utils'; @Injectable() export class SourceTypeConfig { getConfig(): DatabaseModel[] { + const basicType = new DatabaseModel(); const typeEngines = new Array(); - const basicEngine = new DatabaseModel(); - basicEngine.name = StringUtils.format('{0}', + basicType.name = StringUtils.format('{0}', [TranslateUtils.getValue('common.basic')]); - basicEngine.description = TranslateUtils.getValue('tooltip.source.basic'); + basicType.description = TranslateUtils.getValue('tooltip.source.basic'); const basicEngines = new Array(); // ClickHouse basicEngines.push(DatabaseModel.builder(TranslateUtils.getValue('common.clickhouse'), @@ -20,9 +20,34 @@ export class SourceTypeConfig { null, false, null, - './renderer/assets/icon/source/clickhouse.svg')); - basicEngine.engines = basicEngines; - typeEngines.push(basicEngine); + './renderer/assets/icon/source/ClickHouse.svg')); + basicType.engines = basicEngines; + + // -------------- Experimental ---------------- + const experimentalType = new DatabaseModel(); + const experimentalEngines = new Array(); + experimentalType.name = StringUtils.format('{0}', + [TranslateUtils.getValue('common.experimental')]); + experimentalType.description = TranslateUtils.getValue('tooltip.experimental'); + // Presto + experimentalEngines.push(DatabaseModel.builder(TranslateUtils.getValue('common.presto'), + TranslateUtils.getValue('tooltip.source.resto'), + DatabaseEnum.presto, + null, + true, + null, + './renderer/assets/icon/source/Presto.svg')); + // Trino + experimentalEngines.push(DatabaseModel.builder(TranslateUtils.getValue('common.trino'), + TranslateUtils.getValue('tooltip.source.trino'), + DatabaseEnum.trino, + null, + true, + null, + './renderer/assets/icon/source/Trino.svg')); + experimentalType.engines = experimentalEngines; + + typeEngines.push(basicType, experimentalType); return typeEngines; } } diff --git a/src/renderer/db/dexiedb.ts b/src/renderer/db/dexiedb.ts index 61a6ed90..29485dc2 100644 --- a/src/renderer/db/dexiedb.ts +++ b/src/renderer/db/dexiedb.ts @@ -10,7 +10,7 @@ export class DexieDb extends Dexie { constructor() { super('dbm_db'); - this.version(4) + this.version(5) .stores({ QueryHistoryTable: '++id,createdTime,startTime,endTime', SnippetTable: '++id,name,created,updated', diff --git a/src/renderer/editor.theme.scss b/src/renderer/editor.theme.scss index 2696b30b..c138c48b 100644 --- a/src/renderer/editor.theme.scss +++ b/src/renderer/editor.theme.scss @@ -36,6 +36,15 @@ @import "~codemirror/theme/midnight.css"; @import "~codemirror/theme/monokai.css"; @import "~codemirror/theme/moxer.css"; +@import "~codemirror/theme/neat.css"; +@import "~codemirror/theme/neo.css"; +@import "~codemirror/theme/night.css"; +@import "~codemirror/theme/nord.css"; +@import "~codemirror/theme/oceanic-next.css"; +@import "~codemirror/theme/panda-syntax.css"; +@import "~codemirror/theme/paraiso-dark.css"; +@import "~codemirror/theme/paraiso-light.css"; +@import "~codemirror/theme/pastel-on-dark.css"; //@import "~codemirror/theme/"; // Wait for all themes to load after loading, load the hint style to prevent style confusion diff --git a/src/renderer/enum/database.enum.ts b/src/renderer/enum/database.enum.ts index f08ea018..31ea25a5 100644 --- a/src/renderer/enum/database.enum.ts +++ b/src/renderer/enum/database.enum.ts @@ -16,5 +16,7 @@ export enum DatabaseEnum { odbc = 'ODBC', // DataSource Type - clickhosue = 'ClickHouse' + clickhosue = 'ClickHouse', + trino = 'Trino', + presto = 'Presto' } diff --git a/src/renderer/enum/editor/theme.enum.ts b/src/renderer/enum/editor/theme.enum.ts index 077293d4..76fc2ce8 100644 --- a/src/renderer/enum/editor/theme.enum.ts +++ b/src/renderer/enum/editor/theme.enum.ts @@ -35,5 +35,14 @@ export enum EditorThemeEnum { mbo = ('mbo'), 'mdn-like' = ('mdn-like'), midnight = ('midnight'), - moxer = ('moxer') + moxer = ('moxer'), + neat = ('neat'), + neo = ('neo'), + night = ('night'), + nord = ('nord'), + 'oceanic-next' = ('oceanic-next'), + 'panda-syntax' = ('panda-syntax'), + 'paraiso-dark' = ('paraiso-dark'), + 'paraiso-light' = ('paraiso-light'), + 'pastel-on-dark' = ('pastel-on-dark') } diff --git a/src/renderer/services/dbm.promise.ts b/src/renderer/services/dbm.promise.ts new file mode 100644 index 00000000..184ea9da --- /dev/null +++ b/src/renderer/services/dbm.promise.ts @@ -0,0 +1,42 @@ +export class DbmPromise extends Promise { + constructor(timeout, callback) { + // We need to support being called with no milliseconds + // value, because the various Promise methods (`then` and + // such) correctly call the subclass constructor when + // building the new promises they return. + const haveTimeout = typeof timeout === "number"; + const init = haveTimeout ? callback : timeout; + super((resolve, reject) => { + if (haveTimeout) { + const timer = setTimeout(() => { + reject(new Error(`Promise timed out after ${timeout}ms`)); + }, timeout); + init( + (value) => { + clearTimeout(timer); + resolve(value); + }, + (error) => { + clearTimeout(timer); + reject(error); + } + ); + } else { + init(resolve, reject); + } + }); + } + + // Pick your own name of course. (You could even override `resolve` itself + // if you liked; just be sure to do the same arguments detection we do + // above in the constructor, since you need to support the standard use of + // `resolve`.) + static resolveWithTimeout(timeout, x) { + if (!x || typeof x.then !== "function") { + // `x` isn't a thenable, no need for the timeout, + // fulfill immediately + return this.resolve(x); + } + return new this(timeout, x.then.bind(x)); + } +} diff --git a/src/renderer/services/factory.service.ts b/src/renderer/services/factory.service.ts new file mode 100644 index 00000000..e00762fb --- /dev/null +++ b/src/renderer/services/factory.service.ts @@ -0,0 +1,19 @@ +import {DatabaseEnum} from "@renderer/enum/database.enum"; +import {Factory} from "@renderer/factory"; +import {ClickhouseConfig} from "@renderer/config/clickhouse.config"; +import {PrestoConfig} from "@renderer/config/presto.config"; + +export class FactoryService { + public forward(type: string) { + switch (type) { + case DatabaseEnum.clickhosue: + return Factory.create(ClickhouseConfig); + case DatabaseEnum.trino: + case DatabaseEnum.presto: + return Factory.create(PrestoConfig); + default: + new Error("Unsupported database type"); + return null; + } + } +} diff --git a/src/renderer/services/forward.service.ts b/src/renderer/services/forward.service.ts index ca1ff89e..bd94783d 100644 --- a/src/renderer/services/forward.service.ts +++ b/src/renderer/services/forward.service.ts @@ -1,17 +1,22 @@ -import { HttpService } from '@renderer/services/http.service'; -import { SshService } from '@renderer/services/ssh.service'; -import { ResponseModel } from '@renderer/model/response.model'; -import { UrlUtils } from '@renderer/utils/url.utils'; -import { SshModel } from '@renderer/model/ssh.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { SystemBasicModel } from '@renderer/model/system.model'; -import { BasicService } from '@renderer/services/system/basic.service'; +import {HttpService} from '@renderer/services/http.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {ResponseModel} from '@renderer/model/response.model'; +import {UrlUtils} from '@renderer/utils/url.utils'; +import {SshModel} from '@renderer/model/ssh.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {SystemBasicModel} from '@renderer/model/system.model'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {PrestoService} from "@renderer/services/presto.service"; +import {DatabaseEnum} from "@renderer/enum/database.enum"; +import {FactoryService} from "@renderer/services/factory.service"; export class ForwardService { constructor( - private httpService: HttpService, - private sshService: SshService, - private basicService: BasicService + protected basicService: BasicService, + protected factoryService: FactoryService, + protected httpService: HttpService, + protected sshService: SshService, + protected prestoService?: PrestoService, ) { } @@ -23,7 +28,17 @@ export class ForwardService { const configure = request.config; switch (configure.protocol) { case 'HTTP': - return this.httpService.post(UrlUtils.formatUrl(request), sql); + let response; + switch (configure.type) { + case DatabaseEnum.clickhosue: + response = this.httpService.post(UrlUtils.formatUrl(request), sql); + break + case DatabaseEnum.trino: + case DatabaseEnum.presto: + response = this.prestoService.execute(configure, sql); + break + } + return response; case 'SSH': const basicConfig = this.getConfig(); const network = basicConfig.network * 1000; diff --git a/src/renderer/services/management/column.service.ts b/src/renderer/services/management/column.service.ts index 1faaab0f..1b61fd56 100644 --- a/src/renderer/services/management/column.service.ts +++ b/src/renderer/services/management/column.service.ts @@ -1,23 +1,25 @@ -import { Injectable } from '@angular/core'; -import { DatabaseModel } from '@renderer/model/database.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { SqlUtils } from '@renderer/utils/sql.utils'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { ColumnModel } from '@renderer/model/column.model'; -import { ColumnUtils } from '@renderer/utils/column.utils'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {Injectable} from '@angular/core'; +import {DatabaseModel} from '@renderer/model/database.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {SqlUtils} from '@renderer/utils/sql.utils'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {ColumnModel} from '@renderer/model/column.model'; +import {ColumnUtils} from '@renderer/utils/column.utils'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class ColumnService extends ForwardService implements BaseService { constructor(httpService: HttpService, + factoryService: FactoryService, sshService: SshService, basicService: BasicService) { - super(httpService, sshService, basicService); + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/management/database.service.ts b/src/renderer/services/management/database.service.ts index d83dd92c..c3f46532 100644 --- a/src/renderer/services/management/database.service.ts +++ b/src/renderer/services/management/database.service.ts @@ -1,19 +1,21 @@ -import { Injectable } from '@angular/core'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {Injectable} from '@angular/core'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class DatabaseService extends ForwardService implements BaseService { constructor(httpService: HttpService, + factoryService: FactoryService, sshService: SshService, basicService: BasicService) { - super(httpService, sshService, basicService); + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/management/datasource.service.ts b/src/renderer/services/management/datasource.service.ts index 80a995df..56ff978c 100644 --- a/src/renderer/services/management/datasource.service.ts +++ b/src/renderer/services/management/datasource.service.ts @@ -1,28 +1,33 @@ -import { BaseService } from '@renderer/services/base.service'; -import { ResponseModel } from '@renderer/model/response.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { DatasourceModel } from '@renderer/model/datasource.model'; -import { HttpService } from '@renderer/services/http.service'; -import { Injectable } from '@angular/core'; -import { PromiseExtended } from 'dexie'; -import { PersistenceService } from '@renderer/services/persistence.service'; -import { DexieDb } from '@renderer/db/dexiedb'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; +import {BaseService} from '@renderer/services/base.service'; +import {ResponseModel} from '@renderer/model/response.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {DatasourceModel} from '@renderer/model/datasource.model'; +import {HttpService} from '@renderer/services/http.service'; +import {Injectable} from '@angular/core'; +import {PromiseExtended} from 'dexie'; +import {PersistenceService} from '@renderer/services/persistence.service'; +import {DexieDb} from '@renderer/db/dexiedb'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {PrestoService} from "@renderer/services/presto.service"; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class DatasourceService extends PersistenceService implements BaseService { private db: DexieDb; - constructor(httpService: HttpService, - sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + constructor( + basicService: BasicService, + factoryService: FactoryService, + httpService: HttpService, + sshService: SshService, + prestoService: PrestoService) { + super(basicService, factoryService, httpService, sshService, prestoService); this.db = new DexieDb(); } getResponse(request: RequestModel, sql?: string): Promise { - sql = 'SELECT version() AS version'; + sql = this.factoryService.forward(request.config.type).version; return this.forward(request, sql); } @@ -33,9 +38,9 @@ export class DatasourceService extends PersistenceService implements BaseService */ getAll(): PromiseExtended { return this.db.DataSourceTable - .orderBy('created') - .reverse() - .toArray(); + .orderBy('created') + .reverse() + .toArray(); } delete(id: number): PromiseExtended { @@ -69,8 +74,8 @@ export class DatasourceService extends PersistenceService implements BaseService async getByAliasAsync(alias: string): Promise { let dataSource; dataSource = await this.db.DataSourceTable.where('alias') - .equals(alias) - .toArray(); + .equals(alias) + .toArray(); return dataSource.length > 0 ? dataSource[0] : new DatasourceModel(); } } diff --git a/src/renderer/services/management/metadata.service.ts b/src/renderer/services/management/metadata.service.ts index c10da5b4..7418b5a5 100644 --- a/src/renderer/services/management/metadata.service.ts +++ b/src/renderer/services/management/metadata.service.ts @@ -1,20 +1,21 @@ -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { Injectable } from '@angular/core'; -import { ResponseModel } from '@renderer/model/response.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { ConfigModel } from '@renderer/model/config.model'; -import { TypeEnum } from '@renderer/enum/type.enum'; -import { ClickhouseConfig } from '@renderer/config/clickhouse.config'; -import { Factory } from '@renderer/factory'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { DatabaseModel } from '@renderer/model/database.model'; -import { DatabaseEnum } from '@renderer/enum/database.enum'; -import { PropertyModel } from '@renderer/model/property.model'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; -import { FilterModel } from '@renderer/model/filter.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {Injectable} from '@angular/core'; +import {ResponseModel} from '@renderer/model/response.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {ConfigModel} from '@renderer/model/config.model'; +import {TypeEnum} from '@renderer/enum/type.enum'; +import {ClickhouseConfig} from '@renderer/config/clickhouse.config'; +import {Factory} from '@renderer/factory'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {DatabaseModel} from '@renderer/model/database.model'; +import {DatabaseEnum} from '@renderer/enum/database.enum'; +import {PropertyModel} from '@renderer/model/property.model'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FilterModel} from '@renderer/model/filter.model'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class MetadataService extends ForwardService implements BaseService { @@ -22,9 +23,10 @@ export class MetadataService extends ForwardService implements BaseService { WORD = 'ENGINE'; constructor(httpService: HttpService, + factoryService: FactoryService, sshService: SshService, basicService: BasicService) { - super(httpService, sshService, basicService); + super(basicService, factoryService, httpService, sshService); this.baseConfig = Factory.create(ClickhouseConfig); } @@ -68,7 +70,15 @@ export class MetadataService extends ForwardService implements BaseService { } break; case TypeEnum.database: - sql = StringUtils.format(this.baseConfig.tableItems, [config.key]); + if (filter) { + if (filter.precise) { + sql = StringUtils.format(this.baseConfig.tableItemsFilterPrecise, [config.key, filter.value]); + } else { + sql = StringUtils.format(this.baseConfig.tableItemsFilterFuzzy, [config.key, filter.value]); + } + } else { + sql = StringUtils.format(this.baseConfig.tableItems, [config.key]); + } break; case TypeEnum.table: sql = StringUtils.format(this.baseConfig.columnItems, [config.database, config.key]); diff --git a/src/renderer/services/management/table.service.ts b/src/renderer/services/management/table.service.ts index 97d77f77..77d0d64f 100644 --- a/src/renderer/services/management/table.service.ts +++ b/src/renderer/services/management/table.service.ts @@ -1,26 +1,28 @@ -import { Injectable } from '@angular/core'; -import { LogicEnum } from '@renderer/enum/logic.enum'; -import { PropertyEnum } from '@renderer/enum/property.enum'; -import { ColumnModel } from '@renderer/model/column.model'; -import { DatabaseModel } from '@renderer/model/database.model'; -import { PropertyModel } from '@renderer/model/property.model'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { SqlUtils } from '@renderer/utils/sql.utils'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { TableTtlModel } from '@renderer/model/table/table.ttl.model'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {Injectable} from '@angular/core'; +import {LogicEnum} from '@renderer/enum/logic.enum'; +import {PropertyEnum} from '@renderer/enum/property.enum'; +import {ColumnModel} from '@renderer/model/column.model'; +import {DatabaseModel} from '@renderer/model/database.model'; +import {PropertyModel} from '@renderer/model/property.model'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {SqlUtils} from '@renderer/utils/sql.utils'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {TableTtlModel} from '@renderer/model/table/table.ttl.model'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class TableService extends ForwardService implements BaseService { constructor(httpService: HttpService, + factoryService: FactoryService, sshService: SshService, basicService: BasicService) { - super(httpService, sshService, basicService); + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { @@ -220,11 +222,11 @@ export class TableService extends ForwardService implements BaseService { // } // }); properties - .filter(p => p.origin !== undefined && StringUtils.isNotEmpty(p.origin)) - .filter(p => p.value !== undefined) - .forEach(p => { - substr += StringUtils.format('\n {0} = \'{1}\',', [p.origin, p.value]); - }); + .filter(p => p.origin !== undefined && StringUtils.isNotEmpty(p.origin)) + .filter(p => p.value !== undefined) + .forEach(p => { + substr += StringUtils.format('\n {0} = \'{1}\',', [p.origin, p.value]); + }); if (StringUtils.isNotEmpty(substr)) { substr = StringUtils.format('SETTINGS {0}', [substr.substring(0, substr.length - 1)]); } @@ -241,9 +243,9 @@ export class TableService extends ForwardService implements BaseService { break; case PropertyEnum.name: const substr = configure.properties - .filter(element => StringUtils.isNotEmpty(element.value)) - .flatMap(element => StringUtils.format('\'{0}\'', [element.value])) - .join(', '); + .filter(element => StringUtils.isNotEmpty(element.value)) + .flatMap(element => StringUtils.format('\'{0}\'', [element.value])) + .join(', '); sql = StringUtils.format('{0} {1}({2})', [prefix, configure.type, substr]); break; } @@ -253,16 +255,16 @@ export class TableService extends ForwardService implements BaseService { private flatProperties(properties: PropertyModel[]): Map { const map = new Map(); properties - .filter(p => p.isSetting === undefined || p.isSetting) - .forEach(p => { - if (StringUtils.isNotEmpty(p.origin)) { - map.set('type', PropertyEnum.key); - map.set(p.origin, p.value); - } else { - map.set('type', PropertyEnum.name); - map.set(p.name, p.value); - } - }); + .filter(p => p.isSetting === undefined || p.isSetting) + .forEach(p => { + if (StringUtils.isNotEmpty(p.origin)) { + map.set('type', PropertyEnum.key); + map.set(p.origin, p.value); + } else { + map.set('type', PropertyEnum.name); + map.set(p.name, p.value); + } + }); return map; } diff --git a/src/renderer/services/monitor/monitor.service.ts b/src/renderer/services/monitor/monitor.service.ts index 0e591297..43badfbc 100644 --- a/src/renderer/services/monitor/monitor.service.ts +++ b/src/renderer/services/monitor/monitor.service.ts @@ -7,13 +7,17 @@ import { StringUtils } from '@renderer/utils/string.utils'; import { SshService } from '@renderer/services/ssh.service'; import { BasicService } from '@renderer/services/system/basic.service'; import { ForwardService } from '@renderer/services/forward.service'; +import { FactoryService } from "@renderer/services/factory.service"; +import { PrestoService } from "@renderer/services/presto.service"; @Injectable() export class MonitorService extends ForwardService implements BaseService { constructor(httpService: HttpService, sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + basicService: BasicService, + factoryService: FactoryService, + prestoService: PrestoService) { + super(basicService, factoryService, httpService, sshService, prestoService); } getResponse(request: RequestModel, sql?: string): Promise { @@ -21,49 +25,12 @@ export class MonitorService extends ForwardService implements BaseService { } getProcesses(request: RequestModel): Promise { - const sql = ` -SELECT - query_id AS id, - now() AS time, - query AS query, - toUInt64(toUInt64(read_rows) + toUInt64(written_rows)) AS rows, - round(elapsed, 1) AS elapsed, - formatReadableSize(toUInt64(read_bytes) + toUInt64(written_bytes)) AS bytes, - formatReadableSize(memory_usage) AS memoryUsage, - formatReadableSize(read_bytes) AS bytesRead, - formatReadableSize(written_bytes) AS bytesWritten, - cityHash64(query) AS hash, - hostName() AS host -FROM - system.processes -WHERE - round(elapsed, 1) > 0 - `; + const sql = this.factoryService.forward(request.config.type).processesFetchAll; return this.getResponse(request, sql); } getSlowQuery(request: RequestModel, threshold: number): Promise { - const sql = StringUtils.format(` - SELECT - user, - client_hostname AS host, - client_name AS hash, - query AS query, - query_start_time AS time, - query_duration_ms AS elapsed, - round(memory_usage / 1048576) AS memoryUsage, - result_rows AS rows, - result_bytes / 1048576 AS bytes, - read_rows AS readRows, - round(read_bytes / 1048576) AS bytesRead, - written_rows AS writtenRows, - round(written_bytes / 1048576) AS bytesWritten - FROM system.query_log - WHERE type = 2 - AND query_duration_ms >= {0} - ORDER BY query_duration_ms DESC - LIMIT 100 - `, [threshold]); + const sql = StringUtils.format(this.factoryService.forward(request.config.type).slowQueryFetchAll, [threshold]); return this.getResponse(request, sql); } @@ -84,19 +51,7 @@ WHERE is_done = 0 } getConnections(request: RequestModel): Promise { - const sql = ` -SELECT - metric AS categories, - toUInt32(SUM(value)) AS value -FROM - system.metrics -WHERE - metric LIKE '%Connection' -GROUP BY - metric -ORDER BY - metric DESC - `; + const sql = this.factoryService.forward(request.config.type).connectionFetchAll; return this.getResponse(request, sql); } } diff --git a/src/renderer/services/plugin/clickhouse.plugin.service.ts b/src/renderer/services/plugin/clickhouse.plugin.service.ts index 6ea6bcf3..7b2727bc 100644 --- a/src/renderer/services/plugin/clickhouse.plugin.service.ts +++ b/src/renderer/services/plugin/clickhouse.plugin.service.ts @@ -1,18 +1,20 @@ -import { BasePluginService } from '@renderer/services/plugin/base.plugin.service'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { HttpService } from '@renderer/services/http.service'; -import { Injectable } from '@angular/core'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {BasePluginService} from '@renderer/services/plugin/base.plugin.service'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {HttpService} from '@renderer/services/http.service'; +import {Injectable} from '@angular/core'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class ClickhousePluginService extends ForwardService implements BasePluginService { constructor(httpService: HttpService, sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + basicService: BasicService, + factoryService: FactoryService) { + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/presto.service.ts b/src/renderer/services/presto.service.ts new file mode 100644 index 00000000..4459ed19 --- /dev/null +++ b/src/renderer/services/presto.service.ts @@ -0,0 +1,81 @@ +import {Injectable} from "@angular/core"; +import {SystemBasicModel} from "@renderer/model/system.model"; +import {BasicService} from "@renderer/services/system/basic.service"; +import {DatasourceModel} from "@renderer/model/datasource.model"; +import {ResponseDataModel, ResponseModel} from "@renderer/model/response.model"; +import {StringUtils} from "@renderer/utils/string.utils"; +import {timeout, TimeoutError} from 'promise-timeout'; + +@Injectable() +export class PrestoService { + + constructor(private basicService: BasicService) { + } + + private getConfig(): SystemBasicModel { + return this.basicService.get() === null ? new SystemBasicModel() : this.basicService.get(); + } + + execute(configure: DatasourceModel, sql: string): Promise { + const {Client} = require('presto-stream-client'); + const network = this.getConfig().network * 1000; + let client; + const hasAuthentication = (StringUtils.isNotEmpty(configure.username) && StringUtils.isNotEmpty(configure.password)); + if (hasAuthentication) { + client = new Client({ + host: configure.host, + port: configure.port, + user: configure.username, + password: configure.password, + pollInterval: network, + source: 'dbm-client' + }); + } else { + client = new Client({host: configure.host, port: configure.port, pollInterval: network, source: 'dbm-client'}); + } + const response = new ResponseModel(); + const responseData = new ResponseDataModel(); + const somePromise = new Promise((resolve) => { + client.execute({ + query: sql, + catalog: 'hive', + schema: 'default', + objectMode: true + }).then((statement) => { + statement.on('columns', (columns) => { + responseData.headers = columns; + }); + statement.on('data', (rows) => { + responseData.columns.push(rows); + }); + statement.on('end', () => { + response.status = true; + response.data = responseData; + resolve(response); + }); + statement.on('error', (err) => { + response.status = false; + response.message = err?.message; + resolve(response); + }); + }, (err) => { + response.status = false; + response.message = err; + resolve(response); + }); + }); + return timeout(somePromise, network) + .then((thing) => { + return thing; + }) + .catch((err) => { + response.status = false; + if (err instanceof TimeoutError) { + response.message = `Promise timed out after ${this.getConfig().network} ms`; + } else { + response.message = err; + } + return response; + }); + } +} diff --git a/src/renderer/services/query/query.service.ts b/src/renderer/services/query/query.service.ts index 652a4d0e..d1d61319 100644 --- a/src/renderer/services/query/query.service.ts +++ b/src/renderer/services/query/query.service.ts @@ -7,6 +7,8 @@ import { StringUtils } from '@renderer/utils/string.utils'; import { ForwardService } from '@renderer/services/forward.service'; import { SshService } from '@renderer/services/ssh.service'; import { BasicService } from '@renderer/services/system/basic.service'; +import { FactoryService } from "@renderer/services/factory.service"; +import { PrestoService } from "@renderer/services/presto.service"; const {Parser} = require('node-sql-parser'); @@ -14,8 +16,10 @@ const {Parser} = require('node-sql-parser'); export class QueryService extends ForwardService implements BaseService { constructor(httpService: HttpService, sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + basicService: BasicService, + factoryService: FactoryService, + prestoService: PrestoService) { + super(basicService, factoryService, httpService, sshService, prestoService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/snippet/snippet.service.ts b/src/renderer/services/snippet/snippet.service.ts index a07de6fb..debe85e1 100644 --- a/src/renderer/services/snippet/snippet.service.ts +++ b/src/renderer/services/snippet/snippet.service.ts @@ -1,14 +1,15 @@ -import { BaseService } from '@renderer/services/base.service'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { PersistenceService } from '@renderer/services/persistence.service'; -import { DexieDb } from '@renderer/db/dexiedb'; -import { SnippetModel } from '@renderer/model/snippet.model'; -import { PromiseExtended } from 'dexie'; -import { Injectable } from '@angular/core'; -import { HttpService } from '@renderer/services/http.service'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; +import {BaseService} from '@renderer/services/base.service'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {PersistenceService} from '@renderer/services/persistence.service'; +import {DexieDb} from '@renderer/db/dexiedb'; +import {SnippetModel} from '@renderer/model/snippet.model'; +import {PromiseExtended} from 'dexie'; +import {Injectable} from '@angular/core'; +import {HttpService} from '@renderer/services/http.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class SnippetService extends PersistenceService implements BaseService { @@ -16,8 +17,9 @@ export class SnippetService extends PersistenceService implements BaseService { constructor(httpService: HttpService, sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + basicService: BasicService, + factoryService: FactoryService) { + super(basicService, factoryService, httpService, sshService); this.db = new DexieDb(); } @@ -37,9 +39,9 @@ export class SnippetService extends PersistenceService implements BaseService { getAll(): PromiseExtended { return this.db.SnippetTable - .orderBy('id') - .reverse() - .toArray(); + .orderBy('id') + .reverse() + .toArray(); } clear(): boolean { diff --git a/src/renderer/services/tools/migrate.service.ts b/src/renderer/services/tools/migrate.service.ts index a24e0bb0..bb80d46c 100644 --- a/src/renderer/services/tools/migrate.service.ts +++ b/src/renderer/services/tools/migrate.service.ts @@ -1,23 +1,25 @@ -import { Injectable } from '@angular/core'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { BaseService } from '@renderer/services/base.service'; -import { HttpService } from '@renderer/services/http.service'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { DatasourceService } from '../management/datasource.service'; -import { TableService } from '../management/table.service'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {Injectable} from '@angular/core'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {BaseService} from '@renderer/services/base.service'; +import {HttpService} from '@renderer/services/http.service'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {DatasourceService} from '../management/datasource.service'; +import {TableService} from '../management/table.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class MigrateService extends ForwardService implements BaseService { constructor(private tableService: TableService, private datasourceService: DatasourceService, + basicService: BasicService, + factoryService: FactoryService, httpService: HttpService, - sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + sshService: SshService) { + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/services/tools/track.service.ts b/src/renderer/services/tools/track.service.ts index 9a7acd0f..d77d1cae 100644 --- a/src/renderer/services/tools/track.service.ts +++ b/src/renderer/services/tools/track.service.ts @@ -1,21 +1,23 @@ -import { BaseService } from '@renderer/services/base.service'; -import { RequestModel } from '@renderer/model/request.model'; -import { ResponseModel } from '@renderer/model/response.model'; -import { HttpService } from '@renderer/services/http.service'; -import { StringUtils } from '@renderer/utils/string.utils'; -import { Injectable } from '@angular/core'; -import { DatasourceService } from '@renderer/services/management/datasource.service'; -import { SshService } from '@renderer/services/ssh.service'; -import { BasicService } from '@renderer/services/system/basic.service'; -import { ForwardService } from '@renderer/services/forward.service'; +import {BaseService} from '@renderer/services/base.service'; +import {RequestModel} from '@renderer/model/request.model'; +import {ResponseModel} from '@renderer/model/response.model'; +import {HttpService} from '@renderer/services/http.service'; +import {StringUtils} from '@renderer/utils/string.utils'; +import {Injectable} from '@angular/core'; +import {DatasourceService} from '@renderer/services/management/datasource.service'; +import {SshService} from '@renderer/services/ssh.service'; +import {BasicService} from '@renderer/services/system/basic.service'; +import {ForwardService} from '@renderer/services/forward.service'; +import {FactoryService} from "@renderer/services/factory.service"; @Injectable() export class TrackService extends ForwardService implements BaseService { constructor(private datasourceService: DatasourceService, + basicService: BasicService, + factoryService: FactoryService, httpService: HttpService, - sshService: SshService, - basicService: BasicService) { - super(httpService, sshService, basicService); + sshService: SshService) { + super(basicService, factoryService, httpService, sshService); } getResponse(request: RequestModel, sql?: string): Promise { diff --git a/src/renderer/styles.scss b/src/renderer/styles.scss index d6196641..9c509fc7 100644 --- a/src/renderer/styles.scss +++ b/src/renderer/styles.scss @@ -11,3 +11,10 @@ .table-body-flex { overflow: hidden; } + +.ant-avatar>img { + width: 85%; + height: 85%; + display: unset; + object-fit: cover; +} diff --git a/src/shared/assets/integrate/clickhouse.png b/src/shared/assets/integrate/clickhouse.png new file mode 100644 index 00000000..c3986051 Binary files /dev/null and b/src/shared/assets/integrate/clickhouse.png differ diff --git a/src/shared/assets/integrate/presto.png b/src/shared/assets/integrate/presto.png new file mode 100644 index 00000000..d9a89541 Binary files /dev/null and b/src/shared/assets/integrate/presto.png differ diff --git a/src/shared/assets/integrate/trino.png b/src/shared/assets/integrate/trino.png new file mode 100644 index 00000000..ea287325 Binary files /dev/null and b/src/shared/assets/integrate/trino.png differ