Merge branch 'master' into PHRAS-3214_validation-tokens-mess_MASTER

This commit is contained in:
Nicolas Maillat
2020-09-28 13:04:41 +02:00
committed by GitHub
342 changed files with 745908 additions and 3022 deletions

View File

@@ -0,0 +1,19 @@
{
"ignore": [
"foo.js",
"bar/**/*.js"
],
"presets": [
"es2015", "stage-0"
],
"env": {
"start": {
/* TODO: */
/* fill with hmr settings when there is a new release */
/* to play nice with babel 6*/
}
},
/* Add plugins here**/
"plugins": ["babel-plugin-syntax-jsx"]
}

View File

@@ -0,0 +1,30 @@
# http://editorconfig.org
# A special property that should be specified at the top of the file outside of
# any sections. Set to true to stop .editor config file search on current file
root = true
[*]
# Indentation style
# Possible values - tab, space
indent_style = space
# Indentation size in single-spaced characters
# Possible values - an integer, tab
indent_size = 4
# Line ending file format
# Possible values - lf, crlf, cr
end_of_line = lf
# File character encoding
# Possible values - latin1, utf-8, utf-16be, utf-16le
charset = utf-8
# Denotes whether to trim whitespace at the end of lines
# Possible values - true, false
trim_trailing_whitespace = true
# Denotes whether file should end with a newline
# Possible values - true, false
insert_final_newline = true

View File

@@ -0,0 +1,3 @@
NODE_PATH=./src
NODE_ENV=development
PORT=80

View File

@@ -0,0 +1,4 @@
dist/*
node_modules/*
**/node_modules/*
config/**

View File

@@ -0,0 +1,186 @@
{
"root": true,
"parser": "babel-eslint",
"globals": {
"document": true,
"window": true,
"spy",
"mocha",
"stub",
"beforeEach",
"useFakeTimers": true,
"useFakeXMLHttpRequest": true,
"useFakeServer": true
},
"ecmaFeatures": {
"jsx": true,
"modules": true,
"es6": true
},
"env": {
"browser": true,
"es6": true,
"mocha": true,
"node": true
},
"rules": {
// /* airbnb javascript style guide rules */
// "strict": [2, "never"],
// // es6
// //"no-var": 2,
// // variables
//"no-shadow": 2,
"no-shadow-restricted-names": 2,
// "no-unused-vars": [2, {
// "vars": "all",
// "args": "none"
// }],
"no-undef": 2,
// "no-use-before-define": [2, "nofunc"],
// possible errors
"comma-dangle": 0,
//"no-cond-assign": [2, "always"],
"no-debugger": 1,
//"no-alert": 1,
"no-constant-condition": 1,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
//"no-empty": 2,
"no-ex-assign": 2,
"no-extra-boolean-cast": 0,
"no-extra-semi": 2,
"no-func-assign": 2,
"no-inner-declarations": 2,
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-obj-calls": 2,
"no-sparse-arrays": 2,
"no-unreachable": 2,
"use-isnan": 2,
"block-scoped-var": 2,
// best practices
//"consistent-return": 2,
"curly": [2, "multi-line"],
"default-case": 2,
"dot-notation": [2, {
"allowKeywords": true
}],
"eqeqeq": 2,
//"guard-for-in": 2,
"no-caller": 2,
"no-eq-null": 2,
"no-eval": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-fallthrough": 0,
"no-floating-decimal": 2,
"no-implied-eval": 2,
"no-lone-blocks": 2,
//"no-loop-func": 2,
//"no-multi-str": 2,
"no-native-reassign": 2,
//"no-new": 2,
"no-new-func": 2,
// "no-new-wrappers": 2,
"no-octal": 2,
"no-octal-escape": 2,
// "no-param-reassign": [2, {
// "props": false
// }],
"no-proto": 2,
"no-redeclare": 2,
"no-return-assign": 2,
"no-script-url": 2,
"no-self-compare": 2,
"no-sequences": 2,
//"no-throw-literal": 2,
"no-with": 2,
"radix": 2,
// "vars-on-top": 2,
//"wrap-iife": [2, "any"],
"yoda": 2,
// style
"indent": [0, 0],
"brace-style": [2,
"1tbs", {
"allowSingleLine": true
}
],
"quotes": [
2, "single", "avoid-escape"
],
// "camelcase": [2, {
// "properties": "never"
// }],
"comma-spacing": [2, {
"before": false,
"after": true
}],
"comma-style": [2, "last"],
"eol-last": 2,
"key-spacing": [2, {
"beforeColon": false,
"afterColon": true
}],
// "new-cap": [2, {
// "newIsCap": true
// }],
"no-multiple-empty-lines": [2, {
"max": 2
}],
//"no-nested-ternary": 2,
"no-new-object": 2,
"no-spaced-func": 2,
"no-trailing-spaces": 0,
//"no-extra-parens": 2,
"no-underscore-dangle": 0,
"one-var": [2, "never"],
"padded-blocks": 0,
"semi-spacing": [2, {
"before": false,
"after": true
}],
"keyword-spacing": 2,
"space-before-blocks": 2,
"space-infix-ops": 2,
//"spaced-comment": 2,
/* custom rules */
"no-console": 0,
"space-before-function-paren": [2, {
"named": "never",
"anonymous": "always"
}],
"func-names": 0,
//"consistent-this": [2, "this"],
"func-style": [0, "expression"],
//"max-nested-callbacks": [2, 3],
"new-parens": 2,
"no-array-constructor": 2,
"no-else-return": 0,
//"no-inline-comments": 2,
// "no-lonely-if": 2,
"no-mixed-spaces-and-tabs": 1,
"operator-assignment": 0,
"quote-props": [2, "as-needed"],
"sort-vars": [0, {
"ignoreCase": true
}],
"space-in-brackets": [0, "never", {
"arraysInArrays": false,
"arraysInObjects": false,
"singleValue": false,
"objectsInArrays": false,
"objectsInObjects": false,
"propertyName": false
}],
"space-in-parens": [2, "never"],
"space-unary-ops": [2, {
"words": true,
"nonwords": false
}],
"wrap-regex": 1
},
plugins: []
}

View File

@@ -0,0 +1,7 @@
*.log
node_modules
coverage
npm-debug.log
.DS_Store
bower_components
.idea

View File

@@ -0,0 +1 @@
src/

View File

@@ -0,0 +1,26 @@
language: node_js
node_js:
- '13.13.0'
# Use container-based Travis infrastructure.
sudo: false
cache:
directories:
- node_modules
before_install:
- nvm install stable
notifications:
email: true
branches:
except:
- "/^v\\d+\\.\\d+\\.\\d+$/"
after_script:
- npm run coveralls
# Upload to coveralls, but don't _fail_ if coveralls is down.
- cat coverage/lcov.info | node_modules/.bin/coveralls || echo "Coveralls upload failed"

View File

@@ -0,0 +1,5 @@
# Changelog
## 0.1.0
- initial release

View File

