Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quo saepe aspernatur inventore dolorum voluptates consequatur tempore ipsum! Quia, incidunt, aliquam sit veritatis nisi aliquid porro similique ipsa mollitia eaque ex!
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quo saepe aspernatur inventore dolorum voluptates consequatur tempore ipsum! Quia, incidunt, aliquam sit veritatis nisi aliquid porro similique ipsa mollitia eaque ex!
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quo saepe aspernatur inventore dolorum voluptates consequatur tempore ipsum! Quia, incidunt, aliquam sit veritatis nisi aliquid porro similique ipsa mollitia eaque ex!
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quo saepe aspernatur inventore dolorum voluptates consequatur tempore ipsum! Quia, incidunt, aliquam sit veritatis nisi aliquid porro similique ipsa mollitia eaque ex!
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/docs/build.md:
--------------------------------------------------------------------------------
1 | # Build your application
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | To deploy your application you need to build it before. App Framework makes it quite easy for you, bumps the version, compiles the scripts and merges them together. Your logo is used to create many icons and launch screen graphics and at the end all files are compressed to save bandwidth.
8 |
9 | GZIP compression will be done in addition after deployment to Firebase hosting.
10 |
11 | Each build command will update the *build* folder on success.
12 |
13 | - Run `npm run patch` after bug-fixes and improvements (version bump to x.y.z+1)
14 | - Run `npm run minor` after adding new functionality (version bump to x.y+1.0)
15 | - Run `npm run major` after breaking backward-capability (version bump to x+1.0.0)
16 |
--------------------------------------------------------------------------------
/demo/pages/f7ios/animation.vue:
--------------------------------------------------------------------------------
1 |
2 |
This demo demonstrates Framework7 exclusive behavior of dynamic sliding navigation bars. Just click the button below and look how navbar links will change. And don't forget to try swipe-back gesture on next pages:
18 |
19 |
--------------------------------------------------------------------------------
/docs/dev-trouble-shooting.md:
--------------------------------------------------------------------------------
1 | # Trouble shooting
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | The following points should be checked for trouble shooting:
8 |
9 | - Cache is reset (could be done with `npm run reset`)
10 | - No interferences with other files
11 | - Only absolute paths used
12 | - process.env allways considered as object with strings (`process.env.ANY === 'true'`)
13 | - All `require()` commands contain only strings and/or `process.env[...]` as variable
14 | - Values from `window.localStorage` are parsed with `JSON.parse()` before usage
15 |
16 | Let us know if you have points to add.
17 |
18 | ## Debug mode
19 |
20 | Debug mode could be enabled with `debug: true` in the app config file. In code, whenever `env.debug(...)` is called, the input will be logged to debug.log file in the project folder.
21 |
--------------------------------------------------------------------------------
/demo/pages/f7material/bars-deep-navbar.vue:
--------------------------------------------------------------------------------
1 |
2 |
This demo demonstrates Framework7 exclusive behavior of dynamic sliding navigation bars. Just click the button below and look how navbar links will change. And don't forget to try swipe-back gesture on next pages:
19 |
20 |
--------------------------------------------------------------------------------
/docs/knowledge.md:
--------------------------------------------------------------------------------
1 | # Knowledge requirements
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | Before you start to work with App Framework, you should be familiar with the following documentation.
8 |
9 | ## Essentiell
10 |
11 | - [Node.js and npm](https://docs.npmjs.com/getting-started/what-is-npm) for command line interface handling
12 | - [Framework7](https://v1.framework7.io/docs/) and [Framework7-Vue](https://v1.framework7.io/vue/) to develop with HTML and JavaScript
13 |
14 | ## Optional
15 |
16 | - [Vue.js](https://vuejs.org/v2/guide/) to make your application state-based and reactive
17 | - [Firebase](https://firebase.google.com/docs/web/setup) to use the reliable backend service provider
18 | - [Cordova/PhoneGap](https://cordova.apache.org/docs/en/latest/) to use device hardware API plugins
19 | - [iOS design guidelines](https://developer.apple.com/ios/human-interface-guidelines/overview/design-principles/) and [Material design guidelines](https://material.io/guidelines/)
20 |
--------------------------------------------------------------------------------
/scripts/jobs/updateEslintrcFile.js:
--------------------------------------------------------------------------------
1 | // Purpose: Update .eslintrc file according the app config file
2 |
3 | // Load modules
4 | const path = require('../path')
5 | const fs = require('fs-extra')
6 |
7 | // Export promise
8 | module.exports = new Promise((resolve, reject) => {
9 |
10 | // Load configuration file
11 | const appConfig = fs.readJsonSync(path.app('config.json'))
12 |
13 | // Create configuration object
14 | const eslintConfig = appConfig.eslint
15 |
16 | // Rewrite airbnb to airbnb-base
17 | if (eslintConfig.extends === 'airbnb') {
18 | eslintConfig.extends = 'airbnb-base'
19 | }
20 |
21 | // Add Vue plugin
22 | eslintConfig.plugins = ['vue']
23 |
24 | // Add Node and browser environments
25 | eslintConfig.env = {
26 | browser: true,
27 | node: true
28 | }
29 |
30 | // Create/update .eslintrc file
31 | fs.writeJson(path.pkg('.eslintrc'), eslintConfig, { spaces: 2 }, (err) => {
32 | if (err) {
33 | reject('Failed to update the ESLint configuration file.')
34 | } else {
35 | resolve()
36 | }
37 | })
38 |
39 | })
40 |
--------------------------------------------------------------------------------
/demo/pages/f7material/notifications.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Notifications
7 |
8 |
9 |
10 |
11 |
Framework7 comes with simple Notifications component that allows you to show some useful messages to user and request basic actions. Such notification are also called Snackbars & Toasts in Android
19 |
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 scriptPilot
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/material-icons/material-icons.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Material Icons';
3 | font-style: normal;
4 | font-weight: 400;
5 | src: url(MaterialIcons-Regular.eot); /* For IE6-8 */
6 | src: local('Material Icons'),
7 | local('MaterialIcons-Regular'),
8 | url(MaterialIcons-Regular.woff2) format('woff2'),
9 | url(MaterialIcons-Regular.woff) format('woff'),
10 | url(MaterialIcons-Regular.ttf) format('truetype');
11 | }
12 |
13 | .material-icons {
14 | font-family: 'Material Icons';
15 | font-weight: normal;
16 | font-style: normal;
17 | font-size: 24px; /* Preferred icon size */
18 | display: inline-block;
19 | line-height: 1;
20 | text-transform: none;
21 | letter-spacing: normal;
22 | word-wrap: normal;
23 | white-space: nowrap;
24 | direction: ltr;
25 |
26 | /* Support for all WebKit browsers. */
27 | -webkit-font-smoothing: antialiased;
28 | /* Support for Safari and Chrome. */
29 | text-rendering: optimizeLegibility;
30 |
31 | /* Support for Firefox. */
32 | -moz-osx-font-smoothing: grayscale;
33 |
34 | /* Support for IE. */
35 | font-feature-settings: 'liga';
36 | }
37 |
--------------------------------------------------------------------------------
/docs/image-upload-component.md:
--------------------------------------------------------------------------------
1 | # Image upload component
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | In native iOS or Android applications, the `` element does not work.
8 |
9 | App Framework provides you a component, to upload an image to Firebase storage and save the image URI to the Firebase database.
10 |
11 | ## Configuration
12 |
13 | In the configuration file, you have to add the following Cordova plugins:
14 |
15 | ```
16 | "useCordovaPlugins": [
17 | "cordova-plugin-camera",
18 | "cordova-plugin-file"
19 | ]
20 | ```
21 |
22 | ## Usage
23 |
24 | Just add the following component to any of your page components:
25 |
26 | ```
27 |
28 |
29 |
30 | ```
31 |
32 | - `store` is the Firebase storage path to your image (string, no extension)
33 | - `db` is the Firebase database path to save the image URI (string, optional)
34 | - `size` is the maximum image width or height (number, optional, ratio kept)
35 |
36 | Please take care that the storage rules and database rules are correctly configured.
37 |
--------------------------------------------------------------------------------
/demo/pages/f7material/swiper-fade.vue:
--------------------------------------------------------------------------------
1 |
2 |
Framework7 comes with 2 panels (on left and on right), both are optional. They have two different layouts/effects - cover above the content (like left panel here) and reveal (like right panel). You can put absolutely anything inside:
12 | data lists, forms, custom content, and even other isolated app view (like in right panel now) with its own dynamic navbar. Checkout panels:
22 |
23 |
--------------------------------------------------------------------------------
/demo/pages/flexible-routing.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Use multiple ways to fit the routing perfectly to your application needs.
8 |
9 | By default, routes for all nested components are created automatically.
10 |
11 | In addition, you can easily require dynamic and login-protected routes.
12 |
13 |
14 |
Framework7 comes with 2 panels (on left and on right), both are optional. They have two different layouts/effects - cover above the content (like left panel here) and reveal (like right panel). You can put absolutely anything inside:
12 | data lists, forms, custom content, and even other isolated app view (like in right panel now) with its own dynamic navbar. Checkout panels:
35 |
36 |
--------------------------------------------------------------------------------
/docs/cli-commands.md:
--------------------------------------------------------------------------------
1 | # CLI commands
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | 
8 |
9 | - Setup
10 | - `npm install` to install App Framework and setup the project folder
11 | - `npm update` to update App Framework to the latest sub version
12 |
13 | - Testing
14 | - `npm run dev` to start the development server
15 | - `CTRL + C` to stop the development server
16 | - `npm run ios` to open an iOS emulator with a development build
17 | - `npm run android` to open an Android emulator with a development build
18 |
19 | - Building
20 | - `npm run patch` to build after bug-fixes and improvements
21 | - `npm run minor` to build after adding new functionality
22 | - `npm run major` to build after backward-capability breaking changes
23 |
24 | - Deployment
25 | - `npm run firebase` to deploy rules and static files to Firebase
26 | - `npm run database` to deploy database rules to Firebase
27 | - `npm run storage` to deploy storage rules to Firebase
28 | - `npm run hosting` to deploy static files to Firebase
29 | - `npm run ftp` to deploy static files to your FTP server
30 | - `npm run xcode` to deploy static files as iOS Xcode project
31 | - `npm run studio` to deploy static files as Android Studio project
32 |
33 | - Backup
34 | - `npm run backup` to create snapshots of the Firebase database and user list
35 | - `npm run snapshot` to create a snapshot of your project folder
36 |
--------------------------------------------------------------------------------
/docs/setup.md:
--------------------------------------------------------------------------------
1 | # Setup your project
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | ## Installation
8 |
9 | Creating a new application project *my-app* is easily done in the following four steps:
10 |
11 | 1. Run `mkdir my-app` to create a new folder *my-app*
12 | 2. Run `cd my-app` to open the folder *my-app*
13 | 3. Run `echo {} > package.json` to create a *package.json* file
14 | 4. Run `npm install --save-dev app-framework@1` to
15 | - install App Framework and its dependencies
16 | - create the project folder structure
17 | - complete the *package.json* file
18 |
19 | After the installation process finished, you should see [this folder structure](folder-structure.md).
20 |
21 | You can run `npm run dev` to see if your new app opens in the browser.
22 |
23 | ## Update
24 |
25 | If there is a newer version of App Framework available at the [npm repository](https://www.npmjs.com/package/app-framework), there will be an alert at the development server.
26 |
27 | You have to update App Framework per application project by running `npm update --save-dev app-framework`.
28 |
29 | ## Notes
30 |
31 | The proper way to install the App Framework is to include it as a dev-dependency in your app's *package.json* file, i.e. it must be installed as a module, and not cloned as a repo. The *npm install* command will generate the appropriate directories in your app's root directory, and will add the relevant scripts to your app's *package.json* file.
32 |
--------------------------------------------------------------------------------
/demo/pages/f7material/virtual-list.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Virtual List
7 |
8 |
9 |
14 |
15 |
16 |
17 |
Virtual List allows to render lists with huge amount of elements without loss of performance. And it is fully compatible with all Framework7 list components such as Search Bar, Infinite Scroll, Pull To Refresh, Swipeouts (swipe-to-delete) and Sortable.
18 |
Here is the example of virtual list with 10 000 items:
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Nothing found
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/docs/dev-folder-structure.md:
--------------------------------------------------------------------------------
1 | # Folder structure
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | ```
8 | ├── .git/ # Git managed folder (do not modify)
9 | ├── build/ # Latest build files
10 | ├── client/ # Client code files
11 | ├── demo/ # Demo App files
12 | ├── design/ # Design templates (PDF and PPTX)
13 | ├── docs/ # Documentation files (configuration.md is updated on each build)
14 | ├── media/ # Graphics for documentation and promotion
15 | ├── node_modules/ # Installed node modules (do not modify)
16 | ├── scripts/ # Scripts and supporting files
17 | ├── snapshots/ # Snapshot files
18 | ├── vendor/ # Vendor files
19 | ├── .babelrc # Babel configuration file
20 | ├── .gitignore # List of ignored files for Git commits
21 | ├── CHANGELOG.md # Release changelog
22 | ├── config-scheme.json # Scheme for any application configuration file
23 | ├── DEVELOPMENT.md # Development documentation main page
24 | ├── DOCUMENTATION # End user documentation main page
25 | ├── LICENSE # App Framework license file (year is updated on each build)
26 | ├── package.json # App Framework project information
27 | └── README.md # Introduction, Features, Demo App, Documentation link
28 | ```
29 |
--------------------------------------------------------------------------------
/demo/pages/f7material/swiper-nested.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Nested Sliders
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Horizontal Slide 1
14 |
15 |
16 |
17 |
18 |
Vertical Slide 1
19 |
Vertical Slide 2
20 |
Vertical Slide 3
21 |
22 |
23 |
24 |
Horizontal Slide 3
25 |
Horizontal Slide 4
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/docs/cordova-plugins.md:
--------------------------------------------------------------------------------
1 | # Cordova plugins
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | ## Configuration
8 |
9 | App Framework supports well the usage of Cordova / PhoneGap plugins. You just have to add them in the configuration file. Example with [cordova-plugin-badge](https://github.com/katzer/cordova-plugin-badge):
10 |
11 | ```
12 | useCordovaPlugins: [
13 | "cordova-plugin-badge"
14 | ]
15 | ```
16 |
17 | ## Usage
18 |
19 | You can use the plugin now in any of your components. Example:
20 |
21 | ```
22 |
30 | ```
31 |
32 | Take care to use `window.` to access any plugin.
33 |
34 | ## Plugin repository
35 |
36 | You find a list of available plugins here: [https://cordova.apache.org/plugins](https://cordova.apache.org/plugins)
37 |
38 | ## Default plugins
39 |
40 | By default, [cordova-plugin-whitelist](https://github.com/apache/cordova-plugin-whitelist) and [cordova-plugin-statusbar](https://github.com/apache/cordova-plugin-statusbar) are included in the build.
41 |
42 | To simplify the usage, App Framework provides you an easier way to manipulate the status bar - please read the chapter [Status bar style](status-bar-style.md) for details.
43 |
44 | ## Availability
45 |
46 | Cordova plugins are only available in native applications or emulators, in the browser, they are undefined.
47 |
--------------------------------------------------------------------------------
/demo/pages/f7ios/swiper-nested.vue:
--------------------------------------------------------------------------------
1 |
2 |
Virtual List allows to render lists with huge amount of elements without loss of performance. And it is fully compatible with all Framework7 list components such as Search Bar, Infinite Scroll, Pull To Refresh, Swipeouts (swipe-to-delete) and Sortable.
18 |
Here is the example of virtual list with 10 000 items:
19 |
20 |
21 |
22 |
23 |
24 |
25 |
Nothing found
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/docs/page-components.md:
--------------------------------------------------------------------------------
1 | # Page components
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | The structure of each page component is defined in a Framework7-Vue component, so you should be familar with [Vue.js single file components](https://vuejs.org/v2/guide/single-file-components.html) as well as [Framework7-Vue](http://v1.framework7.io/vue/).
8 |
9 | ## File naming
10 |
11 | For page component naming, please read the chapter [Routing](routing.md).
12 |
13 | ## Structure
14 |
15 | A basic page component could look like this *app/pages/home.vue* file:
16 |
17 | ```
18 |
19 |
20 |
21 |
22 | Welcome to your App!
23 |
24 |
25 |
26 | ```
27 |
28 | Please read the [Framework7-Vue documentation](http://v1.framework7.io/vue/page.html) for page component structure details.
29 |
30 | To add CSS, you use the *style* block:
31 |
32 | ```
33 | ...
34 |
35 |
40 | ```
41 |
42 | To scope the style only for that page component, use `
31 | ```
32 |
33 | And to add functionality, you use the *script* block:
34 |
35 | ```
36 | ...
37 |
46 | ```
47 |
48 | In [Framework7-Vue documentation](http://v1.framework7.io/vue/app-layout.html), the app component is described as the *#app* div - you will find all details there.
49 |
50 | [Babel / ES2015](https://babeljs.io/learn-es2015/) is supported in the app component.
51 |
52 | You can pass custom Framework7 parameters to your application in the configuration file. Example:
53 |
54 | ```
55 | "framework7parameters": {
56 | "swipePanel": "left"
57 | }
58 | ```
59 |
--------------------------------------------------------------------------------
/demo/pages/f7material/swiper-3d-cube.vue:
--------------------------------------------------------------------------------
1 |
2 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/docs/application-style.md:
--------------------------------------------------------------------------------
1 | # Application style
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | ## Configuration
8 |
9 | You can set the following style options in the configuration file:
10 |
11 | ```
12 | theme: 'material', // 'ios', 'material', 'ios-material' or 'material-ios'
13 | color: 'indigo', // Any theme color name
14 | layout: 'default' // 'default', 'white' or 'dark'
15 | limitApplicationWidth: 320, // Pixel
16 | limitApplicationHeight: 570, // Pixel
17 | limitedSizeBodyBackgroundColor: '#333333', // HEX color code
18 | showPhoneFrameOnDesktop: true, // true or false
19 | phoneFrameBodyBackgroundColor: '#fafafa', // HEX color code
20 | framework7parameters: {} // Object, see Framework7 documentation
21 | ```
22 |
23 | If you want to change the theme during runtime, you need to use `ios-material` or `material-ios` as value in the configuration. With `ios-material`, the default theme will be ios, but you are able to change the theme to `material`, with `material-ios` in the configuration vice versa.
24 |
25 | You will reduce the build size if you configure either `ios` or `material`.
26 |
27 | Find more information about all theme color and layout options [here](http://v1.framework7.io/docs/color-themes.html).
28 |
29 | ## Runtime modification
30 |
31 | You can modify the style options during runtime in any Vue hook `created` or later:
32 |
33 | ```
34 | created: function () {
35 | this.$root.theme = 'material'
36 | this.$root.color = 'indigo'
37 | this.$root.layout = 'default'
38 | }
39 | ```
40 | The current style is restored after application restart and overwrites the configuration.
41 |
--------------------------------------------------------------------------------
/demo/pages/f7material/swiper-custom.vue:
--------------------------------------------------------------------------------
1 |
2 |
28 |
29 |
--------------------------------------------------------------------------------
/docs/dev-update-vendor-folder.md:
--------------------------------------------------------------------------------
1 | # Update vendor folder
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | ## Framework7
8 |
9 | To be able to use the newest master branch of Framework7 and let developers use their modified Framework7 build, it is shipped directly with App Framework in the *vendor* folder.
10 |
11 | To update Framework7 in the vendor folder:
12 |
13 | 1. Clone [Framework7 repo](https://github.com/nolimits4web/Framework7) in *Framework7* folder next to *app-framework* folder
14 | 2. Run `npm install` in *Framework7* folder
15 | 3. Run `npm run f7` in *app-framework* folder
16 |
17 | The kitchen sink files in the *demo* folder and the *client/theme-colors.json* file are updated as well.
18 |
19 | ## Framework7-Vue
20 |
21 | To be able to use the newest master branch of Framework7-Vue and let developers use their modified Framework7-Vue build, it is shipped directly with App Framework in the *vendor* folder.
22 |
23 | To update Framework7-Vue in the vendor folder:
24 |
25 | 1. Clone [Framework7-Vue repo](https://github.com/nolimits4web/Framework7-Vue) in *Framework7-Vue* folder next to *app-framework* folder
26 | 2. Run `npm install` in *Framework7-Vue* folder
27 | 3. Run `npm run f7vue` in *app-framework* folder
28 |
29 | ## Material Design Icons
30 |
31 | To avoid the need to install the huge Material Design Icons archive and to get the mapping between ligatures and codepoints, it is shipped directly with App Framework in the *vendor* folder.
32 |
33 | To update Material Design Icons in the vendor folder:
34 |
35 | 1. Clone [Material Design Icons repo](https://github.com/google/material-design-icons) in *material-design-icons* folder next to *app-framework* folder
36 | 2. Run `npm run iconfonts` in *app-framework* folder
37 |
38 | The *client/material-codepoints.json* file is updated as well.
39 |
--------------------------------------------------------------------------------
/demo/pages/f7material/swiper-3d-coverflow.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
3D Coverflow Effect
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Slide 1
14 |
Slide 2
15 |
Slide 3
16 |
Slide 4
17 |
Slide 5
18 |
Slide 6
19 |
Slide 7
20 |
Slide 8
21 |
Slide 9
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/docs/status-bar-style.md:
--------------------------------------------------------------------------------
1 | # Status bar style
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | ## Configuration
8 |
9 | You can configure the application status bar style in the configuration file:
10 |
11 | ```
12 | statusbarVisibility: true, // true or false
13 | statusbarTextColor: 'white', // 'black' or 'white'
14 | statusbarBackgroundColor: '#3f51b5', // Hex color code
15 | ```
16 |
17 | **changeStatusbarBackgroundColorOnThemeColorChange**
18 |
19 | This configuration option was removed with App Framework 1.9.15. You can apply the following code to your *app.vue* file to have the same behavior:
20 |
21 | ```
22 | created() {
23 | // Update status bar background and text color after theme color change
24 | this.$watch(() => {
25 | return this.$root.color
26 | }, (newColor, oldColor) => {
27 | this.$root.statusbarTextColor = newColor === 'white' ? 'black' : 'white'
28 | this.$root.statusbarBackgroundColor = newColor === 'white' && window.cordova === undefined ? '000000' : this.$root.colors[this.$root.theme][newColor]
29 | })
30 | }
31 | ```
32 |
33 | ## Runtime modification
34 |
35 | You can modify the application status bar style in any Vue hook `created` or later:
36 |
37 | ```
38 | created: function () {
39 | this.$root.statusbarVisibility = true
40 | this.$root.statusbarTextColor = 'white'
41 | this.$root.statusbarBackgroundColor = '#3f51b5'
42 | }
43 | ```
44 |
45 | The current style is restored after application restart and overwrites the configuration.
46 |
47 | ## Limitations
48 |
49 | - Changing the status bar visibility is limited to native applications
50 | - Changing the status bar text color is limited to iOS native applications
51 | - Changing the status bar background color is limited to native or homescreen applications
52 |
--------------------------------------------------------------------------------
/demo/pages/f7ios/swiper-3d-coverflow.vue:
--------------------------------------------------------------------------------
1 |
2 |
One of the main target of Framework7 is to have native look and feeling of iOS application. And Framework7 is the only framework that solves it and offers 1:1 page animation with smooth parallax effect, changing opacity and shadow when loading
14 | new page.
15 |
16 |
17 |
Swipe Back
18 |
19 |
20 |
One of Framework7' killing feature is supporting of iOS well known swipe back gesture from left border of screen when you want to get to the previous page. It simply works, and works perfectly as you expect it to do. Just swipe from left (or drag
21 | with mouse) area of the page to see smooth transition to the previous page. It is not just A-B transition. It really follows your finger with parallax animation while touch!
22 |
23 |
24 |
Dynamic Navbar
25 |
26 |
27 |
As was mentioned already Framework7 makes everything to give you a feel of native iOS app. And one of the significant feature that improves this feeling is the dynamic navigation bar (navbar). You can see how its elements sliding and fading during
28 | pages transition and when you swipe back.
Photo Browser is a standalone and highly configurable component that allows to open window with photo viewer and navigation elements with the following features:
12 |
13 |
Swiper between photos
14 |
Multi-gestures support for zooming
15 |
Toggle zoom by double tap on photo
16 |
Single click on photo to toggle Exposition mode
17 |
18 |
Photo Browser could be opened in a three ways - as a Standalone component, in Popup, and as separate Page:
For Popup and Standalone types, Photo Browser suppots 2 default themes - default Light (like in previous examples) and Dark theme. Here is a Dark theme examples:
Framework7 comes with default 10 iOS color themes set and three layout color themes (default, dark and pure white):
12 |
13 |
Choose Layout Theme
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
Choose Color Theme
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/docs/state-restoration.md:
--------------------------------------------------------------------------------
1 | # State restoration
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | After an application switch or closure, the application state may be reset. This means, if your user changed the page or tab, scrolled, opened modals, put in some data before - everything will be gone.
8 |
9 | App Framework has an automatic state restoration on each application restart, to let your users continue with the same application state they have had before they left the application.
10 |
11 | This restoration includes the following elements:
12 |
13 | - URL history per view (requires unique class or ID attribute per view)
14 | - Selected tabs (requires unique ID attribute per page)
15 | - Scroll positions
16 | - Side panels
17 | - Action sheets (requires unique ID attribute)
18 | - Login screens (requires unique ID attribute)
19 | - Pickers (requires unique ID attribute)
20 | - Popups (requires unique ID attribute)
21 | - Form inputs (requires unique form ID attribute and unique NAME attributes per form)
22 | - Focus on form input (requires unique form ID attribute and unique NAME attributes per form)
23 | - Page component data
24 |
25 | The state is not restored for standard modals, popovers and code-generated modals.
26 |
27 | If you use `v-model` on an input, the state will be restored by page component data, you can use a name attribute to restore the form focus, but it is not required in this case to restore form input.
28 |
29 | ## URL history per view
30 |
31 | With App Framework > 1.9.0. and configuration setting `restoreHistory: false`, only the last URL per view will be restored.
32 |
33 | This solves issues where pages have been loaded several times in the DOM.
34 |
35 | But you have to take care now to assign a `href` or `back-link-url` property to each backlink, as described in the Framework7-Vue documentation for [links](http://v1.framework7.io/vue/link.html) or [navbars](http://v1.framework7.io/vue/navbar.html).
36 |
37 | ## Page component data
38 |
39 | With App Framework > 1.11.0 you can disable the page component data restoration with `restoreComponentData: false` in the configuration file.
40 |
--------------------------------------------------------------------------------
/demo/pages/f7material/photo-browser.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Photo Browser
7 |
8 |
9 |
10 |
11 |
Photo Browser is a standalone and highly configurable component that allows to open window with photo viewer and navigation elements with the following features:
12 |
13 |
Swiper between photos
14 |
Multi-gestures support for zooming
15 |
Toggle zoom by double tap on photo
16 |
Single click on photo to toggle Exposition mode
17 |
18 |
Photo Browser could be opened in a three ways - as a Standalone component, in Popup, and as separate Page:
For Popup and Standalone types, Photo Browser suppots 2 default themes - default Light (like in previous examples) and Dark theme. Here is a Dark theme examples:
Just pull page down to let the magic happen. Note that pull-to-refresh feature is optimised for touch and native scrolling so it may not work on desktop browser.
Just pull page down to let the magic happen. Note that pull-to-refresh feature is optimised for touch and native scrolling so it may not work on desktop browser.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sit amet rhoncus odio. Suspendisse vel lectus neque. Mauris tincidunt dolor a felis vulputate, at accumsan risus convallis. Sed pulvinar malesuada enim, a consequat felis lobortis
13 | a. Morbi faucibus felis in libero lacinia blandit. Pellentesque vitae volutpat metus. In venenatis mauris massa, sed hendrerit augue pulvinar nec. Sed justo magna, lacinia vel tincidunt sed, tristique sit amet est. Nam iaculis dictum laoreet.
14 | Donec sed risus sed mauris ultricies aliquam sit amet in enim. Nullam tellus est, imperdiet et adipiscing consequat, consectetur vel nibh. Cras massa nibh, volutpat sit amet velit vel, suscipit tincidunt enim. Curabitur luctus elit id pharetra
15 | bibendum. Nulla ut dui eget nulla hendrerit commodo. Pellentesque placerat mi eget dolor rutrum, consectetur mattis mi tincidunt.
16 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sit amet rhoncus odio. Suspendisse vel lectus neque. Mauris tincidunt dolor a felis vulputate, at accumsan risus convallis. Sed pulvinar malesuada enim, a consequat felis lobortis
17 | a. Morbi faucibus felis in libero lacinia blandit. Pellentesque vitae volutpat metus. In venenatis mauris massa, sed hendrerit augue pulvinar nec. Sed justo magna, lacinia vel tincidunt sed, tristique sit amet est. Nam iaculis dictum laoreet.
18 | Donec sed risus sed mauris ultricies aliquam sit amet in enim. Nullam tellus est, imperdiet et adipiscing consequat, consectetur vel nibh. Cras massa nibh, volutpat sit amet velit vel, suscipit tincidunt enim. Curabitur luctus elit id pharetra
19 | bibendum. Nulla ut dui eget nulla hendrerit commodo. Pellentesque placerat mi eget dolor rutrum, consectetur mattis mi tincidunt.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sit amet rhoncus odio. Suspendisse vel lectus neque. Mauris tincidunt dolor a felis vulputate, at accumsan risus convallis. Sed pulvinar malesuada enim, a consequat felis lobortis
13 | a. Morbi faucibus felis in libero lacinia blandit. Pellentesque vitae volutpat metus. In venenatis mauris massa, sed hendrerit augue pulvinar nec. Sed justo magna, lacinia vel tincidunt sed, tristique sit amet est. Nam iaculis dictum laoreet.
14 | Donec sed risus sed mauris ultricies aliquam sit amet in enim. Nullam tellus est, imperdiet et adipiscing consequat, consectetur vel nibh. Cras massa nibh, volutpat sit amet velit vel, suscipit tincidunt enim. Curabitur luctus elit id pharetra
15 | bibendum. Nulla ut dui eget nulla hendrerit commodo. Pellentesque placerat mi eget dolor rutrum, consectetur mattis mi tincidunt.
16 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sit amet rhoncus odio. Suspendisse vel lectus neque. Mauris tincidunt dolor a felis vulputate, at accumsan risus convallis. Sed pulvinar malesuada enim, a consequat felis lobortis
17 | a. Morbi faucibus felis in libero lacinia blandit. Pellentesque vitae volutpat metus. In venenatis mauris massa, sed hendrerit augue pulvinar nec. Sed justo magna, lacinia vel tincidunt sed, tristique sit amet est. Nam iaculis dictum laoreet.
18 | Donec sed risus sed mauris ultricies aliquam sit amet in enim. Nullam tellus est, imperdiet et adipiscing consequat, consectetur vel nibh. Cras massa nibh, volutpat sit amet velit vel, suscipit tincidunt enim. Curabitur luctus elit id pharetra
19 | bibendum. Nulla ut dui eget nulla hendrerit commodo. Pellentesque placerat mi eget dolor rutrum, consectetur mattis mi tincidunt.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sit amet rhoncus odio. Suspendisse vel lectus neque. Mauris tincidunt dolor a felis vulputate, at accumsan risus convallis. Sed pulvinar malesuada enim, a consequat felis lobortis
13 | a. Morbi faucibus felis in libero lacinia blandit. Pellentesque vitae volutpat metus. In venenatis mauris massa, sed hendrerit augue pulvinar nec. Sed justo magna, lacinia vel tincidunt sed, tristique sit amet est. Nam iaculis dictum laoreet.
14 | Donec sed risus sed mauris ultricies aliquam sit amet in enim. Nullam tellus est, imperdiet et adipiscing consequat, consectetur vel nibh. Cras massa nibh, volutpat sit amet velit vel, suscipit tincidunt enim. Curabitur luctus elit id pharetra
15 | bibendum. Nulla ut dui eget nulla hendrerit commodo. Pellentesque placerat mi eget dolor rutrum, consectetur mattis mi tincidunt.
16 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sit amet rhoncus odio. Suspendisse vel lectus neque. Mauris tincidunt dolor a felis vulputate, at accumsan risus convallis. Sed pulvinar malesuada enim, a consequat felis lobortis
17 | a. Morbi faucibus felis in libero lacinia blandit. Pellentesque vitae volutpat metus. In venenatis mauris massa, sed hendrerit augue pulvinar nec. Sed justo magna, lacinia vel tincidunt sed, tristique sit amet est. Nam iaculis dictum laoreet.
18 | Donec sed risus sed mauris ultricies aliquam sit amet in enim. Nullam tellus est, imperdiet et adipiscing consequat, consectetur vel nibh. Cras massa nibh, volutpat sit amet velit vel, suscipit tincidunt enim. Curabitur luctus elit id pharetra
19 | bibendum. Nulla ut dui eget nulla hendrerit commodo. Pellentesque placerat mi eget dolor rutrum, consectetur mattis mi tincidunt.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sit amet rhoncus odio. Suspendisse vel lectus neque. Mauris tincidunt dolor a felis vulputate, at accumsan risus convallis. Sed pulvinar malesuada enim, a consequat felis lobortis
13 | a. Morbi faucibus felis in libero lacinia blandit. Pellentesque vitae volutpat metus. In venenatis mauris massa, sed hendrerit augue pulvinar nec. Sed justo magna, lacinia vel tincidunt sed, tristique sit amet est. Nam iaculis dictum laoreet.
14 | Donec sed risus sed mauris ultricies aliquam sit amet in enim. Nullam tellus est, imperdiet et adipiscing consequat, consectetur vel nibh. Cras massa nibh, volutpat sit amet velit vel, suscipit tincidunt enim. Curabitur luctus elit id pharetra
15 | bibendum. Nulla ut dui eget nulla hendrerit commodo. Pellentesque placerat mi eget dolor rutrum, consectetur mattis mi tincidunt.
16 |
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sit amet rhoncus odio. Suspendisse vel lectus neque. Mauris tincidunt dolor a felis vulputate, at accumsan risus convallis. Sed pulvinar malesuada enim, a consequat felis lobortis
17 | a. Morbi faucibus felis in libero lacinia blandit. Pellentesque vitae volutpat metus. In venenatis mauris massa, sed hendrerit augue pulvinar nec. Sed justo magna, lacinia vel tincidunt sed, tristique sit amet est. Nam iaculis dictum laoreet.
18 | Donec sed risus sed mauris ultricies aliquam sit amet in enim. Nullam tellus est, imperdiet et adipiscing consequat, consectetur vel nibh. Cras massa nibh, volutpat sit amet velit vel, suscipit tincidunt enim. Curabitur luctus elit id pharetra
19 | bibendum. Nulla ut dui eget nulla hendrerit commodo. Pellentesque placerat mi eget dolor rutrum, consectetur mattis mi tincidunt.
How about an activity indicator? Framework 7 has a nice one. The F7 preloader is made with SVG and animated with CSS so it can be easily resized. Two options are available: the default is for light background and another one is for dark background.
12 | The HTML is pretty easy, just add a .preloader class to any element. For the dark background option, also add a .preloader-white class. Here are some examples:
13 |
14 |
15 |
Default:
16 |
White:
17 |
Big:
18 |
White:
19 |
20 |
21 |
Preloader also support all default color themes:
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
With app.showIndicator() you can call small overlay with indicator:
How about an activity indicator? Framework 7 has a nice one. The F7 preloader is made with SVG and animated with CSS so it can be easily resized. Two options are available: the default is for light background and another one is for dark background.
12 | The HTML is pretty easy, just add a .preloader class to any element. For the dark background option, also add a .preloader-white class. Here are some examples:
13 |
14 |
15 |
Default:
16 |
White:
17 |
Big:
18 |
White:
19 |
20 |
21 |
Preloader also support all default color themes:
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
With app.showIndicator() you can call small overlay with indicator:
There are 1:1 replacements of native Alert, Prompt and Confirm modals. They support callbacks, have very easy api and can be combined with each other. Check these examples:
This feature doesn't allow to open multiple modals at the same time, and will automatically open next modal when you close the current one. Such behavior is similar to browser native alerts:
33 |
34 |
--------------------------------------------------------------------------------
/docs/dev-way-of-working.md:
--------------------------------------------------------------------------------
1 | # Way of working
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | ## Changes
8 |
9 | For each change to App Framework code, please follow these steps:
10 |
11 | 1. Create an issue
12 | - Will be categorized as "new feature", "bug" or "improvement"
13 | - Should be discussed for new features
14 | 2. Create a branch
15 | - Should be named "feature-123", "fix-123" or "enhancement-123" where 123 is the issue number
16 | 3. Develop the solution
17 | - Update the postinstall routine to apply changes to previous versions
18 | - On variables change, check dependencies in source code
19 | - On file change, check dependencies in source code
20 | 4. Test the solution
21 | - On macOS / Windows / Linux after changes to *scripts* folder
22 | - On iOS / Android / Web after changes to *client* or *demo* folder
23 | - With a new / updated project after changes to the postinstall routine
24 | 5. Update the documentation
25 | - Features in file *README.md*
26 | - Documentation in folder *docs*
27 | 6. Commit the branch as a pull request
28 |
29 | ## Pull requests
30 |
31 | For each new pull request, please follow these steps:
32 |
33 | 1. Verify the testing
34 | - Discuss findings in the pull request
35 | 2. Verify the documentation update
36 | - Discuss findings in the pull request
37 | 3. Merge the pull request and delete the branch
38 | 4. Add the issue in file *CHANGELOG.md* for the next version
39 | 6. Close the issue with reference to the pull request
40 |
41 | ## Releases
42 |
43 | For each release, please follow these steps:
44 |
45 | 1. Build a new App Framework version and commit it to GitHub
46 | - Run `npm run patch` after bug-fixes and improvements (version bump to x.y.z+1)
47 | - Run `npm run minor` after adding new functionality (version bump to x.y+1.0)
48 | - Run `npm run major` after breaking backward-capability (version bump to x+1.0.0)
49 | 2. Update the version with release date in file *CHANGELOG.md* and commit it to GitHub
50 | 3. Publish to the [npm repository](https://www.npmjs.com/package/app-framework) with `npm publish`
51 | 4. Deploy new Demo App version
52 | - to Firebase hosting with `npm run firebase`
53 | - to Google Play Store, update all information before commit ([read documentation](deploy.md))
54 | - to Apple App Store, update all information before commit ([read documentation](deploy.md))
55 | 5. Update external documentation
56 | - [Framework7-Vue: Overview](https://v1.framework7.io/vue/)
57 | - [Framework7-Vue: Starter App Templates](https://v1.framework7.io/vue/templates.html)
58 | 6. Promote new version
59 |
--------------------------------------------------------------------------------
/scripts/cmd.js:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Purpose: Run a child process and, depending on the result, run onSuccess() or onError() callbacks.
4 |
5 | cmd(workingDirectory , commands , [onSuccess , [onError ]])
6 |
7 | */
8 |
9 | 'use strict'
10 |
11 | // Import modules
12 | let alert = require('./alert')
13 | let type = require('./type')
14 | let cp = require('child_process')
15 | let path = require('path')
16 |
17 | // Export function
18 | module.exports = function (workingDirectory, commands, onSuccess, onError) {
19 | // Check number of argument
20 | if (arguments.length < 2 < arguments.length > 4) {
21 | alert('cmd() funtions needs two to four arguments.', 'issue')
22 | }
23 | // Check working directory
24 | if (type(workingDirectory) === 'array') {
25 | workingDirectory = path.resolve.apply(null, workingDirectory)
26 | } else if (type(workingDirectory) !== 'string') {
27 | alert('cmd() functions needs string as first argument.', 'issue')
28 | }
29 | // Check commands
30 | if (type(commands) === 'string') {
31 | commands = commands.split(' ')
32 | } else if (type(commands) !== 'array') {
33 | alert('cmd() functions needs string or array as second argument.', 'issue')
34 | }
35 | // Check onSuccess
36 | if (type(onSuccess) === 'string') {
37 | let msg = onSuccess
38 | onSuccess = function () {
39 | alert(msg)
40 | }
41 | } else if (onSuccess === undefined || type(onSuccess) === 'null') {
42 | onSuccess = function () {}
43 | } else if (type(onSuccess) !== 'function') {
44 | alert('cmd() functions needs null, string or function as third argument.', 'issue')
45 | }
46 | // Check onError
47 | if (type(onError) === 'string') {
48 | let msg = onError
49 | onError = function () {
50 | alert(msg, 'error')
51 | }
52 | } else if (onError === undefined) {
53 | onError = function () {
54 | process.exit(process.env.subProcess === 'true' ? 1 : 0)
55 | }
56 | } else if (type(onError) !== 'function') {
57 | alert('cmd() functions needs string or function as fourth argument.', 'issue')
58 | }
59 | // Define child process environment variables, set subProcess to "true"
60 | let env = JSON.parse(JSON.stringify(process.env))
61 | env.subProcess = true
62 | // Run sub process
63 | cp.spawn(commands.shift(), commands, {
64 | cwd: workingDirectory,
65 | env: env,
66 | stdio: 'inherit',
67 | shell: true
68 | })
69 | // Callback on sub process closure
70 | .on('close', function (exitCode) {
71 | if (exitCode === 0) {
72 | onSuccess()
73 | } else {
74 | onError()
75 | }
76 | })
77 | }
78 |
--------------------------------------------------------------------------------
/demo/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "App Framework",
3 | "defaultLanguage": "en",
4 | "defaultLanguageFallback": false,
5 | "theme": "material-ios",
6 | "color": "indigo",
7 | "layout": "default",
8 | "statusbarVisibility": false,
9 | "statusbarTextColor": "white",
10 | "statusbarBackgroundColor": "#3f51b5",
11 | "iconBackgroundColor": "#ffffff",
12 | "useIconFonts": {
13 | "framework7": true,
14 | "material": true,
15 | "ion": false,
16 | "fontawesome": false
17 | },
18 | "limitApplicationWidth": 320,
19 | "limitApplicationHeight": 570,
20 | "limitedSizeBodyBackgroundColor": "#333333",
21 | "showPhoneFrameOnDesktop": true,
22 | "phoneFrameBodyBackgroundColor": "#fafafa",
23 | "framework7parameters": {},
24 | "materialSubnavbarFix": true,
25 | "restoreHistory": true,
26 | "restoreComponentData": true,
27 | "completeRoutesFile": true,
28 | "firebase": {
29 | "apiKey": "AIzaSyAvzTiqd9fKR-h47Uxl4iXwqSMU1VjGdII",
30 | "authDomain": "app-framework-9045a.firebaseapp.com",
31 | "databaseURL": "https://app-framework-9045a.firebaseio.com",
32 | "storageBucket": "app-framework-9045a.appspot.com",
33 | "projectId": "app-framework-9045a",
34 | "allowEmailLogin": true,
35 | "allowEmailRegistration": true
36 | },
37 | "devFirebase": {
38 | "deployDevRulesOnTesting": false,
39 | "apiKey": "AIzaSyBL0Xxsc-jFZ2BnmQV08T4O9B56HJVpwXk",
40 | "authDomain": "dev-app-framework.firebaseapp.com",
41 | "databaseURL": "https://dev-app-framework.firebaseio.com",
42 | "storageBucket": "dev-app-framework.appspot.com",
43 | "projectId": "app-framework-9045a",
44 | "allowEmailLogin": true,
45 | "allowEmailRegistration": false
46 | },
47 | "loginRequiredForAllPages": false,
48 | "appStoreId": "de.scriptpilot.app-framework",
49 | "playStoreId": "de.scriptpilot.appframework",
50 | "useCordovaPlugins": [
51 | "cordova-plugin-camera",
52 | "cordova-plugin-file"
53 | ],
54 | "cordovaPreferences": {
55 | "DisallowOverscroll": true
56 | },
57 | "resetLocalStorageOnVersionChange": false,
58 | "preloadImages": true,
59 | "buildSourcemaps": false,
60 | "editorConfig": {
61 | "root": "true",
62 | "[*]": null,
63 | "indent_style": "space",
64 | "indent_size": 2,
65 | "charset": "utf-8",
66 | "trim_trailing_whitespace": "true",
67 | "insert_final_newline": "true",
68 | "end_of_line": "lf",
69 | "max_line_length": "null"
70 | },
71 | "eslint": {
72 | "extends": "standard",
73 | "rules": {}
74 | },
75 | "fixCodeOnTest": true,
76 | "fixCodeOnBuild": true,
77 | "devServerPort": "8080",
78 | "gitignore": {},
79 | "npmignore": {},
80 | "debug": false
81 | }
82 |
--------------------------------------------------------------------------------
/docs/data-object.md:
--------------------------------------------------------------------------------
1 | # Global data object
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | App Framework provides a global persistent data object for common used data or settings.
8 |
9 | The data object will be restored on each application reload and is accessible in any Vue hook `created` or later.
10 |
11 | ## With App Framework v1.13.2 or later
12 |
13 | **Save data**
14 | - Template: `Save data`
15 | - Script: `this.$db('main.sub', 'value')`
16 |
17 | **Get data**
18 | - Template: `{{$db('main.sub')}}`
19 | - Script: `this.$db('main.sub')`
20 |
21 | **Remove data**
22 | - Template: `Remove data`
23 | - Script: `this.$db('main.sub', null)`
24 |
25 | **Notes**
26 |
27 | `main.sub` mean the paths within the data object. With a point, you can realize nested objects. Example:
28 |
29 | ```
30 | {
31 | "main": {
32 | "sub": "value"
33 | }
34 | }
35 | ```
36 |
37 | ## With App Framework v1.12 or later
38 |
39 | **Save data**
40 |
41 | - Template: ```Save data```
42 | - Script: ```this.$save('main.sub', 'value')```
43 |
44 | **Get data**
45 |
46 | - Template: ```{{$get.main.sub}}```
47 | - Script: ```this.$get.main.sub```
48 |
49 | **Remove data**
50 |
51 | - Template: ```Remove data```
52 | - Script: ```this.$remove('main.sub')```
53 |
54 | ## With App Framework v1.11 or before
55 |
56 | - To save data, use `this.$root.saveData(path, value)`
57 | - To remove data, use `this.$root.removeData(path)`
58 | - To retrieve data, use `this.$root.data.path`
59 |
60 | The *path* must be a string, use a a point to nest data. Example:
61 |
62 | ```
63 | created: function () {
64 | this.$root.saveData('greeting', 'Hello!')
65 | this.$root.saveData('names', {first: 'Jan', second: 'Tom', third: 'Sophie'})
66 | this.$root.removeData('names.second')
67 | }
68 | ```
69 |
70 | Now, the data object will look like following:
71 |
72 | ```
73 | {
74 | greeting: 'Hello!',
75 | names: {
76 | first: 'Jan',
77 | third: 'Sophie'
78 | }
79 | }
80 | ```
81 |
82 | Example for the usage in templates:
83 |
84 | ```
85 |
86 |
UTC date: {{$root.data.dateString}}
87 |
88 | Update date
89 | Remove date
90 |
91 |
92 | ```
93 |
94 | Do not modify `$root.data` directly, because there wont be any update triggered.
95 |
--------------------------------------------------------------------------------
/scripts/checkLanguageFiles.js:
--------------------------------------------------------------------------------
1 | // Purpose: Check language files, compare to default language file and sort each file by keys
2 |
3 | // Load modules
4 | const env = require('./env')
5 | const alert = require('./alert')
6 | const found = require('./found')
7 | const fs = require('fs-extra')
8 | const path = require('path')
9 | const abs = require('path').resolve
10 | const rec = require('recursive-readdir-sync')
11 | const sort = require('sort-keys-recursive')
12 |
13 | // Define language folder
14 | const langFolder = abs(env.app, 'lang')
15 |
16 | // Check if default language file exists
17 | const defaultLangFile = abs(langFolder, env.cfg.defaultLanguage + '.json')
18 | if (!found(defaultLangFile)) {
19 | alert(`Default language file lang/${env.cfg.defaultLanguage}.json not found.`, 'error')
20 | }
21 |
22 | // Check if all language files are valid and sort each by key
23 | const langPatterns = {}
24 | try {
25 | const files = rec(langFolder)
26 | files.forEach((file) => {
27 | const patterns = fs.readJsonSync(file)
28 | const language = path.basename(file).slice(0, -5)
29 | langPatterns[language] = patterns
30 | fs.writeJsonSync(file, sort(patterns), { spaces: 2 })
31 | })
32 | } catch (err) {
33 | alert('Failed to read language files.', 'issue')
34 | }
35 |
36 | // Check all files if they have flat key:string pairs
37 | for (let lang in langPatterns) {
38 | let errors = 0
39 | for (let key in langPatterns[lang]) {
40 | if (typeof langPatterns[lang][key] !== 'string') {
41 | errors++
42 | }
43 | }
44 | if (errors > 0) {
45 | alert(`Language file lang/${lang}.json should contain plain key:string pairs.`, 'error')
46 | }
47 | }
48 |
49 | // Compare languages files to default language file
50 | // Loop all languages
51 | for (let lang in langPatterns) {
52 | // It's not the default language
53 | if (lang !== env.cfg.defaultLanguage) {
54 | const diffs = []
55 | // Loop all items of the default language
56 | if (env.cfg.defaultLanguageFallback === false) {
57 | for (let key in langPatterns[env.cfg.defaultLanguage]) {
58 | // Missing items
59 | if (langPatterns[lang][key] === undefined) {
60 | diffs.push(`"${key}" is missing`)
61 | }
62 | }
63 | }
64 | // Loop all items of the second language
65 | for (let key in langPatterns[lang]) {
66 | // Too much items
67 | if (langPatterns[env.cfg.defaultLanguage][key] === undefined) {
68 | diffs.push(`"${key}" is too much`)
69 | }
70 | }
71 | // Differences found
72 | if (diffs.length > 0) {
73 | alert(`Language file lang/${lang}.json is different to the default one:\n- ` + diffs.join('\n- '), 'error')
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/docs/images.md:
--------------------------------------------------------------------------------
1 | # Images
2 |
3 | > This page is part of the [App Framework Documentation](../DOCUMENTATION.md)
4 |
5 |
6 |
7 | ## Image usage
8 |
9 | To use images in your application, you have to save them first in the `app/images` folder and point to them with a relative path in the *src* attribute.
10 |
11 | ```
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ```
20 |
21 | To remove images, you should remove the image tag first and delete the file afterwards.
22 |
23 | ## Dynamic image usage
24 |
25 | During the build process, all *src* attributes are parsed by Webpack and mapped to the hashed image files. This does only work, if the *src* contains a string only - no variables.
26 |
27 | So, for dynamic images, you should use single *img* elements and display them or not.
28 |
29 | The following example shows *imageA.png* initially and after five seconds *imageB.png*.
30 |
31 | ```
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
54 | ```
55 |
56 | Another solution is, that you require all images in the script:
57 |
58 | ```
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
80 | ```
81 |
82 | ## Image preloading
83 |
84 | App Framework provides image preloading by default. This means, all files in the folder `app/images` are loaded while the preloading page is shown and before the application is initialized.
85 |
86 | This could increase the initial loading time, but will improve the behavior of your application because all images are immediately visible.
87 |
88 | To disable image preloading, set `preloadImages: false` in the configuration file. To use the updated setting, you have to restart the development server.
89 |
90 | To update the preloader after adding new images to your application, you have to restart the development server as well.
91 |
--------------------------------------------------------------------------------
/demo/app.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |