feat(site): initial scaffolding [WIP] (#1)

* feat(site): initial scaffolding

* fix(redirect): 404

* feat(CNAME): reference to tauri-apps.org

* feat(CNAME): add CNAME to build script CMD

* feat(work): various things, including patterns page

* feat(sidebar): Now scroll works

- needed to close the sidebar, because there is no docheight
- added a # to urls

* feat(slides): add landing carousel

* feat(landing): add ministories and roadmap and mermaid

* feat(links): update links, enhance mermaid

* feat(patterns): stylish page, 5 patterns, dynamic mermaid
- note: trollbridge -> api-bridge
- update mermaid

* feat(patterns):
- add multiwin pattern
- add pattern icons
- rename patterns
- add config section with dynamic markdown
- use keep-alive
- minor revisions to landing page

* feat(security): add docs/security page

* feat(patterns): add cloudish flowchart

* feat(patterns): fix infobar for mobile

* feat(quasar): update deps

* feat(examples): basic scaffolding

* feat(patterns): mosts, bests

* feat(patterns): icons

* feat(build): last manual build
This commit is contained in:
nothingismagick
2019-09-23 23:27:08 +02:00
committed by GitHub
parent 2171fa6c68
commit e9e0b5beda
199 changed files with 16516 additions and 0 deletions

1
README.md Normal file
View File

@@ -0,0 +1 @@
The online docs for Tauri

View File

@@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

View File

@@ -0,0 +1,2 @@
/dist
/src/markdown

View File

@@ -0,0 +1,55 @@
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true
},
extends: [
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
'plugin:vue/essential',
'@vue/standard'
],
// required to lint *.vue files
plugins: [
'vue'
],
globals: {
'ga': true, // Google Analytics
'cordova': true,
'__statics': true,
'process': true
},
// add your custom rules here
rules: {
// allow async-await
'generator-star-spacing': 'off',
// allow paren-less arrow functions
'arrow-parens': 'off',
'one-var': 'off',
'import/first': 'off',
'import/named': 'error',
'import/namespace': 'error',
'import/default': 'error',
'import/export': 'error',
'import/extensions': 'off',
'import/no-unresolved': 'off',
'import/no-extraneous-dependencies': 'off',
'prefer-promise-reject-errors': 'off',
// allow console.log during development only
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// allow debugger during development only
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}

20
docs-generator/.gitignore vendored Normal file
View File

@@ -0,0 +1,20 @@
.quasar
.DS_Store
.thumbs.db
node_modules
/dist
/src-cordova/node_modules
/src-cordova/platforms
/src-cordova/plugins
/src-cordova/www
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln

View File

@@ -0,0 +1,8 @@
// https://github.com/michael-ciniawsky/postcss-load-config
module.exports = {
plugins: [
// to edit target browsers: use "browserslist" field in package.json
require('autoprefixer')
]
}

35
docs-generator/.stylintrc Normal file
View File

@@ -0,0 +1,35 @@
{
"blocks": "never",
"brackets": "never",
"colons": "never",
"colors": "always",
"commaSpace": "always",
"commentSpace": "always",
"cssLiteral": "never",
"depthLimit": false,
"duplicates": true,
"efficient": "always",
"extendPref": false,
"globalDupe": true,
"indentPref": 2,
"leadingZero": "never",
"maxErrors": false,
"maxWarnings": false,
"mixed": false,
"namingConvention": false,
"namingConventionStrict": false,
"none": "never",
"noImportant": false,
"parenSpace": "never",
"placeholder": false,
"prefixVarsWithDollar": "always",
"quotePref": "single",
"semicolons": "never",
"sortOrder": false,
"stackedProperties": "never",
"trailingWhitespace": "never",
"universal": "never",
"valid": true,
"zeroUnits": "never",
"zIndexNormalize": false
}

26
docs-generator/README.md Normal file
View File

@@ -0,0 +1,26 @@
# Quasar App (docs-generator)
A Quasar Framework app
## Install the dependencies
```bash
yarn
```
### Start the app in development mode (hot-code reloading, error reporting, etc.)
```bash
quasar dev
```
### Lint the files
```bash
yarn run lint
```
### Build the app for production
```bash
quasar build
```
### Customize the configuration
See [Configuring quasar.conf.js](https://quasar.dev/quasar-cli/quasar-conf-js).

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
docs-generator/app-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@quasar/babel-preset-app'
]
}

View File

@@ -0,0 +1,44 @@
{
"name": "docs-generator",
"version": "0.0.1",
"description": "Tauri Documentation",
"productName": "Tauri Documentation",
"cordovaId": "org.cordova.quasar.app",
"author": "Daniel Thompson-Yvetot <denjell@quasar.dev>",
"private": true,
"scripts": {
"build": "quasar build && cp ./src/CNAME ./dist/spa && cp ./src/404.html ./dist/spa && cp -r ./dist/spa/. ../docs",
"lint": "eslint --ext .js,.vue src",
"lint-fix": "eslint --ext .js,.vue src --fix",
"test": "echo \"No test specified\" && exit 0"
},
"dependencies": {
"@quasar/extras": "^1.3.2",
"mermaid": "^8.3.1",
"quasar": "^1.1.4"
},
"devDependencies": {
"@quasar/app": "^1.1.2",
"@quasar/quasar-app-extension-colorize": "^1.0.0-alpha.1",
"@quasar/quasar-app-extension-icon-genie": "1.0.1",
"@quasar/quasar-app-extension-qactivity": "^1.0.0-beta.3",
"@quasar/quasar-app-extension-qmarkdown": "^1.0.0-beta.21",
"@quasar/quasar-app-extension-qmediaplayer": "^1.0.13",
"@quasar/quasar-app-extension-qpublish": "^1.0.0-alpha.7",
"@quasar/quasar-app-extension-qribbon": "^1.0.0-beta.6",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.10.0",
"eslint-loader": "^2.1.1",
"eslint-plugin-vue": "^5.0.0",
"quasar-app-extension-qautomate": "^1.0.0-alpha.5"
},
"engines": {
"node": ">= 8.9.0",
"npm": ">= 5.6.0",
"yarn": ">= 1.6.0"
},
"browserslist": [
"last 1 version, not dead, ie >= 11"
]
}

View File

@@ -0,0 +1,191 @@
// Configuration for your app
// https://quasar.dev/quasar-cli/quasar-conf-js
module.exports = function (ctx) {
return {
// app boot file (/src/boot)
// --> boot files are part of "main.js"
boot: [
'mermaid'
],
css: [
'app.styl'
],
extras: [
// 'ionicons-v4',
// 'mdi-v3',
'fontawesome-v5',
// 'eva-icons',
'themify',
// 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
'roboto-font', // optional, you are not bound to it
'material-icons' // optional, you are not bound to it
],
framework: {
// iconSet: 'ionicons-v4',
// lang: 'de', // Quasar language
// all: true, // --- includes everything; for dev only!
components: [
'QCard',
'QCardSection',
'QCardActions',
'QDialog',
'QExpansionItem',
'QLayout',
'QHeader',
'QDrawer',
'QFooter',
'QPageContainer',
'QPage',
'QToolbar',
'QToolbarTitle',
'QBtn',
'QBtnGroup',
'QIcon',
'QList',
'QItem',
'QItemSection',
'QItemLabel',
'QPageScroller',
'QScrollArea',
'QSeparator',
'QTabs',
'QTab',
'QTabPanels',
'QTabPanel',
'QPageSticky',
'QBtnDropdown',
'QChip',
'QCarousel',
'QCarouselSlide',
'QParallax',
'QRating'
],
directives: [
'Ripple', 'Scroll', 'ClosePopup'
],
// Quasar plugins
plugins: [
'Notify'
]
},
supportIE: true,
build: {
scopeHoisting: true,
vueRouterMode: 'history',
// publicPath: 'tauri',
// vueCompiler: true,
// gzip: true,
// analyze: true,
// extractCSS: false,
extendWebpack (cfg) {
cfg.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /node_modules/,
options: {
formatter: require('eslint').CLIEngine.getFormatter('stylish')
}
})
}
},
devServer: {
// https: true,
// port: 8080,
open: true // opens browser window automatically
},
// animations: 'all', // --- includes all animations
animations: [],
ssr: {
pwa: false
},
pwa: {
// workboxPluginMode: 'InjectManifest',
// workboxOptions: {}, // only for NON InjectManifest
manifest: {
// name: 'Quasar App',
// short_name: 'Quasar App',
// description: 'A Quasar Framework app',
display: 'standalone',
orientation: 'portrait',
background_color: '#ffffff',
theme_color: '#027be3',
icons: [
{
'src': 'statics/icons/icon-128x128.png',
'sizes': '128x128',
'type': 'image/png'
},
{
'src': 'statics/icons/icon-192x192.png',
'sizes': '192x192',
'type': 'image/png'
},
{
'src': 'statics/icons/icon-256x256.png',
'sizes': '256x256',
'type': 'image/png'
},
{
'src': 'statics/icons/icon-384x384.png',
'sizes': '384x384',
'type': 'image/png'
},
{
'src': 'statics/icons/icon-512x512.png',
'sizes': '512x512',
'type': 'image/png'
}
]
}
},
cordova: {
// id: 'org.cordova.quasar.app',
// noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
},
electron: {
// bundler: 'builder', // or 'packager'
extendWebpack (cfg) {
// do something with Electron main process Webpack cfg
// chainWebpack also available besides this extendWebpack
},
packager: {
// https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
// OS X / Mac App Store
// appBundleId: '',
// appCategoryType: '',
// osxSign: '',
// protocol: 'myapp://path',
// Windows only
// win32metadata: { ... }
},
builder: {
// https://www.electron.build/configuration/configuration
// appId: 'docs-generator'
}
}
}
}

View File

@@ -0,0 +1,29 @@
{
"@quasar/qmarkdown": {},
"@quasar/qribbon": {},
"@quasar/qpublish": {},
"@quasar/icon-genie": {
"minify_dev": "zopfli",
"minify_build": "zopfli",
"cordova": {
"background_color": "#000074",
"splashscreen_type": "pure"
},
"build_always": false,
"__internal": {
"dev": {
"spa": {
"iconHash": "1223e08a3a2fc40fc5fffd4fa30cb0be"
}
},
"build": {
"spa": {
"iconHash": "1223e08a3a2fc40fc5fffd4fa30cb0be"
}
}
}
},
"@quasar/colorize": {},
"@quasar/qmediaplayer": {},
"@quasar/qactivity": {}
}

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>404 Redirect</title>
<script>
sessionStorage.redirect = location.href;
</script>
<meta http-equiv="refresh" content="0;URL='/'"></meta>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,14 @@
<template>
<div id="q-app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
</style>

1
docs-generator/src/CNAME Normal file
View File

@@ -0,0 +1 @@
tauri-apps.org

View File

@@ -0,0 +1,30 @@
export function copyHeading (id) {
const text = window.location.origin + window.location.pathname + '#' + id
var textArea = document.createElement('textarea')
textArea.className = 'fixed-top'
textArea.value = text
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
document.execCommand('copy')
document.body.removeChild(textArea)
this.$q.notify({
message: 'Anchor has been copied to clipboard.',
color: 'white',
textColor: 'primary',
icon: 'done',
position: 'top',
timeout: 2000
})
}
export function slugify (str) {
return encodeURIComponent(String(str).trim().replace(/\s+/g, '-'))
}
export function makeUrl (slug) {
window.location = window.location.origin + window.location.pathname + '#' + slug
}

View File