@@ -0,0 +1,19 @@
##The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,15 @@
## Changelog
### Changed
- Breaking change
### Fixes
- PHRAS-XXX: Short description of bug and fix
- Short description of bug and fix without issue/ticket
### Adds
- PHRAS-XXX: Short feature description
- Short feature description without issue/ticket
### Removes
- PHRAS-XXX: Short feature removal description
- Short feature removal description without issue/ticket

View File

@@ -0,0 +1,50 @@
# Phraseanet Production Client
[![Build Status](https://travis-ci.org/alchemy-fr/Phraseanet-production-client.svg?branch=master)](https://travis-ci.org/alchemy-fr/Phraseanet-production-client)
[![devDependency Status](https://david-dm.org/alchemy-fr/Phraseanet-production-client/dev-status.svg)](https://david-dm.org/alchemy-fr/Phraseanet-production-client#info=devDependencies)
[![Dependency Status](https://david-dm.org/alchemy-fr/Phraseanet-production-client.svg)](https://david-dm.org/alchemy-fr/Phraseanet-production-client)
[![Coverage Status](https://coveralls.io/repos/github/alchemy-fr/Phraseanet-production-client/badge.svg?branch=master)](https://coveralls.io/github/alchemy-fr/Phraseanet-production-client?branch=master)
## Requirements
Node `^5.0.0`.
## Dev workflow
- Go to Phraseanet-production-client-folder
- Install dependancies for dev : ```npm install```
- make your modification
- Generate dist ```npm run dist```
- ```make install_asset``` to copy assets in www/assets folder
- If features is finished ```dist``` folder is to be commited
## Available commands
* `npm run production` - Build task that generate a minified script for production
* `npm run clean` - Remove the `dist` folder and it's files
* `npm run eslint:source` - Lint the source
* `npm run eslint:common` - Lint the unit tests shared by Karma and Mocha
* `npm run eslint:server` - Lint the unit tests for server
* `npm run eslint:browser` - Lint the unit tests for browser
* `npm run eslint:fix` - ESLint will try to fix as many issues as possible in your source files
* `npm run clean` - Remove the coverage report and the *dist* folder
* `npm run test` - Runs unit tests for both server and the browser
* `npm run test:browser` - Runs the unit tests for browser / client
* `npm run test:server` - Runs the unit tests on the server
* `npm run watch:server` - Run all unit tests for server & watch files for changes
* `npm run watch:browser` - Run all unit tests for browser & watch files for changes
* `npm run karma:firefox` - Run all unit tests with Karma & Firefox
* `npm run karma:chrome` - Run all unit tests with Karma & Chrome
* `npm run karma:ie` - Run all unit tests with Karma & Internet Explorer
* `npm run packages` - List installed packages
* `npm run package:purge` - Remove all dependencies
* `npm run package:reinstall` - Reinstall all dependencies
* `npm run package:check` - shows a list over dependencies with a higher version number then the current one - if any
* `npm run package:upgrade` - Automaticly upgrade all devDependencies & dependencies, and update package.json
* `npm run package:dev` - Automaticly upgrade all devDependencies and update package.json
* `npm run package:prod` - Automaticly upgrade all dependencies and update package.json
* `npm run asset-server` - starts a asset server with hot module replacement (WDS) on port 8080
## Credits
based on [Trolly](https://github.com/Kflash/trolly) an es6 boilerplate by [KFlash](https://github.com/kflash)

View File

@@ -0,0 +1,6 @@
import pkg from '../package.json';
export default [
pkg.name + '',
' version ' + pkg.version
];

View File

@@ -0,0 +1,15 @@
const _root = __dirname + '/../';
module.exports = {
// path helpers
_app: 'app',
minified: 'app.min.js',
dev: 'app.js',
eslintDir: _root + '.eslintrc',
distDir: _root + 'dist',
sourceDir: _root + 'src/',
testDir: _root + 'tests',
setupDir: _root + 'tests/setup/node.js',
karmaConf: _root + 'config/karma.conf.js'
};

View File

@@ -0,0 +1,45 @@
/* eslint-disable */
import dotenv from 'dotenv';
import path from 'path';
import {
defaults
}
from 'lodash';
dotenv.load({
silent: false,
path: path.resolve(__dirname, '../.env')
});
const {
ENVIRONMENT,
HOT_RELOAD,
NODE_ENV,
HOST,
PORT,
WEBPACK_DEV_SERVER_PORT
} = defaults(process.env, {
ENVIRONMENT: 'development',
// localhost
HOST: 'localhost',
// port to use with the asset server
PORT: '8000'
}),
IS_PROD = () => {
return ( NODE_ENV === 'production' || ENVIRONMENT === 'prod' || ENVIRONMENT === 'production' );
},
IS_DEV = !IS_PROD,
ENVIRONMENT_NAME = IS_PROD ? 'production' : 'development';
process.env.NODE_ENV = IS_PROD ? 'production' : 'development';
export default {
IS_PROD,
IS_DEV,
ENVIRONMENT_NAME,
HOST,
PORT,
WEBPACK_DEV_SERVER_PORT,
HOT_RELOAD
};
/* eslint-enable */

View File

@@ -0,0 +1,102 @@
import webpackConfig from './webpack/webpack.karma.config';
// Karma configuration here
module.exports = function(config) {
config.set({
// list of files to exclude
exclude: [],
// list of files / patterns to load in the browser
files: [
'./node_modules/jquery/dist/jquery.js',
'./node_modules/babel-polyfill/dist/polyfill.js',
'./node_modules/phantomjs-polyfill/bind-polyfill.js',
'./test/**/*.browser.js'
],
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: [
'sinon-chai',
'sinon',
'chai',
'mocha'
], //use mocha and sinon-chai as framework
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
// 'src/**/*.js': ['coverage'],
'test/**/*.browser.js': ['webpack', 'sourcemap']
},
// test results reporter to use
reporters: ['progress', 'mocha','coverage'],
coverageReporter: {
reporters: [{
type: 'text'
}, {
type: 'lcovonly',
subdir: '.'
}, {
type: 'html',
dir: 'coverage/'
}
]
},
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true
},
plugins: [
'karma-sinon-chai',
'karma-sinon',
'karma-chai',
'karma-webpack',
'karma-mocha',
'karma-mocha-reporter',
'karma-phantomjs-launcher',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-ie-launcher',
'karma-coverage',
'karma-sourcemap-loader'
],
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera (has to be installed with `npm install karma-opera-launcher`)
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
// - PhantomJS
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
browsers: ['PhantomJS'],
browserDisconnectTimeout: 10000,
browserDisconnectTolerance: 2,
// concurrency level how many browser should be started simultaneously
concurrency: 4,
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 100000,
browserNoActivityTimeout: 30000,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
});
if (process.env.TRAVIS) {
config.logLevel = config.LOG_DEBUG;
// Karma (with socket.io 1.x) buffers by 50 and 50 tests can take a long time on IEs;-)
config.browserNoActivityTimeout = 120000;
// Debug logging into a file, that we print out at the end of the build.
config.loggers.push({
type: 'file',
filename: 'logs/karma.log'
});
}
};

View File

@@ -0,0 +1,15 @@
/* eslint-disable */
process.env.NODE_ENV = 'development';
global.babel = require('babel-core/register');
global.chai = require("chai");
// global.$ = require("jquery");
global.chaiAsPromised = require("chai-as-promised");
global.chai.use(chaiAsPromised);
global.expect = global.chai.expect;
global.sinon = require('sinon');
global.BROWSER = false;

View File

@@ -0,0 +1,9 @@
./test/**/*.spec.js
--require ./config/mocha.conf.js
--reporter spec
--ui bdd
--compilers js:babel-core/register
--recursive
--timeout 15000
--bail

View File

@@ -0,0 +1,170 @@
/**
* WEBPACK CONFIG
*
*/
/* eslint-disable no-var */
require('babel-core/register');
// Webpack config for development
const webpack = require('webpack');
const path = require('path');
const pkg = require('../../package.json');
// const banner = require('../banner');
const WebpackNotifierPlugin = require('webpack-notifier');
const config = require('../config');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// add loader for external stylesheets:
var extractCSS = new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
});
module.exports = {
// entry points
entry: {
production: config.sourceDir + 'prod/index.js',
lightbox: config.sourceDir + 'lightbox/index.js',
'lightbox-mobile': config.sourceDir + 'lightbox-mobile/index.js',
permaview: config.sourceDir + 'permaview/index.js',
authenticate: [config.sourceDir + 'authenticate/index.js'],
account: [config.sourceDir + 'account/index.js'],
'skin-000000': [config.sourceDir + 'skins/skin-000000.js'],
'skin-959595': [config.sourceDir + 'skins/skin-959595.js'],
'skin-FFFFFF': [config.sourceDir + 'skins/skin-FFFFFF.js']
},
cache: true,
watch: true,
devtool: 'inline-source-map',
output: {
path: config.distDir,
filename: '[name].js',
chunkFilename: 'lazy-[name].js',
libraryTarget: 'umd',
library: config._app,
publicPath: '/assets/production/'
},
module: {
rules: [
{
test: /\.js$/,
enforce: 'pre',
loader: 'eslint-loader',
exclude: /node_modules/,
include: path.join(__dirname, '../../src')
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'stage-0'] },
}],
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:6].[ext]',
}
}
],
exclude: /node_modules/
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[hash:6].[ext]'
}
}
]
},
{
test: /\.css$/,
use: [
"style-loader",
"css-loader"
]
},
{
test: /videojs-flash\.js$/,
loader: 'script-loader'
},
// exclude skins as inline-css in dev env
// {
// test: /\.scss$/,
// exclude: /src\/skins\//,
// loaders: ['style', 'css', 'resolve-url', 'sass?sourceMap']
// },
// only skins are extracted as external file in dev env:
// every css should be exported as file in dev env
{
test: /\.scss$/,
// exclude: /src\/(?!skins)/,
// include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
'css-loader',
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
],
publicPath: './'
})
},{
test: require.resolve('jquery-lazyload'),
use: "imports-loader?this=>window"
}, {
test: require.resolve('geonames-server-jquery-plugin/jquery.geonames'),
use: "imports-loader?this=>window"
}, {
test: require.resolve('bootstrap-multiselect'),
use: "imports-loader?this=>window"
}
]
},
resolve: {
extensions: ['*', '.js', '.css', '.scss']
},
plugins: [
new WebpackNotifierPlugin({
alwaysNotify: true
}),
// new webpack.BannerPlugin(banner),
new webpack.ProvidePlugin({
"videojs": "video.js",
"window.videojs": "video.js"
}),
new webpack.DefinePlugin({
'__DEV__': true,
'process.env.NODE_ENV': JSON.stringify('development'),
VERSION: JSON.stringify(pkg.version)
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
chunks: ['production', 'lightbox'],
minChunks: 2
}),
new webpack.LoaderOptionsPlugin({
debug: true,
options: {
eslint: {
configFile: config.eslintDir
}
}
}),
extractCSS
// i18next
],
externals: {
jquery: 'jQuery',
ui: 'jQuery.ui'
}
};

