[DE][mobile] framework7-react project
40
apps/documenteditor/mobile/.gitignore
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
|
||||
|
||||
# Production build
|
||||
www/
|
74
apps/documenteditor/mobile/README.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
# Desktop Editor
|
||||
|
||||
## Framework7 CLI Options
|
||||
|
||||
Framework7 app created with following options:
|
||||
|
||||
```
|
||||
{
|
||||
"cwd": "E:\\Work\\Projects\\WebOffice\\web-apps\\apps\\documenteditor\\mobile",
|
||||
"type": [
|
||||
"web"
|
||||
],
|
||||
"name": "Desktop Editor",
|
||||
"framework": "react",
|
||||
"template": "split-view",
|
||||
"cssPreProcessor": "less",
|
||||
"bundler": "webpack",
|
||||
"webpack": {
|
||||
"developmentSourceMap": true,
|
||||
"productionSourceMap": true,
|
||||
"hashAssets": false,
|
||||
"preserveAssetsPaths": false,
|
||||
"inlineAssets": true
|
||||
},
|
||||
"theming": {
|
||||
"customColor": false,
|
||||
"color": "#007aff",
|
||||
"darkTheme": false,
|
||||
"iconFonts": true,
|
||||
"fillBars": false
|
||||
},
|
||||
"customBuild": false
|
||||
}
|
||||
```
|
||||
|
||||
## NPM Scripts
|
||||
|
||||
* 🔥 `start` - run development server
|
||||
* 🔧 `dev` - run development server
|
||||
* 🔧 `build-dev` - build web app using development mode (faster build without minification and optimization)
|
||||
* 🔧 `build-prod` - build web app for production
|
||||
|
||||
## WebPack
|
||||
|
||||
There is a webpack bundler setup. It compiles and bundles all "front-end" resources. You should work only with files located in `/src` folder. Webpack config located in `build/webpack.config.js`.
|
||||
|
||||
Webpack has specific way of handling static assets (CSS files, images, audios). You can learn more about correct way of doing things on [official webpack documentation](https://webpack.js.org/guides/asset-management/).
|
||||
## Assets
|
||||
|
||||
Assets (icons, splash screens) source images located in `assets-src` folder. To generate your own icons and splash screen images, you will need to replace all assets in this directory with your own images (pay attention to image size and format), and run the following command in the project directory:
|
||||
|
||||
```
|
||||
framework7 assets
|
||||
```
|
||||
|
||||
Or launch UI where you will be able to change icons and splash screens:
|
||||
|
||||
```
|
||||
framework7 assets --ui
|
||||
```
|
||||
|
||||
## Documentation & Resources
|
||||
|
||||
* [Framework7 Core Documentation](https://framework7.io/docs/)
|
||||
|
||||
* [Framework7 React Documentation](https://framework7.io/react/)
|
||||
|
||||
* [Framework7 Icons Reference](https://framework7.io/icons/)
|
||||
* [Community Forum](https://forum.framework7.io)
|
||||
|
||||
## Support Framework7
|
||||
|
||||
Love Framework7? Support project by donating or pledging on patreon:
|
||||
https://patreon.com/vladimirkharlampidi
|
BIN
apps/documenteditor/mobile/assets-src/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
apps/documenteditor/mobile/assets-src/web-icon.png
Normal file
After Width: | Height: | Size: 15 KiB |
12
apps/documenteditor/mobile/babel.config.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@babel/preset-react',
|
||||
['@babel/preset-env', {
|
||||
modules: false,
|
||||
}],
|
||||
],
|
||||
plugins: [
|
||||
'@babel/plugin-transform-runtime',
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
],
|
||||
};
|
36
apps/documenteditor/mobile/build/build.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
const webpack = require('webpack');
|
||||
const ora = require('ora');
|
||||
const rm = require('rimraf');
|
||||
const chalk = require('chalk');
|
||||
const config = require('./webpack.config.js');
|
||||
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
const target = process.env.TARGET || 'web';
|
||||
const isCordova = target === 'cordova'
|
||||
|
||||
const spinner = ora(env === 'production' ? 'building for production...' : 'building development version...');
|
||||
spinner.start();
|
||||
|
||||
rm(isCordova ? './cordova/www' : './www/', (removeErr) => {
|
||||
if (removeErr) throw removeErr;
|
||||
|
||||
webpack(config, (err, stats) => {
|
||||
if (err) throw err;
|
||||
spinner.stop();
|
||||
|
||||
process.stdout.write(`${stats.toString({
|
||||
colors: true,
|
||||
modules: false,
|
||||
children: false, // If you are using ts-loader, setting this to true will make TypeScript errors show up during build.
|
||||
chunks: false,
|
||||
chunkModules: false,
|
||||
})}\n\n`);
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
console.log(chalk.red('Build failed with errors.\n'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log(chalk.cyan('Build complete.\n'));
|
||||
});
|
||||
});
|
232
apps/documenteditor/mobile/build/webpack.config.js
Normal file
|
@ -0,0 +1,232 @@
|
|||
const webpack = require('webpack');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
|
||||
|
||||
const path = require('path');
|
||||
|
||||
function resolvePath(dir) {
|
||||
return path.join(__dirname, '..', dir);
|
||||
}
|
||||
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
const target = process.env.TARGET || 'web';
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
mode: env,
|
||||
entry: {
|
||||
app: './src/js/app.js',
|
||||
},
|
||||
output: {
|
||||
path: resolvePath('./'),
|
||||
filename: 'js/[name].js',
|
||||
chunkFilename: 'js/[name].js',
|
||||
publicPath: '',
|
||||
hotUpdateChunkFilename: 'hot/hot-update.js',
|
||||
hotUpdateMainFilename: 'hot/hot-update.json',
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx', '.json'],
|
||||
alias: {
|
||||
|
||||
'@': resolvePath('src'),
|
||||
},
|
||||
|
||||
},
|
||||
watch: true,
|
||||
watchOptions: {
|
||||
aggregateTimeout: 600,
|
||||
poll: 1000,
|
||||
},
|
||||
externals: {
|
||||
jquery: 'jQuery'
|
||||
},
|
||||
devtool: env === 'production' ? 'source-map' : 'source-map',
|
||||
devServer: {
|
||||
hot: true,
|
||||
open: false,
|
||||
compress: true,
|
||||
contentBase: '/www/',
|
||||
disableHostCheck: true,
|
||||
historyApiFallback: true,
|
||||
watchOptions: {
|
||||
poll: 1000,
|
||||
},
|
||||
},
|
||||
optimization: {
|
||||
minimizer: [new TerserPlugin({
|
||||
sourceMap: true,
|
||||
})],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(mjs|js|jsx)$/,
|
||||
use: 'babel-loader',
|
||||
include: [
|
||||
resolvePath('src'),
|
||||
resolvePath('node_modules/framework7'),
|
||||
|
||||
resolvePath('node_modules/framework7-react'),
|
||||
|
||||
resolvePath('node_modules/template7'),
|
||||
resolvePath('node_modules/dom7'),
|
||||
resolvePath('node_modules/ssr-window'),
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
(env === 'development' ? 'style-loader' : {
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
publicPath: '../www'
|
||||
}
|
||||
}),
|
||||
'css-loader',
|
||||
'postcss-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.styl(us)?$/,
|
||||
use: [
|
||||
(env === 'development' ? 'style-loader' : {
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
publicPath: '../www'
|
||||
}
|
||||
}),
|
||||
'css-loader',
|
||||
'postcss-loader',
|
||||
'stylus-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: [
|
||||
(env === 'development' ? 'style-loader' : {
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
publicPath: '../www'
|
||||
}
|
||||
}),
|
||||
'css-loader',
|
||||
'postcss-loader',
|
||||
'less-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(sa|sc)ss$/,
|
||||
use: [
|
||||
(env === 'development' ? 'style-loader' : {
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
publicPath: '../www'
|
||||
}
|
||||
}),
|
||||
'css-loader',
|
||||
'postcss-loader',
|
||||
'sass-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'images/[name].[ext]',
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac|m4a)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'media/[name].[ext]',
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'fonts/[name].[ext]',
|
||||
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /jquery.+\.js$/,
|
||||
use: [{
|
||||
loader: 'expose-loader',
|
||||
options: 'jQuery'
|
||||
},{
|
||||
loader: 'expose-loader',
|
||||
options: '$'
|
||||
}]
|
||||
},
|
||||
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify(env),
|
||||
'process.env.TARGET': JSON.stringify(target),
|
||||
}),
|
||||
|
||||
...(env === 'production' ? [
|
||||
new OptimizeCSSPlugin({
|
||||
cssProcessorOptions: {
|
||||
safe: true,
|
||||
map: { inline: false },
|
||||
},
|
||||
}),
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
] : [
|
||||
// Development only plugins
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NamedModulesPlugin(),
|
||||
]),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: './index.html',
|
||||
template: './index_dev.html',
|
||||
inject: true,
|
||||
minify: env === 'production' ? {
|
||||
collapseWhitespace: true,
|
||||
removeComments: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
useShortDoctype: true
|
||||
} : false,
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'css/[name].css',
|
||||
}),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
noErrorOnMissing: true,
|
||||
from: resolvePath('src/static'),
|
||||
to: resolvePath('www/static'),
|
||||
},
|
||||
|
||||
],
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
$: "jquery",
|
||||
jQuery: "jquery"
|
||||
}),
|
||||
|
||||
],
|
||||
};
|
BIN
apps/documenteditor/mobile/fonts/Framework7Icons-Regular.eot
Normal file
BIN
apps/documenteditor/mobile/fonts/Framework7Icons-Regular.ttf
Normal file
BIN
apps/documenteditor/mobile/fonts/Framework7Icons-Regular.woff
Normal file
BIN
apps/documenteditor/mobile/fonts/Framework7Icons-Regular.woff2
Normal file
BIN
apps/documenteditor/mobile/fonts/MaterialIcons-Regular.eot
Normal file
BIN
apps/documenteditor/mobile/fonts/MaterialIcons-Regular.ttf
Normal file
BIN
apps/documenteditor/mobile/fonts/MaterialIcons-Regular.woff
Normal file
BIN
apps/documenteditor/mobile/fonts/MaterialIcons-Regular.woff2
Normal file
26
apps/documenteditor/mobile/framework7.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"cwd": "E:\\Work\\Projects\\WebOffice\\web-apps\\apps\\documenteditor\\mobile",
|
||||
"type": [
|
||||
"web"
|
||||
],
|
||||
"name": "Desktop Editor",
|
||||
"framework": "react",
|
||||
"template": "split-view",
|
||||
"cssPreProcessor": "less",
|
||||
"bundler": "webpack",
|
||||
"webpack": {
|
||||
"developmentSourceMap": true,
|
||||
"productionSourceMap": true,
|
||||
"hashAssets": false,
|
||||
"preserveAssetsPaths": false,
|
||||
"inlineAssets": true
|
||||
},
|
||||
"theming": {
|
||||
"customColor": false,
|
||||
"color": "#007aff",
|
||||
"darkTheme": false,
|
||||
"iconFonts": true,
|
||||
"fillBars": false
|
||||
},
|
||||
"customBuild": false
|
||||
}
|
|
@ -1,224 +1,89 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!--
|
||||
Customize this policy to fit your own app's needs. For more guidance, see:
|
||||
https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
|
||||
Some notes:
|
||||
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
|
||||
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
|
||||
* Enable inline JS: add 'unsafe-inline' to default-src
|
||||
-->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content:">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
|
||||
|
||||
<title>ONLYOFFICE Documents</title>
|
||||
<meta name="theme-color" content="#007aff">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<title>Desktop Editor</title>
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<link rel="apple-touch-icon" href="static/icons/apple-touch-icon.png">
|
||||
<link rel="icon" href="static/icons/favicon.png">
|
||||
|
||||
|
||||
<!-- built styles file will be auto injected -->
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
const getUrlParams = () => {
|
||||
let e,
|
||||
a = /\+/g, // Regex for replacing addition symbol with a space
|
||||
r = /([^&=]+)=?([^&]*)/g,
|
||||
d = s => decodeURIComponent(s.replace(a, " ")),
|
||||
q = window.location.search.substring(1),
|
||||
urlParams = {};
|
||||
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:400,300,500,700" rel="stylesheet" type="text/css">
|
||||
<!-- App styles -->
|
||||
while (e = r.exec(q))
|
||||
urlParams[d(e[1])] = d(e[2]);
|
||||
|
||||
<!-- splash -->
|
||||
return urlParams;
|
||||
};
|
||||
|
||||
<style type="text/css">
|
||||
.loadmask {
|
||||
left: 0;
|
||||
top: 0;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
border: none;
|
||||
background-color: #f4f4f4;
|
||||
z-index: 10000;
|
||||
const encodeUrlParam = str => str.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
|
||||
let params = getUrlParams(),
|
||||
lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
|
||||
logo = /*params["headerlogo"] ? encodeUrlParam(params["headerlogo"]) : */null,
|
||||
logoOO = null;
|
||||
if (!logo) {
|
||||
logoOO = /Android/.test(navigator.userAgent) ? "../../common/mobile/resources/img/header/header-logo-android.png" : "../../common/mobile/resources/img/header/header-logo-ios.png";
|
||||
}
|
||||
|
||||
window.frameEditorId = params["frameEditorId"];
|
||||
window.parentOrigin = params["parentOrigin"];
|
||||
|
||||
let brendpanel = document.getElementsByClassName('brendpanel')[0];
|
||||
if (brendpanel) {
|
||||
if (/Android/.test(navigator.userAgent)) {
|
||||
brendpanel.classList.add('android');
|
||||
}
|
||||
brendpanel.classList.add('visible');
|
||||
|
||||
.loadmask > .brendpanel {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
height: 68px;
|
||||
background-color: #e2e2e2;
|
||||
opacity: 0;
|
||||
let elem = document.querySelector('.loading-logo');
|
||||
if (elem) {
|
||||
logo && (elem.innerHTML = '<img src=' + logo + '>');
|
||||
logoOO && (elem.innerHTML = '<img src=' + logoOO + '>');
|
||||
elem.style.opacity = 1;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel.visible {
|
||||
opacity: 1;
|
||||
var placeholder = document.getElementsByClassName('placeholder')[0];
|
||||
if (placeholder && /Android/.test(navigator.userAgent)) {
|
||||
placeholder.classList.add('android');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
.loadmask > .brendpanel.android {
|
||||
height: 80px;
|
||||
background: #446995;
|
||||
}
|
||||
<script type="text/javascript" src="../../../vendor/jquery/jquery.min.js"></script>
|
||||
|
||||
.loadmask > .brendpanel > div {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
height: 100%;
|
||||
}
|
||||
<div id="app"></div>
|
||||
|
||||
<!-- built script files will be auto injected -->
|
||||
|
||||
.loadmask > .brendpanel .loading-logo {
|
||||
max-width: 200px;
|
||||
height: 20px;
|
||||
margin: 0 auto;
|
||||
margin-top: 12px;
|
||||
line-height: 14px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel .loading-logo > img {
|
||||
display: inline-block;
|
||||
max-width: 100px;
|
||||
max-height: 20px;
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel .circle {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 14px;
|
||||
margin: 0 16px;
|
||||
margin-bottom: 10px;
|
||||
align-self: flex-end;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.loadmask > .brendpanel.android .circle {
|
||||
margin-bottom: 12px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.loadmask > .placeholder {
|
||||
background: #fbfbfb;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding-top: 65px;
|
||||
}
|
||||
|
||||
.loadmask > .placeholder.android {
|
||||
padding-top: 75px;
|
||||
}
|
||||
|
||||
.loadmask > .placeholder > .line {
|
||||
height: 15px;
|
||||
margin: 30px;
|
||||
background: #e2e2e2;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
-webkit-animation: flickerAnimation 2s infinite ease-in-out;
|
||||
-moz-animation: flickerAnimation 2s infinite ease-in-out;
|
||||
-o-animation: flickerAnimation 2s infinite ease-in-out;
|
||||
animation: flickerAnimation 2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
@keyframes flickerAnimation {
|
||||
0% { opacity:0.1; }
|
||||
50% { opacity:1; }
|
||||
100% { opacity:0.1; }
|
||||
}
|
||||
@-o-keyframes flickerAnimation{
|
||||
0% { opacity:0.1; }
|
||||
50% { opacity:1; }
|
||||
100% { opacity:0.1; }
|
||||
}
|
||||
@-moz-keyframes flickerAnimation{
|
||||
0% { opacity:0.1; }
|
||||
50% { opacity:1; }
|
||||
100% { opacity:0.1; }
|
||||
}
|
||||
@-webkit-keyframes flickerAnimation{
|
||||
0% { opacity:0.1; }
|
||||
50% { opacity:1; }
|
||||
100% { opacity:0.1; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="loading-mask" class="loadmask"><div class="brendpanel"><div><div class="circle"></div><div class="loading-logo"></div><div class="circle"></div></div></div><div class="placeholder"><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div></div></div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function getUrlParams() {
|
||||
var e,
|
||||
a = /\+/g, // Regex for replacing addition symbol with a space
|
||||
r = /([^&=]+)=?([^&]*)/g,
|
||||
d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
|
||||
q = window.location.search.substring(1),
|
||||
urlParams = {};
|
||||
|
||||
while (e = r.exec(q))
|
||||
urlParams[d(e[1])] = d(e[2]);
|
||||
|
||||
return urlParams;
|
||||
}
|
||||
|
||||
function encodeUrlParam(str) {
|
||||
return str.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
var params = getUrlParams(),
|
||||
lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
|
||||
logo = /*params["headerlogo"] ? encodeUrlParam(params["headerlogo"]) : */null,
|
||||
logoOO = null;
|
||||
if (!logo) {
|
||||
logoOO = /Android/.test(navigator.userAgent) ? "../../common/mobile/resources/img/header/header-logo-android.png" : "../../common/mobile/resources/img/header/header-logo-ios.png";
|
||||
}
|
||||
|
||||
window.frameEditorId = params["frameEditorId"];
|
||||
window.parentOrigin = params["parentOrigin"];
|
||||
|
||||
var brendpanel = document.getElementsByClassName('brendpanel')[0];
|
||||
if (brendpanel) {
|
||||
if (/Android/.test(navigator.userAgent)) {
|
||||
brendpanel.classList.add('android');
|
||||
}
|
||||
brendpanel.classList.add('visible');
|
||||
|
||||
var elem = document.querySelector('.loading-logo');
|
||||
if (elem) {
|
||||
logo && (elem.innerHTML = '<img src=' + logo + '>');
|
||||
logoOO && (elem.innerHTML = '<img src=' + logoOO + '>');
|
||||
elem.style.opacity = 1;
|
||||
}
|
||||
var placeholder = document.getElementsByClassName('placeholder')[0];
|
||||
if (placeholder && /Android/.test(navigator.userAgent)) {
|
||||
placeholder.classList.add('android');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../../../vendor/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../../../vendor/xregexp/xregexp-all-min.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../../../../sdkjs/develop/sdkjs/word/scripts.js"></script>
|
||||
<script>
|
||||
var ua = navigator.userAgent;
|
||||
|
||||
if (/Sailfish/.test(ua) || /Jolla/.test(ua)) {
|
||||
document.write('<script type="text/javascript" src="../../../vendor/iscroll/iscroll.min.js"><\/script>');
|
||||
|
||||
if (!/Android/.test(ua)) {
|
||||
var ua = navigator.userAgent + ';Android 5.0;';
|
||||
Object.defineProperty(navigator, 'userAgent', {
|
||||
get: function () { return ua; }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
window.sdk_scripts.forEach(function(item){
|
||||
document.write('<script type="text/javascript" src="' + item + '"><\/script>');
|
||||
});
|
||||
|
||||
window.requireTimeourError = function(){
|
||||
var reqerr;
|
||||
|
||||
if ( lang == 'de') reqerr = 'Die Verbindung ist zu langsam, einige Komponenten konnten nicht geladen werden. Aktualisieren Sie bitte die Seite.';
|
||||
else if ( lang == 'es') reqerr = 'La conexión es muy lenta, algunos de los componentes no han podido cargar. Por favor recargue la página.';
|
||||
else if ( lang == 'fr') reqerr = 'La connexion est trop lente, certains des composants n\'ons pas pu être chargé. Veuillez recharger la page.';
|
||||
else if ( lang == 'ru') reqerr = 'Слишком медленное соединение, не удается загрузить некоторые компоненты. Пожалуйста, обновите страницу.';
|
||||
else reqerr = 'The connection is too slow, some of the components could not be loaded. Please reload the page.';
|
||||
|
||||
return reqerr;
|
||||
};
|
||||
</script>
|
||||
<!-- application -->
|
||||
<script data-main="app-dev" src="../../../vendor/requirejs/require.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
<script src="js/app.js"></script></body>
|
||||
</html>
|
89
apps/documenteditor/mobile/index_dev.html
Normal file
|
@ -0,0 +1,89 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<!--
|
||||
Customize this policy to fit your own app's needs. For more guidance, see:
|
||||
https://github.com/apache/cordova-plugin-whitelist/blob/master/README.md#content-security-policy
|
||||
Some notes:
|
||||
* https://ssl.gstatic.com is required only on Android and is needed for TalkBack to function properly
|
||||
* Disables use of inline scripts in order to mitigate risk of XSS vulnerabilities. To change this:
|
||||
* Enable inline JS: add 'unsafe-inline' to default-src
|
||||
-->
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: gap: content:">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
|
||||
|
||||
<meta name="theme-color" content="#007aff">
|
||||
<meta name="format-detection" content="telephone=no">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<title>Desktop Editor</title>
|
||||
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<link rel="apple-touch-icon" href="static/icons/apple-touch-icon.png">
|
||||
<link rel="icon" href="static/icons/favicon.png">
|
||||
|
||||
|
||||
<!-- built styles file will be auto injected -->
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
const getUrlParams = () => {
|
||||
let e,
|
||||
a = /\+/g, // Regex for replacing addition symbol with a space
|
||||
r = /([^&=]+)=?([^&]*)/g,
|
||||
d = s => decodeURIComponent(s.replace(a, " ")),
|
||||
q = window.location.search.substring(1),
|
||||
urlParams = {};
|
||||
|
||||
while (e = r.exec(q))
|
||||
urlParams[d(e[1])] = d(e[2]);
|
||||
|
||||
return urlParams;
|
||||
};
|
||||
|
||||
const encodeUrlParam = str => str.replace(/&/g, '&')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>');
|
||||
|
||||
let params = getUrlParams(),
|
||||
lang = (params["lang"] || 'en').split(/[\-\_]/)[0],
|
||||
logo = /*params["headerlogo"] ? encodeUrlParam(params["headerlogo"]) : */null,
|
||||
logoOO = null;
|
||||
if (!logo) {
|
||||
logoOO = /Android/.test(navigator.userAgent) ? "../../common/mobile/resources/img/header/header-logo-android.png" : "../../common/mobile/resources/img/header/header-logo-ios.png";
|
||||
}
|
||||
|
||||
window.frameEditorId = params["frameEditorId"];
|
||||
window.parentOrigin = params["parentOrigin"];
|
||||
|
||||
let brendpanel = document.getElementsByClassName('brendpanel')[0];
|
||||
if (brendpanel) {
|
||||
if (/Android/.test(navigator.userAgent)) {
|
||||
brendpanel.classList.add('android');
|
||||
}
|
||||
brendpanel.classList.add('visible');
|
||||
|
||||
let elem = document.querySelector('.loading-logo');
|
||||
if (elem) {
|
||||
logo && (elem.innerHTML = '<img src=' + logo + '>');
|
||||
logoOO && (elem.innerHTML = '<img src=' + logoOO + '>');
|
||||
elem.style.opacity = 1;
|
||||
}
|
||||
var placeholder = document.getElementsByClassName('placeholder')[0];
|
||||
if (placeholder && /Android/.test(navigator.userAgent)) {
|
||||
placeholder.classList.add('android');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="../../../vendor/jquery/jquery.min.js"></script>
|
||||
|
||||
<div id="app"></div>
|
||||
|
||||
<!-- built script files will be auto injected -->
|
||||
|
||||
</body>
|
||||
</html>
|
63
apps/documenteditor/mobile/package.json
Normal file
|
@ -0,0 +1,63 @@
|
|||
{
|
||||
"name": "desktop-editor",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"description": "Desktop Editor",
|
||||
"repository": "",
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
"start": "npm run dev",
|
||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.config.js",
|
||||
"build-dev": "cross-env NODE_ENV=development node ./build/build.js",
|
||||
"build-prod": "cross-env NODE_ENV=production node ./build/build.js",
|
||||
"postinstall": "cpy ./node_modules/framework7-icons/fonts/*.* ./src/fonts/"
|
||||
},
|
||||
"browserslist": [
|
||||
"Android >= 7",
|
||||
"IOS >= 11",
|
||||
"Safari >= 11",
|
||||
"Chrome >= 49",
|
||||
"Firefox >= 31",
|
||||
"Samsung >= 5"
|
||||
],
|
||||
"dependencies": {
|
||||
"dom7": "^2.1.5",
|
||||
"framework7": "^5.7.10",
|
||||
"framework7-icons": "^3.0.1",
|
||||
"framework7-react": "^5.7.10",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"template7": "^1.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.10.5",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.10.5",
|
||||
"@babel/preset-env": "^7.10.4",
|
||||
"@babel/preset-react": "^7.10.4",
|
||||
"@babel/runtime": "^7.10.5",
|
||||
"babel-loader": "^8.1.0",
|
||||
"chalk": "^4.1.0",
|
||||
"copy-webpack-plugin": "^6.0.3",
|
||||
"cpy-cli": "^3.1.1",
|
||||
"cross-env": "^7.0.2",
|
||||
"css-loader": "^4.0.0",
|
||||
"file-loader": "^6.0.0",
|
||||
"html-webpack-plugin": "^4.3.0",
|
||||
"less": "^3.12.2",
|
||||
"less-loader": "^6.2.0",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||
"ora": "^4.0.5",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"style-loader": "^1.2.1",
|
||||
"terser-webpack-plugin": "^3.0.7",
|
||||
"url-loader": "^4.1.0",
|
||||
"webpack": "^4.44.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-dev-server": "^3.11.0"
|
||||
}
|
||||
}
|
5
apps/documenteditor/mobile/postcss.config.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-preset-env': {},
|
||||
},
|
||||
};
|
256
apps/documenteditor/mobile/src/components/app.jsx
Normal file
|
@ -0,0 +1,256 @@
|
|||
import React from 'react';
|
||||
|
||||
import {
|
||||
App,
|
||||
Panel,
|
||||
Views,
|
||||
View,
|
||||
Popup,
|
||||
Page,
|
||||
Navbar,
|
||||
Toolbar,
|
||||
NavRight,
|
||||
Link,
|
||||
Block,
|
||||
BlockTitle,
|
||||
LoginScreen,
|
||||
LoginScreenTitle,
|
||||
List,
|
||||
ListItem,
|
||||
ListInput,
|
||||
ListButton,
|
||||
BlockFooter
|
||||
} from 'framework7-react';
|
||||
|
||||
import routes from '../js/routes';
|
||||
|
||||
import '../../../../common/Gateway.js';
|
||||
import '../../../../common/main/lib/util/utils.js';
|
||||
|
||||
export default class extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.state = {
|
||||
// Framework7 Parameters
|
||||
f7params: {
|
||||
name: 'Desktop Editor', // App name
|
||||
theme: 'auto', // Automatic theme detection
|
||||
|
||||
|
||||
|
||||
// App routes
|
||||
routes: routes,
|
||||
},
|
||||
// Login screen demo data
|
||||
username: '',
|
||||
password: '',
|
||||
}
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<App params={ this.state.f7params } >
|
||||
|
||||
{/* Left panel with cover effect when hidden */}
|
||||
<Panel left cover themeDark visibleBreakpoint={960}>
|
||||
<View>
|
||||
<Page>
|
||||
<Navbar title="Left Panel"/>
|
||||
<BlockTitle>Left View Navigation</BlockTitle>
|
||||
<List>
|
||||
<ListItem link="/left-page-1/" title="Left Page 1"/>
|
||||
<ListItem link="/left-page-2/" title="Left Page 2"/>
|
||||
</List>
|
||||
</Page>
|
||||
</View>
|
||||
</Panel>
|
||||
|
||||
|
||||
{/* Right panel with reveal effect*/}
|
||||
<Panel right reveal themeDark>
|
||||
<View>
|
||||
<Page>
|
||||
<Navbar title="Right Panel"/>
|
||||
<Block>Right panel content goes here</Block>
|
||||
</Page>
|
||||
</View>
|
||||
</Panel>
|
||||
|
||||
|
||||
{/* Your main view, should have "view-main" class */}
|
||||
<View main className="safe-areas" url="/" />
|
||||
|
||||
{/* Popup */}
|
||||
<Popup id="my-popup">
|
||||
<View>
|
||||
<Page>
|
||||
<Navbar title="Popup">
|
||||
<NavRight>
|
||||
<Link popupClose>Close</Link>
|
||||
</NavRight>
|
||||
</Navbar>
|
||||
<Block>
|
||||
<p>Popup content goes here.</p>
|
||||
</Block>
|
||||
</Page>
|
||||
</View>
|
||||
</Popup>
|
||||
</App>
|
||||
)
|
||||
}
|
||||
alertLoginData() {
|
||||
this.$f7.dialog.alert('Username: ' + this.state.username + '<br>Password: ' + this.state.password, () => {
|
||||
this.$f7.loginScreen.close();
|
||||
});
|
||||
}
|
||||
componentDidMount() {
|
||||
this.$f7ready((f7) => {
|
||||
|
||||
// Call F7 APIs here
|
||||
});
|
||||
|
||||
const script = document.createElement("script");
|
||||
script.src = "../../../../sdkjs/develop/sdkjs/word/scripts.js";
|
||||
script.async = true;
|
||||
script.onload = () => {
|
||||
let dep_scripts = ['../../../vendor/xregexp/xregexp-all-min.js',
|
||||
'../../../vendor/sockjs/sockjs.min.js',
|
||||
'../../../vendor/jszip/jszip.min.js',
|
||||
'../../../vendor/jszip-utils/jszip-utils.min.js'];
|
||||
dep_scripts.push(...sdk_scripts);
|
||||
|
||||
const promise_get_script = (scriptpath) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const script = document.createElement("script");
|
||||
script.src = scriptpath;
|
||||
script.onload = () => {
|
||||
console.log('loaded ' + scriptpath);
|
||||
resolve('ok');
|
||||
};
|
||||
script.onerror = () => {
|
||||
console.log('error ' + scriptpath);
|
||||
reject('error');
|
||||
};
|
||||
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
};
|
||||
|
||||
const loadConfig = data => {
|
||||
let me = this;
|
||||
console.log('load config');
|
||||
|
||||
me.editorConfig = Object.assign({}, this.editorConfig, data);
|
||||
// me.appOptions.user = Common.Utils.fillUserInfo(me.editorConfig.user, me.editorConfig.lang, "Local.User"/*me.textAnonymous*/);
|
||||
};
|
||||
|
||||
const loadDocument = data => {
|
||||
this.permissions = {};
|
||||
this.document = data.doc;
|
||||
|
||||
let docInfo = {};
|
||||
|
||||
if (data.doc) {
|
||||
this.permissions = Object.assign(this.permissions, data.doc.permissions);
|
||||
|
||||
let _permissions = Object.assign({}, data.doc.permissions),
|
||||
_user = new Asc.asc_CUserInfo();
|
||||
// _user.put_Id(this.appOptions.user.id);
|
||||
// _user.put_FullName(this.appOptions.user.fullname);
|
||||
|
||||
docInfo = new Asc.asc_CDocInfo();
|
||||
docInfo.put_Id(data.doc.key);
|
||||
docInfo.put_Url(data.doc.url);
|
||||
docInfo.put_Title(data.doc.title);
|
||||
docInfo.put_Format(data.doc.fileType);
|
||||
docInfo.put_VKey(data.doc.vkey);
|
||||
docInfo.put_Options(data.doc.options);
|
||||
docInfo.put_UserInfo(_user);
|
||||
docInfo.put_CallbackUrl(this.editorConfig.callbackUrl);
|
||||
docInfo.put_Token(data.doc.token);
|
||||
docInfo.put_Permissions(_permissions);
|
||||
docInfo.put_EncryptedInfo(this.editorConfig.encryptionKeys);
|
||||
|
||||
// var enable = !this.editorConfig.customization || (this.editorConfig.customization.macros!==false);
|
||||
// docInfo.asc_putIsEnabledMacroses(!!enable);
|
||||
// enable = !this.editorConfig.customization || (this.editorConfig.customization.plugins!==false);
|
||||
// docInfo.asc_putIsEnabledPlugins(!!enable);
|
||||
|
||||
// let type = /^(?:(pdf|djvu|xps))$/.exec(data.doc.fileType);
|
||||
// if (type && typeof type[1] === 'string') {
|
||||
// this.permissions.edit = this.permissions.review = false;
|
||||
// }
|
||||
}
|
||||
|
||||
this.api.asc_registerCallback('asc_onGetEditorPermissions', onEditorPermissions);
|
||||
// this.api.asc_registerCallback('asc_onLicenseChanged', _.bind(this.onLicenseChanged, this));
|
||||
// this.api.asc_registerCallback('asc_onRunAutostartMacroses', _.bind(this.onRunAutostartMacroses, this));
|
||||
this.api.asc_setDocInfo(docInfo);
|
||||
this.api.asc_getEditorPermissions(this.editorConfig.licenseUrl, this.editorConfig.customerId);
|
||||
|
||||
// Common.SharedSettings.set('document', data.doc);
|
||||
|
||||
// if (data.doc) {
|
||||
// DE.getController('Toolbar').setDocumentTitle(data.doc.title);
|
||||
// if (data.doc.info) {
|
||||
// data.doc.info.author && console.log("Obsolete: The 'author' parameter of the document 'info' section is deprecated. Please use 'owner' instead.");
|
||||
// data.doc.info.created && console.log("Obsolete: The 'created' parameter of the document 'info' section is deprecated. Please use 'uploaded' instead.");
|
||||
// }
|
||||
// }
|
||||
};
|
||||
|
||||
const onEditorPermissions = params => {
|
||||
let me = this;
|
||||
const licType = params.asc_getLicenseType();
|
||||
|
||||
me.appOptions.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit);
|
||||
// me.appOptions.canEdit = (me.permissions.edit !== false || me.permissions.review === true) && // can edit or review
|
||||
// (me.editorConfig.canRequestEditRights || me.editorConfig.mode !== 'view') && // if mode=="view" -> canRequestEditRights must be defined
|
||||
// (!me.appOptions.isReviewOnly || me.appOptions.canLicense) && // if isReviewOnly==true -> canLicense must be true
|
||||
// me.isSupportEditFeature();
|
||||
// me.appOptions.isEdit = me.appOptions.canLicense && me.appOptions.canEdit && me.editorConfig.mode !== 'view';
|
||||
|
||||
// me.api.asc_setViewMode(!me.appOptions.isEdit);
|
||||
me.api.asc_setViewMode(false);
|
||||
me.api.asc_LoadDocument();
|
||||
me.api.Resize();
|
||||
};
|
||||
|
||||
const _process_array = (array, fn) => {
|
||||
let results = [];
|
||||
return array.reduce(function(p, item) {
|
||||
return p.then(function() {
|
||||
return fn(item).then(function(data) {
|
||||
results.push(data);
|
||||
return results;
|
||||
});
|
||||
});
|
||||
}, Promise.resolve());
|
||||
};
|
||||
|
||||
_process_array(dep_scripts, promise_get_script)
|
||||
.then ( result => {
|
||||
this.api = new Asc.asc_docs_api({
|
||||
'id-view' : 'editor_sdk',
|
||||
'mobile' : true,
|
||||
// 'translate': translate
|
||||
});
|
||||
|
||||
this.appOptions = {};
|
||||
|
||||
Common.Gateway.on('init', loadConfig);
|
||||
// Common.Gateway.on('showmessage', _.bind(me.onExternalMessage, me));
|
||||
Common.Gateway.on('opendocument', loadDocument);
|
||||
Common.Gateway.appReady();
|
||||
}, error => {
|
||||
console.log('promise failed ' + error);
|
||||
});
|
||||
};
|
||||
|
||||
script.onerror = () => {
|
||||
console.log('error');
|
||||
};
|
||||
|
||||
document.body.appendChild(script);
|
||||
}
|
||||
}
|
31
apps/documenteditor/mobile/src/css/app.less
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* Left Panel right border when it is visible by breakpoint */
|
||||
.panel-left.panel-in-breakpoint:before {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
background: rgba(0,0,0,0.1);
|
||||
content: '';
|
||||
z-index: 6000;
|
||||
}
|
||||
|
||||
/* Hide navbar link which opens left panel when it is visible by breakpoint */
|
||||
.panel-left.panel-in-breakpoint ~ .view .navbar .panel-open[data-panel="left"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/*
|
||||
Extra borders for main view and left panel for iOS theme when it behaves as panel (before breakpoint size)
|
||||
*/
|
||||
.ios .panel-left:not(.panel-in-breakpoint).panel-in ~ .view-main:before,
|
||||
.ios .panel-left:not(.panel-in-breakpoint).panel-closing ~ .view-main:before {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 1px;
|
||||
background: rgba(0,0,0,0.1);
|
||||
content: '';
|
||||
z-index: 6000;
|
||||
}
|
61
apps/documenteditor/mobile/src/css/icons.css
Normal file
|
@ -0,0 +1,61 @@
|
|||
/* Material Icons Font (for MD theme) */
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../fonts/MaterialIcons-Regular.eot);
|
||||
src: local('Material Icons'),
|
||||
local('MaterialIcons-Regular'),
|
||||
url(../fonts/MaterialIcons-Regular.woff2) format('woff2'),
|
||||
url(../fonts/MaterialIcons-Regular.woff) format('woff'),
|
||||
url(../fonts/MaterialIcons-Regular.ttf) format('truetype');
|
||||
}
|
||||
.material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
font-feature-settings: 'liga';
|
||||
}
|
||||
|
||||
/* Framework7 Icons Font (for iOS theme) */
|
||||
@font-face {
|
||||
font-family: 'Framework7 Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url("../fonts/Framework7Icons-Regular.eot");
|
||||
src: url("../fonts/Framework7Icons-Regular.woff2") format("woff2"),
|
||||
url("../fonts/Framework7Icons-Regular.woff") format("woff"),
|
||||
url("../fonts/Framework7Icons-Regular.ttf") format("truetype");
|
||||
}
|
||||
.f7-icons {
|
||||
font-family: 'Framework7 Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 28px;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
text-rendering: optimizeLegibility;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-feature-settings: "liga";
|
||||
-moz-font-feature-settings: "liga=1";
|
||||
-moz-font-feature-settings: "liga";
|
||||
font-feature-settings: "liga";
|
||||
text-align: center;
|
||||
}
|
BIN
apps/documenteditor/mobile/src/fonts/Framework7Icons-Regular.eot
Normal file
BIN
apps/documenteditor/mobile/src/fonts/Framework7Icons-Regular.ttf
Normal file
BIN
apps/documenteditor/mobile/src/fonts/MaterialIcons-Regular.eot
Normal file
BIN
apps/documenteditor/mobile/src/fonts/MaterialIcons-Regular.ttf
Normal file
BIN
apps/documenteditor/mobile/src/fonts/MaterialIcons-Regular.woff
Normal file
BIN
apps/documenteditor/mobile/src/fonts/MaterialIcons-Regular.woff2
Normal file
32
apps/documenteditor/mobile/src/js/app.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
// Import React and ReactDOM
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
// Import Framework7
|
||||
import Framework7 from 'framework7/framework7-lite.esm.bundle.js';
|
||||
|
||||
// Import Framework7-React Plugin
|
||||
import Framework7React from 'framework7-react';
|
||||
|
||||
import jQuery from 'jquery';
|
||||
window.jQuery = jQuery;
|
||||
window.$ = jQuery;
|
||||
|
||||
// Import Framework7 Styles
|
||||
import 'framework7/css/framework7.bundle.css';
|
||||
|
||||
// Import Icons and App Custom Styles
|
||||
import '../css/icons.css';
|
||||
import '../css/app.less';
|
||||
|
||||
// Import App Component
|
||||
import App from '../components/app.jsx';
|
||||
|
||||
// Init F7 React Plugin
|
||||
Framework7.use(Framework7React)
|
||||
|
||||
// Mount React App
|
||||
ReactDOM.render(
|
||||
React.createElement(App),
|
||||
document.getElementById('app'),
|
||||
);
|
78
apps/documenteditor/mobile/src/js/routes.js
Normal file
|
@ -0,0 +1,78 @@
|
|||
|
||||
import HomePage from '../pages/home.jsx';
|
||||
|
||||
import LeftPage1 from '../pages/left-page-1.jsx';
|
||||
import LeftPage2 from '../pages/left-page-2.jsx';
|
||||
import DynamicRoutePage from '../pages/dynamic-route.jsx';
|
||||
import RequestAndLoad from '../pages/request-and-load.jsx';
|
||||
|
||||
var routes = [
|
||||
{
|
||||
path: '/',
|
||||
component: HomePage,
|
||||
},
|
||||
{
|
||||
path: '/left-page-1/',
|
||||
component: LeftPage1,
|
||||
},
|
||||
{
|
||||
path: '/left-page-2/',
|
||||
component: LeftPage2,
|
||||
},
|
||||
{
|
||||
path: '/dynamic-route/blog/:blogId/post/:postId/',
|
||||
component: DynamicRoutePage,
|
||||
},
|
||||
{
|
||||
path: '/request-and-load/user/:userId/',
|
||||
async: function (routeTo, routeFrom, resolve, reject) {
|
||||
// Router instance
|
||||
var router = this;
|
||||
|
||||
// App instance
|
||||
var app = router.app;
|
||||
|
||||
// Show Preloader
|
||||
app.preloader.show();
|
||||
|
||||
// User ID from request
|
||||
var userId = routeTo.params.userId;
|
||||
|
||||
// Simulate Ajax Request
|
||||
setTimeout(function () {
|
||||
// We got user data from request
|
||||
var user = {
|
||||
firstName: 'Vladimir',
|
||||
lastName: 'Kharlampidi',
|
||||
about: 'Hello, i am creator of Framework7! Hope you like it!',
|
||||
links: [
|
||||
{
|
||||
title: 'Framework7 Website',
|
||||
url: 'http://framework7.io',
|
||||
},
|
||||
{
|
||||
title: 'Framework7 Forum',
|
||||
url: 'http://forum.framework7.io',
|
||||
},
|
||||
]
|
||||
};
|
||||
// Hide Preloader
|
||||
app.preloader.hide();
|
||||
|
||||
// Resolve route to load page
|
||||
resolve(
|
||||
{
|
||||
component: RequestAndLoad,
|
||||
},
|
||||
{
|
||||
context: {
|
||||
user: user,
|
||||
}
|
||||
}
|
||||
);
|
||||
}, 1000);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
37
apps/documenteditor/mobile/src/pages/dynamic-route.jsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Page, Navbar, Block, Link } from 'framework7-react';
|
||||
|
||||
export default class DynamicRoutePage extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Page>
|
||||
<Navbar title="Dynamic Route" backLink="Back" />
|
||||
<Block strong>
|
||||
<ul>
|
||||
<li><b>Url:</b> {this.$f7route.url}</li>
|
||||
<li><b>Path:</b> {this.$f7route.path}</li>
|
||||
<li><b>Hash:</b> {this.$f7route.hash}</li>
|
||||
<li><b>Params:</b>
|
||||
<ul>
|
||||
{Object.keys(this.$f7route.params).map(key => (
|
||||
<li key={key}><b>{key}:</b> {this.$f7route.params[key]}</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>Query:</b>
|
||||
<ul>
|
||||
{Object.keys(this.$f7route.query).map(key => (
|
||||
<li key={key}><b>{key}:</b> {this.$f7route.query[key]}</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
<li><b>Route:</b> {this.$f7route.route.path}</li>
|
||||
</ul>
|
||||
</Block>
|
||||
<Block strong>
|
||||
<Link onClick={() => this.$f7router.back()}>Go back via Router API</Link>
|
||||
</Block>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
}
|
38
apps/documenteditor/mobile/src/pages/home.jsx
Normal file
|
@ -0,0 +1,38 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
Page,
|
||||
View,
|
||||
Navbar,
|
||||
NavLeft,
|
||||
NavTitle,
|
||||
NavTitleLarge,
|
||||
NavRight,
|
||||
Link,
|
||||
Toolbar,
|
||||
Block,
|
||||
BlockTitle,
|
||||
List,
|
||||
ListItem,
|
||||
Row,
|
||||
Col,
|
||||
Button
|
||||
} from 'framework7-react';
|
||||
|
||||
export default () => (
|
||||
<Page name="home">
|
||||
{/* Top Navbar */}
|
||||
<Navbar large sliding={false}>
|
||||
<NavLeft>
|
||||
<Link iconIos="f7:menu" iconAurora="f7:menu" iconMd="material:menu" panelOpen="left" />
|
||||
</NavLeft>
|
||||
<NavTitle sliding>Desktop Editor</NavTitle>
|
||||
<NavRight>
|
||||
<Link iconIos="f7:menu" iconAurora="f7:menu" iconMd="material:menu" panelOpen="right" />
|
||||
</NavRight>
|
||||
<NavTitleLarge>Desktop Editor</NavTitleLarge>
|
||||
</Navbar>
|
||||
{/* Page content */}
|
||||
<View id="editor_sdk">
|
||||
</View>
|
||||
</Page>
|
||||
);
|
15
apps/documenteditor/mobile/src/pages/left-page-1.jsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
import React from 'react';
|
||||
import { Page, Navbar, Block } from 'framework7-react';
|
||||
|
||||
export default () => (
|
||||
<Page>
|
||||
<Navbar title="Left Page 1" backLink="Back" />
|
||||
<Block strong>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Reprehenderit deserunt vel accusamus voluptatem neque! Laborum, et facilis at. Est dolorem, reprehenderit, sed repellendus at cum incidunt labore vel perferendis excepturi?</p>
|
||||
<p>Tempore accusantium quaerat officiis dolores ullam, perferendis labore assumenda. A sint quo necessitatibus temporibus ipsam adipisci et quos aliquid officiis, facilis nulla ut aperiam assumenda magnam blanditiis exercitationem facere non!</p>
|
||||
<p>Omnis accusamus harum, vero dolores itaque, asperiores laudantium eligendi ipsa, labore dignissimos unde temporibus eius assumenda, obcaecati fuga et. Et provident at consectetur vel temporibus ea nam, veritatis excepturi obcaecati.</p>
|
||||
<p>Aspernatur dolorum nostrum est sapiente deleniti in. Placeat itaque expedita dignissimos, suscipit tenetur necessitatibus sunt excepturi quisquam, doloremque repudiandae mollitia in. Nesciunt quo vel, dolorum magni nihil officia reprehenderit libero.</p>
|
||||
<p>Fugit nesciunt nobis at doloribus labore, voluptatem quis, distinctio, saepe illo adipisci qui molestias fugiat ut! Quasi animi possimus temporibus repudiandae quam aspernatur, recusandae libero, reiciendis distinctio cupiditate nesciunt a.</p>
|
||||
</Block>
|
||||
</Page>
|
||||
);
|
14
apps/documenteditor/mobile/src/pages/left-page-2.jsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
import React from 'react';
|
||||
import { Page, Navbar, Block } from 'framework7-react';
|
||||
|
||||
export default () => (
|
||||
<Page>
|
||||
<Navbar title="Left Page 2" backLink="Back" />
|
||||
<Block strong>
|
||||
<p>Maxime tempore, repellendus? Sequi saepe provident quas, neque assumenda dicta odit eaque nesciunt facere mollitia totam voluptate aspernatur vel corporis repudiandae commodi ad cumque repellendus. Saepe officia iure repellat repellendus.</p>
|
||||
<p>Ea maiores accusantium non fuga dicta, vero minus veniam! Ipsum eveniet vero voluptate veritatis aspernatur hic dicta adipisci, debitis. Sint quam aperiam repellat quis perspiciatis accusantium ipsum nulla soluta temporibus.</p>
|
||||
<p>Necessitatibus ipsum culpa doloremque, nostrum atque totam minima itaque! Blanditiis nobis nam repudiandae, ut nostrum voluptate accusantium atque, veniam libero quaerat corporis laborum earum rem nihil unde. Vitae cum, aliquam?</p>
|
||||
<p>Debitis aliquid nemo maxime recusandae, mollitia sed error vero. Atque molestiae rem necessitatibus nam voluptas quaerat, reiciendis, excepturi quis facilis, quod cupiditate vitae voluptate repudiandae! Unde impedit aut id ut?</p>
|
||||
</Block>
|
||||
</Page>
|
||||
);
|
35
apps/documenteditor/mobile/src/pages/request-and-load.jsx
Normal file
|
@ -0,0 +1,35 @@
|
|||
import React from 'react';
|
||||
import { Page, Navbar, Block, List, ListItem } from 'framework7-react';
|
||||
|
||||
export default class extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
user: props.f7route.context.user,
|
||||
};
|
||||
|
||||
}
|
||||
render() {
|
||||
const user = this.state.user;
|
||||
return (
|
||||
<Page>
|
||||
<Navbar title={`${user.firstName} ${user.lastName}`} backLink="Back" />
|
||||
<Block strong>
|
||||
{user.about}
|
||||
</Block>
|
||||
<List>
|
||||
{user.links.map((link, index) => (
|
||||
<ListItem
|
||||
key={index}
|
||||
link={link.url}
|
||||
title={link.title}
|
||||
external
|
||||
target="_blank"
|
||||
></ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
}
|
BIN
apps/documenteditor/mobile/src/static/icons/128x128.png
Normal file
After Width: | Height: | Size: 7 KiB |
BIN
apps/documenteditor/mobile/src/static/icons/144x144.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
apps/documenteditor/mobile/src/static/icons/152x152.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
apps/documenteditor/mobile/src/static/icons/192x192.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
apps/documenteditor/mobile/src/static/icons/256x256.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
apps/documenteditor/mobile/src/static/icons/512x512.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
apps/documenteditor/mobile/src/static/icons/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
apps/documenteditor/mobile/src/static/icons/favicon.png
Normal file
After Width: | Height: | Size: 7 KiB |