@@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="67.407623mm"
height="62.908276mm"
viewBox="0 0 238.84591 222.90334"
id="svg3570"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="quasar-logo-full.svg">
<defs
id="defs3572" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="-39.753589"
inkscape:cy="27.706388"
inkscape:document-units="px"
inkscape:current-layer="g4895-4-4"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1056"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1" />
<metadata
id="metadata3575">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-277.71988,-312.33911)">
<g
id="g4895-4-4"
transform="translate(1419.0442,398.9018)">
<g
transform="translate(-29.620665,-4)"
id="g4579-2-20">
<g
id="g4445-2-0"
transform="translate(12.499948,7.809312)">
<g
inkscape:export-ydpi="44.860481"
inkscape:export-xdpi="44.860481"
inkscape:export-filename="/home/emanuele/Desktop/logo1.png"
transform="translate(-712.85583,-503.26814)"
id="g4561-6-7-0">
<g
transform="translate(16.233481,0)"
style="font-style:normal;font-weight:normal;font-size:50.25774765px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#263238;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="flowRoot4513-6-6-08">
<path
d="m -402.73125,631.46823 q -0.6125,0.0438 -1.3125,0.0875 -0.65625,0 -1.4,0 l -9.31875,0 q -12.81875,0 -12.81875,-8.44375 l 0,-13.475 q 0,-8.26875 12.6,-8.26875 l 9.75625,0 q 12.6,0 12.6,8.26875 l 0,13.475 q 0,5.03125 -4.4625,7.04375 l 3.10625,2.14375 q 1.35625,0.83125 1.35625,1.70625 0,0.875 -0.7,1.3125 -0.65625,0.48125 -1.88125,0.48125 -0.30625,0 -0.7875,-0.13125 -0.4375,-0.0875 -1.05,-0.48125 l -5.6875,-3.71875 z m 5.38125,-21.74375 q 0,-4.76875 -7.9625,-4.76875 l -9.58125,0 q -7.9625,0 -7.9625,4.76875 l 0,13.3875 q 0,4.94375 8.3125,4.94375 l 8.88125,0 q 8.3125,0 8.3125,-4.94375 l 0,-13.3875 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
id="path3428" />
<path
d="m -368.0585,631.64323 q -11.2875,0 -11.2875,-6.9125 l 0,-12.73125 q 0,-1.8375 2.31875,-1.8375 2.31875,0 2.31875,1.8375 l 0,12.775 q 0,3.325 6.475,3.325 l 8.3125,0 q 6.475,0 6.475,-3.325 l 0,-12.775 q 0,-1.8375 2.31875,-1.8375 2.3625,0 2.3625,1.8375 l 0,12.73125 q 0,6.9125 -11.2875,6.9125 l -8.00625,0 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
id="path3430" />
<path
d="m -327.2833,631.64323 q -9.3625,0 -9.3625,-5.81875 l 0,-2.49375 q 0,-5.775 9.3625,-5.775 l 18.59375,0 0,-0.65625 q 0,-3.0625 -5.38125,-3.0625 l -6.16875,0 q -2.1875,0 -2.1875,-1.70625 0,-1.75 2.1875,-1.75 l 6.16875,0 q 9.93125,0 9.93125,6.51875 l 0,8.575 q 0,6.16875 -9.5375,6.16875 l -13.60625,0 z m 13.34375,-3.4125 q 5.25,0 5.25,-2.8875 l 0,-4.76875 -18.24375,0 q -5.11875,0 -5.11875,2.66875 l 0,2.275 q 0,2.7125 5.11875,2.7125 l 12.99375,0 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
id="path3432" />
<path
d="m -262.77031,626.74323 q 0,4.9 -9.975,4.9 l -17.0625,0 q -2.1875,0 -2.1875,-1.70625 0,-1.70625 2.1875,-1.70625 l 17.0625,0 q 5.38125,0 5.38125,-1.4875 l 0,-2.45 q 0,-1.4875 -5.38125,-1.4875 l -9.0125,0 q -9.975,0 -9.975,-4.76875 l 0,-2.05625 q 0,-5.6 10.28125,-5.6 l 5.99375,0 q 2.23125,0 2.23125,1.75 0,0.875 -0.6125,1.3125 -0.56875,0.39375 -1.61875,0.39375 l -5.99375,0 q -5.73125,0 -5.73125,2.14375 l 0,1.925 q 0,1.79375 5.6875,1.79375 l 9.0125,0 q 9.7125,0 9.7125,4.4625 l 0,2.58125 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
id="path3434" />
<path
d="m -241.91709,631.64323 q -9.3625,0 -9.3625,-5.81875 l 0,-2.49375 q 0,-5.775 9.3625,-5.775 l 18.59375,0 0,-0.65625 q 0,-3.0625 -5.38125,-3.0625 l -6.16875,0 q -2.1875,0 -2.1875,-1.70625 0,-1.75 2.1875,-1.75 l 6.16875,0 q 9.93125,0 9.93125,6.51875 l 0,8.575 q 0,6.16875 -9.5375,6.16875 l -13.60625,0 z m 13.34375,-3.4125 q 5.25,0 5.25,-2.8875 l 0,-4.76875 -18.24375,0 q -5.11875,0 -5.11875,2.66875 l 0,2.275 q 0,2.7125 5.11875,2.7125 l 12.99375,0 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
id="path3436" />
<path
d="m -205.62285,617.33698 q 0,-6.95625 11.2875,-6.95625 l 3.36875,0 q 2.23125,0 2.23125,1.79375 0,1.79375 -2.23125,1.79375 l -3.54375,0 q -6.475,0 -6.475,3.28125 l 0,12.775 q 0,1.8375 -2.31875,1.8375 -2.31875,0 -2.31875,-1.8375 l 0,-12.6875 z"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:43.75px;font-family:'Neuropol X';-inkscape-font-specification:'Neuropol X';text-align:start;letter-spacing:5px;word-spacing:0px;text-anchor:start;fill:#263238;fill-opacity:1"
id="path3438" />
</g>
</g>
</g>
</g>
<g
id="g5443-0-1-5-1-9"
transform="matrix(0.55595317,0,0,0.55595317,-521.93484,-328.66104)"
inkscape:export-filename="/home/emanuele/Desktop/logo1.png"
inkscape:export-xdpi="44.860481"
inkscape:export-ydpi="44.860481">
<g
inkscape:export-ydpi="3.4165223"
inkscape:export-xdpi="3.4165223"
transform="matrix(0.09527033,0,0,0.09527033,-1695.2716,706.62921)"
id="g8856-6-1-1-9-0-1-9">
<circle
r="1485"
cy="-1361.2571"
cx="8317.3574"
id="circle8858-1-3-7-6-5-3-0"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:50;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
inkscape:export-xdpi="10.031387"
inkscape:export-ydpi="10.031387" />
<path
inkscape:export-ydpi="10.031387"
inkscape:export-xdpi="10.031387"
style="opacity:1;fill:#263238;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:square;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 8560.3823,-1361.3029 a 242.947,242.947 0 0 1 -242.947,242.948 242.947,242.947 0 0 1 -242.947,-242.948 242.947,242.947 0 0 1 242.947,-242.946 242.947,242.947 0 0 1 242.947,242.946 z"
id="path8860-5-4-8-2-9-0-9"
inkscape:connector-curvature="0" />
<path
id="path8862-5-5-9-1-3-6-3"
d="m 9395.8755,-1984.028 a 1245.372,1245.372 0 0 0 -190.8415,-249.4971 l -280.8618,162.1556 c -87.542,-74.7796 -187.0349,-132.0588 -293.2407,-169.9527 -95.8868,97.1766 -172.0602,205.7604 -226.9672,323.8487 312.6411,-21.2772 635.5313,91.8725 935.2898,326.0721 l 176.7612,-102.0532 a 1245.372,1245.372 0 0 0 -120.1398,-290.5734 z"
clip-path="none"
mask="none"
style="fill:#1976d2;fill-opacity:1"
inkscape:connector-curvature="0"
inkscape:transform-center-x="-514.04855"
inkscape:transform-center-y="-444.04649" />
<path
inkscape:transform-center-y="265.80217"
inkscape:transform-center-x="-689.63727"
inkscape:connector-curvature="0"
style="fill:#42a5f5;fill-opacity:1"
mask="none"
clip-path="none"
d="m 9395.9474,-738.70387 a 1245.372,1245.372 0 0 0 120.6501,-290.02213 l -280.8618,-162.1557 c 20.99,-113.2034 20.8488,-228.0063 0.563,-338.9302 -132.1008,-34.4521 -264.2238,-46.1283 -393.9448,-34.635 174.7471,260.1165 238.2017,596.32248 185.2582,973.02076 l 176.7612,102.05309 a 1245.372,1245.372 0 0 0 191.5741,-249.33082 z"
id="path8864-4-8-1-2-4-4-4" />
<path
id="path8866-7-5-5-0-6-4-7"
d="m 8317.501,-115.97954 a 1245.372,1245.372 0 0 0 311.4916,-40.52501 l 0,-324.31131 c 108.5321,-38.42382 207.8837,-95.94755 293.8037,-168.97752 -36.214,-131.6287 -92.1636,-251.88868 -166.9776,-358.48372 -137.894,281.39369 -397.3296,504.44998 -750.0316,646.9487 l 0,204.10623 a 1245.372,1245.372 0 0 0 311.7139,41.24263 z"
clip-path="none"
mask="none"
style="fill:#1976d2;fill-opacity:1"
inkscape:connector-curvature="0"
inkscape:transform-center-x="-117.49007"
inkscape:transform-center-y="639.34029" />
<path
inkscape:transform-center-y="444.04652"
inkscape:transform-center-x="514.04857"
inkscape:connector-curvature="0"
style="fill:#42a5f5;fill-opacity:1"
mask="none"
clip-path="none"
d="m 7238.9827,-738.57936 a 1245.372,1245.372 0 0 0 190.8415,249.49714 l 280.8618,-162.15566 c 87.5421,74.77965 187.0349,132.05879 293.2407,169.95271 95.8868,-97.17659 172.0602,-205.76036 226.9672,-323.8487 -312.6411,21.27714 -635.5313,-91.87254 -935.2898,-326.07203 l -176.7612,102.0531 a 1245.372,1245.372 0 0 0 120.1398,290.57344 z"
id="path8868-6-7-4-7-2-7-3" />
<path
id="path8870-5-3-9-3-5-5-1"
d="m 7238.9108,-1983.9035 a 1245.372,1245.372 0 0 0 -120.6501,290.0221 l 280.8618,162.1557 c -20.99,113.2035 -20.8488,228.0063 -0.563,338.9302 132.1008,34.4521 264.2238,46.1283 393.9448,34.635 -174.7471,-260.1165 -238.2017,-596.3225 -185.2582,-973.0207 l -176.7612,-102.0532 a 1245.372,1245.372 0 0 0 -191.5741,249.3309 z"
clip-path="none"
mask="none"
style="fill:#1976d2;fill-opacity:1"
inkscape:connector-curvature="0"
inkscape:transform-center-x="689.63729"
inkscape:transform-center-y="-265.80221" />
<path
inkscape:transform-center-y="-639.34032"
inkscape:transform-center-x="117.49005"
inkscape:connector-curvature="0"
style="fill:#42a5f5;fill-opacity:1"
mask="none"
clip-path="none"
d="m 8317.3572,-2606.6279 a 1245.372,1245.372 0 0 0 -311.4915,40.525 l -1e-4,324.3113 c -108.5321,38.4239 -207.8837,95.9476 -293.8037,168.9776 36.214,131.6287 92.1637,251.8886 166.9776,358.4837 137.894,-281.3937 397.3296,-504.45 750.0316,-646.9487 l 1e-4,-204.1063 a 1245.372,1245.372 0 0 0 -311.714,-41.2426 z"
id="path8872-6-3-2-1-3-3-7" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

View File

@@ -0,0 +1,20 @@
import * as mermaid from 'mermaid'
mermaid.initialize({
startOnLoad: true,
logLevel: 'debug',
theme: 'neutral',
fontFamily: '"Roboto"',
securityLevel: 'loose',
flowchart: {
useMaxWidth: true,
htmlLabels: true,
curve: 'basis'
}
})
export default ({ Vue }) => {
Vue.prototype.$mermaid = mermaid
}
export { mermaid }

View File

View File