View File

@@ -0,0 +1,37 @@
/* eslint-disable no-var, strict */
require('babel-core/register');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const environment = require('../environment');
const config = require('./webpack.development.config');
config.devServer = {
hot: true
}
config.plugins = [
// Used for hot-reload
new webpack.HotModuleReplacementPlugin()
];
new WebpackDevServer(webpack(config), {
publicPath: 'http://localhost:8080/assets/',
// Configure hot replacement
// The rest is terminal configurations
quiet: false,
noInfo: true,
historyApiFallback: {
index: './templates/index.html'
},
stats: {
colors: true
}
// We fire up the development server and give notice in the terminal
// that we are starting the initial bundle
}).listen(8080, environment.HOST, function(err, result) {
if (err) {
console.log(err);
}
console.log('The asset server is listening at localhost: 8080');
});

View File

@@ -0,0 +1,100 @@
// Webpack config for development
import webpack from 'webpack';
import path from 'path';
import config from '../config';
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// add loader for external stylesheets:
var extractCSS = new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
});
module.exports = {
cache: true,
devtool: 'inline-source-map',
output: {},
module: {
rules: [
{
test: /\.js$/,
enforce: 'post',
include: path.resolve('src/'),
use: 'istanbul-instrumenter-loader'
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
]
},
{
test: /\.scss$/,
// exclude: /src\/(?!skins)/,
// include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
use: ExtractTextPlugin.extract({
use: [
'css-loader',
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
],
publicPath: './'
})
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:6].[ext]',
}
}
],
exclude: /node_modules/
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[hash:6].[ext]'
}
}
]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'stage-0'] },
}],
},
{
test: require.resolve('jquery-lazyload'),
use: "imports-loader?this=>window"
}
]
},
resolve: {
extensions: ['*', '.js', '.css']
},
externals: {
jquery: 'jQuery',
ui: 'jQuery.ui'
},
plugins: [
new webpack.NormalModuleReplacementPlugin(/\.css$/, path.resolve('./src', './empty.js')),
new webpack.LoaderOptionsPlugin({
debug: true
}),
extractCSS
],
devServer: {
hot: true
}
};

View File

