Merge branch 'dev-v7.7' into temp-U4-10275
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
"globals": {
|
||||
"angular": false,
|
||||
"_": false,
|
||||
"$", false,
|
||||
"$": false,
|
||||
"tinymce": false,
|
||||
"tinyMCE": false,
|
||||
"FileReader": false,
|
||||
@@ -47,7 +47,7 @@
|
||||
"window": false,
|
||||
"LazyLoad": false,
|
||||
"ActiveXObject": false,
|
||||
"Bloodhound", false
|
||||
"Bloodhound": false
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
#Belle
|
||||
|
||||
Umbraco 7 UI, codename "Belle" Built on AngularJS, bower, Lazyload.js and Twitter Bootstrap
|
||||
|
||||
|
||||
##Introduction
|
||||
Slides from the initial demonstration of Belle done at the Umbraco DK Fest can be found here:
|
||||
|
||||
http://rawgithub.com/umbraco/Umbraco.Web.Ui.Client/build/master/Presentation/index.html
|
||||
|
||||
|
||||
##Running the site with mocked data
|
||||
|
||||
This won't require any database or setup, as everything is running through node. All you have to do is install
|
||||
node and grunt on either windows or OSX and the entire setup is ready for you.
|
||||
|
||||
|
||||
###Install node.js
|
||||
We need node to run tests and automated less compiling and other automated tasks. go to http://nodejs.org. Node.js is a powerfull javascript engine, which allows us to run all our tests and tasks written in javascript locally.
|
||||
|
||||
*note:* On windows you might need to restart explorer.exe to register node.
|
||||
|
||||
|
||||
###Install dependencies
|
||||
Next we need to install all the required packages. This is done with the package tool, included with node.js, open /src/Umbraco.Web.UI.Client in cmd.exe or osx terminal and run the command:
|
||||
|
||||
npm install
|
||||
|
||||
this will fetch all needed packages to your local machine.
|
||||
|
||||
|
||||
###Install grunt globally
|
||||
Grunt is a task runner for node.js, and we use it for all automated tasks in the build process. For convenience we need to install it globally on your machine, so it can be used directly in cmd.exe or the terminal.
|
||||
|
||||
So run the command:
|
||||
|
||||
npm install grunt-cli -g
|
||||
|
||||
*note:* On windows you might need to restart explorer.exe to register the grunt cmd.
|
||||
|
||||
*note:* On OSX you might need to run:
|
||||
|
||||
sudo npm install grunt-cli -g
|
||||
|
||||
Now that you have node and grunt installed, you can open `/src/Umbraco.Web.UI.Client` in either `cmd.exe` or terminal and run:
|
||||
|
||||
grunt dev
|
||||
|
||||
This will build the site, merge less files, run tests and create the /Build folder, and finally open the site in your
|
||||
browser.
|
||||
|
||||
|
||||
##Limitations
|
||||
The current prototype simply uses in-memory storage, so no database dependencies. It is aimed at showing UI, not a complete functional client-server setup.
|
||||
|
||||
|
||||
##Project Structure
|
||||
|
||||
All project files are located in /src/Umbraco.Web.UI.Client which only contains client-side files, everything
|
||||
related to asp.net are in /src/Umbraco.Web.UI
|
||||
|
||||
after building Belle files are located in /build/belle, with all files following AngularJs
|
||||
conventions:
|
||||
|
||||
###Folders
|
||||
- */Umbraco.Web.Ui.Client/build/lib:* Dependencies
|
||||
- */Umbraco.Web.Ui.Client/build/js:* Application javascript files
|
||||
- */Umbraco.Web.Ui.Client/build/views/common/:* Main application views
|
||||
- */Umbraco.Web.Ui.Client/build/views/[sectioname]/pagename Editors html
|
||||
- */Umbraco.Web.Ui.Client/build/views/propertyeditors:* Property Editors html
|
||||
|
||||
|
||||
###Files
|
||||
- */Umbraco.Web.Ui.Client/build/js/app.js:* Main umbraco application / modules
|
||||
- */Umbraco.Web.Ui.Client/build/js/loader.js:* lazyload configuration for dependencies
|
||||
- */Umbraco.Web.Ui.Client/build/js/routes.js:* Application routes
|
||||
- */Umbraco.Web.Ui.Client/build/js/umbraco.controllers.js:* Application controllers
|
||||
- */Umbraco.Web.Ui.Client/build/js/umbraco.services.js:* Application services
|
||||
- */Umbraco.Web.Ui.Client/build/js/umbraco.filters.js:* Application filters
|
||||
- */Umbraco.Web.Ui.Client/build/js/umbraco.directives.js:* Application directives
|
||||
- */Umbraco.Web.Ui.Client/build/js/umbraco.resources.js:* Application resources, like content, media, users, members etc
|
||||
- */Umbraco.Web.Ui.Client/build/js/umbraco.mocks.js:* Fake Application resources, for running the app without a server
|
||||
|
||||
##Getting started
|
||||
The current app is built, following conventions from angularJs and bootstrap. To get started with the applicaton you will need to atleast know the basics of these frameworks
|
||||
|
||||
###AngularJS
|
||||
- Excellent introduction videos on http://www.egghead.io/
|
||||
- Official guide at: http://docs.angularjs.org/guide/
|
||||
|
||||
###Require.js
|
||||
- Introduction: http://javascriptplayground.com/blog/2012/07/requirejs-amd-tutorial-introduction
|
||||
- Require.js website: http://requirejs.org/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,59 @@
|
||||
"angular-local-storage": "~0.2.3",
|
||||
"moment": "~2.10.3",
|
||||
"ace-builds": "^1.2.3",
|
||||
"font-awesome": "~4.2",
|
||||
"clipboard": "1.7.1"
|
||||
},
|
||||
|
||||
"install": {
|
||||
|
||||
"path": "lib-bower",
|
||||
|
||||
"ignore": [
|
||||
"font-awesome",
|
||||
"angular",
|
||||
"bootstrap",
|
||||
"codemirror"
|
||||
],
|
||||
|
||||
"sources": {
|
||||
"moment": "bower_components/moment/min/moment-with-locales.js",
|
||||
|
||||
"underscore": [
|
||||
"bower_components/underscore/underscore-min.js",
|
||||
"bower_components/underscore/underscore-min.map"
|
||||
],
|
||||
|
||||
"jquery": [
|
||||
"bower_components/jquery/dist/jquery.min.js",
|
||||
"bower_components/jquery/dist/jquery.min.map"
|
||||
],
|
||||
|
||||
"angular-dynamic-locale": [
|
||||
"bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js",
|
||||
"bower_components/angular-dynamic-locale/tmhDynamicLocale.min.js.map"
|
||||
],
|
||||
|
||||
"angular-local-storage": [
|
||||
"bower_components/angular-local-storage/dist/angular-local-storage.min.js",
|
||||
"bower_components/angular-local-storage/dist/angular-local-storage.min.js.map"
|
||||
],
|
||||
|
||||
"tinymce": [
|
||||
"bower_components/tinymce/tinymce.min.js"
|
||||
],
|
||||
|
||||
"typeahead.js": "bower_components/typeahead.js/dist/typeahead.bundle.min.js",
|
||||
|
||||
"rgrove-lazyload":"bower_components/rgrove-lazyload/lazyload.js",
|
||||
|
||||
"ng-file-upload":"bower_components/ng-file-upload/ng-file-upload.min.js",
|
||||
|
||||
"jquery-ui":"bower_components/jquery-ui/jquery-ui.min.js",
|
||||
|
||||
"jquery-migrate":"bower_components/jquery-migrate/jquery-migrate.min.js",
|
||||
|
||||
"clipboard": "bower_components/clipboard/dist/clipboard.min.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,601 +0,0 @@
|
||||
module.exports = function (grunt) {
|
||||
|
||||
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask('default', ['jshint:dev', 'build', 'karma:unit']);
|
||||
grunt.registerTask('dev', ['jshint:dev', 'build-dev', 'webserver', 'open:dev', 'watch']);
|
||||
grunt.registerTask('docserve', ['docs:api', 'connect:docserver', 'open:docs', 'watch:docs']);
|
||||
grunt.registerTask('vs', ['jshint:dev', 'build-dev', 'watch']);
|
||||
|
||||
//TODO: Too much watching, this brings windows to it's knees when in dev mode
|
||||
//run by the watch task
|
||||
grunt.registerTask('watch-js', ['jshint:dev', 'concat', 'copy:app', 'copy:mocks', 'copy:canvasdesigner', 'copy:vs', 'karma:unit']);
|
||||
grunt.registerTask('watch-less', ['recess:build', 'recess:installer', 'recess:nonodes', 'recess:canvasdesigner', 'postcss', 'copy:canvasdesigner', 'copy:assets', 'copy:vs']);
|
||||
grunt.registerTask('watch-html', ['copy:views', 'copy:vs']);
|
||||
grunt.registerTask('watch-installer', ['concat:install', 'concat:installJs', 'copy:installer', 'copy:vs']);
|
||||
grunt.registerTask('watch-canvasdesigner', ['copy:canvasdesigner', 'concat:canvasdesignerJs', 'copy:vs']);
|
||||
grunt.registerTask('watch-test', ['jshint:dev', 'karma:unit']);
|
||||
|
||||
//triggered from grunt
|
||||
grunt.registerTask('build', ['concat', 'recess:build', 'recess:installer', 'recess:nonodes', 'recess:canvasdesigner', 'postcss', 'bower-install-simple', 'bower', 'copy', 'clean:post']);
|
||||
|
||||
//triggered from grunt dev vs or grunt vs
|
||||
grunt.registerTask('build-dev', ['clean:pre', 'concat', 'recess:build', 'recess:installer', 'recess:nonodes', 'postcss', 'bower-install-simple', 'bower', 'copy']);
|
||||
|
||||
//utillity tasks
|
||||
grunt.registerTask('docs', ['ngdocs']);
|
||||
grunt.registerTask('webserver', ['connect:devserver']);
|
||||
|
||||
|
||||
// Print a timestamp (useful for when watching)
|
||||
grunt.registerTask('timestamp', function () {
|
||||
grunt.log.subhead(Date());
|
||||
});
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
buildVersion: grunt.option('buildversion') || '7',
|
||||
connect: {
|
||||
devserver: {
|
||||
options: {
|
||||
port: 9990,
|
||||
hostname: '0.0.0.0',
|
||||
base: './build',
|
||||
middleware: function(connect, options) {
|
||||
return [
|
||||
//uncomment to enable CSP
|
||||
// util.csp(),
|
||||
//util.rewrite(),
|
||||
connect.favicon('images/favicon.ico'),
|
||||
connect.static(options.base),
|
||||
connect.directory(options.base)
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
testserver: {},
|
||||
docserver: {
|
||||
options: {
|
||||
port: 8880,
|
||||
hostname: '0.0.0.0',
|
||||
base: './docs/api',
|
||||
middleware: function(connect, options) {
|
||||
return [
|
||||
//uncomment to enable CSP
|
||||
// util.csp(),
|
||||
//util.rewrite(),
|
||||
connect.static(options.base),
|
||||
connect.directory(options.base)
|
||||
];
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
open: {
|
||||
dev: {
|
||||
path: 'http://localhost:9990/belle/'
|
||||
},
|
||||
docs: {
|
||||
path: 'http://localhost:8880/index.html'
|
||||
}
|
||||
},
|
||||
|
||||
distdir: 'build/belle',
|
||||
vsdir: '../Umbraco.Web.UI/umbraco',
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
banner:
|
||||
'/*! <%= pkg.title || pkg.name %>\n' +
|
||||
'<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' +
|
||||
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;\n' +
|
||||
' * Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n */\n',
|
||||
src: {
|
||||
js: ['src/**/*.js', 'src/*.js'],
|
||||
|
||||
common: ['src/common/**/*.js'],
|
||||
controllers: ['src/**/*.controller.js'],
|
||||
|
||||
specs: ['test/**/*.spec.js'],
|
||||
scenarios: ['test/**/*.scenario.js'],
|
||||
samples: ['sample files/*.js'],
|
||||
html: ['src/index.html', 'src/install.html'],
|
||||
|
||||
everything: ['src/**/*.*', 'test/**/*.*', 'docs/**/*.*'],
|
||||
|
||||
tpl: {
|
||||
app: ['src/views/**/*.html'],
|
||||
common: ['src/common/**/*.tpl.html']
|
||||
},
|
||||
less: ['src/less/belle.less'], // recess:build doesn't accept ** in its file patterns
|
||||
prod: ['<%= distdir %>/js/*.js']
|
||||
},
|
||||
|
||||
clean: {
|
||||
pre: ['<%= distdir %>/*'],
|
||||
post: ['<%= distdir %>/js/*.dev.js']
|
||||
},
|
||||
|
||||
copy: {
|
||||
assets: {
|
||||
files: [{ dest: '<%= distdir %>/assets', src: '**', expand: true, cwd: 'src/assets/' }]
|
||||
},
|
||||
|
||||
config: {
|
||||
files: [{ dest: '<%= distdir %>/../config', src: '**', expand: true, cwd: 'src/config/' }]
|
||||
},
|
||||
|
||||
installer: {
|
||||
files: [{ dest: '<%= distdir %>/views/install', src: '**/*.html', expand: true, cwd: 'src/installer/steps' }]
|
||||
},
|
||||
|
||||
canvasdesigner: {
|
||||
files: [
|
||||
{ dest: '<%= distdir %>/preview', src: '**/*.html', expand: true, cwd: 'src/canvasdesigner' },
|
||||
{ dest: '<%= distdir %>/preview/editors', src: '**/*.html', expand: true, cwd: 'src/canvasdesigner/editors' },
|
||||
{ dest: '<%= distdir %>/assets/less', src: '**/*.less', expand: true, cwd: 'src/canvasdesigner/editors' },
|
||||
{ dest: '<%= distdir %>/js', src: 'canvasdesigner.config.js', expand: true, cwd: 'src/canvasdesigner/config' },
|
||||
{ dest: '<%= distdir %>/js', src: 'canvasdesigner.palettes.js', expand: true, cwd: 'src/canvasdesigner/config' },
|
||||
{ dest: '<%= distdir %>/js', src: 'canvasdesigner.front.js', expand: true, cwd: 'src/canvasdesigner' }
|
||||
]
|
||||
},
|
||||
|
||||
vendor: {
|
||||
files: [{ dest: '<%= distdir %>/lib', src: '**', expand: true, cwd: 'lib/' }]
|
||||
},
|
||||
|
||||
views: {
|
||||
files: [{ dest: '<%= distdir %>/views', src: ['**/*.*', '!**/*.controller.js'], expand: true, cwd: 'src/views' }]
|
||||
},
|
||||
|
||||
app: {
|
||||
files: [
|
||||
{ dest: '<%= distdir %>/js', src: '*.js', expand: true, cwd: 'src/' }
|
||||
]
|
||||
},
|
||||
|
||||
mocks: {
|
||||
files: [{ dest: '<%= distdir %>/js', src: '*.js', expand: true, cwd: 'src/common/mocks/' }]
|
||||
},
|
||||
|
||||
vs: {
|
||||
files: [
|
||||
//everything except the index.html root file!
|
||||
//then we need to figure out how to not copy all the test stuff either!?
|
||||
{ dest: '<%= vsdir %>/assets', src: '**', expand: true, cwd: '<%= distdir %>/assets' },
|
||||
{ dest: '<%= vsdir %>/js', src: '**', expand: true, cwd: '<%= distdir %>/js' },
|
||||
{ dest: '<%= vsdir %>/views', src: '**', expand: true, cwd: '<%= distdir %>/views' },
|
||||
{ dest: '<%= vsdir %>/preview', src: '**', expand: true, cwd: '<%= distdir %>/preview' },
|
||||
{ dest: '<%= vsdir %>/lib', src: '**', expand: true, cwd: '<%= distdir %>/lib' }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
karma: {
|
||||
unit: { configFile: 'test/config/karma.conf.js', keepalive: true },
|
||||
e2e: { configFile: 'test/config/e2e.js', keepalive: true },
|
||||
watch: { configFile: 'test/config/unit.js', singleRun: false, autoWatch: true, keepalive: true }
|
||||
},
|
||||
|
||||
concat: {
|
||||
index: {
|
||||
src: ['src/index.html'],
|
||||
dest: '<%= distdir %>/index.html',
|
||||
options: {
|
||||
process: true
|
||||
}
|
||||
},
|
||||
install: {
|
||||
src: ['src/installer/installer.html'],
|
||||
dest: '<%= distdir %>/installer.html',
|
||||
options: {
|
||||
process: true
|
||||
}
|
||||
},
|
||||
|
||||
installJs: {
|
||||
src: ['src/installer/**/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.installer.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
canvasdesignerJs: {
|
||||
src: ['src/canvasdesigner/canvasdesigner.global.js', 'src/canvasdesigner/canvasdesigner.controller.js', 'src/canvasdesigner/editors/*.js', 'src/canvasdesigner/lib/*.js'],
|
||||
dest: '<%= distdir %>/js/canvasdesigner.panel.js'
|
||||
},
|
||||
|
||||
controllers: {
|
||||
src: ['src/controllers/**/*.controller.js', 'src/views/**/*.controller.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.controllers.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
services: {
|
||||
src: ['src/common/services/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.services.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
security: {
|
||||
src: ['src/common/security/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.security.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
resources: {
|
||||
src: ['src/common/resources/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.resources.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
testing: {
|
||||
src: ['src/common/mocks/*/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.testing.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
directives: {
|
||||
src: ['src/common/directives/**/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.directives.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
},
|
||||
|
||||
filters: {
|
||||
src: ['src/common/filters/*.js'],
|
||||
dest: '<%= distdir %>/js/umbraco.filters.js',
|
||||
options: {
|
||||
banner: "<%= banner %>\n(function() { \n\n",
|
||||
footer: "\n\n})();"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
uglify: {
|
||||
options: {
|
||||
mangle: true
|
||||
},
|
||||
combine: {
|
||||
files: {
|
||||
'<%= distdir %>/js/umbraco.min.js': ['<%= distdir %>/js/umbraco.*.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
recess: {
|
||||
build: {
|
||||
files: {
|
||||
'<%= distdir %>/assets/css/<%= pkg.name %>.css':
|
||||
['<%= src.less %>']
|
||||
},
|
||||
options: {
|
||||
compile: true,
|
||||
compress: true
|
||||
}
|
||||
},
|
||||
nonodes: {
|
||||
files: {
|
||||
'<%= distdir %>/assets/css/nonodes.style.min.css':
|
||||
['src/less/pages/nonodes.less']
|
||||
},
|
||||
options: {
|
||||
compile: true,
|
||||
compress: true
|
||||
}
|
||||
},
|
||||
installer: {
|
||||
files: {
|
||||
'<%= distdir %>/assets/css/installer.css':
|
||||
['src/less/installer.less']
|
||||
},
|
||||
options: {
|
||||
compile: true,
|
||||
compress: true
|
||||
}
|
||||
},
|
||||
canvasdesigner: {
|
||||
files: {
|
||||
'<%= distdir %>/assets/css/canvasdesigner.css':
|
||||
['src/less/canvas-designer.less', 'src/less/helveticons.less']
|
||||
},
|
||||
options: {
|
||||
compile: true,
|
||||
compress: true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
postcss: {
|
||||
options: {
|
||||
processors: [
|
||||
// add vendor prefixes
|
||||
require('autoprefixer-core')({
|
||||
browsers: 'last 2 versions'
|
||||
})
|
||||
]
|
||||
},
|
||||
dist: {
|
||||
src: '<%= distdir %>/assets/css/<%= pkg.name %>.css'
|
||||
}
|
||||
},
|
||||
|
||||
ngTemplateCache: {
|
||||
views: {
|
||||
files: {
|
||||
'<%= distdir %>/js/umbraco.views.js': 'src/views/**/*.html'
|
||||
},
|
||||
options: {
|
||||
trim: 'src/',
|
||||
module: 'umbraco.views'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
docs: {
|
||||
files: ['docs/src/**/*.md'],
|
||||
tasks: ['watch-docs', 'timestamp']
|
||||
},
|
||||
css: {
|
||||
files: 'src/**/*.less',
|
||||
tasks: ['watch-less', 'timestamp'],
|
||||
options: {
|
||||
livereload: true,
|
||||
},
|
||||
},
|
||||
js: {
|
||||
files: ['src/**/*.js', 'src/*.js'],
|
||||
tasks: ['watch-js', 'timestamp'],
|
||||
},
|
||||
test: {
|
||||
files: ['test/**/*.js'],
|
||||
tasks: ['watch-test', 'timestamp'],
|
||||
},
|
||||
installer: {
|
||||
files: ['src/installer/**/*.*'],
|
||||
tasks: ['watch-installer', 'timestamp'],
|
||||
},
|
||||
canvasdesigner: {
|
||||
files: ['src/canvasdesigner/**/*.*'],
|
||||
tasks: ['watch-canvasdesigner', 'timestamp'],
|
||||
},
|
||||
html: {
|
||||
files: ['src/views/**/*.html', 'src/*.html'],
|
||||
tasks: ['watch-html', 'timestamp']
|
||||
},
|
||||
options: {
|
||||
interval: 500
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
ngdocs: {
|
||||
options: {
|
||||
dest: 'docs/api',
|
||||
startPage: '/api',
|
||||
title: "Umbraco Backoffice UI API Documentation",
|
||||
html5Mode: false,
|
||||
styles: [
|
||||
'docs/umb-docs.css'
|
||||
],
|
||||
image: "https://our.umbraco.org/assets/images/logo.svg"
|
||||
},
|
||||
api: {
|
||||
src: ['src/common/**/*.js', 'docs/src/api/**/*.ngdoc'],
|
||||
title: 'API Documentation'
|
||||
},
|
||||
tutorials: {
|
||||
src: [],
|
||||
title: ''
|
||||
}
|
||||
},
|
||||
|
||||
eslint:{
|
||||
src: ['<%= src.common %>','<%= src.controllers %>'],
|
||||
options: {quiet: true}
|
||||
},
|
||||
|
||||
jshint: {
|
||||
dev: {
|
||||
files: {
|
||||
src: ['<%= src.common %>']
|
||||
},
|
||||
options: {
|
||||
curly: true,
|
||||
eqeqeq: true,
|
||||
immed: true,
|
||||
latedef: "nofunc",
|
||||
newcap: true,
|
||||
noarg: true,
|
||||
sub: true,
|
||||
boss: true,
|
||||
//NOTE: This is required so it doesn't barf on reserved words like delete when doing $http.delete
|
||||
es5: true,
|
||||
eqnull: true,
|
||||
//NOTE: we need to use eval sometimes so ignore it
|
||||
evil: true,
|
||||
//NOTE: we need to check for strings such as "javascript:" so don't throw errors regarding those
|
||||
scripturl: true,
|
||||
//NOTE: we ignore tabs vs spaces because enforcing that causes lots of errors depending on the text editor being used
|
||||
smarttabs: true,
|
||||
globals: {}
|
||||
}
|
||||
},
|
||||
build: {
|
||||
files: {
|
||||
src: ['<%= src.prod %>']
|
||||
},
|
||||
options: {
|
||||
curly: true,
|
||||
eqeqeq: true,
|
||||
immed: true,
|
||||
latedef: "nofunc",
|
||||
newcap: true,
|
||||
noarg: true,
|
||||
sub: true,
|
||||
boss: true,
|
||||
//NOTE: This is required so it doesn't barf on reserved words like delete when doing $http.delete
|
||||
es5: true,
|
||||
eqnull: true,
|
||||
//NOTE: we need to use eval sometimes so ignore it
|
||||
evil: true,
|
||||
//NOTE: we need to check for strings such as "javascript:" so don't throw errors regarding those
|
||||
scripturl: true,
|
||||
//NOTE: we ignore tabs vs spaces because enforcing that causes lots of errors depending on the text editor being used
|
||||
smarttabs: true,
|
||||
globalstrict: true,
|
||||
globals: { $: false, jQuery: false, define: false, require: false, window: false }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
bower: {
|
||||
dev: {
|
||||
dest: '<%= distdir %>/lib',
|
||||
options: {
|
||||
expand: true,
|
||||
ignorePackages: ['bootstrap'],
|
||||
packageSpecific: {
|
||||
'moment': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['min/moment-with-locales.js']
|
||||
},
|
||||
'typeahead.js': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['dist/typeahead.bundle.min.js']
|
||||
},
|
||||
'underscore': {
|
||||
files: ['underscore-min.js', 'underscore-min.map']
|
||||
},
|
||||
'rgrove-lazyload': {
|
||||
files: ['lazyload.js']
|
||||
},
|
||||
'bootstrap-social': {
|
||||
files: ['bootstrap-social.css']
|
||||
},
|
||||
'font-awesome': {
|
||||
files: ['css/font-awesome.min.css', 'fonts/*']
|
||||
},
|
||||
"jquery": {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['dist/jquery.min.js', 'dist/jquery.min.map']
|
||||
},
|
||||
'jquery-ui': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['jquery-ui.min.js']
|
||||
},
|
||||
'jquery-migrate': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['jquery-migrate.min.js']
|
||||
},
|
||||
'tinymce': {
|
||||
files: ['plugins/**', 'themes/**', 'tinymce.min.js']
|
||||
},
|
||||
'angular-dynamic-locale': {
|
||||
files: ['tmhDynamicLocale.min.js', 'tmhDynamicLocale.min.js.map']
|
||||
},
|
||||
'ng-file-upload': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['ng-file-upload.min.js']
|
||||
},
|
||||
'angular-local-storage': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['dist/angular-local-storage.min.js']
|
||||
},
|
||||
'codemirror': {
|
||||
files: [
|
||||
'lib/codemirror.js',
|
||||
'lib/codemirror.css',
|
||||
|
||||
'mode/css/*',
|
||||
'mode/javascript/*',
|
||||
'mode/xml/*',
|
||||
'mode/htmlmixed/*',
|
||||
|
||||
'addon/search/*',
|
||||
'addon/edit/*',
|
||||
'addon/selection/*',
|
||||
'addon/dialog/*'
|
||||
]
|
||||
},
|
||||
'ace-builds': {
|
||||
files: [
|
||||
'src-min-noconflict/ace.js',
|
||||
|
||||
'src-min-noconflict/ext-language_tools.js',
|
||||
'src-min-noconflict/ext-searchbox.js',
|
||||
'src-min-noconflict/ext-settings_menu.js',
|
||||
|
||||
'src-min-noconflict/snippets/text.js',
|
||||
'src-min-noconflict/snippets/javascript.js',
|
||||
|
||||
'src-min-noconflict/theme-chrome.js',
|
||||
|
||||
'src-min-noconflict/mode-razor.js',
|
||||
'src-min-noconflict/mode-javascript.js',
|
||||
|
||||
'src-min-noconflict/worker-javascript.js',
|
||||
]
|
||||
},
|
||||
'clipboard': {
|
||||
keepExpandedHierarchy: false,
|
||||
files: ['dist/clipboard.min.js']
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
expand: true
|
||||
}
|
||||
},
|
||||
|
||||
"bower-install-simple": {
|
||||
options: {
|
||||
color: true
|
||||
},
|
||||
"dev": {}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-recess');
|
||||
grunt.loadNpmTasks('grunt-postcss');
|
||||
|
||||
grunt.loadNpmTasks('grunt-karma');
|
||||
|
||||
grunt.loadNpmTasks('grunt-open');
|
||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||
grunt.loadNpmTasks("grunt-bower-install-simple");
|
||||
grunt.loadNpmTasks('grunt-bower');
|
||||
grunt.loadNpmTasks('grunt-ngdocs');
|
||||
|
||||
grunt.loadNpmTasks('grunt-eslint');
|
||||
grunt.loadNpmTasks('grunt-hustler');
|
||||
};
|
||||
389
src/Umbraco.Web.UI.Client/gulpfile.js
Normal file
389
src/Umbraco.Web.UI.Client/gulpfile.js
Normal file
@@ -0,0 +1,389 @@
|
||||
var gulp = require('gulp');
|
||||
var watch = require('gulp-watch');
|
||||
var concat = require('gulp-concat');
|
||||
var rename = require('gulp-rename');
|
||||
var wrap = require("gulp-wrap-js");
|
||||
var sort = require('gulp-sort');
|
||||
var connect = require('gulp-connect');
|
||||
var open = require('gulp-open');
|
||||
var runSequence = require('run-sequence');
|
||||
|
||||
var _ = require('lodash');
|
||||
var MergeStream = require('merge-stream');
|
||||
|
||||
//Less + css
|
||||
var postcss = require('gulp-postcss');
|
||||
var less = require('gulp-less');
|
||||
var autoprefixer = require('autoprefixer');
|
||||
var cssnano = require('cssnano');
|
||||
|
||||
// Documentation
|
||||
var gulpDocs = require('gulp-ngdocs');
|
||||
|
||||
// Testing
|
||||
var karmaServer = require('karma').Server;
|
||||
|
||||
/***************************************************************
|
||||
Helper functions
|
||||
***************************************************************/
|
||||
function processJs(files, out) {
|
||||
|
||||
return gulp.src(files)
|
||||
.pipe(sort())
|
||||
.pipe(concat(out))
|
||||
.pipe(wrap('(function(){\n%= body %\n})();'))
|
||||
.pipe(gulp.dest(root + targets.js));
|
||||
|
||||
console.log(out + " compiled");
|
||||
}
|
||||
|
||||
function processLess(files, out) {
|
||||
|
||||
var processors = [
|
||||
autoprefixer,
|
||||
cssnano
|
||||
];
|
||||
|
||||
return gulp.src(files)
|
||||
.pipe(less())
|
||||
.pipe(postcss(processors))
|
||||
.pipe(rename(out))
|
||||
.pipe(gulp.dest(root + targets.css));
|
||||
|
||||
console.log(out + " compiled");
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
Paths and destinations
|
||||
Each group is iterated automatically in the setup tasks below
|
||||
***************************************************************/
|
||||
var sources = {
|
||||
|
||||
//less files used by backoffice and preview
|
||||
//processed in the less task
|
||||
less: {
|
||||
installer: { files: ["src/less/installer.less"], out: "installer.css" },
|
||||
nonodes: { files: ["src/less/pages/nonodes.less"], out: "nonodes.style.min.css"},
|
||||
preview: { files: ['src/less/canvas-designer.less', 'src/less/helveticons.less'], out: "canvasdesigner.css" },
|
||||
umbraco: { files: ["src/less/belle.less"], out: "umbraco.css" }
|
||||
},
|
||||
|
||||
//js files for backoffie
|
||||
//processed in the js task
|
||||
js: {
|
||||
preview: { files: ["src/canvasdesigner/**/*.js"], out: "umbraco.canvasdesigner.js" },
|
||||
installer: { files: ["src/installer/**/*.js"], out: "umbraco.installer.js" },
|
||||
|
||||
controllers: { files: ["src/{views,controllers}/**/*.controller.js"], out: "umbraco.controllers.js" },
|
||||
directives: { files: ["src/common/directives/**/*.js"], out: "umbraco.directives.js" },
|
||||
filters: { files: ["src/common/filters/**/*.js"], out: "umbraco.filters.js" },
|
||||
resources: { files: ["src/common/resources/**/*.js"], out: "umbraco.resources.js" },
|
||||
services: { files: ["src/common/services/**/*.js"], out: "umbraco.services.js" },
|
||||
security: { files: ["src/common/security/**/*.js"], out: "umbraco.security.js" }
|
||||
},
|
||||
|
||||
//selectors for copying all views into the build
|
||||
//processed in the views task
|
||||
views:{
|
||||
umbraco: {files: ["src/views/**/*html"], folder: ""},
|
||||
preview: { files: ["src/canvasdesigner/**/*.html"], folder: "../preview"},
|
||||
installer: {files: ["src/installer/steps/*.html"], folder: "install"}
|
||||
},
|
||||
|
||||
//globs for file-watching
|
||||
globs:{
|
||||
views: "./src/views/**/*.html",
|
||||
less: "./src/less/**/*.less",
|
||||
js: "./src/*.js",
|
||||
lib: "./lib/**/*",
|
||||
bower: "./lib-bower/**/*",
|
||||
assets: "./src/assets/**"
|
||||
}
|
||||
};
|
||||
|
||||
var root = "../Umbraco.Web.UI/Umbraco/";
|
||||
var targets = {
|
||||
js: "js/",
|
||||
lib: "lib/",
|
||||
views: "views/",
|
||||
css: "assets/css/",
|
||||
assets: "assets/"
|
||||
};
|
||||
|
||||
|
||||
/**************************
|
||||
* Main tasks for the project to prepare backoffice files
|
||||
**************************/
|
||||
|
||||
// Build - build the files ready for production
|
||||
gulp.task('build', function(cb) {
|
||||
runSequence(["dependencies", "js", "less", "views"], "test:unit", cb);
|
||||
});
|
||||
|
||||
// Dev - build the files ready for development and start watchers
|
||||
gulp.task('dev', function(cb) {
|
||||
runSequence(["dependencies", "js", "less", "views"], "watch", cb);
|
||||
});
|
||||
|
||||
// Docserve - build and open the back office documentation
|
||||
gulp.task('docserve', function(cb) {
|
||||
runSequence('docs', 'connect:docs', 'open:docs', cb);
|
||||
});
|
||||
|
||||
/**************************
|
||||
* Task processes and copies all dependencies, either installed by bower, npm or stored locally in the project
|
||||
**************************/
|
||||
gulp.task('dependencies', function () {
|
||||
|
||||
//bower component specific copy rules
|
||||
//this is to patch the sometimes wonky rules these libs are distrbuted under
|
||||
|
||||
//as we do multiple things in this task, we merge the multiple streams
|
||||
var stream = new MergeStream();
|
||||
|
||||
//Tinymce
|
||||
stream.add(
|
||||
gulp.src(["./bower_components/tinymce/plugins/**",
|
||||
"./bower_components/tinymce/themes/**"],
|
||||
{ base: "./bower_components/tinymce/" })
|
||||
.pipe(gulp.dest(root + targets.lib + "/tinymce"))
|
||||
);
|
||||
|
||||
//font-awesome
|
||||
stream.add(
|
||||
gulp.src(["./bower_components/font-awesome/fonts/*",
|
||||
"./bower_components/font-awesome/css/font-awesome.min.css"],
|
||||
{ base: "./bower_components/font-awesome/" })
|
||||
.pipe(gulp.dest(root + targets.lib + "/font-awesome"))
|
||||
);
|
||||
|
||||
// ace Editor
|
||||
stream.add(
|
||||
gulp.src(["bower_components/ace-builds/src-min-noconflict/ace.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/ext-language_tools.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/ext-searchbox.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/ext-settings_menu.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/snippets/text.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/snippets/javascript.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/theme-chrome.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/mode-razor.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/mode-javascript.js",
|
||||
"bower_components/ace-builds/src-min-noconflict/worker-javascript.js"],
|
||||
{ base: "./bower_components/ace-builds/" })
|
||||
.pipe(gulp.dest(root + targets.lib + "/ace-builds"))
|
||||
);
|
||||
|
||||
// code mirror
|
||||
stream.add(
|
||||
gulp.src([
|
||||
"bower_components/codemirror/lib/codemirror.js",
|
||||
"bower_components/codemirror/lib/codemirror.css",
|
||||
|
||||
"bower_components/codemirror/mode/css/*",
|
||||
"bower_components/codemirror/mode/javascript/*",
|
||||
"bower_components/codemirror/mode/xml/*",
|
||||
"bower_components/codemirror/mode/htmlmixed/*",
|
||||
|
||||
"bower_components/codemirror/addon/search/*",
|
||||
"bower_components/codemirror/addon/edit/*",
|
||||
"bower_components/codemirror/addon/selection/*",
|
||||
"bower_components/codemirror/addon/dialog/*"],
|
||||
{ base: "./bower_components/codemirror/" })
|
||||
.pipe(gulp.dest(root + targets.lib + "/codemirror"))
|
||||
);
|
||||
|
||||
//copy over libs which are not on bower (/lib) and
|
||||
//libraries that have been managed by bower-installer (/lib-bower)
|
||||
stream.add(
|
||||
gulp.src(sources.globs.lib)
|
||||
.pipe(gulp.dest(root + targets.lib))
|
||||
);
|
||||
|
||||
stream.add(
|
||||
gulp.src(sources.globs.bower)
|
||||
.pipe(gulp.dest(root + targets.lib))
|
||||
);
|
||||
|
||||
//Copies all static assets into /root / assets folder
|
||||
//css, fonts and image files
|
||||
stream.add(
|
||||
gulp.src(sources.globs.assets)
|
||||
.pipe(gulp.dest(root + targets.assets))
|
||||
);
|
||||
|
||||
// Copies all the less files related to the preview into their folder
|
||||
//these are not pre-processed as preview has its own less combiler client side
|
||||
stream.add(
|
||||
gulp.src("src/canvasdesigner/editors/*.less")
|
||||
.pipe(gulp.dest(root + targets.assets + "/less"))
|
||||
);
|
||||
|
||||
return stream;
|
||||
});
|
||||
|
||||
|
||||
/**************************
|
||||
* Copies all angular JS files into their seperate umbraco.*.js file
|
||||
**************************/
|
||||
gulp.task('js', function () {
|
||||
|
||||
//we run multiple streams, so merge them all together
|
||||
var stream = new MergeStream();
|
||||
|
||||
stream.add(
|
||||
gulp.src(sources.globs.js)
|
||||
.pipe(gulp.dest(root + targets.js))
|
||||
);
|
||||
|
||||
_.forEach(sources.js, function (group) {
|
||||
stream.add (processJs(group.files, group.out) );
|
||||
});
|
||||
|
||||
return stream;
|
||||
});
|
||||
|
||||
gulp.task('less', function () {
|
||||
|
||||
var stream = new MergeStream();
|
||||
|
||||
_.forEach(sources.less, function (group) {
|
||||
stream.add( processLess(group.files, group.out) );
|
||||
});
|
||||
|
||||
return stream;
|
||||
});
|
||||
|
||||
|
||||
gulp.task('views', function () {
|
||||
|
||||
var stream = new MergeStream();
|
||||
|
||||
_.forEach(sources.views, function (group) {
|
||||
|
||||
console.log("copying " + group.files + " to " + root + targets.views + group.folder)
|
||||
|
||||
stream.add (
|
||||
gulp.src(group.files)
|
||||
.pipe( gulp.dest(root + targets.views + group.folder) )
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
return stream;
|
||||
});
|
||||
|
||||
|
||||
gulp.task('watch', function () {
|
||||
|
||||
var stream = new MergeStream();
|
||||
var watchInterval = 500;
|
||||
|
||||
//Setup a watcher for all groups of javascript files
|
||||
_.forEach(sources.js, function (group) {
|
||||
|
||||
if(group.watch !== false){
|
||||
|
||||
stream.add(
|
||||
|
||||
watch(group.files, { ignoreInitial: true, interval: watchInterval }, function (file) {
|
||||
|
||||
console.info(file.path + " has changed, added to: " + group.out);
|
||||
processJs(group.files, group.out);
|
||||
|
||||
})
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
stream.add(
|
||||
//watch all less files and trigger the less task
|
||||
watch(sources.globs.less, { ignoreInitial: true, interval: watchInterval }, function () {
|
||||
gulp.run(['less']);
|
||||
})
|
||||
);
|
||||
|
||||
//watch all views - copy single file changes
|
||||
stream.add(
|
||||
watch(sources.globs.views, { interval: watchInterval })
|
||||
.pipe(gulp.dest(root + targets.views))
|
||||
);
|
||||
|
||||
//watch all app js files that will not be merged - copy single file changes
|
||||
stream.add(
|
||||
watch(sources.globs.js, { interval: watchInterval })
|
||||
.pipe(gulp.dest(root + targets.js))
|
||||
);
|
||||
|
||||
return stream;
|
||||
});
|
||||
|
||||
/**************************
|
||||
* Build Backoffice UI API documentation
|
||||
**************************/
|
||||
gulp.task('docs', [], function (cb) {
|
||||
|
||||
var options = {
|
||||
html5Mode: false,
|
||||
startPage: '/api',
|
||||
title: "Umbraco Backoffice UI API Documentation",
|
||||
dest: 'docs/api',
|
||||
styles: ['docs/umb-docs.css'],
|
||||
image: "https://our.umbraco.org/assets/images/logo.svg"
|
||||
}
|
||||
|
||||
return gulpDocs.sections({
|
||||
api: {
|
||||
glob: ['src/common/**/*.js', 'docs/src/api/**/*.ngdoc'],
|
||||
api: true,
|
||||
title: 'API Documentation'
|
||||
}
|
||||
})
|
||||
.pipe(gulpDocs.process(options))
|
||||
.pipe(gulp.dest('docs/api'));
|
||||
cb();
|
||||
});
|
||||
|
||||
gulp.task('connect:docs', function (cb) {
|
||||
connect.server({
|
||||
root: 'docs/api',
|
||||
livereload: true,
|
||||
fallback: 'docs/api/index.html',
|
||||
port: 8880
|
||||
});
|
||||
cb();
|
||||
});
|
||||
|
||||
gulp.task('open:docs', function (cb) {
|
||||
|
||||
var options = {
|
||||
uri: 'http://localhost:8880/index.html'
|
||||
};
|
||||
|
||||
gulp.src(__filename)
|
||||
.pipe(open(options));
|
||||
cb();
|
||||
});
|
||||
|
||||
/**************************
|
||||
* Build tests
|
||||
**************************/
|
||||
|
||||
// Karma test
|
||||
gulp.task('test:unit', function() {
|
||||
new karmaServer({
|
||||
configFile: __dirname + "/test/config/karma.conf.js",
|
||||
keepalive: true
|
||||
})
|
||||
.start();
|
||||
});
|
||||
|
||||
gulp.task('test:e2e', function() {
|
||||
new karmaServer({
|
||||
configFile: __dirname + "/test/config/e2e.js",
|
||||
keepalive: true
|
||||
})
|
||||
.start();
|
||||
});
|
||||
@@ -193,10 +193,10 @@
|
||||
|
||||
// Reset container width
|
||||
// Required here as we reset the width earlier on and the grid mixins don't override early enough
|
||||
.navbar-static-top .container,
|
||||
.navbar-static-top .container,
|
||||
.navbar-fixed-top .container,
|
||||
.navbar-fixed-bottom .container {
|
||||
#grid > .core > .span(@gridColumns);
|
||||
.navbar-fixed-bottom .container {
|
||||
width: (@gridColumnWidth * @gridColumns) + (@gridGutterWidth * (@gridColumns - 1));
|
||||
}
|
||||
|
||||
// Fixed to top
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:umbraco/umbraco-cms.git"
|
||||
"url": "https://github.com/umbraco/Umbraco-CMS.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://issues.umbraco.org"
|
||||
@@ -14,38 +14,35 @@
|
||||
"engines": {
|
||||
"node": ">= 0.8.4"
|
||||
},
|
||||
"scripts": {
|
||||
"install": "bower-installer",
|
||||
"test": "karma start test/config/karma.conf.js --singlerun",
|
||||
"build": "gulp"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"autoprefixer-core": "~5.2.1",
|
||||
"bower": "^1.4.1",
|
||||
"eslint": "^0.23.0",
|
||||
"eslint-plugin-angular": "0.0.13",
|
||||
"grunt": "~0.4.0",
|
||||
"grunt-bower": "^0.19.0",
|
||||
"grunt-bower-install-simple": "^1.1.3",
|
||||
"grunt-contrib-clean": "~0.4.0",
|
||||
"grunt-contrib-concat": "~0.1.3",
|
||||
"grunt-contrib-connect": "~0.3.0",
|
||||
"grunt-contrib-copy": "~0.7.0",
|
||||
"grunt-contrib-jshint": "~0.2.0",
|
||||
"grunt-contrib-uglify": "~0.1.1",
|
||||
"grunt-contrib-watch": "~0.3.1",
|
||||
"grunt-eslint": "^15.0.0",
|
||||
"grunt-html2js": "~0.1.0",
|
||||
"grunt-hustler": "^4.0.6",
|
||||
"grunt-karma": "~0.5",
|
||||
"grunt-ngdocs": "~0.1.2",
|
||||
"grunt-open": "~0.2.0",
|
||||
"grunt-postcss": "~0.6.0",
|
||||
"grunt-recess": "~0.3",
|
||||
"karma": "~0.9",
|
||||
"karma-chrome-launcher": "0.0.2",
|
||||
"karma-coffee-preprocessor": "0.0.1",
|
||||
"karma-firefox-launcher": "0.0.2",
|
||||
"karma-jasmine": "0.0.1",
|
||||
"karma-phantomjs-launcher": "0.0.2",
|
||||
"karma-requirejs": "0.0.1",
|
||||
"karma-script-launcher": "0.0.1",
|
||||
"phantomjs": "~1.9.1-0"
|
||||
"autoprefixer": "^6.5.0",
|
||||
"bower-installer": "^1.2.0",
|
||||
"cssnano": "^3.7.6",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-connect": "^5.0.0",
|
||||
"gulp-less": "^3.1.0",
|
||||
"gulp-ngdocs": "^0.3.0",
|
||||
"gulp-open": "^2.0.0",
|
||||
"gulp-postcss": "^6.2.0",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-sort": "^2.0.0",
|
||||
"gulp-watch": "^4.3.10",
|
||||
"gulp-wrap": "^0.13.0",
|
||||
"gulp-wrap-js": "^0.4.1",
|
||||
"jasmine-core": "^2.5.2",
|
||||
"karma": "^1.7.0",
|
||||
"karma-jasmine": "^1.1.0",
|
||||
"karma-phantomjs-launcher": "^1.0.4",
|
||||
"less": "^2.6.1",
|
||||
"lodash": "^4.16.3",
|
||||
"merge-stream": "^1.0.1",
|
||||
"run-sequence": "^2.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@ LazyLoad.js([
|
||||
'../js/umbraco.security.js',
|
||||
'../ServerVariables',
|
||||
'../lib/spectrum/spectrum.js',
|
||||
|
||||
'../js/canvasdesigner.panel.js',
|
||||
'../js/umbraco.canvasdesigner.js',
|
||||
], function () {
|
||||
jQuery(document).ready(function () {
|
||||
angular.bootstrap(document, ['Umbraco.canvasdesigner']);
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
}
|
||||
*/
|
||||
|
||||
$scope.showReset = false;
|
||||
|
||||
//set defaults if they are not available
|
||||
if ($scope.config.disableToggle === undefined) {
|
||||
$scope.config.disableToggle = false;
|
||||
@@ -36,13 +38,13 @@
|
||||
if ($scope.config.minPasswordLength === undefined) {
|
||||
$scope.config.minPasswordLength = 0;
|
||||
}
|
||||
|
||||
|
||||
//set the model defaults
|
||||
if (!angular.isObject($scope.passwordValues)) {
|
||||
//if it's not an object then just create a new one
|
||||
$scope.passwordValues = {
|
||||
newPassword: null,
|
||||
oldPassword: null,
|
||||
oldPassword: null,
|
||||
reset: null,
|
||||
answer: null
|
||||
};
|
||||
@@ -61,11 +63,11 @@
|
||||
|
||||
//the value to compare to match passwords
|
||||
if (!isNew) {
|
||||
$scope.confirm = "";
|
||||
$scope.passwordValues.confirm = "";
|
||||
}
|
||||
else if ($scope.passwordValues.newPassword && $scope.passwordValues.newPassword.length > 0) {
|
||||
//if it is new and a new password has been set, then set the confirm password too
|
||||
$scope.confirm = $scope.passwordValues.newPassword;
|
||||
$scope.passwordValues.confirm = $scope.passwordValues.newPassword;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -86,6 +88,7 @@
|
||||
$scope.changing = true;
|
||||
//if there was a previously generated password displaying, clear it
|
||||
$scope.passwordValues.generatedPassword = null;
|
||||
$scope.passwordValues.confirm = null;
|
||||
};
|
||||
|
||||
$scope.cancelChange = function () {
|
||||
@@ -120,25 +123,13 @@
|
||||
unsubscribe[u]();
|
||||
}
|
||||
});
|
||||
|
||||
$scope.showReset = function () {
|
||||
return $scope.config.enableReset;
|
||||
};
|
||||
|
||||
|
||||
$scope.showOldPass = function () {
|
||||
return $scope.config.hasPassword &&
|
||||
!$scope.config.allowManuallyChangingPassword &&
|
||||
!$scope.config.enablePasswordRetrieval && !$scope.passwordValues.reset;
|
||||
!$scope.config.enablePasswordRetrieval && !$scope.showReset;
|
||||
};
|
||||
|
||||
$scope.showNewPass = function () {
|
||||
return !$scope.passwordValues.reset;
|
||||
};
|
||||
|
||||
$scope.showConfirmPass = function () {
|
||||
return !$scope.passwordValues.reset;
|
||||
};
|
||||
|
||||
|
||||
//TODO: I don't think we need this or the cancel button, this can be up to the editor rendering this directive
|
||||
$scope.showCancelBtn = function () {
|
||||
return $scope.config.disableToggle !== true && $scope.config.hasPassword;
|
||||
|
||||
@@ -5,48 +5,54 @@
|
||||
*
|
||||
*
|
||||
**/
|
||||
function currentUserResource($q, $http, umbRequestHelper) {
|
||||
function currentUserResource($q, $http, umbRequestHelper, umbDataFormatter) {
|
||||
|
||||
//the factory object returned
|
||||
return {
|
||||
//the factory object returned
|
||||
return {
|
||||
|
||||
performSetInvitedUserPassword: function (newPassword) {
|
||||
performSetInvitedUserPassword: function (newPassword) {
|
||||
|
||||
if (!newPassword) {
|
||||
return angularHelper.rejectedPromise({ errorMsg: 'newPassword cannot be empty' });
|
||||
}
|
||||
if (!newPassword) {
|
||||
return angularHelper.rejectedPromise({ errorMsg: 'newPassword cannot be empty' });
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"currentUserApiBaseUrl",
|
||||
"PostSetInvitedUserPassword"),
|
||||
angular.toJson(newPassword)),
|
||||
'Failed to change password');
|
||||
},
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"currentUserApiBaseUrl",
|
||||
"PostSetInvitedUserPassword"),
|
||||
angular.toJson(newPassword)),
|
||||
'Failed to change password');
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.currentUserResource#changePassword
|
||||
* @methodOf umbraco.resources.currentUserResource
|
||||
*
|
||||
* @description
|
||||
* Changes the current users password
|
||||
*
|
||||
* @returns {Promise} resourcePromise object containing the user array.
|
||||
*
|
||||
*/
|
||||
changePassword: function (changePasswordArgs) {
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"currentUserApiBaseUrl",
|
||||
"PostChangePassword"),
|
||||
changePasswordArgs),
|
||||
'Failed to change password');
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.currentUserResource#changePassword
|
||||
* @methodOf umbraco.resources.currentUserResource
|
||||
*
|
||||
* @description
|
||||
* Changes the current users password
|
||||
*
|
||||
* @returns {Promise} resourcePromise object containing the user array.
|
||||
*
|
||||
*/
|
||||
changePassword: function (changePasswordArgs) {
|
||||
|
||||
changePasswordArgs = umbDataFormatter.formatChangePasswordModel(changePasswordArgs);
|
||||
if (!changePasswordArgs) {
|
||||
throw 'No password data to change';
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.post(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"currentUserApiBaseUrl",
|
||||
"PostChangePassword"),
|
||||
changePasswordArgs),
|
||||
'Failed to change password');
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
angular.module('umbraco.resources').factory('currentUserResource', currentUserResource);
|
||||
|
||||
@@ -87,6 +87,7 @@ function tinyMceService(dialogService, $log, imageHelper, $http, $timeout, macro
|
||||
editor.addButton('umbmediapicker', {
|
||||
icon: 'custom icon-picture',
|
||||
tooltip: 'Media Picker',
|
||||
stateSelector: 'img',
|
||||
onclick: function () {
|
||||
|
||||
var selectedElm = editor.selection.getNode(),
|
||||
|
||||
@@ -7,8 +7,30 @@
|
||||
* @description A helper object used to format/transform JSON Umbraco data, mostly used for persisting data to the server
|
||||
**/
|
||||
function umbDataFormatter() {
|
||||
|
||||
return {
|
||||
|
||||
formatChangePasswordModel: function(model) {
|
||||
if (!model) {
|
||||
return null;
|
||||
}
|
||||
var trimmed = _.omit(model, ["confirm", "generatedPassword"])
|
||||
|
||||
//ensure that the pass value is null if all child properties are null
|
||||
var allNull = true;
|
||||
var vals = _.values(trimmed);
|
||||
for (var k = 0; k < vals.length; k++) {
|
||||
if (vals[k] !== null && vals[k] !== undefined) {
|
||||
allNull = false;
|
||||
}
|
||||
}
|
||||
if (allNull) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
},
|
||||
|
||||
formatContentTypePostData: function (displayModel, action) {
|
||||
|
||||
//create the save model from the display model
|
||||
@@ -82,6 +104,7 @@
|
||||
|
||||
//create the save model from the display model
|
||||
var saveModel = _.pick(displayModel, 'id', 'parentId', 'name', 'username', 'culture', 'email', 'startContentIds', 'startMediaIds', 'userGroups', 'message', 'changePassword');
|
||||
saveModel.changePassword = this.formatChangePasswordModel(saveModel.changePassword);
|
||||
|
||||
//make sure the userGroups are just a string array
|
||||
var currGroups = saveModel.userGroups;
|
||||
@@ -221,7 +244,8 @@
|
||||
});
|
||||
saveModel.email = propEmail.value;
|
||||
saveModel.username = propLogin.value;
|
||||
saveModel.password = propPass.value;
|
||||
|
||||
saveModel.password = this.formatChangePasswordModel(propPass.value);
|
||||
|
||||
var selectedGroups = [];
|
||||
for (var n in propGroups.value) {
|
||||
|
||||
@@ -1 +1 @@
|
||||
angular.module("umbraco.install", ["umbraco.directives"]);
|
||||
angular.module("umbraco.install", ["umbraco.directives"]);
|
||||
@@ -125,7 +125,7 @@ body {
|
||||
|
||||
@media (max-width: 500px) {
|
||||
#search-form .form-search {
|
||||
width: ~"(calc(~'100%' - ~'80px'))";
|
||||
width: calc(100% - 80px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ body {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
width: ~"(calc(~'100%' - ~'80px'))"; // 80px is the fixed left menu for toggling the different browser sizes
|
||||
width: calc(100% - 80px); // 80px is the fixed left menu for toggling the different browser sizes
|
||||
position: absolute;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
@@ -155,7 +155,7 @@
|
||||
@media (max-width: 500px) {
|
||||
.umb-overlay.umb-overlay-left {
|
||||
margin-left: 41px;
|
||||
width: ~"(calc(~'100%' - ~'41px'))";
|
||||
width: calc(100% - 41px);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ a.umb-package-details__back-link {
|
||||
.umb-package-details__main-content {
|
||||
flex: 1 1 auto;
|
||||
margin-right: 30px;
|
||||
width: ~"(calc(~'100%' - ~'@{sidebarwidth}' - ~'30px'))"; // Make sure that the main content area doesn't gets affected by inline styling
|
||||
width: calc(~'100%' - ~'@{sidebarwidth}' - ~'30px'); // Make sure that the main content area doesn't gets affected by inline styling
|
||||
}
|
||||
|
||||
.umb-package-details__sidebar {
|
||||
|
||||
@@ -356,7 +356,7 @@
|
||||
.umb-panel-header-content-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100px;
|
||||
height: 99px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ ul.sections li.help {
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: ~"(calc(~'100%' - ~'5px'))"; //subtract 4px orange border + 1px border-right for sections
|
||||
width: calc(100% - 5px); //subtract 4px orange border + 1px border-right for sections
|
||||
}
|
||||
|
||||
ul.sections li.help a {
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
<form name="inviteUserPasswordForm" novalidate="" ng-submit="inviteSavePassword()" val-form-manager>
|
||||
<div class="form" ng-if="inviteStep === 1">
|
||||
<h1 style="margin-bottom: 10px; text-align: left;">Hi, {{invitedUser.name}}</h1>
|
||||
<p style="line-height: 1.6; margin-bottom: 25px;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non libero vel turpis ultrices pharetra.</p>
|
||||
<p style="line-height: 1.6; margin-bottom: 25px;">
|
||||
<localize key="user_inviteWelcomeMessage">Welcome to Umbraco! Just need to get your password and avatar setup and then you're good to go</localize>
|
||||
</p>
|
||||
|
||||
<div class="control-group" ng-class="{error: setPasswordForm.password.$invalid}">
|
||||
<label>
|
||||
|
||||
@@ -137,6 +137,9 @@ angular.module("umbraco")
|
||||
|
||||
currentUserResource.changePassword($scope.changePasswordModel.value).then(function(data) {
|
||||
|
||||
//reset old data
|
||||
clearPasswordFields();
|
||||
|
||||
//if the password has been reset, then update our model
|
||||
if (data.value) {
|
||||
$scope.changePasswordModel.value.generatedPassword = data.value;
|
||||
@@ -167,8 +170,9 @@ angular.module("umbraco")
|
||||
}
|
||||
|
||||
function clearPasswordFields() {
|
||||
$scope.changePasswordModel.value.oldPassword = "";
|
||||
$scope.changePasswordModel.value.newPassword = "";
|
||||
$scope.changePasswordModel.confirm = "";
|
||||
$scope.changePasswordModel.value.confirm = "";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -12,12 +12,13 @@
|
||||
</div>
|
||||
<div ng-switch-when="true">
|
||||
<ng-form name="passwordForm">
|
||||
<umb-control-group alias="resetPassword" label="@user_resetPassword" ng-show="$parent.showReset()">
|
||||
<umb-control-group alias="resetPassword" label="@user_resetPassword" ng-show="$parent.config.enableReset">
|
||||
<input type="checkbox" ng-model="$parent.passwordValues.reset"
|
||||
id="Checkbox1"
|
||||
name="resetPassword"
|
||||
val-server-field="resetPassword"
|
||||
no-dirty-check />
|
||||
no-dirty-check
|
||||
ng-change="$parent.$parent.showReset = !$parent.$parent.showReset"/>
|
||||
<span class="help-inline" val-msg-for="resetPassword" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
@@ -33,7 +34,7 @@
|
||||
<span class="help-inline" val-msg-for="oldPassword" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group alias="password" label="@user_newPassword" ng-if="$parent.showNewPass()" required="true">
|
||||
<umb-control-group alias="password" label="@user_newPassword" ng-if="!$parent.showReset" required="true">
|
||||
<input type="password" name="password" ng-model="$parent.passwordValues.newPassword"
|
||||
class="input-block-level umb-textstring textstring"
|
||||
required
|
||||
@@ -46,8 +47,8 @@
|
||||
<span class="help-inline" val-msg-for="password" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group alias="confirmpassword" label="@user_confirmNewPassword" ng-if="$parent.showConfirmPass()" required="true">
|
||||
<input type="password" name="confirmpassword" ng-model="$parent.confirm"
|
||||
<umb-control-group alias="confirmpassword" label="@user_confirmNewPassword" ng-if="!$parent.showReset" required="true">
|
||||
<input type="password" name="confirmpassword" ng-model="$parent.passwordValues.confirm"
|
||||
class="input-block-level umb-textstring textstring"
|
||||
val-compare="password"
|
||||
no-dirty-check
|
||||
@@ -65,4 +66,5 @@
|
||||
</ng-form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,7 @@ angular.module("umbraco")
|
||||
$scope.control.value = {
|
||||
focalPoint: selectedImage.focalPoint,
|
||||
id: selectedImage.id,
|
||||
udi: selectedImage.udi,
|
||||
image: selectedImage.image,
|
||||
altText: selectedImage.altText
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
vm.labels = {};
|
||||
vm.maxFileSize = Umbraco.Sys.ServerVariables.umbracoSettings.maxFileSize + "KB";
|
||||
vm.acceptedFileTypes = mediaHelper.formatFileTypes(Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes);
|
||||
vm.emailIsUsername = true;
|
||||
vm.usernameIsEmail = Umbraco.Sys.ServerVariables.umbracoSettings.usernameIsEmail;
|
||||
|
||||
//create the initial model for change password
|
||||
vm.changePasswordModel = {
|
||||
@@ -68,7 +68,7 @@
|
||||
setUserDisplayState();
|
||||
formatDatesToLocal(vm.user);
|
||||
|
||||
vm.emailIsUsername = user.email === user.username;
|
||||
vm.usernameIsEmail = Umbraco.Sys.ServerVariables.umbracoSettings.usernameIsEmail && user.email === user.username;
|
||||
|
||||
//go get the config for the membership provider and add it to the model
|
||||
authResource.getMembershipProviderConfig().then(function (data) {
|
||||
|
||||
@@ -43,11 +43,11 @@
|
||||
<span class="help-inline" val-msg-for="email" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_username" ng-if="!vm.emailIsUsername" required="true">
|
||||
<umb-control-group label="@general_username" ng-if="!vm.usernameIsEmail" required="true">
|
||||
<input
|
||||
type="text"
|
||||
localize="placeholder"
|
||||
placeholder="@placeholders_entername"
|
||||
placeholder="@placeholders_enterusername"
|
||||
class="input-block-level"
|
||||
ng-model="vm.user.username"
|
||||
umb-auto-focus name="username"
|
||||
|
||||
@@ -59,10 +59,14 @@
|
||||
|
||||
function selectUserGroup(userGroup, selection, event) {
|
||||
|
||||
// only allow selection if user is member of the group or admin
|
||||
// Only allow selection if user is member of the group or admin
|
||||
if (currentUser.userGroups.indexOf(userGroup.group.alias) === -1 && currentUser.userGroups.indexOf("admin") === -1) {
|
||||
return;
|
||||
}
|
||||
// Disallow selection of the admin group, the checkbox is not visible in the UI, but clicking(and thous selecting) is still possible.
|
||||
// Currently selection can only be used for deleting, and the Controller will also disallow deleting the admin group.
|
||||
if (userGroup.group.alias === "admin")
|
||||
return;
|
||||
|
||||
if (userGroup.selected) {
|
||||
var index = selection.indexOf(userGroup.group.id);
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
<a class="umb-list-item" ng-click="vm.clickUserGroup(group)" ng-class="{'umb-list-item--selected': group.selected}" href="" ng-switch-when="true">
|
||||
<div style="margin-right: 25px;">
|
||||
<div class="umb-list-checkbox"
|
||||
ng-hide="group.group.alias === 'admin'"
|
||||
ng-class="{'umb-list-checkbox--visible': vm.selection.length > 0}"
|
||||
ng-click="vm.selectUserGroup(group, vm.selection, $event)" >
|
||||
<umb-checkmark checked="group.selected"></umb-checkmark>
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
vm.selectedBulkUserGroups = [];
|
||||
|
||||
vm.usernameIsEmail = Umbraco.Sys.ServerVariables.umbracoSettings.usernameIsEmail;
|
||||
|
||||
vm.allowDisableUser = true;
|
||||
vm.allowEnableUser = true;
|
||||
vm.allowUnlockUser = true;
|
||||
@@ -50,24 +52,31 @@
|
||||
"selected": true
|
||||
};
|
||||
|
||||
//don't set this if no email is configured
|
||||
if (Umbraco.Sys.ServerVariables.umbracoSettings.emailServerConfigured) {
|
||||
//don't show the invite button if no email is configured
|
||||
if (Umbraco.Sys.ServerVariables.umbracoSettings.showUserInvite) {
|
||||
vm.defaultButton = {
|
||||
labelKey: "user_inviteUser",
|
||||
handler: function () {
|
||||
handler: function() {
|
||||
vm.setUsersViewState('inviteUser');
|
||||
}
|
||||
};
|
||||
vm.subButtons = [
|
||||
{
|
||||
labelKey: "user_createUser",
|
||||
handler: function () {
|
||||
vm.setUsersViewState('createUser');
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
vm.subButtons = [
|
||||
{
|
||||
else {
|
||||
vm.defaultButton = {
|
||||
labelKey: "user_createUser",
|
||||
handler: function () {
|
||||
vm.setUsersViewState('createUser');
|
||||
}
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
vm.toggleFilter = toggleFilter;
|
||||
vm.setUsersViewState = setUsersViewState;
|
||||
|
||||
@@ -325,6 +325,13 @@
|
||||
<span class="help-inline" val-msg-for="name" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_username" label-for="username" required="true" ng-if="!vm.usernameIsEmail">
|
||||
<input type="text" name="username" localize="placeholder" placeholder="@placeholders_enterusername" class="input-block-level"
|
||||
ng-model="vm.newUser.username" val-server-field="Username" ng-required="vm.usernameIsEmail" />
|
||||
<span class="help-inline" val-msg-for="username" val-toggle-msg="required"><localize key="general_required">Required</localize></span>
|
||||
<span class="help-inline" val-msg-for="username" val-toggle-msg="valServerField"></span>
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group label="@general_email" label-for="email" required="true">
|
||||
<input type="email" name="email" localize="placeholder" placeholder="@placeholders_enteremail" class="input-block-level"
|
||||
ng-model="vm.newUser.email" required val-email val-server-field="Email" />
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module.exports = function(karma) {
|
||||
karma.configure({
|
||||
module.exports = function(config) {
|
||||
|
||||
config.set({
|
||||
|
||||
// base path, that will be used to resolve files and exclude
|
||||
basePath: '../..',
|
||||
|
||||
@@ -7,31 +9,23 @@ module.exports = function(karma) {
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'lib/../build/belle/lib/jquery/jquery.min.js',
|
||||
|
||||
//libraries
|
||||
'lib-bower/jquery/jquery.min.js',
|
||||
'lib/angular/1.1.5/angular.js',
|
||||
'lib/angular/1.1.5/angular-cookies.min.js',
|
||||
'lib/angular/1.1.5/angular-mocks.js',
|
||||
'lib/angular/angular-ui-sortable.js',
|
||||
|
||||
/*
|
||||
For angular 1.2:
|
||||
'lib/angular/1.2/angular.js',
|
||||
'lib/angular/1.2/angular-route.min.js',
|
||||
'lib/angular/1.2/angular-touch.min.js',
|
||||
'lib/angular/1.2/angular-cookies.min.js',
|
||||
'lib/angular/1.2/angular-animate.min.js',
|
||||
'lib/angular/1.2/angular-mocks.js',*/
|
||||
|
||||
|
||||
'lib/../build/belle/lib/underscore/underscore-min.js',
|
||||
'lib/../build/belle/lib/moment/moment-with-locales.js',
|
||||
'lib-bower/underscore/underscore-min.js',
|
||||
'lib-bower/moment/moment-with-locales.js',
|
||||
'lib/umbraco/Extensions.js',
|
||||
'lib/../build/belle/lib/rgrove-lazyload/lazyload.js',
|
||||
'lib/../build/belle/lib/angular-local-storage/angular-local-storage.min.js',
|
||||
'lib-bower/rgrove-lazyload/lazyload.js',
|
||||
'lib-bower//angular-local-storage/angular-local-storage.min.js',
|
||||
|
||||
//app bootstrap and loader
|
||||
'test/config/app.unit.js',
|
||||
'src/common/mocks/umbraco.servervariables.js',
|
||||
|
||||
//application files
|
||||
'src/common/directives/**/*.js',
|
||||
'src/common/filters/*.js',
|
||||
'src/common/services/*.js',
|
||||
@@ -39,8 +33,9 @@ module.exports = function(karma) {
|
||||
'src/common/resources/*.js',
|
||||
'src/common/mocks/**/*.js',
|
||||
'src/views/**/*.controller.js',
|
||||
'test/unit/**/*.spec.js',
|
||||
{pattern: 'lib/**/*.js', watched: true, served: true, included: false}
|
||||
|
||||
//tests
|
||||
'test/unit/**/*.spec.js'
|
||||
],
|
||||
|
||||
// list of files to exclude
|
||||
@@ -66,7 +61,7 @@ module.exports = function(karma) {
|
||||
// level of logging
|
||||
// possible values: karma.LOG_DISABLE || karma.LOG_ERROR || karma.LOG_WARN || karma.LOG_INFO || karma.LOG_DEBUG
|
||||
// CLI --log-level debug
|
||||
logLevel: karma.LOG_INFO,
|
||||
logLevel: config.LOG_WARN,
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
// CLI --auto-watch --no-auto-watch
|
||||
|
||||
Reference in New Issue
Block a user