@@ -0,0 +1,124 @@
<template>
<section :id="slugifiedTitle" class="q-pa-md overflow-auto">
<q-card flat bordered class="no-shadow">
<q-toolbar>
<q-ribbon
position="left"
color="rgba(0,0,0,.58)"
background-color="#c0c0c0"
leaf-color="#a0a0a0"
leaf-position="bottom"
decoration="rounded-out"
>
<q-toolbar-title
class="example-title"
style="padding: 5px 20px;"
@click="copyHeading(slugifiedTitle)"><span class="ellipsis">{{ title }}</span></q-toolbar-title>
</q-ribbon>
</q-toolbar>
<q-separator v-if="this.$slots.default" />
<q-card-section v-if="this.$slots.default">
<slot></slot>
</q-card-section>
<q-separator />
<q-expansion-item
group="someGroup"
caption="Code"
>
<q-card>
<q-tabs
v-model="tab"
dense
class="text-grey"
active-color="primary"
indicator-color="primary"
align="left"
narrow-indicator
>
<q-tab name="template" v-if="parts.template" label="Template" />
<q-tab name="script" v-if="parts.script" label="Script" />
<q-tab name="style" v-if="parts.style" label="Style" />
</q-tabs>
<q-separator />
<q-tab-panels v-model="tab" animated>
<q-tab-panel v-if="parts.template" name="template">
<q-markdown :src="parts.template" />
</q-tab-panel>
<q-tab-panel v-if="parts.script" name="script">
<q-markdown :src="parts.script" />
</q-tab-panel>
<q-tab-panel v-if="parts.style" name="style">
<q-markdown :src="parts.style" />
</q-tab-panel>
</q-tab-panels>
</q-card>
</q-expansion-item>
<q-separator />
<component v-bind:is="name" style="overflow: hidden;" />
</q-card>
</section>
</template>
<script>
import { copyHeading, slugify } from 'assets/page-utils'
export default {
name: 'ExampleCard',
components: {
TauriBasic: () => import('../examples/TauriBasic'),
TauriAdvanced: () => import('../examples/TauriAdvanced')
},
props: {
title: {
type: String,
required: true
},
name: {
type: String,
required: true
},
tagParts: {
type: Object,
default: () => {}
}
},
data () {
return {
tab: 'template',
parts: {}
}
},
mounted () {
this.updateParts()
},
computed: {
slugifiedTitle () {
return slugify(this.title)
}
},
methods: {
copyHeading,
updateParts () {
this.parts = {}
Object.keys(this.tagParts).forEach(key => {
if (this.tagParts[key] !== '') {
this.parts[key] = '```\n' + this.tagParts[key] + '\n```'
}
})
}
}
}
</script>

View File

@@ -0,0 +1,28 @@
<template>
<h1 :id="slugifiedTitle" class="q-markdown--heading-h1 q-markdown--title-heavy example-title" @click="copyHeading(slugifiedTitle)">{{ title }}</h1>
</template>
<script>
import { copyHeading, slugify } from 'assets/page-utils'
export default {
name: 'ExampleTitle',
props: {
title: {
type: String,
required: true
}
},
computed: {
slugifiedTitle () {
return slugify(this.title)
}
},
methods: {
copyHeading
}
}
</script>

View File

@@ -0,0 +1,164 @@
<template>
<div class="full-width q-pa-md">
<q-page-sticky expand class="page-header fixed-top shadow-8 scroll-determined" v-scroll="scrolled" style="position:fixed!important">
<q-chip outline dense square icon="star" icon-right="star" class="claim text-weight-light text-black bg-cyan-1 shadow-8" style="top: 84%">Build more secure native apps with fast, tiny binaries.</q-chip>
<div class="bg-container scroll-determined q-pa-md q-ml-lg"></div>
<div>
<router-link to="/">
<img src="statics/tauri-wordmark.png" class="tauri-name scroll-determined" style="cursor:pointer">
</router-link>
<div v-if="buttons" class="row" style="margin-top:90px">
<q-btn dense size="small" to="/docs/quickstart" class="btn" label="Quick Start" no-caps color="yellow-2" text-color="black"/>
<q-btn dense size="small" to="/docs/patterns" class="btn" label="Patterns" no-caps color="yellow-2" text-color="black"/>
<q-btn v-if="showDocs" dense size="small" to="/docs" class="btn" label="Docs" no-caps color="yellow-2" text-color="black"/>
</div>
<div v-else class="absolute-right" style="margin:18px 35px 0 0;">
<q-btn-dropdown dense color="yellow-2" :label="current" no-caps text-color="black" class="q-mr-lg">
<q-list color="yellow-2" >
<q-item clickable v-close-popup to="/docs" v-if="showDocs" @click="current='Docs'">
<q-item-section>
<q-item-label>Docs</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup to="/docs/quickstart">
<q-item-section>
<q-item-label>Quick Start</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup to="/docs/patterns">
<q-item-section>
<q-item-label>Patterns</q-item-label>
</q-item-section>
</q-item>
<q-item clickable v-close-popup to="/docs/environment">
<q-item-section>
<q-item-label>Environment</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div>
</div>
</q-page-sticky>
<main class="flex flex-start justify-center">
<div class="q-pa-sm col-12-sm col-10-md col-8-lg" style="max-width: 1024px; width: 100%;">
<slot></slot>
</div>
</main>
</div>
</template>
<script>
export default {
name: 'Hero',
data () {
return {
buttons: true,
current: 'Menu',
height: 270,
heightName: 140,
heightPic: 250,
heightClaim: 100,
rightDrawerOpen: this.$q.platform.is.desktop
}
},
mounted () {
// this.scrolled(document.offset().top)
},
computed: {
showDocs () {
const { showDocslink } = this.$route.meta
return typeof showDocslink === 'undefined' || showDocslink
}
},
methods: {
scrolled (position) {
const pos = position / 4
this.height = 270 - (pos)
this.heightName = 140 - (pos)
this.heightPic = 250 - (pos)
this.heightClaim = 220 - (pos)
// todo: cleanup, use vuex, be faster!
// the buttons
if (pos >= 50 && this.buttons !== false) {
this.buttons = false
document.getElementsByClassName('scroll-determined')[0].setAttribute('style', `height: 70px`)
// the icon
document.getElementsByClassName('scroll-determined')[1].setAttribute('style', `height: 55px;width: 55px;transform: rotate(${position}deg)`)
// the name
document.getElementsByClassName('tauri-name')[0].setAttribute('style', `
height: 35px;
`)
// claim
// document.getElementById('claim').setAttribute('style', `top: 58px`)
// the sidebar id="scrollHolder" style="height:50%"
document.getElementsByClassName('q-drawer__content')[0].setAttribute('style', `background-color: #FDFADE;margin-top: 60px;padding-top:20px`)
document.getElementById('scrollHolder').setAttribute('style', `height: calc(100% - 132px)`)
document.getElementById('padding').setAttribute('style', `height: 40px`)
} else if (this.buttons === false) {
document.getElementsByClassName('scroll-determined')[1].setAttribute('style', `height: 55px;width: 55px;transform: rotate(${position}deg)`)
} else {
document.getElementsByClassName('scroll-determined')[1].setAttribute('style', `transform: rotate(${position}deg)`)
}
/*
document.getElementsByClassName('scroll-determined')[0].setAttribute('style', `height: ${this.height}px`)
// the icon
document.getElementsByClassName('scroll-determined')[1].setAttribute('style', `height: ${this.heightPic - 5}px;width: ${this.heightPic}px;transform: rotate(${position}deg)`)
// the name
document.getElementsByClassName('tauri-name')[0].setAttribute('style', `
height: ${this.heightName}px;
`)
// claim
document.getElementById('claim').setAttribute('style', `top: ${this.heightClaim}px`)
// the sidebar
document.getElementsByClassName('q-drawer__content')[0].setAttribute('style', `margin-top: ${this.height + 10}px`)
*/
}
}
}
</script>
<style lang="stylus">
.q-menu
z-index 1000000
.tauri-name
max-height 100px
min-height 20px
max-width 50%
height inherit
position fixed
margin auto
top 15px
left 0
right 0
.page-header
height 270px
z-index 1000000
border-bottom 2px solid #212111
.bg-container
background-image url(/statics/thetaTauri_logo.png)
background-repeat no-repeat
background-size contain
position absolute
left -5px
top 5px
height 250px
width 250px
max-height 250px
max-width 250px
min-height 60px
min-width 60px
.claim
position absolute
margin 0 auto
left 20px
right 20px
width 330px
text-align center
color darkred
i
color #0099dd
text-shadow 0 0 1px rebeccapurple
</style>

View File

@@ -0,0 +1,266 @@
// app global css
// Tauri color scheme
// background: #231F20
// highlight: #FFFCDF
// text: #283238
$fgColor ?= #263239
$bgColor ?= #263239
h2, h3, h4
padding-top 50px!important
.qribbon__container
position relative
.qribbon__horizontal--left
position unset !important
padding unset !important
margin-left -22px !important
z-index 1 !important
&:before
margin-left -22px
.example-title
cursor pointer
&:after
content ' #'
opacity 0
&:hover:after
opacity 1
.example-page
padding 16px 46px
font-weight 300
max-width 900px
margin-left auto
margin-right auto
body
padding 0
margin 0
/* font-family "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif */
/* font-size 16px */
line-height 1.5
background-color #FFFDFA
color #606c71
a
color #1e6bb8
text-decoration none
&:hover
text-decoration underline
.btn
display inline-block
margin-bottom 1rem
color rgba(255, 255, 255, 0.7)
background-color rgba(255, 255, 255, 0.08)
border-color rgba(255, 255, 255, 0.2)
border-style solid
border-width 1px
border-radius 0.3rem
transition color 0.2s, background-color 0.2s, border-color 0.2s
&:hover
color rgba(255, 255, 255, 0.8)
text-decoration none
background-color rgba(255, 255, 255, 0.2)
border-color rgba(255, 255, 255, 0.3)
.btn + .btn
margin-left 1rem
.page-header
color #fff
text-align center
background-color $bgColor
background-image linear-gradient(120deg, $bgColor, $fgColor)
@media screen and (min-width 64em)
.page-header
padding 2rem 1rem 1rem 1rem
@media screen and (min-width 42em) and (max-width 64em)
.page-header
padding 2rem 1rem 1rem 1rem
@media screen and (max-width 42em)
.page-header
padding 2rem 1rem 1rem 1rem
.project-name
font-weight 700
margin-top 0
margin-bottom 0.1rem
@media screen and (min-width 64em)
.project-name
font-size 3.25rem
@media screen and (min-width 42em) and (max-width 64em)
.project-name
font-size 2.25rem
@media screen and (max-width 42em)
.project-name
font-size 1.75rem
.project-tagline
margin-bottom 2rem
font-weight normal
opacity 0.7
@media screen and (min-width 64em)
.project-tagline
font-size 1.25rem
@media screen and (min-width 42em) and (max-width 64em)
.project-tagline
font-size 1.15rem
@media screen and (max-width 42em)
.project-tagline
font-size 1rem
.main-content :first-child
margin-top 0
.main-content img
max-width 100%
.main-content h1, .main-content h2, .main-content h3, .main-content h4, .main-content h5, .main-content h6
margin-top 2rem
margin-bottom 1rem
font-weight normal
color $fgColor
.main-content p
margin-bottom 1em
.main-content code
padding 2px 4px
font-family Consolas, "Liberation Mono", Menlo, Courier, monospace
font-size 0.9rem
color #383e41
background-color #f3f6fa
border-radius 0.3rem
.main-content pre
padding 0.8rem
margin-top 0
margin-bottom 1rem
font 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace
color #567482
word-wrap normal
background-color #f3f6fa
border solid 1px #dce6f0
border-radius 0.3rem
.main-content pre > code
padding 0
margin 0
font-size 0.9rem
color #567482
word-break normal
white-space pre
background transparent
border 0
.main-content .highlight
margin-bottom 1rem
.main-content .highlight pre
margin-bottom 0
word-break normal
.main-content .highlight pre, .main-content pre
padding 0.8rem
overflow auto
font-size 0.9rem
line-height 1.45
border-radius 0.3rem
.main-content pre code, .main-content pre tt
display inline
max-width initial
padding 0
margin 0
overflow initial
line-height inherit
word-wrap normal
background-color transparent
border 0
.main-content pre code:before, .main-content pre code:after, .main-content pre tt:before, .main-content pre tt:after
content normal
.main-content ul, .main-content ol
margin-top 0
.main-content blockquote
padding 0 1rem
margin-left 0
color #819198
border-left 0.3rem solid #dce6f0
.main-content blockquote > :first-child
margin-top 0
.main-content blockquote > :last-child
margin-bottom 0
.main-content table
display block
width 100%
overflow auto
word-break normal
word-break keep-all
.main-content table th
font-weight bold
.main-content table th, .main-content table td
padding 0.5rem 1rem
border 1px solid #e9ebec
.main-content dl
padding 0
.main-content dl dt
padding 0
margin-top 1rem
font-size 1rem
font-weight bold
.main-content dl dd
padding 0
margin-bottom 1rem
.main-content hr
height 2px
padding 0
margin 1rem 0
background-color #eff0f1
border 0
@media screen and (min-width 64em)
.main-content
max-width 64rem
padding 2rem 6rem
margin 0 auto
font-size 1.1rem
@media screen and (min-width 42em) and (max-width 64em)
.main-content
padding 2rem 4rem
font-size 1.1rem
@media screen and (max-width 42em)
.main-content
padding 2rem 1rem
font-size 1rem
.site-footer
padding-top 2rem
margin-top 2rem
border-top solid 1px #eff0f1
.site-footer-owner
display block
font-weight bold
.site-footer-credits
color #819198
@media screen and (min-width 64em)
.site-footer
font-size 1rem
@media screen and (min-width 42em) and (max-width 64em)
.site-footer
font-size 1rem
@media screen and (max-width 42em)
.site-footer
font-size 0.9rem