@@ -0,0 +1,131 @@
require('babel-core/register');
// Webpack config for creating the production bundle.
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const WebpackNotifierPlugin = require('webpack-notifier');
const PKG_LOCATION = require(path.join(__dirname, '../../package.json'));
const config = require('../config');
const webpackConfig = require('./webpack.development.config');
// add loader for external stylesheets:
var extractCSS = new ExtractTextPlugin({
filename: '[name].css',
allChunks: true
});
module.exports = Object.assign({}, webpackConfig, {
cache: false,
devtool: false,
watch: false,
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [{
loader: 'babel-loader',
options: { presets: ['es2015', 'stage-0'] },
}],
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 10000,
name: '[name].[hash:6].[ext]',
}
}
],
exclude: /node_modules/
},
{
test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[hash:6].[ext]'
}
}
]
},
{
test: /\.css$/,
use: [
"style-loader",
"css-loader"
]
},
{
test: /videojs-flash\.js$/,
loader: 'script-loader'
},
// exclude skins as inline-css in dev env
// {
// test: /\.scss$/,
// exclude: /src\/skins\//,
// loaders: ['style', 'css', 'resolve-url', 'sass']
// },
// only skins are extracted as external file in dev env:
{
test: /\.scss$/,
// exclude: /src\/(?!skins)/,
// include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
use: ExtractTextPlugin.extract({
use: [
'css-loader',
'resolve-url-loader',
{ loader: 'sass-loader', options: { sourceMap: true } }
],
publicPath: './'
})
},
{
test: require.resolve('jquery-lazyload'),
use: "imports-loader?this=>window"
}, {
test: require.resolve('geonames-server-jquery-plugin/jquery.geonames'),
use: "imports-loader?this=>window"
}, {
test: require.resolve('bootstrap-multiselect'),
use: "imports-loader?this=>window"
}
]
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"videojs": "video.js",
"window.videojs": "video.js"
}),
// Notifier
new WebpackNotifierPlugin({
title: PKG_LOCATION.name,
alwaysNotify: true
}),
// optimizations
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'__DEV__': false,
'process.env.NODE_ENV': JSON.stringify('production'),
VERSION: JSON.stringify(PKG_LOCATION.version)
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
chunks: ['production', 'lightbox'],
minChunks: 2
}),
new webpack.LoaderOptionsPlugin({
debug: true
}),
extractCSS
],
devServer: {
hot: true
}
});

View File

@@ -0,0 +1,58 @@
require('babel-core/register');
// Webpack config for creating the minified production bundle.
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const WebpackNotifierPlugin = require('webpack-notifier');
const PKG_LOCATION = require(path.join(__dirname, '../../package.json'));
const config = require('../config');
const webpackConfig = require('./webpack.production.config')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
var extractCSS = new ExtractTextPlugin({
filename: '[name].min.css',
allChunks: true
});
module.exports = Object.assign({}, webpackConfig, {
output: {
path: config.distDir,
filename: '[name].min.js',
chunkFilename: 'lazy-[name].min.js',
libraryTarget: 'umd',
library: config._app,
publicPath: '/assets/production/'
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"videojs": "video.js",
"window.videojs": "video.js"
}),
// Notifier
new WebpackNotifierPlugin({
title: PKG_LOCATION.name,
alwaysNotify: true
}),
// optimizations
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'__DEV__': false,
'process.env.NODE_ENV': JSON.stringify('production'),
VERSION: JSON.stringify(PKG_LOCATION.version)
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
chunks: ['production', 'lightbox'],
minChunks: 2
}),
extractCSS,
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.min\.css$/,
cssProcessorOptions: { discardComments: { removeAll: true }, zindex: false }
})
]
});

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 B

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

64093
Phraseanet-production-client/dist/lazy-1.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

45303
Phraseanet-production-client/dist/lazy-3.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["app"] = factory();
else
root["app"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/assets/production/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 250);
/******/ })
/************************************************************************/
/******/ ({
/***/ 250:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(251);
/***/ }),
/***/ 251:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Skin entry point (only for webpack generation of css)
*/
__webpack_require__(252);
/***/ }),
/***/ 252:
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ })
/******/ });
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,107 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["app"] = factory();
else
root["app"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/assets/production/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 250);
/******/ })
/************************************************************************/
/******/ ({
/***/ 250:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(251);
/***/ }),
/***/ 251:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Skin entry point (only for webpack generation of css)
*/
__webpack_require__(252);
/***/ }),
/***/ 252:
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ })
/******/ });
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["app"] = factory();
else
root["app"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/assets/production/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 253);
/******/ })
/************************************************************************/
/******/ ({
/***/ 253:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(254);
/***/ }),
/***/ 254:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Skin entry point (only for webpack generation of css)
*/
__webpack_require__(255);
/***/ }),
/***/ 255:
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ })
/******/ });
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,107 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["app"] = factory();
else
root["app"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/assets/production/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 253);
/******/ })
/************************************************************************/
/******/ ({
/***/ 253:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(254);
/***/ }),
/***/ 254:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Skin entry point (only for webpack generation of css)
*/
__webpack_require__(255);
/***/ }),
/***/ 255:
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ })
/******/ });
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,107 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["app"] = factory();
else
root["app"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/assets/production/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 256);
/******/ })
/************************************************************************/
/******/ ({
/***/ 256:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(257);
/***/ }),
/***/ 257:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Skin entry point (only for webpack generation of css)
*/
__webpack_require__(258);
/***/ }),
/***/ 258:
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ })
/******/ });
});

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,107 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["app"] = factory();
else
root["app"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/assets/production/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 256);
/******/ })
/************************************************************************/
/******/ ({
/***/ 256:
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(257);
/***/ }),
/***/ 257:
/***/ (function(module, exports, __webpack_require__) {
"use strict";
/**
* Skin entry point (only for webpack generation of css)
*/
__webpack_require__(258);
/***/ }),
/***/ 258:
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ })
/******/ });
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

View File

@@ -0,0 +1,2 @@
require('babel-core/register');
module.exports = require('./config/karma.conf');

View File

@@ -0,0 +1,2 @@
*
!.gitignore

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,168 @@
{
"name": "phraseanet-production-client",
"version": "0.34.272-d",
"description": "Phraseanet frontend dependencies",
"scripts": {
"clean": "rimraf dist",
"dev": "npm run clean && set NODE_ENV=devlopment && npx webpack --config ./config/webpack/webpack.development.config.js --progress --profile --colors",
"production": "npm run clean && set NODE_ENV=production && npx webpack --config ./config/webpack/webpack.production.config.js --progress --profile --colors",
"dist": "npm run clean && set NODE_ENV=production && npx webpack --config ./config/webpack/webpack.production.config.js --progress --profile --colors && npx webpack --config ./config/webpack/webpack.production.minified.config.js --progress --profile --colors",
"test": "npm run test:browser",
"test:server": "mocha --opts config/mocha.opts",
"test:browser": "./node_modules/.bin/karma start --single-run",
"watch:server": "npm run test:server -- --watch",
"watch:browser": "./node_modules/.bin/karma start --auto-watch --no-single-run",
"eslint:source": "eslint ./src/**/*.js",
"eslint:fix": "eslint --fix ./src/**/*.js",
"eslint:common": "eslint ./test/**/*.common.js",
"eslint:server": "eslint ./test/**/*.server.js",
"eslint:browser": "eslint ./test/**/*.browser.js",
"karma:firefox": "./node_modules/.bin/karma start --browsers=Firefox",
"karma:chrome": "./node_modules/.bin/karma start --browsers=Chrome",
"karma:ie": "./node_modules/.bin/karma start --browsers=IE",
"karma:all": "./node_modules/.bin/karma start --browsers=PhantomJS,Chrome,Firefox",
"packages": "npm list --depth=0",
"package:purge": "rm -rf node_modules",
"package:reinstall": "npm run package:purge && npm install",
"package:check": "./node_modules/.bin/ncu",
"package:upgrade": "./node_modules/.bin/ncu -u",
"package:prod": "./node_modules/.bin/ncu -u",
"package:dev": "./node_modules/.bin/ncu -p -u",
"asset-server": "node config/webpack/webpack.hot.assets.config",
"publish-patch": "git add -A && npm run dist && git commit && git push -u origin 4.1 && git push --tags && npm version patch && npm publish",
"publish-minor": "git add -A && npm run dist && git commit && git push -u origin 4.1 && git push --tags && npm version minor && npm publish",
"postpublish": "git push origin 4.1 --follow-tags"
},
"pre-commit": [
"test"
],
"repository": {
"type": "git",
"url": "git+https://github.com/alchemy-fr/Phraseanet-production-client.git"
},
"keywords": [
"phraseanet"
],
"files": [
"dist",
"src"
],
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
"babel-eslint": "^7.2.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-polyfill": "^6.23.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"chai": "^3.5.0",
"chai-as-promised": "^7.1.1",
"coveralls": "^2.13.1",
"css-loader": "^0.28.4",
"dotenv": "^4.0.0",
"eslint": "^4.18.2",
"eslint-config-airbnb": "^15.1.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.1.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"imports-loader": "^0.7.1",
"istanbul-instrumenter-loader": "^3.0.0",
"karma": "^1.7.0",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1",
"karma-coverage": "^1.1.1",
"karma-firefox-launcher": "^1.0.1",
"karma-ie-launcher": "^1.0.0",
"karma-mocha": "^1.3.0",
"karma-mocha-reporter": "^2.2.3",
"karma-phantomjs-launcher": "^1.0.4",
"karma-sinon": "^1.0.5",
"karma-sinon-chai": "^1.3.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.31",
"karma-webpack": "^2.0.4",
"lodash": "^4.17.15",
"lolex": "^2.1.2",
"mocha": "^3.5.0",
"node-sass": "^4.14.0",
"nodemon": "^1.11.0",
"npm-check-updates": "^2.12.1",
"npmlog": "^4.1.2",
"optimize-css-assets-webpack-plugin": "^3.0.0",
"phantomjs-polyfill": "0.0.2",
"phantomjs-prebuilt": "^2.1.16",
"postcss-loader": "^2.0.6",
"pre-commit": "^1.2.2",
"resolve-url-loader": "^2.1.0",
"rimraf": "^2.6.1",
"sass-loader": "^6.0.6",
"sinon": "^2.1.0",
"sinon-chai": "^2.12.0",
"style-loader": "^0.18.2",
"url-loader": "^0.5.9",
"webpack": "^3.4.1",
"webpack-dev-server": "^2.6.1",
"webpack-notifier": "^1.5.0"
},
"babel": {
"ignore": [
"packages/babel-cli/src/babel-plugin/templates"
]
},
"devEngines": {
"node": ">=4.1 <6",
"npm": ">=3.1 <5"
},
"author": {
"name": "Florian Blouet",
"email": "florian.blouet@gmail.com"
},
"bugs": "https://github.com/alchemy-fr/Phraseanet-production-client/issues",
"homepage": "https://github.com/alchemy-fr/Phraseanet-production-client",
"license": "MIT",
"dependencies": {
"@mapbox/mapbox-gl-language": "^0.9.2",
"@turf/turf": "^5.1.6",
"axios": "^0.19.2",
"backbone": "^1.3.3",
"blueimp-file-upload": "^9.15.0",
"blueimp-load-image": "^2.14.0",
"bootstrap-multiselect": "^0.9.13-1",
"bootstrap-sass": "^2.3.2",
"es6-promise": "^4.1.1",
"geonames-server-jquery-plugin": "^0.2.2",
"humane-js": "^3.2.2",
"i18next": "^8.4.3",
"i18next-xhr-backend": "^1.4.2",
"jquery": "^3.2.1",
"jquery-lazyload": "^1.9.7",
"jquery-treeview": "https://github.com/alchemy-fr/jquery-treeview.git",
"jquery-ui": "^1.10.4",
"jquery-ui-datepicker-with-i18n": "^1.10.4",
"jquery.fancytree": "~2.7",
"jquery.tree": "0.0.5",
"js-cookie": "^2.1.0",
"leaflet": "^0.7.7",
"leaflet-contextmenu": "^1.0.0",
"leaflet-draw": "^0.3.0",
"lodash.merge": "^4.6.2",
"mapbox": "^1.0.0-beta10",
"mapbox-gl": "^1.11.0",
"mapbox-gl-circle": "^1.6.5",
"mapbox.js": "^2.4.0",
"nouislider": "^9.2.0",
"pym.js": "^1.3.1",
"rx": "^4.1.0",
"sprintf-js": "^1.1.1",
"underscore": "^1.8.3",
"video.js": "^7.5.5",
"videojs-flash": "^2.1.0",
"videojs-hotkeys": "^0.2.20",
"zxcvbn": "^4.4.2"
}
}

View File

@@ -0,0 +1,74 @@
import $ from 'jquery';
import ConfigService from './../components/core/configService';
import LocaleService from '../components/locale';
import merge from 'lodash.merge';
import defaultConfig from './config';
import Emitter from '../components/core/emitter';
import account from './../components/account';
$(document).ready(() => {
// hide or show callback url input whether user choose a web or dektop application
$('#form_create input[name=type]').bind('click', function () {
if ($(this).val() === 'desktop') {
$('#form_create .callback-control-group').hide().find('input').val('');
} else {
$('#form_create .callback-control-group').show();
}
});
});
class Bootstrap {
app;
configService;
localeService;
appServices;
constructor(userConfig) {
const configuration = merge({}, defaultConfig, userConfig);
this.appEvents = new Emitter();
this.configService = new ConfigService(configuration);
this.onConfigReady();
return this;
}
onConfigReady() {
this.appServices = {
configService: this.configService,
localeService: this.localeService,
appEvents: this.appEvents
};
/**
* add components
*/
$(document).ready(() => {
let accountService = account(this.appServices);
accountService.initialize({
$container: $('body')
});
switch (this.configService.get('state')) {
case 'editAccount':
accountService.editAccount();
break;
case 'editSession':
accountService.editSession();
break;
default:
}
});
}
}
const bootstrap = (userConfig) => {
return new Bootstrap(userConfig);
};
export default bootstrap;

View File

@@ -0,0 +1,7 @@
let defaultConfig = {
locale: 'fr',
basePath: '/',
translations: '/prod/language.json',
};
export default defaultConfig;

View File

@@ -0,0 +1,10 @@
import bootstrap from './bootstrap';
let accountApp = {
bootstrap
};
if (typeof window !== 'undefined') {
window.accountApp = accountApp;
}
module.exports = accountApp;

View File