View File

@@ -0,0 +1,19 @@
// Quasar Stylus Variables
// --------------------------------------------------
// To customize the look and feel of this app, you can override
// the Stylus variables found in Quasar's source Stylus files.
// Check documentation for full list of Quasar variables
// It's highly recommended to change the default colors
// to match your app's branding.
// Tip: Use the "Theme Builder" on Quasar's documentation website.
$primary = #027BE3
$secondary = #26A69A
$accent = #9C27B0
$positive = #21BA45
$negative = #C10015
$info = #31CCEC
$warning = #d1bb37

View File

View File

@@ -0,0 +1,23 @@
<template>
<div class="q-pa-md">
<p>You can put any regular Vue code (SFC) into one of these files.</p>
<p>It will be displayed as an example.</p>
<p>template, script, and css will be separated out into 3 parts and each will have a tab.</p>
</div>
</template>
<script>
export default {
data () {
return {
var1: 10,
var2: 'string'
}
}
}
</script>
<style lang="stylus">
.my-class
background-color black
</style>

View File

@@ -0,0 +1,22 @@
<template>
<div class="q-pa-md">
<p>You can put any regular Vue code (SFC) into one of these files.</p>
<p>It will be displayed as an example.</p>
</div>
</template>
<script>
export default {
data () {
return {
var1: 10,
var2: 'string'
}
}
}
</script>
<style lang="stylus">
.my-class
background-color black
</style>

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<title><%= htmlWebpackPlugin.options.productName %></title>
<meta charset="utf-8">
<title>Tauri Apps</title>
<meta name="title" content="Tauri Apps - Make smaller, faster more secure native apps">
<meta name="og:title" content="Tauri Apps - Make smaller, faster more secure native apps">
<meta name="twitter:title" content="Tauri Apps - Make smaller, faster more secure native apps">
<meta name="description" content="Tauri is a toolchain for building highly secure native apps that have tiny binaries and are very fast. Whether coming from the front-end with Angular, React or Vue - or building Rust-native solutions, Tauri solves the hard problems of safe User Interfaces.">
<meta name="og:description" content="Tauri is a toolchain for building highly secure native apps that have tiny binaries and are very fast. Whether coming from the front-end with Angular, React or Vue - or building Rust-native solutions, Tauri solves the hard problems of safe User Interfaces." >
<meta name="twitter:description" content="Tauri is a toolchain for building highly secure native apps that have tiny binaries and are very fast. Whether coming from the front-end with Angular, React or Vue - or building Rust-native solutions, Tauri solves the hard problems of safe User Interfaces.">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@tauriapps">
<meta property="og:type" content="article">
<meta property="og:image" content="https://tauri-apps.org/statics/thetaTauri-logo.png">
<meta property="og:site_name" content="Tauri Apps">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (htmlWebpackPlugin.options.ctx.mode.cordova) { %>, viewport-fit=cover<% } %>">
<link rel="icon" type="image/png" href="statics/app-logo-128x128.png">
<link rel="icon" type="image/png" sizes="16x16" href="statics/icons/favicon-16x16.png">
<link rel="icon" type="image/png" sizes="32x32" href="statics/icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="statics/icons/favicon-96x96.png">
<link rel="icon" type="image/ico" href="statics/icons/favicon.ico">
</head>
<body style="background-repeat:repeat-x;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAASLCAIAAADbE0BzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAVUlEQVRYhe3NIQ6AQBBD0Zl2ViC4Bh7J/R0h3AaPIJBsAhrzxTO/ojHNiyICF4/DoYiIfVtVVaoq2X601mSra7aVmbItScrMztvX3b92AAAAAACAH5wLVw2ltqAZ/QAAAABJRU5ErkJggg==)">
<!-- DO NOT touch the following DIV -->
<div id="q-app"></div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,143 @@
<template>
<q-layout view="hHh lpR ffr">
<q-btn
flat
dense
round
@click="rightDrawerOpen = !rightDrawerOpen"
aria-label="Menu"
color="cyan-1"
class="fixed-right"
style="margin:16px 12px 0 0;z-index:1000001"
>
<q-icon name="menu" />
</q-btn>
<q-drawer
ref="drawer"
v-model="rightDrawerOpen"
side="right"
bordered
behavior="mobile"
content-style="background-color: #FDFADE;margin-top: 260px;padding-top:30px;"
>
<q-scroll-area
id="scrollHolder"
style="height:calc(100% - 320px)"
:thumb-style="{ right: '3px', borderRadius: '2px', background: '#ffaa00', width: '6px', opacity: 0.5 }"
>
<q-list dense>
<q-item
v-for="item in toc"
:key="item.id"
clickable
v-ripple
dense
@click="scrollTo(item.id)"
:active="activeToc === item.id"
>
<!--<q-item-section v-if="item.level > 1" side> </q-item-section>-->
<q-item-section
:class="`toc-item toc-level-${item.level}`"
>{{ item.label }}</q-item-section>
</q-item>
</q-list>
</q-scroll-area>
<div class="absolute-bottom full-width text-center bg-cyan-1">
<q-separator></q-separator>
<div class="q-pa-sm" style="font-size:0.9em">
Tauri is an Open Source Project<br/>
<a href="https://github.com/tauri-apps/tauri" target="_blank" rel="noreferrer">GitHub</a>
&nbsp;||&nbsp;
<a href="https://opencollective.com/tauri" target="_blank" rel="noreferrer">Donate</a>
&nbsp;||&nbsp;
<router-link to="/governance-and-guidance">Governance</router-link>
</div>
</div>
</q-drawer>
<q-page-container>
<keep-alive include="Patterns">
<router-view />
</keep-alive>
</q-page-container>
<div class="full-width text-center bg-cyan-1">
<q-separator></q-separator>
<div class="row q-pa-sm" style="font-size:0.9em">
<div class="col-6 col-md-4 col-sm-3" dense>
<q-item to="/contact" class="text-center" dense>Email</q-item>
<q-item to="/contact" class="text-center" dense>Discord</q-item>
<q-item to="/contact" class="text-center" dense>Twitter</q-item>
<q-item to="/contact" class="text-center" dense>Medium</q-item>
<q-item to="/contact" class="text-center" dense>Dev.to</q-item>
<q-item to="/contact" class="text-center" dense>Github</q-item>
</div>
</div>
</div>
</q-layout>
</template>
<script>
import { mapGetters } from 'vuex'
import { scroll } from 'quasar'
const { getScrollTarget, setScrollPosition } = scroll
import { slugify, makeUrl } from 'assets/page-utils'
export default {
name: 'MainLayout',
data () {
return {
rightDrawerOpen: false,
activeToc: 0
}
},
computed: {
...mapGetters({
toc: 'common/toc'
})
},
mounted () {
// code to handle anchor link on refresh/new page, etc
if (location.hash !== '') {
const id = location.hash.substring(1, location.hash.length)
this.scrollTo(id)
}
},
methods: {
scrollTo (id) {
this.$refs.drawer.hide()
this.activeToc = id
const el = document.getElementById(id)
if (el) {
setTimeout(() => {
this.scrollPage(el)
makeUrl(slugify(id))
}, 200)
}
},
scrollPage (el) {
const target = getScrollTarget(el)
const current = window.pageYOffset || document.documentElement.scrollTop
let offset = el.offsetTop - 50
if (current <= 50) offset = el.offsetTop - 250
setScrollPosition(target, offset, 500)
}
}
}
</script>
<style lang="stylus">
h2
margin-left -10px!important
.toc-level
&-2
margin-left 0
font-weight 800
&-3
margin-left 10px
</style>

View File

@@ -0,0 +1,53 @@
<template>
<q-layout view="lHh Lpr lFf">
<q-header elevated class="glossy">
<q-toolbar>
<q-btn
flat
dense
round
@click="leftDrawerOpen = !leftDrawerOpen"
aria-label="Menu"
>
<q-icon name="menu"></q-icon>
</q-btn>
<q-toolbar-title v-if="$q.screen.width > 500">
Tauri <!-- <span class="text-subtitle2">v{{ version }}</span> -->
</q-toolbar-title>
<div>Quasar v{{ $q.version }}</div>
</q-toolbar>
</q-header>
<q-drawer
v-model="leftDrawerOpen"
bordered
content-class="bg-grey-2"
>
<!-- QScrollArea is optional -->
<q-scroll-area class="fit q-pa-sm">
<!-- Content here -->
</q-scroll-area>
</q-drawer>
<q-page-container>
<!-- This is where pages get injected -->
<router-view />
</q-page-container>
</q-layout>
</template>
<script>
export default {
// name: 'LayoutName',
data () {
return {
leftDrawer: true
}
}
}
</script>

View File