@@ -0,0 +1,86 @@
import $ from 'jquery';
import ConfigService from './../components/core/configService';
import LocaleService from '../components/locale';
import merge from 'lodash.merge';
import defaultConfig from './config';
import Emitter from '../components/core/emitter';
import authentication from './../components/authentication';
class Bootstrap {
app;
configService;
localeService;
appServices;
constructor(userConfig) {
const configuration = merge({}, defaultConfig, userConfig);
this.appEvents = new Emitter();
this.configService = new ConfigService(configuration);
this.localeService = new LocaleService({
configService: this.configService
});
this.localeService.fetchTranslations()
.then(() => {
this.onConfigReady();
});
return this;
}
onConfigReady() {
this.appServices = {
configService: this.configService,
localeService: this.localeService,
appEvents: this.appEvents
};
// export translation for backward compatibility:
// window.language = this.localeService.getTranslations();
/**
* add components
*/
$(document).ready(() => {
let authService = authentication(this.appServices);
authService.initialize();
switch (this.configService.get('state')) {
case 'login':
authService.login();
break;
case 'forgotPassword':
authService.forgotPassword();
break;
case 'renewPassword':
authService.renewPassword();
break;
case 'register':
authService.register();
break;
case 'registerProvider':
authService.registerProvider();
break;
case 'renewEmail':
authService.renewEmail();
break;
case 'changePassword':
authService.changePassword();
break;
default:
}
});
}
}
const bootstrap = (userConfig) => {
return new Bootstrap(userConfig);
};
export default bootstrap;

View File

@@ -0,0 +1,7 @@
let defaultConfig = {
locale: 'fr',
basePath: '/',
translations: '/login/language.json',
};
export default defaultConfig;

View File

@@ -0,0 +1,10 @@
import bootstrap from './bootstrap';
let authenticateApp = {
bootstrap
};
if (typeof window !== 'undefined') {
window.authenticateApp = authenticateApp;
}
module.exports = authenticateApp;

View File

@@ -0,0 +1,236 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import geonames from './../authentication/common/geonames';
const account = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = (options) => {
let {$container} = options;
$container.on('click', '.alert .alert-block-close a', function (e) {
e.preventDefault();
$(this).closest('.alert').alert('close');
return false;
});
// revoke third party application access
$('a.app-btn').bind('click', function (e) {
e.preventDefault();
var $this = $(this);
$.ajax({
type: 'GET',
url: $this.attr('href'),
dataType: 'json',
data: {revoke: $this.hasClass('authorize') ? 0 : 1},
success: function (data) {
if (data.success) {
var li = $this.closest('li');
var hidden = $('.app-btn.hidden , .status.hidden', li);
var notHidden = $('.app-btn:not(.hidden), .status:not(.hidden)', li);
hidden.removeClass('hidden');
notHidden.addClass('hidden');
}
}
});
});
// generate new access token
$('a#generate_access').bind('click', function (e) {
e.preventDefault();
var $this = $(this);
$.ajax({
type: 'POST',
url: $this.attr('href'),
dataType: 'json',
data: {
usr_id: $this.closest('div').attr('id')
},
success: function (data) {
if (data.success) {
$('#my_access_token').empty().append(data.token);
}
}
});
});
//modify application callback url
$('.modifier_callback').bind('click', function () {
var modifierBtn = $(this);
var saveBtn = $('a.save_callback');
var input = $('.url_callback_input');
var inputVal = input.html();
modifierBtn.hide();
saveBtn.show();
// wrapp current calback in an input
input
.empty()
.wrapInner(''
+ '<input value="' + inputVal + '"'
+ ' name="oauth_callback" size="50" type="text"/>'
);
$('.url_callback').off();
// save new callback
saveBtn.bind('click', function (e) {
e.preventDefault();
var callback = $('input[name=oauth_callback]').val();
$.ajax({
type: 'POST',
url: saveBtn.attr('href'),
dataType: 'json',
data: {callback: callback},
success: function (data) {
if (data.success) {
input.empty().append(callback);
} else {
input.empty().append(inputVal);
}
modifierBtn.show();
saveBtn.hide();
}
});
});
});
//modify application webhook url
$('.webhook-modify-btn').bind('click', function () {
var modifierBtn = $(this);
var saveBtn = $('a.save_webhook');
var input = $('.url_webhook_input');
var inputVal = input.html();
modifierBtn.hide();
saveBtn.show();
// wrapp current calback in an input
input
.empty()
.wrapInner(''
+ '<input value="' + inputVal + '"'
+ ' name="oauth_webhook" size="50" type="text"/>'
);
$('.url_webhook').off();
// save new callback
saveBtn.bind('click', function (e) {
e.preventDefault();
var webhook = $('input[name=oauth_webhook]').val();
$.ajax({
type: 'POST',
url: saveBtn.attr('href'),
dataType: 'json',
data: {webhook: webhook},
success: function (data) {
if (data.success) {
input.empty().append(webhook);
} else {
input.empty().append(inputVal);
}
modifierBtn.show();
saveBtn.hide();
}
});
});
});
// hide or show callback url input whether user choose a web or dektop application
/* $('#form_create input[name=type]').bind('click', function () {
if ($(this).val() === 'desktop') {
$('#form_create .callback-control-group').hide().find('input').val('');
} else {
$('#form_create .callback-control-group').show();
}
});*/
// authorize password grant type or not
$('.grant-type').bind('click', function () {
var $this = $(this);
$.ajax({
type: 'POST',
url: $this.attr('value'),
dataType: 'json',
data: {grant: $this.is(':checked') ? '1' : '0'},
success: function (data) {
}
});
});
// delete an application
/* $('a.delete-app').bind('click', function (e) {
e.preventDefault();
var $this = $(this);
var li = $this.closest('li');
$.ajax({
type: 'DELETE',
url: $this.attr('href'),
dataType: 'json',
data: {},
success: function (data) {
if (data.success) {
li.find('.modal').modal('hide');
li.remove();
}
}
});
});*/
};
const editAccount = () => {
$('legend').bind('click', function () {
$('.form-info').hide(200);
$($(this).data('target')).show();
});
geonames.init($('#form_geonameid'), {
server: configService.get('geonameServerUrl'),
limit: 40
});
};
const editSession = () => {
var modal = $('#modal-delete-confirm').modal({
show: false
});
$('a.delete-session').bind('click', function (e) {
e.preventDefault();
modal
.data('delete-url', $(this).prop('href'))
.modal('toggle');
return false;
});
$('a.confirm-delete').on('click', function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: modal.data('delete-url'),
dataType: 'json',
success: function (data) {
if (data.success) {
$('#row-' + data.session_id).closest('tr').remove();
}
modal.modal('toggle');
}
});
});
};
return {initialize, editAccount, editSession}
};
export default account;

View File

@@ -0,0 +1,56 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import RenewPasswordForm from './common/forms/views/formType/passwordSetter';
const changePassword = (services) => {
const {configService, localeService, appEvents} = services;
const initialize = () => {
require.ensure([], () => {
services.zxcvbn = require('zxcvbn');
new RenewPasswordForm({
services,
el: $('form[name=passwordChangeForm]'),
rules: [
{
name: 'oldPassword',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'password[password]',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'password[password]',
rules: 'min_length[5]',
message: localeService.t('validation_length_min', {
postProcess: 'sprintf',
sprintf: ['5']
})
},
{
name: 'password[confirm]',
rules: 'matches[password[password]]',
message: localeService.t('password_match')
}
]
});
});
};
return {initialize};
};
export default changePassword;

View File

@@ -0,0 +1,278 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
var FormValidator = function (rules, handlers) {
// rules setted by user
this.rules = rules || [];
// custom callbacks
this.handlers = handlers || [];
// final fields to validate
this.fields = [];
var self = this;
_.each(this.rules, function (field) {
if ('name' in field && 'rules' in field) {
self._addField(field);
}
});
};
// Validate method, argument is the serialize form
FormValidator.prototype.validate = function (inputs) {
var self = this;
// possible errors
this.errors = [];
// inputs present in form
this.inputs = {};
_.each(_.groupBy(inputs, function (input) {
return input.name;
}), function (fields, name) {
self.inputs[name] = fields;
});
this._validateForm();
return this;
};
FormValidator.prototype.getErrors = function () {
return this.errors;
};
FormValidator.prototype.hasErrors = function () {
return this.errors.length > 0;
};
FormValidator.prototype.getRules = function () {
return this.rules;
};
FormValidator.prototype._addField = function (field) {
this.fields.push({
name: field.name,
rules: field.rules,
message: field.message || 'An error ocurred on input[name=' + field.name + '], you can edit this message by setting a "message" property in your rule definition object',
value: null,
type: field.type || 'text'
});
};
FormValidator.prototype._validateForm = function () {
var self = this;
this.errors = [];
_.each(this.fields, function (field) {
if (_.has(self.inputs, field.name)) {
// values can be multiple
var values = [];
_.each(self.inputs[field.name], function (field) {
return values.push(field.value);
});
field.value = values.join(',');
self._validateField(field);
} else if (field.type === 'checkbox' || field.type === 'radio' || field.type === 'select' || field.type === 'multiple') {
field.value = '';
self._validateField(field);
}
});
};
FormValidator.prototype._validateField = function (field) {
var self = this;
var ruleRegex = /^(.+?)\[(.+)\]$/;
var rules = field.rules.split('|');
// Run through the rules and execute the validation methods as needed
_.every(rules, function (method) {
var param = null;
var failed = false;
var parts = ruleRegex.exec(method);
// If the rule has a parameter (i.e. matches[param]) split it out
if (parts) {
method = parts[1];
param = parts[2];
}
// If the hook is defined, run it to find any validation errors
if (typeof self._hooks[method] === 'function') {
if (!self._hooks[method].apply(self, [field, param])) {
failed = true;
}
} else if (method.substring(0, 9) === 'callback_') {
// Custom method. Execute the handler if it was registered
method = method.substring(9, method.length);
if (typeof self.handlers[method] === 'function') {
if (this.handlers[method].apply(self, [field.value, param]) === false) {
failed = true;
}
}
}
// If the hook failed, add a message to the errors array
if (failed) {
self.errors.push({
name: field.name,
value: field.value,
message: field.message,
rule: method
});
}
// Breaks loop iteration
return failed;
});
};
FormValidator.prototype.Regexp = {
numericRegex: /^[0-9]+$/,
integerRegex: /^\-?[0-9]+$/,
decimalRegex: /^\-?[0-9]*\.?[0-9]+$/,
emailRegex: /^[^@]+@[^@]+\.[^@]+$/,
alphaRegex: /^[a-z]+$/i,
alphaNumericRegex: /^[a-z0-9]+$/i,
alphaDashRegex: /^[a-z0-9_\-]+$/i,
naturalRegex: /^[0-9]+$/i,
naturalNoZeroRegex: /^[1-9][0-9]*$/i,
// IP v6 a v4 or hostname, by Mikulas Dite see http://stackoverflow.com/a/9209720/96656
ipRegex: /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$/i,
numericDashRegex: /^[\d\-\s]+$/,
urlRegex: /^((http|https):\/\/(\w+:{0,1}\w*@)?(\S+)|)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/
};
// Object containing all of the validation hooks
FormValidator.prototype._hooks = {
required: function (field) {
var value = field.value;
return (value !== null && value !== '');
},
equal: function (field, defaultName) {
return field.value === defaultName;
},
matches: function (field, matchName) {
if (typeof this.inputs[matchName] === 'undefined') {
return false;
}
var el = this.inputs[matchName].shift();
if (el) {
return field.value === el.value;
}
return false;
},
valid_email: function (field) {
return this.Regexp.emailRegex.test(field.value);
},
valid_emails: function (field) {
var result = field.value.split(',');
for (var i = 0; i < result.length; i++) {
if (!this.Regexp.emailRegex.test($.trim(result[i]))) {
return false;
}
}
return true;
},
min_length: function (field, length) {
if (field.type === 'multiple') {
return _.filter(field.value.split(','), function (value) {
return value !== '';
}).length >= parseInt(length, 10)
}
if (!this.Regexp.numericRegex.test(length)) {
return false;
}
return (field.value.length >= parseInt(length, 10));
},
max_length: function (field, length) {
if (field.type === 'multiple') {
return _.filter(field.value.split(','), function (value) {
return value !== '';
}).length <= parseInt(length, 10)
}
if (!this.Regexp.numericRegex.test(length)) {
return false;
}
return (field.value.length <= parseInt(length, 10));
},
exact_length: function (field, length) {
if (field.type === 'multiple') {
return _.filter(field.value.split(','), function (value) {
return value !== '';
}).length === parseInt(length, 10)
}
if (!this.Regexp.numericRegex.test(length)) {
return false;
}
return (field.value.length === parseInt(length, 10));
},
greater_than: function (field, param) {
if (!this.Regexp.decimalRegex.test(field.value)) {
return false;
}
return (parseFloat(field.value) > parseFloat(param));
},
less_than: function (field, param) {
if (!this.Regexp.decimalRegex.test(field.value)) {
return false;
}
return (parseFloat(field.value) < parseFloat(param));
},
alpha: function (field) {
return (this.Regexp.alphaRegex.test(field.value));
},
alpha_numeric: function (field) {
return (this.Regexp.alphaNumericRegex.test(field.value));
},
alpha_dash: function (field) {
return (this.Regexp.alphaDashRegex.test(field.value));
},
numeric: function (field) {
return (this.Regexp.numericRegex.test(field.value));
},
integer: function (field) {
return (this.Regexp.integerRegex.test(field.value));
},
decimal: function (field) {
return (this.Regexp.decimalRegex.test(field.value));
},
is_natural: function (field) {
return (this.Regexp.naturalRegex.test(field.value));
},
is_natural_no_zero: function (field) {
return (this.Regexp.naturalNoZeroRegex.test(field.value));
},
valid_ip: function (field) {
return (this.Regexp.ipRegex.test(field.value));
},
valid_url: function (field) {
return (this.Regexp.urlRegex.test(field.value));
}
};
export default FormValidator;

View File

@@ -0,0 +1,60 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
var ErrorView = Backbone.View.extend({
tagName: 'div',
initialize: function (options) {
options = options || {};
if (options.name === undefined) {
throw 'Missing name attribute in error view';
}
if (options.errorTemplate === undefined) {
throw 'Missing errorTemplate attribute in error view';
}
this.name = options.name;
this.errorTemplate = options.errorTemplate;
this.errors = options.errors || {};
this.onRenderError = options.onRenderError || null;
},
render: function () {
if (this.errors.length > 0) {
var template = _.template($(this.errorTemplate).html(), {
errors: this.errors
});
this.$el.html(template);
if (_.isFunction(this.onRenderError)) {
this.onRenderError(this.name, this.$el);
}
} else {
this.reset();
}
return this;
},
renderErrors: function (errors) {
this.errors = errors;
this.render();
return this;
},
reset: function () {
this.$el.empty();
}
});
export default ErrorView;