@@ -0,0 +1,17 @@
## Consumption Paradigms
Its not about optimizing for the individual developer, but for the team. Tauri is not opinionated about what framework your web-interface is built with, and offers you easily configurable options.
This combination of power, safety and usability are why we chose Rust to be the default binding for Tauri. It is our intention to provide the most safe and performant native app experience (for devs and app consumers), out of the box.
To this end, we have spent a great deal of time creating an especially secure localhost-free backend for the security conscious application-artisans. This means that your app does not use a localhost server, as is generally the case with cordova apps. This also has the positive side effect, that less code is needed and the final binaries are smaller.
### For new projects
If you are making a greenfield project, you can literally choose anything that compiles to JS (soon WASM will also be supported).
### For existing projects
While it may seem at first glance complex, the fact that Tauri is framework agnostic and polyglot makes it very flexible. Chances are good that you already have a working legacy (or not so legacy) system that just doesn't warrant a completely new architecting - so you shouldn't have to retool in order to
::: tip
This means that legacy systems can be relatively trivially given a [brownfield development](https://en.wikipedia.org/wiki/Brownfield_(software_development)) treatment. :star:
:::

View File

@@ -0,0 +1,17 @@
The Tauri API
```
whitelist: { // all whitelist values are default:false
all: false, // use this flag to enable all API features
answer: false, // enable rust to direct the UI
bridge: false, // enable Quasar Bridge
event: false, // enable binding to message
execute: false, // enable application execution
listFiles: false, // list files in a directory
open: false, // open link in a browser
readBinaryFile: false, // read binary file from local filesystem
readTextFile: false, // read text file from local filesystem
setTitle: false, // set the window title
writeFile: false // write file to local filesystem
},
```

View File

@@ -0,0 +1,7 @@
## examples
```js
return {
stuff: 'wow'
}
```

View File

@@ -0,0 +1,33 @@
## Sustainability
One of the main goals of the organizational structure of Tauri is to guarantee the sustainability of Tauri and the health and well-being of its contributors. The world of Open Source is fraught with peril and discord, and we have taken measures to ensure the longevity of Tauri. This document explains how we go about doing so.
### Organizational Structure
Tauri apps is governed by the community and work is done in the context of public working groups. Each working group has a dedicated channel on the Discord server as well as a Team on GitHub. Other than that, each WG is free to use whatever type of organizational model it chooses.
The current working groups are:
- WG Governance & Guidance
- WG Tech
- WG Education
- WG Media
- WG Security
With the exception of the security working group, which is by invite only and convenes privately, all other working groups are public and open to any and all participants.
Please visit [this repository](https://github.com/tauri-apps/governance-and-guidance) to get more information.
### Code of Conduct
Everyone participating in the Tauri commnunity is expected to follow a code of conduct that you can at the [Governance and Guidance:Code of Conduct](https://github.com/tauri-apps/governance-and-guidance/blob/master/CODE_OF_CONDUCT.md).
### Social Contract
We have a Social Contract that informs our decision making and organization. You can read about it here: [Governance and Guidance:Social Contract](https://github.com/tauri-apps/governance-and-guidance/blob/master/SOCIAL_CONTRACT.md).
### Licensing
We, the contributors to Tauri Apps, use the MIT and Apache licenses for all code content. Images and bodies of text, unless otherwise noted are CC-BY-ND-NC.
### Trademark
It is a permissible use of the name "Tauri App" or the Tauri logo to show that a project uses Tauri. Any language that gives the impression that the Tauri Apps organization approves, authorizes or otherwise supports a project, person or company is not permissible without written authorization from the Guidance and Governance Working Group.
### Sourcecred
We use sourcecred for tracking contributions, and once we have enough funding to cover our operational costs, we will use it to distribute funds fairly amongst contributors.
You can have a look here: https://sourcecred.teamopen.dev/prototype/tauri-apps

View File

@@ -0,0 +1,4 @@
## Donations and Sponsoring
>At the moment the best way to support the development of Tauri is to visit our [Open Collective](https://opencollective.com/tauri) page and make a donation. Funds go first and foremost to covering the overhead of the project, additional funds will be distributed to all contributors using a sourcecred-based system. Thanks for consideration! :heart:
If you are interested in sponsoring Tauri and want to accelerate the development of specific components, we encourage you to reach out to the team.

View File

@@ -0,0 +1,73 @@
# Introduction
There are many ways to use Tauri, and on this page we have collected 4 major patterns.
## Cloudish
The Cloudish recipe is a pattern for maximum flexibility and app performance.
### Features
- ships with a rust-based localhost server
- works out of the box
- can utilize CSP for extra security
### Best When
- starting out building Tauri apps if you have never used Rust before.
### Pros
- easy to use
- best WebAPI compliance
### Cons:
- hard to secure against Man in the Machine attacks
- gives you an easy excuse not to learn Rust
## Trollbridge
The Trollbridge recipe is a pattern for the highest degree of operational security.
### Features
- render UI securely at bootstrap
- promise based message passing
- RW access to filesystem
- STDOUT access to other binaries
- extensible with Rust functions
- whitelist for functional codegen
- runtime message salting
- fASLR & AoT Compiling
### Best When
- you are paranoid about security but still need the power of Rust.
### Pros
- highly configurable and infinitely extensible
### Cons
- rust skills virtually required
## Cloudbridge
The Cloudbridge combines the flexibility of a localhost and the security of the bridge.
### Features
- all bridge features
- all localhost features
### Best When
- your project is complex and you need all the power available.
### Pros
- best of both worlds
### Cons
- rust skills helpful
- complexity can make it challenging to keep your application from becoming bloated
## Hermit
The Hermit recipe is a pattern for ultimate application isolation where all logic is self-contained.
### Features
- render UI securely at bootstrap
- no communication with Rust
- CSP blocks all external resources
- fASLR & AoT Compiling
### Best When
- you want to limit interaction with anything outside of the scope of the user interface like for a game.
### Pros
- safest possible distribution target
### Cons
- limited device interaction

View File

@@ -0,0 +1,138 @@
## Test Drive
This assumes you have git, node 10LTS, yarn, rust and cargo installed. If not, see below.
```
git clone https://github.com/tauri-apps/smoke-tests
cd smoke-tests/test
yarn
cargo install --path node_modules/@tauri-apps/tauri/tools/rust/cargo-tauri-bundle --force
yarn tauri build
```
After tauri has compiled its rust resources, look in the `src-tauri/target/release/bundle`.
## Add Rust and Build Toolchain
### Windows 64 or 32 bit
You will need to have Visual Studio and windows-build-tools installed.
First you should visit the [Microsoft docs](https://docs.microsoft.com/en-us/visualstudio/install/install-visual-studio?view=vs-2019) and install Visual Studio.
$ npm install --global windows-build-tools
If you are running Windows 64-bit, download and run [rustupinit.exe](https://win.rustup.rs/x86_64) and then follow the onscreen instructions.
If you are running Windows 32-bit, download and run [rustupinit.exe](https://win.rustup.rs/i686) and then follow the onscreen instructions.
### Arch
According to the Arch manual, this is something you were born knowing. But seriously, if you want to help out explaining how newbies to Arch can do this, please feel free to make a PR to this doc.
### BSD
Similar to Arch, you already have everything installed because you compile kernels. However:
- Execution on OpenBSD requires wxallowed mount(8) option.
- FreeBSD is also supported, to install webkit2 run pkg install webkit2-gtk3.
### Ubuntu
First install Ubuntu then:
$ sudo apt update && sudo apt install libwebkit2gtk-4.0-dev build-essential
### MacOS
$ brew install gcc
### Everybody except Windows
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
> We have audited this bash script, and it does what it says it is supposed to do. Nevertheless, before blindly curl-bashing a script, it is always wise to look at it first. Here is file as a mere [download link](https://sh.rustup.rs)
Make sure that `rustc` and `cargo` are in your $PATH. Run
$ rustc --version
latest update on 2019-07-04, rust version 1.37.0
and make sure you are on latest update on 2019-07-04, rust version 1.37.0 - otherwise be sure to update.
$ rustup update stable
$ rustup override set 1.37.0
## About `rustup` (from their [website](https://rustup.rs))
`rustup` installs rustc, cargo, rustup and other standard tools to Cargo's bin directory. On Unix it is located at `$HOME/.cargo/bin` and on Windows at `%USERPROFILE%\.cargo\bin`. This is the same directory that cargo install will install Rust programs and Cargo plugins.
This directory will be in your `$PATH` environment variable, which means you can run them from the shell without further configuration. **Open a new shell** and type the following:
$ rustc --version
or run:
source $HOME/.cargo/env
# and then
$ rustc --version
If you don't see 1.37.0 or later, then you'll need to upgrade your rust.
$ rustup update stable
$ rustup override set 1.37.0
### bundler
After you have installed Rust and the build toolchain, it is wise to open a new shell before continuing.
Setup the bundler:
$ cargo install --path node_modules/@tauri-apps/tauri/tools/rust/cargo-tauri-bundle --force
Want to debug?
#### *nix
$ cd src-tauri
$ RUST_DEBUG=1 cargo build
#### Windows
$ cd src-tauri
$ set RUST_DEBUG=1
$ cargo build
## experimental anti-bloat features
see: https://github.com/RazrFalcon/cargo-bloat
https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html
https://doc.rust-lang.org/cargo/reference/manifest.html#the-profile-sections
### Bundler
add this to your `/src-tauri/Cargo.toml` (currently being used in the /test project)
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
incremental = false
opt-level = "z"
### upx
UPX, **Ultimate Packer for eXecutables**, is a dinosaur amongst the binary packers. This 23-year old, well-maintained piece of kit is GPL-v2 licensed with a pretty liberal usage declaration. Our understanding of the licensing is that you can use it for any purposes (commercial or otherwise) without needing to change your license unless you modify the source code of UPX.
Basically it compresses the binary and decompresses it at runtime. It should work for pretty much any binary type out there. Read more: https://github.com/upx/upx
> You should know that this technique might flag your binary as a virus on Windows and MacOS - so use at your own discretion, and as always validate with Frida and do real distribution testing!
#### Usage on MacOS
$ brew install upx
$ yarn tauri build
$ upx --ultra-brute src-tauri/target/release/bundle/osx/app.app/Contents/MacOS/app
Ultimate Packer for eXecutables
Copyright (C) 1996 - 2018
UPX 3.95 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 26th 2018
File size Ratio Format Name
-------------------- ------ ----------- -----------
963140 -> 274448 28.50% macho/amd64 app
## error reporting
Please report all library errors at https://github.com/tauri-apps/tauri

View File

View File

@@ -0,0 +1,54 @@
## Security
This guide seeks to explain the high level concepts and Security Features at the core of Tauri's design that make you, your apps and your users safer by default.
::: tip Please Note
While we take every opportunity to help you harden your application - there are always underlying threats like BIOS attacks, memory rowhammering and other operating system vulnerabilities that are constantly being discovered and (in the best cases) responsibly disclosed.
Furthermore, there are many ways that development teams can cut corners and either leak sensitive information or leave doors wide open to any of a range of attacks. Security is a never-ending quest, and your users count on you to keep them safe.
Therefore, we highly recommend that you take some time to consider the security ramifications of everything that your application does, especially in the context of running on the semi-hostile platform of end-user devices.
If you need help or want a review, you are welcome to contact the Tauri team for security consultation.
:::
### Security Researchers
If you feel that there is a security concern or issue with anything in Tauri, please do not publicly comment on your findings. Instead, reach out directly to our security team:
> <center>security@tauri-apps.org</center>
Although we do not currently have a budget for Security Bounties, in some cases we will consider rewarding responsible disclosure with our limited resources.
## Secure by Design
### Dynamic Ahead of Time Compilation
This process of compilation happens several times during the build phase of a Tauri app. By using a dynamic Ahead of Time compiler, you can generate code references that are unique for every session and are still technically static code units.
### One Time Pad Tokenization and Hashing
Hashing important messages with a OTP salt, you are able to encrypt messages between the UI and the Rust backend.
### functional ASLR
Functional address Space Layout Randomization techniques randomize function names at runtime and can implement OTP hashing so no two sessions are ever the same. We propose a novel type of function naming at boot time and optionally after every execution. Using a UID for each function pointer prevents static attacks.
### Bridge, don't serve
Instead of passing potentially unsafe functions, a bridge can be used to pass messages and commands to named brokers at each respective side of the bridge. Most of the time you don't NEED a local server, and its inclusion opens security gaps in the final application.
### API Whitelisting
You have the ability to pick and choose which API functions are available to the UI and to Rust. If they are not enabled, the code will not be shipped with your app, which reduces binary size and attack surface.
### Kamikaze Function Injection
This advanced type of fASLR using the `EVENT` API endpoint, is a promise wrapped in a closure (with randomized handle) that Rust inserts at runtime into the Webview, where its interface is locked within the promise resolution handler and is nulled after execution.
### Content Security Policy Management
Preventing unauthorized code execution for websites has long since been "resolved" by using CSPs. Tauri can inject CSPs into the index.html of the user interface, and when using a localhost server it will also send these headers to the UI or any other clients that connect with it.
### Decompilation is Difficult
This means that your apps cannot be easily decompiled as is the case with Electron ASAR files, which makes the process of reverse engineering your project much more time intensive and requires specialist training.
### Signed Binaries
Because the entire project is shipped within a monolithic binary, code can be signed for all distributables. This makes it virtually impossible for hackers to change an installed Application without the operating system noticing. [Reference](https://github.com/electron/asar/issues/123)
### Post-Binary Analysis
Use industrial-grade pentester-tooling (via our custom Tauri-Frida GUI) to discover and fix security weaknesses in your final binaries.
### Post-Binary Enhancement
After the build is before the shipping, and Tauri will provide you with advanced processes for integrated licensing including multi-layer checksums,
## Audits
We have not yet undertaken an audit, but this is planned to be realized before the 1.0 stable release.

View File

@@ -0,0 +1,10 @@
## Technical Details
The current user interface in Tauri apps leverages Cocoa/WebKit on macOS, gtk-webkit2 on Linux and MSHTML (IE10/11) or Webkit via EdgeHTML / Chakra on Windows. **Tauri** is based on the MIT licensed prior work known as [webview](https://github.com/zserge/webview) and [web-view]().
## Roadmap

View File

@@ -0,0 +1,53 @@
<template>
<hero>
<div id="padding" style="padding-top:260px"></div>
<q-markdown :src="markdown" toc @data="onToc" no-line-numbers />
<q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
<q-btn fab icon="keyboard_arrow_up" color="primary" />
</q-page-scroller>
</hero>
</template>
<script>
import Hero from '../components/Hero'
import markdown from '../markdown/api.md'
export default {
name: 'API',
components: {
Hero
},
data () {
return {
markdown: markdown
}
},
computed: {
toc:
{
get () {
return this.$store.state.common.toc
},
set (toc) {
this.$store.commit('common/toc', toc)
}
}
},
methods: {
onToc (toc) {
// add anything not picked uip by the markdown processor
// toc.push({ id: 'Tauri-API', label: 'Tauri API', level: 1, children: Array(0) })
// toc.push({ id: 'Donate', label: 'Donate', level: 1, children: Array(0) })
this.toc = toc
}
}
}
</script>

View File

View File

@@ -0,0 +1,22 @@
<template>
<div class="fixed-center text-center">
<p>
<img
src="~assets/sad.svg"
style="width:30vw;max-width:150px;"
>
</p>
<p class="text-faded">Sorry, nothing here...<strong>(404)</strong></p>
<q-btn
color="secondary"
style="width:200px;"
@click="$router.push('/')"
>Go back</q-btn>
</div>
</template>
<script>
export default {
name: 'Error404'
}
</script>

View File

@@ -0,0 +1,94 @@
<template>
<hero>
<div id="padding" style="padding-top:260px"></div>
<q-markdown>
You can add markdown to your page by surrounding it with `q-markdown` tag.
Be aware, markdown is sensitive to being on left side, otherwise will wrap it in blocks (indented).
</q-markdown>
Here is the imported Markdown:
<q-markdown :src="markdown" toc @data="onToc" />
<example-title title="Basic" />
<example-card title="Tauri - Basic" name="TauriBasic" :tag-parts="getTagParts(require('!!raw-loader!../examples/TauriBasic.vue').default)" />
<example-card title="Tauri - Advanced" name="TauriAdvanced" :tag-parts="getTagParts(require('!!raw-loader!../examples/TauriAdvanced.vue').default)" />
</hero>
</template>
<script>
import Hero from '../components/Hero'
import ExampleTitle from '../components/ExampleTitle'
import ExampleCard from '../components/ExampleCard'
import { slugify } from 'assets/page-utils'
import getTagParts from '@quasar/quasar-app-extension-qmarkdown/src/lib/getTagParts'
import markdown from '../markdown/examples.md'
export default {
name: 'Examples',
components: {
Hero,
ExampleTitle,
ExampleCard
},
data () {
return {
tempToc: [],
markdown: markdown
}
},
mounted () {
this.toc = []
this.tempToc = []
// example of top-level toc
this.addToToc('Basic')
// example of second-level toc
this.addToToc('Tauri - Basic', 2)
this.addToToc('Tauri - Advanced', 2)
// add the toc to right drawer
this.toc = this.tempToc
},
computed: {
toc:
{
get () {
return this.$store.state.common.toc
},
set (toc) {
this.$store.commit('common/toc', toc)
}
}
},
methods: {
getTagParts,
addToToc (name, level = 1) {
const slug = slugify(name)
this.tempToc.push({
children: [],
id: slug,
label: name,
level: level
})
},
onToc (toc) {
// add anything not picked up by the markdown processor
// toc.push({ id: 'Tauri-API', label: 'Tauri API', level: 1, children: Array(0) })
// toc.push({ id: 'Donate', label: 'Donate', level: 1, children: Array(0) })
this.toc = toc
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,53 @@
<template>
<hero>
<div id="padding" style="padding-top:260px"></div>
<q-markdown :src="markdown" toc @data="onToc" />
<q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
<q-btn fab icon="keyboard_arrow_up" color="primary" />
</q-page-scroller>
</hero>
</template>
<script>
import Hero from '../components/Hero'
import markdown from '../markdown/governance.md'
export default {
name: 'Governance',
components: {
Hero
},
data () {
return {
markdown: markdown
}
},
computed: {
toc:
{
get () {
return this.$store.state.common.toc
},
set (toc) {
this.$store.commit('common/toc', toc)
}
}
},
methods: {
onToc (toc) {
// add anything not picked uip by the markdown processor
// toc.push({ id: 'Tauri-API', label: 'Tauri API', level: 1, children: Array(0) })
// toc.push({ id: 'Donate', label: 'Donate', level: 1, children: Array(0) })
this.toc = toc
}
}
}
</script>

View File

@@ -0,0 +1,61 @@
<template>
<hero>
<div id="padding" style="padding-top:260px"></div>
<q-markdown :src="markdown" toc @data="onToc" />
<!--
<component-api
title="Tauri API"
:json="json"
/>
-->
<q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
<q-btn fab icon="keyboard_arrow_up" color="primary" />
</q-page-scroller>
</hero>
</template>
<script>
import Hero from '../components/Hero'
import markdown from '../markdown/tauri.md'
import json from '../json/tauri.json'
export default {
name: 'PageIndex',
components: {
Hero
},
data () {
return {
markdown: markdown,
json: json
}
},
computed: {
toc:
{
get () {
return this.$store.state.common.toc
},
set (toc) {
// console.log('toc:', toc)
this.$store.commit('common/toc', toc)
}
}
},
methods: {
onToc (toc) {
// add anything not picked uip by the markdown processor
toc.push({ id: 'Tauri-API', label: 'Tauri API', level: 1, children: Array(0) })
toc.push({ id: 'Donate', label: 'Donate', level: 1, children: Array(0) })
this.toc = toc
}
}
}
</script>

View File

@@ -0,0 +1,378 @@
<template>
<hero>
<div id="padding" style="padding-top:240px"></div>
<q-carousel
animated
v-model="slide"
infinite
:autoplay="5000"
navigation
control-color="cyan-1"
height="420px"
style="overflow:hidden!important;width:100%;background:transparent;color:black!important;border-radius:5px"
>
<q-carousel-slide v-for="(slideItem) in slides" v-bind:key="slideItem.id" :name="slideItem.title" class="column no-wrap" :img-src="slideItem.img" @mouseover="credits = true" @mouseleave="credits = false">
<div class="text-h3 text-weight-thin bg-amber-3 absolute-left q-pa-md text-center" style="width:350px;opacity:0.8;padding-top:220px;"> {{ slideItem.title }}</div>
<h6 class="q-pa-sm bg-yellow-1 full-width text-center" style="margin:270px -25px 0 0!important;z-index:1;font-size:1.2em; border-radius:4px;">
{{ slideItem.text }}
</h6>
<q-btn v-if="credits" size="xs" dense class="absolute-top-right q-ma-lg" style="width:180px;z-index:1" color="blue-grey-9" text-color="white" type="a" :href="`https://unsplash.com/${slideItem.unsplashLink}`">
<span style="display:inline-block;padding:2px 3px"><svg xmlns="http://www.w3.org/2000/svg" style="height:12px;width:auto;position:relative;vertical-align:middle;top:-2px;fill:white" viewBox="0 0 32 32"><path d="M10 9V0h12v9H10zm12 5h10v18H0V14h10v9h12v-9z"></path></svg></span><span style="display:inline-block;padding:2px 3px">Image by: {{ slideItem.unsplashName }}</span>
</q-btn>
</q-carousel-slide>
</q-carousel>
<div id="Quicklinks" class="row full-width wrap justify-center items-center content-center items-start q-mt-xl">
<q-card class="q-ma-md col-md-3 col-sm-5 q-mt-sm bg-cyan-1" flat bordered v-for="(item, index) in actions" :key="index">
<q-icon :name="item.icon" class="float-left q-pa-lg q-ma-xs text-h5" style="margin: 11px 5px -1px 10px"></q-icon>
<q-card-section>
{{ item.claim }}
</q-card-section>
<q-card-actions align="center">
<q-btn color="yellow-2" text-color="black" :to="item.btnTarget" :label="item.btnLabel"></q-btn>
</q-card-actions>
</q-card>
</div>
<!-- roadmap -->
<q-card id="Roadmap" class="q-ma-xl full-width bg-cyan-1" flat bordered>
<q-card-section class="justify-center items-center content-center text-center">
<div style="position:absolute;top:130px;left:30px;width:5px;height:20px;background:#E0F7FA;z-index:2"></div>
<div style="position:absolute;bottom:50px;left:30px;width:5px;height:20px;background:#E0F7FA;z-index:2"></div>
<q-activity
dense
bar-color="rgba(0,0,0,0.2)"
bar-width="3px"
bar-distance="15px"
style="margin-top:110px"
>
<q-activity-item
v-for="(item, index) in timeline"
:key="index"
:icon="item.icon"
:icon-color="item.iconColor"
:icon-text-color="item.iconTextColor"
icon-size="2.5em"
icon-font-size="0.55em"
style="padding-bottom:5px;padding-top:5px;margin-left:-9px;"
>
<q-item class="inline-block vertical-middle text-left">
<q-item-section>
<q-item-label class="text-weight-bold">{{ item.label }}</q-item-label>
<q-item-label caption lines="2">{{ item.caption }}</q-item-label>
</q-item-section>
</q-item>
<q-chip dense color="yellow-1" class="vertical-middle side-text">
{{ item.time }}
</q-chip>
</q-activity-item>
</q-activity>
<small class="text-weight-light text-black">Notice: This roadmap is subject to change.</small>
<q-parallax
:height="130"
src="statics/images/skycave.jpg"
class="full-width"
style="position:absolute;top:0;left:0;"
/>
<div style="position:absolute;left:0;top:0;right:0;height:130px;background: linear-gradient(0deg, rgba(224,247,250,1) 5%, rgba(224,247,250,0.9) 30%, rgba(224,247,250,0.7) 60%, rgba(224,247,250,0.45) 80%, rgba(224,247,250,0) 100%);z-index:10"></div>
<h2 class="text-weight-thin" style="position:absolute;top:-4px;z-index:100;left:10px; right:10px;margin:auto;text-shadow:0 0 5px white,0 0 2px white; color:#253239">ROADMAP</h2>
</q-card-section>
</q-card>
<q-markdown :src="markdown" toc @data="onToc" />
<q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
<q-btn fab icon="keyboard_arrow_up" color="primary" />
</q-page-scroller>
</hero>
</template>
<script>
import Hero from '../components/Hero'
import markdown from '../markdown/landing.md'
let images = [
'statics/images/locks.jpg',
'statics/images/hammers.jpg',
'statics/images/lightning.jpg',
'statics/images/feather.jpg',
'statics/images/bigben.jpg',
'statics/images/boat.jpg'
]
export default {
name: 'PageIndex',
components: {
Hero
},
mounted () {
// have to do this to squeeze perf on slow connections because the
// method that quasar uses to change the slide actually forces a
// request from the server because of background:url() call
// which is TONS of useless traffic - and makes a flash of white
// between slides on some browsers (iOS for example)
for (let x = 0; x < images.length; x++) {
let img = new Image()
img.crossOrigin = 'Anonymous'
img.onload = () => {
let canvas = document.createElement('CANVAS')
let ctx = canvas.getContext('2d')
canvas.height = img.naturalHeight
canvas.width = img.naturalWidth
ctx.drawImage(img, 0, 0)
const res = canvas.toDataURL('image/jpeg')
if (res.length >= 1) {
this.slides[x].img = res
}
canvas = null
}
img.src = images[x]
}
},
data () {
return {
bundle: false,
mermTex: '',
slide: 'SECURITY',
credits: false,
markdown: markdown,
slides: [
{
title: 'SECURITY',
text: 'is the Tauri-Team\'s biggest priority and drives our innovation.',
img: 'statics/images/locks.jpg',
unsplashLink: '@dynamicwang',
unsplashName: 'Dynamic Wang'
},
{
title: 'BROWNFIELD',
text: 'compatibility with any front-end framework means you don\'t have to change your stack.',
img: 'statics/images/hammers.jpg',
unsplashLink: '@Sucrebrut',
unsplashName: 'Sucrebrut'
},
{
title: 'MEMORY',
text: 'footprint of a Tauri App is less than half of the size of an Electron app.',
img: 'statics/images/lightning.jpg',
unsplashLink: '@ian_froome_photography',
unsplashName: 'Ian Froome'
},
{
title: 'BUNDLE',
text: 'size of a Tauri App can be less than 600KB.',
img: 'statics/images/feather.jpg',
unsplashLink: '@_javardh_001',
unsplashName: 'Javardh'
},
{
title: 'RELIABILITY',
text: 'of the underlying code base is why we forked critical libraries.',
img: 'statics/images/bigben.jpg',
unsplashLink: '@louisk_',
unsplashName: 'Louis. K'
},
{
title: 'FLOSS',
text: 'licensing is possible with Tauri, but not with Chromium consumers, like Electron.',
img: 'statics/images/boat.jpg',
unsplashLink: '@jplenio',
unsplashName: 'Johannes Plenio'
}
],
actions: [
{
icon: 'ti-lock',
claim: 'Tauri is a polyglot toolchain for building more secure native apps with both tiny and fast binaries.',
btnLabel: 'Get Setup!',
btnTarget: '/docs/quickstart'
},
{
icon: 'ti-settings',
claim: 'Tauri lets you use any frontend-framework to build apps, and it can be integrated into any pipeline.',
btnLabel: 'Learn How!',
btnTarget: '/docs/examples'
},
{
icon: 'ti-package',
claim: 'Tauri helps you build and bundle binaries for major desktop platforms (mobile & wasm coming soon).',
btnLabel: 'Ship It!',
btnTarget: '/docs/bundler'
},
{
icon: 'ti-shift-right',
claim: 'Tauri has many design patterns to help you choose important features with simple configuration.',
btnLabel: 'Discover!',
btnTarget: '/docs/patterns'
},
{
icon: 'ti-shield',
claim: 'With security features baked in and many additional tools available, you code be safer than ever.',
btnLabel: 'Be Safer!',
btnTarget: '/docs/security'
},
{
icon: 'ti-gift',
claim: 'As a sustainable FLOSS project, we do our best to mitigate bus-factor and are open to everyone.',
btnLabel: 'Join Us!',
btnTarget: '/governance-and-guidance'
}
],
timeline: [
{
icon: 'ti-target',
iconColor: 'blue',
iconTextColor: 'white',
label: 'CLI',
caption: 'Generate, develop and build Tauri apps from the command line.',
time: 'Q4 2019'
},
{
icon: 'ti-crown',
iconColor: 'blue',
iconTextColor: 'white',
label: 'API',
caption: 'Finalize, audit, write documentation and create examples for the smoke-tests.',
time: 'Q4 2019'
},
{
icon: 'ti-pulse',
iconColor: 'blue',
iconTextColor: 'white',
label: 'Testing & CI',
caption: 'Implement CI with testing and bundle-pipeline validation.',
time: 'Q4 2019'
},
{
icon: 'ti-layers-alt',
iconColor: 'blue',
iconTextColor: 'white',
label: 'Desktop Bundler',
caption: 'Bundle for all major desktops from native systems.',
time: 'Q4 2019'
},
{
icon: 'ti-flag-alt',
iconColor: 'red',
iconTextColor: 'white',
label: 'Alpha Release',
caption: 'Mostly stable on desktop, edge cases and bugs acceptable.',
time: 'Q4 2019'
},
{
icon: 'ti-layers',
iconColor: 'blue',
iconTextColor: 'white',
label: 'Mobile Bundler',
caption: 'Bundle to all major mobile device operating systems.',
time: 'Q4 2019'
},
{
icon: 'ti-bolt',
iconColor: 'blue',
iconTextColor: 'white',
label: 'WASM Bundler',
caption: 'Manufacture WASM bundler for use in websites.',
time: 'Q1 2020'
},
{
icon: 'ti-control-shuffle',
iconColor: 'blue',
iconTextColor: 'white',
label: 'Cross Compiler',
caption: 'Generate bundled binaries from select operating system environments.',
time: 'Q1 2020'
},
{
icon: 'ti-panel',
iconColor: 'blue',
iconTextColor: 'white',
label: 'App Tray',
caption: 'Desktop Cross-platform Icon Tray.',
time: 'Q1 2020'
},
{
icon: 'ti-flag-alt',
iconColor: 'red',
iconTextColor: 'white',
label: 'Beta Release',
caption: 'Mostly stable on Desktop & Mobile.',
time: 'Q1 2020'
},
{
icon: 'ti-direction-alt',
iconColor: 'blue',
iconTextColor: 'white',
label: 'Alternative Renderer',
caption: 'Candidate presentation for Webview Alternatives, including GL windowing.',
time: 'Q2 2020'
},
{
icon: 'ti-slice',
iconColor: 'blue',
iconTextColor: 'white',
label: 'Tauri-Frida',
caption: 'A decompiler and threat analyzer for Tauri Apps, using Frida.',
time: 'Q3 2020'
},
{
icon: 'ti-flag-alt',
iconColor: 'red',
iconTextColor: 'white',
label: 'Stable Release',
caption: 'Stable on On all Platforms.',
time: 'Q3 2020'
},
{
icon: 'ti-world',
iconColor: 'blue',
iconTextColor: 'white',
label: 'Other Bindings',
caption: 'Go, Nim, Python, C++ and other bindings are possible with the stable API.',
time: 'Q1 2021'
},
{
icon: 'ti-infinite',
iconColor: 'blue',
iconTextColor: 'white',
label: 'The Future',
caption: 'Something missing? Got a great idea? We want you to help us make it happen.',
time: '& BEYOND'
}
]
}
},
computed: {
toc: {
get () {
return this.$store.state.common.toc
},
set (toc) {
this.$store.commit('common/toc', toc)
}
}
},
methods: {
onToc (toc) {
toc.unshift({ id: 'Roadmap', label: 'Roadmap', level: 2, children: Array(0) })
toc.unshift({ id: 'Quicklinks', label: 'Quick Links', level: 2, children: Array(0) })
this.toc = toc
},
extendMarkdown (md) {
md.use(this.mermaid)
},
mermaid (md, options) {
md.renderer.rules.fence = (tokens, idx, options, env, slf) => {
const token = tokens[idx]
const code = token.content.trim()
return `<div class="mermaid">\n${code}\n</div>\n`
}
}
}
}
</script>
<style lang="stylus">
#Donations-and-Sponsoring
text-align: center
i.themify-icon.ti-star::before
margin-top -4px!important
</style>

View File

@@ -0,0 +1,471 @@
<template>
<hero>
<div id="padding" style="padding-top:260px"></div>
<p class="q-mt-xl">Tauri patterns are descriptions of use-cases that are entirely configurable within the Tauri configuration file. These are not the limits of what Tauri can do, and there are probably more out there. If you discover one, why not get in touch and help us update this collection!
</p>
<q-card class="q-mt-xl">
<q-card-section class="text-center" style="padding-bottom:-20px">
<q-btn class="q-mx-xs" outline flat dense no-caps v-for="p in patterns" v-bind:key="p.id" @click="pattern = p.name" :class="{'bg-cyan-2 text-black': pattern === p.name}" :disabled="pattern === p.name">{{ p.name }}</q-btn>
</q-card-section>
<q-separator></q-separator>
<q-card-section class="bg-cyan-1">
<q-ribbon :leaf-color="yellow.dark" :background-color="yellow.light" color="black" style="margin:-16px" type="corner" position="top-right">
<small class="q-pa-md text-weight-bold">{{ active.most }}</small>
</q-ribbon>
<div id="tryout" class="fit row inline wrap justify-center" style="margin-top:26px">
<img class="col-1 q-mt-lg q-mr-md" :src="`statics/patterns/${pattern}.png`" style="height:50px; width:auto">
<h4 class="col-grow text-weight-light text-cyan-10" style="margin:-30px 0">{{ pattern }}</h4>
<span class="col-12 q-pa-sm text-weight-bold text-black" style="margin:-25px 0 0 110px">{{ active.bestWhen }}</span>
<div class="col-grow"></div>
<div class="col-12 alight-right justify-end q-ma-sm">
<div class="row">
<span class="col-6 text-right q-pr-sm" style="white-space: nowrap">Ease of Use: </span>
<q-rating class="col-6 inline-block" color="cyan-10" readonly v-model="active.ratings.easeOfUse"></q-rating>
</div>
<div class="row">
<span class="col-6 text-right q-pr-sm">Extensibility: </span>
<q-rating class="col-6 inline-block" color="cyan-10" readonly v-model="active.ratings.extensibility"></q-rating>
</div>
<div class="row">
<span class="col-6 text-right q-pr-sm">Security: </span>
<q-rating class="col-6 inline-block" color="cyan-10" readonly v-model="active.ratings.security"></q-rating>
</div>
</div>
</div>
</q-card-section>
<q-separator></q-separator>
<q-card-section>
<p class="row">{{ active.intro }}</p>
<div class="text-center" id="temp" v-html="graph"></div>
</q-card-section>
<q-separator></q-separator>
<q-card-section>
<ul class="text-weight-bold"> Features:
<li class="text-weight-regular row-12" v-for="p in active.features" v-bind:key="p.id" >{{ p }}</li>
</ul>
<ul class="text-weight-bold"> Pros:
<li class="text-weight-regular row-12" v-for="p in active.pros" v-bind:key="p.id" >{{ p }}</li>
</ul>
<ul class="text-weight-bold"> Cons:
<li class="text-weight-regular row-12" v-for="p in active.cons" v-bind:key="p.id">{{ p }}</li>
</ul>
</q-card-section>
<q-separator></q-separator>
<q-card-section>
<h6>Configuration</h6>
<span>tauri.conf.js</span>
<q-markdown :src="active.configMD" toc @data="onToc" no-line-numbers />
</q-card-section>
</q-card>
<!-- <q-markdown :src="markdown" toc @data="onToc" /> -->
<q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
<q-btn fab icon="keyboard_arrow_up" color="primary" />
</q-page-scroller>
</hero>
</template>
<script>
import Hero from '../components/Hero'
// import markdown from '../markdown/patterns.md'
// import * as mermaid from 'mermaid'
const colors = {
blue: {
light: '#BAE5F2',
dark: '#77CFE4'
},
yellow: {
light: '#EFD3AF',
dark: '#D08050'
}
}
export default {
name: 'Patterns',
components: {
Hero
},
data () {
return {
// markdown: markdown,
mermaidHTML: '',
blue: colors.blue,
yellow: colors.yellow,
graph: '',
clearfix: ' ',
pattern: 'Cloudish',
patterns: [
{
name: 'Hermit',
most: 'MOST SECURE',
intro: 'The Hermit recipe is a pattern for ultimate application isolation where all logic is self-contained in the Window and the binary exists merely to bootstrap the Window. There is no communication back to Rust from the Window, there is no localhost server, and the Window has no access to any remote resources.',
ratings: {
easeOfUse: 5,
security: 5,
extensibility: 0
},
bestWhen: 'Best when you want to lock down your app from all external influences.',
configMD: `
\`\`\`
tauri: {
embeddedServer: {
active: false // do not use a localhost server
},
whitelist: {
all: false, // disable and tree-shake all api functions
},
security: {
csp: 'default-src data: \\'unsafe-eval\\' \\'unsafe-inline\\''
fASLR: 'aot' // bootstrap with dynamic AOT of interface at every launch
}
}
\`\`\`
`,
graph: `graph LR
A==>H
H==>F
subgraph WEBVIEW
F
end
subgraph RUST
A
end
A[fa:fa-cog Binary ]
F[fa:fa-window-maximize Window]
H{Bootstrap}
style RUST fill:${colors.yellow.light},stroke:${colors.yellow.dark},stroke-width:4px
style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`
},
{
name: 'Bridge',
most: 'MOST POPULAR',
intro: 'The Bridge recipe is a secure pattern where messages are passed between brokers via an implicit bridge using the API.',
bestWhen: 'Best when you want two-way communication between Rust and WebView.',
ratings: {
easeOfUse: 4,
security: 4,
extensibility: 5
},
features: [
'render UI securely at bootstrap',
'promise based message passing',
'RW access to filesystem',
'STDOUT access to other binaries',
'extensible with Rust functions',
'whitelist for functional codegen',
'runtime message salting',
'fASLR & AoT Compiling'
],
pros: [
'highly configurable',
'infinitely extensible'
],
cons: [
'rust skills virtually required'
],
configMD: `
\`\`\`
tauri: {
embeddedServer: {
active: false // do not use a localhost server
},
whitelist: { // all whitelist values are default:false
all: true, // use this flag to enable all API features
answer: false, // enable rust to direct the UI
bridge: false, // enable Quasar Bridge
event: false, // enable binding to message
execute: false, // enable application execution
listFiles: false, // list files in a directory
open: false, // open link in a browser
readBinaryFile: false, // read binary file from local filesystem
readTextFile: false, // read text file from local filesystem
setTitle: false, // set the window title
writeFile: false // write file to local filesystem
},
security: {
csp: 'default-src data: \\'unsafe-eval\\' \\'unsafe-inline\\'',
messageSalt: 'none', // one of: ['none'|'aot'|'otp']
fASLR: 'none' // one of: ['none'|'aot'|'otp']
}
}
\`\`\`
`,
graph: `graph LR
H==>F
subgraph WEBVIEW
F-.-E
end
D-->E
E-->D
B-->D
D-->B
subgraph RUST
A==>H
A-->B
B-.-C
B-.-G
end
A[Binary]
B{Rust Broker}
C[Subprocess 2]
G[Subprocess 1]
D(( API BRIDGE ))
E{JS Broker}
F[Window]
H{Bootstrap}
click D "/docs/api" "Visit the API page"
style D fill:#ccc,stroke:#333,stroke-width:4px,color:white
style RUST fill:${colors.yellow.light},stroke:${colors.yellow.dark},stroke-width:4px
style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`
},
{
name: 'Cloudish',
most: 'MOST EASY',
intro: 'The Cloudish recipe is a pattern for maximum flexibility and app performance. It uses a localhost server, which means that your app will technically be available to other processes, like browsers and potentially other devices on the network. All of your assets are baked into the binary, but served as if they were distinct files.',
ratings: {
easeOfUse: 4,
security: 2,
extensibility: 3
},
bestWhen: 'Best when you have never used Rust before.',
configMD: `
\`\`\`
tauri: {
embeddedServer: {
active: true // ship with a localhost server
},
whitelist: {
all: false // disable entire API
},
security: {
csp: 'default-src data: http: https: \\'unsafe-eval\\' \\'unsafe-inline\\''
}
}
\`\`\`
`,
graph: `graph LR
H==>F
H==>D
D-->F
F-->D
subgraph RUST
A==>H
end
subgraph WEBVIEW
F
end
subgraph SERVER
D
E-->D
end
A[Binary]
D(( localhost ))
E[bundled resources]
F[Window]
H{Bootstrap}
style RUST fill:${colors.yellow.light},stroke:${colors.yellow.dark},stroke-width:4px
style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px
style SERVER fill:#49A24A,stroke:#2B6063,stroke-width:4px`
},
{
name: 'Cloudbridge',
most: 'MOST COMPLEX',
intro: 'The Cloudbridge recipe combines the flexibility of a localhost and the security of the bridge. With so many features, it can be easy to get lost.',
ratings: {
easeOfUse: 2,
security: 2,
extensibility: 5
},
bestWhen: 'Best when your project is complex and you need all available options.',
configMD: `
\`\`\`
tauri: {
embeddedServer: {
active: true // ship with a localhost server
},
whitelist: {
all: true // enable entire API
},
security: {
csp: 'default-src data: http: https: \\'unsafe-eval\\' \\'unsafe-inline\\''
}
}
\`\`\`
`,
graph: `graph LR
A== Bootstrap ==>F
A[Rust Binary]
F[WebView Window]
`
},
{
name: 'Kamikaze',
most: 'MOST AWESOME',
intro: 'The Kamikaze recipe is a minimal usage of the Bridge pattern, which only allows interaction between Rust and the Window via expiring JS Promise Closures that are injected into the Window by Rust and nulled as part of the callback.',
ratings: {
easeOfUse: 2,
security: 5,
extensibility: 4
},
bestWhen: 'Best when you want Rust to drive the Webview.',
configMD: `
\`\`\`
tauri: {
embeddedServer: {
active: false // do not use a localhost server
},
whitelist: { // all API endpoints are default true
event: true, // Use the EVENT API for injections
},
security: {
csp: 'default-src data: \\'unsafe-eval\\' \\'unsafe-inline\\'',
fASLR: 'aot' // bootstrap with dynamic AOT of interface on launch
messageSalt: 'otp', // use One-Time-Pads for injected function handles
eventRecycle: 0 // never use an event twice
}
}
\`\`\`
`,
graph: `graph LR
H==>F
G-.->B
B-->G
subgraph WEBVIEW
G-->F
end
subgraph RUST
A-->B
A==>H
end
A[Binary]
B[API:Event]
F[Window]
G((Promise Closure))
H{Bootstrap}
style RUST fill:${colors.yellow.light},stroke:${colors.yellow.dark},stroke-width:4px
style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`
},
{
name: 'Multiwin',
most: 'MOSTLY VAPOR',
intro: 'The Multiwin recipe will allow you to have multiple windows, some of which may be GL based. It is not yet available, but is in the research phase.',
ratings: {
easeOfUse: 1,
security: 5,
extensibility: 4
},
bestWhen: 'Best when you need more than one window.',
configMD: `
\`\`\`
tauri: {
embeddedServer: {
active: false // do not use a localhost server
},
whitelist: { // all API endpoints are default true
event: true, // Use the EVENT API for injections
},
security: {
csp: 'default-src data: \\'unsafe-eval\\' \\'unsafe-inline\\'',
fASLR: 'aot' // bootstrap with dynamic AOT of interface on launch
messageSalt: 'otp', // use One-Time-Pads for injected function handles
eventRecycle: 0 // never use an event twice
}
}
\`\`\`
`,
graph: `graph LR
A==>H
H==>F
H==>G
subgraph WEBVIEW
F
end
subgraph GLUTIN
G
end
subgraph RUST
A
end
A[Binary]
F[Window]
G[GL Window]
H{Bootstrap}
style GLUTIN stroke:${colors.blue.dark},stroke-width:4px
style RUST fill:${colors.yellow.light},stroke:${colors.yellow.dark},stroke-width:4px
style WEBVIEW fill:${colors.blue.light},stroke:${colors.blue.dark},stroke-width:4px`
}
]
}
},
watch: {
pattern: {
handler (val, oldVal) {
oldVal = !oldVal ? 'none' : oldVal
val = !val ? 'none' : val
let pattern = this.patterns.find(pattern => pattern.name === val)
if (typeof pattern !== 'undefined') this.goMermaid(pattern.graph)
},
immediate: true
}
},
computed: {
toc: {
get () {
return this.$store.state.common.toc
},
set (toc) {
this.$store.commit('common/toc', toc)
}
},
active: {
get () {
return this.patterns.find(p => p.name === this.pattern)
}
}
},
mounted () {
},
methods: {
onToc (toc) {
// add anything not picked uip by the markdown processor
// toc.push({ id: 'Tauri-API', label: 'Tauri API', level: 1, children: Array(0) })
// toc.push({ id: 'Donate', label: 'Donate', level: 1, children: Array(0) })
this.toc = toc
},
goMermaid (pattern) {
// null it so that we don't accidentally append
this.graph = null
// const thing = `graph LR\nA --> B\nA[${val}]`
// otherwise mermaid gets lost
this.$nextTick(() => {
this.graph = this.$mermaid.render('mermaid', pattern)
// then measure height of svg
// resize card / dom
})
}
}
}
</script>
<style lang="stylus">
.active
ba
</style>

View File

@@ -0,0 +1,57 @@
<template>
<hero>
<div id="padding" style="padding-top:260px"></div>
<q-markdown :src="markdown" toc @data="onToc" line-number-alt="$" />
<q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
<q-btn fab icon="keyboard_arrow_up" color="warning" />
</q-page-scroller>
</hero>
</template>
<script>
import Hero from '../components/Hero'
import markdown from '../markdown/quickstart.md'
export default {
name: 'PageIndex',
components: {
Hero
},
data () {
return {
markdown: markdown
}
},
computed: {
toc:
{
get () {
return this.$store.state.common.toc
},
set (toc) {
// console.log('toc:', toc)
this.$store.commit('common/toc', toc)
}
}
},
methods: {
onToc (toc) {
// add anything not picked uip by the markdown processor
// toc.push({ id: 'Tauri-API', label: 'Tauri API', level: 1, children: Array(0) })
// toc.push({ id: 'Donate', label: 'Donate', level: 1, children: Array(0) })
this.toc = toc
}
}
}
</script>
<style lang="stylus">
.q-markdown--line-numbers-wrapper
margin-bottom 14px
</style>

View File

@@ -0,0 +1,59 @@
<template>
<hero>
<div id="padding" style="padding-top:260px"></div>
<q-markdown :src="markdown" toc @data="onToc" line-number-alt="$" />
<q-page-scroller position="bottom-right" :scroll-offset="150" :offset="[18, 18]">
<q-btn fab icon="keyboard_arrow_up" color="warning" />
</q-page-scroller>
</hero>
</template>
<script>
import Hero from '../components/Hero'
import markdown from '../markdown/security.md'
import json from '../json/tauri.json'
export default {
name: 'PageIndex',
components: {
Hero
},
data () {
return {
markdown: markdown,
json: json
}
},
computed: {
toc:
{
get () {
return this.$store.state.common.toc
},
set (toc) {
// console.log('toc:', toc)
this.$store.commit('common/toc', toc)
}
}
},
methods: {
onToc (toc) {
// add anything not picked uip by the markdown processor
// toc.push({ id: 'Tauri-API', label: 'Tauri API', level: 1, children: Array(0) })
// toc.push({ id: 'Donate', label: 'Donate', level: 1, children: Array(0) })
this.toc = toc
}
}
}
</script>
<style lang="stylus">
.q-markdown--line-numbers-wrapper
margin-bottom 14px
</style>

View File

@@ -0,0 +1,26 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'
Vue.use(VueRouter)
/*
* If not building with SSR mode, you can
* directly export the Router instantiation
*/
export default function (/* { store, ssrContext } */) {
const Router = new VueRouter({
scrollBehavior: () => ({ x: 0, y: 0 }),
routes,
// Leave these as is and change from quasar.conf.js instead!
// quasar.conf.js -> build -> vueRouterMode
// quasar.conf.js -> build -> publicPath
mode: process.env.VUE_ROUTER_MODE,
base: process.env.VUE_ROUTER_BASE
})
return Router
}

View File

@@ -0,0 +1,37 @@
const routes = [
{
// redirect to docs
path: '/',
component: () => import('layouts/MainLayout.vue'),
children: [
{ path: '', component: () => import('pages/Landing.vue') },
{ path: '/governance-and-guidance', component: () => import('pages/Governance.vue') }
]
},
{
path: '/docs',
meta: {
showDocslink: false
},
component: () => import('layouts/MainLayout.vue'),
children: [
{ path: '', component: () => import('pages/Index.vue') },
{ path: '/docs/quickstart', component: () => import('pages/Quickstart.vue') },
{ path: '/docs/patterns', component: () => import('pages/Patterns.vue') },
{ path: '/docs/examples', component: () => import('pages/Examples.vue') },
{ path: '/docs/security', component: () => import('pages/Security.vue') },
{ path: '/docs/api', component: () => import('pages/API.vue') }
]
}
]
// Always leave this as last one
if (process.env.MODE !== 'ssr') {
routes.push({
path: '*',
component: () => import('pages/Error404.vue')
})
}
export default routes

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="681" height="680"><path d="M251.377 192.765c-2.535 1.659-13.497 26.255-16.865 37.841-1.255 4.319-2.163 5.688-4.301 6.49-12.319 4.622-39.151 19.298-37.783 20.666.308.307 1.35-.143 2.316-1.001 4.174-3.709 33.443-17.761 36.995-17.761.498 0 .129 4.387-.819 9.75-5.833 32.988-1.628 68.804 11.728 99.896 1.974 4.595 3.986 8.354 4.471 8.354 1.235 0 1.259.079-2.534-8.245-6.588-14.456-11.504-33.088-13.655-51.755-1.965-17.056.018-46.552 3.989-59.347.539-1.734 2.384-7.653 4.101-13.153 1.717-5.5 5.538-15.062 8.492-21.25 2.953-6.187 5.284-11.243 5.179-11.235-.105.009-.696.346-1.314.75m128.135 21.849c-20.856 5.042-38.762 22.174-45.869 43.886-4.19 12.801-3.905 29.193.738 42.545 10.434 30.004 41.143 48.376 71.119 42.547 22.957-4.464 41.885-21.645 49.674-45.092 1.971-5.932 2.319-8.984 2.279-20-.041-11.4-.373-13.935-2.692-20.596-7.611-21.867-25.201-38.496-45.875-43.369-7.934-1.87-21.46-1.834-29.374.079m1.69 8.408c-14.102 3.695-25.227 11.799-33.295 24.255-5.606 8.656-8.028 16.597-8.609 28.223-.612 12.267 1.168 20.788 6.437 30.814 7.104 13.52 18.997 23.374 33.605 27.843 9.734 2.978 25.325 2.291 34.66-1.528 16.19-6.623 28.248-20.318 33.617-38.181 2.771-9.221 2.356-23.789-.97-34.026-6.219-19.139-22.367-33.923-41.473-37.973-8.882-1.882-15.174-1.732-23.972.573M480.5 423.655c-6.338 4.345-27.577 14.76-33.5 16.428-2.475.697-4.994 1.637-5.598 2.088-2.567 1.92-24.445 5.929-36.869 6.756-24.414 1.625-49.07-2.287-69.673-11.055-7.419-3.156-7.86-3.269-7.86-2.004 0 1.17 16.945 7.587 26.661 10.096 25.444 6.571 55.324 6.637 80.339.179 4.125-1.065 7.633-1.812 7.796-1.66.739.689-8.284 25.531-11.846 32.617-2.185 4.345-3.592 7.9-3.127 7.9 1.621 0 12.492-24.692 15.643-35.532 1.277-4.391 2.178-5.76 4.323-6.564 11.759-4.412 36.956-18.064 38.776-21.009 1.295-2.096-.197-1.578-5.065 1.76" fill="undefined" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View File

@@ -0,0 +1,4 @@
/*
export function someAction (context) {
}
*/

View File

@@ -0,0 +1,2 @@
export const titlebarHeight = (state) => state.titlebarHeight
export const toc = (state) => state.toc

View File

@@ -0,0 +1,12 @@
import state from './state'
import * as getters from './getters'
import * as mutations from './mutations'
import * as actions from './actions'
export default {
namespaced: true,
state,
getters,
mutations,
actions
}

View File

@@ -0,0 +1,6 @@
export const titlebarHeight = (state, height) => {
state.titlebarHeight = height
}
export const toc = (state, toc) => {
state.toc = toc
}

View File

@@ -0,0 +1,4 @@
export default {
titlebarHeight: 0,
toc: []
}

Some files were not shown because too many files have changed in this diff Show More