View File

@@ -0,0 +1,89 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
import Validator from './../validator';
import InputView from './input';
var Form = Backbone.View.extend({
events: {
submit: '_onSubmit'
},
initialize: function (options) {
options = options || {};
var self = this;
if (options.services !== undefined) {
this.services = options.services;
}
this.errorTemplate = options.errorTemplate || '#field_errors';
this.onRenderError = options.onRenderError || null;
// get a new validator defined rules
this.validator = new Validator(options.rules || []);
this.inputViews = {};
// creates input views for each input
_.each(this.$el.serializeArray(), function (input) {
self._addInputView(input);
});
},
_onSubmit: function (event) {
var self = this;
// reset previous errors in the view
this._resetInputErrors();
// validate new values
this.validator.validate(this.$el.serializeArray());
if (this.validator.hasErrors()) {
// cancel submit
event.preventDefault();
// group errors by input
_.each(_.groupBy(this.validator.getErrors(), function (error) {
return error.name;
}), function (errors, name) {
// show new errors in the views
if (name in self.inputViews) {
self.inputViews[name].showErrors(errors);
} else {
// Because serialize array do not serialize non checked input
// We must create view for errored input name on the fly
var input = {name: name};
self._addInputView(input);
self.inputViews[name].showErrors(errors);
}
});
}
},
_resetInputErrors: function () {
_.each(this.inputViews, function (view) {
view.resetErrors();
});
},
_addInputView: function (input) {
var name = input.name;
this.inputViews[name] = new InputView({
name: name,
el: $('input[name="' + name + '"], select[name="' + name + '"], textarea[name="' + name + '"]', this.$el).first().closest('div'),
errorTemplate: this.errorTemplate,
onRenderError: this.onRenderError
});
return this;
}
});
export default Form;

View File

@@ -0,0 +1,76 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
import FormView from './../form';
var PasswordSetterForm = FormView.extend({
events: function () {
return _.extend({}, FormView.prototype.events, {
'keyup input[type=password]': 'onPasswordKeyup'
});
},
onPasswordKeyup: function (event) {
var input = $(event.target);
var password = input.val();
var inputView = this.inputViews[input.attr('name')];
var bg = $('.password_strength_bg', inputView.$el);
var label = $('.password_strength_label', inputView.$el);
var desc = $('.password_strength_desc', inputView.$el);
var css = {
width: '0%',
'background-color': 'rgb(39, 39, 30)'
};
var result = '';
if (password.length > 0) {
var passMeter = this.services.zxcvbn(input.val());
switch (passMeter.score) {
case 0:
case 1:
css = {
width: '25%',
'background-color': 'rgb(200, 24, 24)'
};
result = this.services.localeService.t('weak');
break;
case 2:
css = {
width: '50%',
'background-color': 'rgb(255, 172, 29)'
};
result = this.services.localeService.t('ordinary');
break;
case 3:
css = {
width: '75%',
'background-color': 'rgb(166, 192, 96)'
};
result = this.services.localeService.t('good');
break;
case 4:
css = {
width: '100%',
'background-color': 'rgb(39, 179, 15)'
};
result = this.services.localeService.t('great');
break;
default:
}
}
bg.css(css);
label.css({color: css['background-color']});
desc.css({color: css['background-color']}).html(result);
}
});
export default PasswordSetterForm;

View File

@@ -0,0 +1,49 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import _ from 'underscore';
import Backbone from 'backbone';
import ErrorView from './error';
import MultiViews from './../../multiviews';
var InputView = Backbone.View.extend(_.extend({}, MultiViews, {
initialize: function (options) {
options = options || {};
if (options.name === undefined) {
throw 'Missing name attribute in input view';
}
if (options.errorTemplate === undefined) {
throw 'Missing errorTemplate attribute in input view';
}
this.name = options.name;
this.errorView = new ErrorView({
name: this.name,
errorTemplate: options.errorTemplate,
onRenderError: options.onRenderError || null
});
},
render: function () {
this._assignView({'.error-view': this.errorView});
},
showErrors: function (errors) {
this.render();
this.errorView.renderErrors(errors);
return this;
},
resetErrors: function () {
this.errorView.reset();
}
}));
export default InputView;

View File

@@ -0,0 +1,43 @@
import $ from 'jquery';
require('jquery-ui');
require('geonames-server-jquery-plugin/jquery.geonames.js');
const geonames = {
init: function ($field, options) {
var geocompleter = $field.geocompleter(options);
// On focus add select-state
geocompleter.geocompleter('autocompleter', 'on', 'autocompletefocus', function (event, ui) {
$('li', $(event.originalEvent.target)).closest('li').removeClass('selected');
$('a.ui-state-active, a.ui-state-hover, a.ui-state-focus', $(event.originalEvent.target)).closest('li').addClass('selected');
});
// On search request add loading-state
geocompleter.geocompleter('autocompleter', 'on', 'autocompletesearch', function (event, ui) {
$(this).attr('autocomplete', 'false');
$(this).addClass('input-loading');
$(this).removeClass('input-error');
});
// On response remove loading-state
geocompleter.geocompleter('autocompleter', 'on', 'autocompleteresponse', function (event, ui) {
$(this).removeClass('input-loading');
});
// On close menu remove loading-state
geocompleter.geocompleter('autocompleter', 'on', 'autocompleteclose', function (event, ui) {
$(this).removeClass('input-loading');
});
// On request error add error-state
geocompleter.geocompleter('autocompleter', 'on', 'geotocompleter.request.error', function (jqXhr, status, error) {
$(this).removeClass('input-loading');
$(this).addClass('input-error');
});
return geocompleter;
}
};
export default geonames;

View File

@@ -0,0 +1,26 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import _ from 'underscore';
export default {
// bind a subview to a DOM element
_assignView: function (selector, view) {
var selectors;
if (_.isObject(selector)) {
selectors = selector;
} else {
selectors = {};
selectors[selector] = view;
}
if (!selectors) return;
_.each(selectors, function (view, selector) {
view.setElement(this.$(selector)).render();
}, this);
}
};

View File

@@ -0,0 +1,36 @@
/*
* This file is part of Phraseanet
*
* (c) 2005-2016 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import $ from 'jquery';
import ForgotPassWordForm from './common/forms/views/form';
const forgotPassword = (services) => {
const { configService, localeService, appEvents } = services;
const initialize = () => {
new ForgotPassWordForm({
el: $('form[name=forgottenPasswordForm]'),
rules: [
{
name: 'email',
rules: 'required',
message: localeService.t('validation_blank')
},
{
name: 'email',
rules: 'valid_email',
message: localeService.t('validation_email')
}
]
});
};
return {initialize};
};
export default forgotPassword;

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