├── .bowerrc
├── .gitignore
├── .gulp
├── build.js
├── demo.js
├── docs.js
├── e2e-tests.js
├── inject.js
├── proxy.js
├── server.js
├── styles.js
├── unit-tests.js
└── watch.js
├── .jshintrc
├── .yo-rc.json
├── LICENSE
├── README.md
├── bower.json
├── deploy_version.sh
├── dist
├── angular-weui.js
└── angular-weui.min.js
├── docs
├── demo-gallery.html
├── demo.html
├── scripts
│ ├── app-75093ba9.js
│ └── vendor-b4efd6af.js
└── styles
│ ├── app-e8d70c78.css
│ └── vendor-70892d8a.css
├── gulpfile.js
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── src
├── css
│ ├── actionsheet.styl
│ ├── gallery.styl
│ └── toast.styl
├── js
│ ├── Dialog.js
│ ├── Toast.js
│ ├── action-sheet.js
│ ├── button.js
│ ├── core.js
│ ├── form.js
│ ├── gallery.js
│ ├── loading.js
│ ├── module.js
│ ├── ng-swiper.js
│ ├── progress.js
│ └── wx-jssdk.js
└── weui
│ └── template
│ ├── action-sheet
│ └── action-sheet.html
│ ├── dialog
│ ├── android.html
│ └── default.html
│ ├── form
│ ├── input-image.html
│ └── input-textarea.html
│ ├── gallery
│ └── gallery.html
│ ├── loading
│ └── loading.html
│ ├── toast
│ ├── complete.html
│ ├── loading.html
│ └── message.html
│ └── wu-window.html
└── test
├── e2e
├── main.po.js
└── main.spec.js
├── serve
├── demo-gallery.html
├── demo.html
├── demo_js
│ ├── test-gallery.js
│ └── test.js
└── images
│ └── pic_article.png
└── unit
└── localize-test.js
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Eclipse template
3 | *.pydevproject
4 | .metadata
5 | .gradle
6 | bin/
7 | tmp/
8 | *.tmp
9 | *.bak
10 | *.swp
11 | *~.nib
12 | local.properties
13 | .settings/
14 | .loadpath
15 |
16 | # Eclipse Core
17 | .project
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # JDT-specific (Eclipse Java Development Tools)
29 | .classpath
30 |
31 | # Java annotation processor (APT)
32 | .factorypath
33 |
34 | # PDT-specific
35 | .buildpath
36 |
37 | # sbteclipse plugin
38 | .target
39 |
40 | # TeXlipse plugin
41 | .texlipse
42 |
43 |
44 | ### Windows template
45 | # Windows image file caches
46 | Thumbs.db
47 | ehthumbs.db
48 |
49 | # Folder config file
50 | Desktop.ini
51 |
52 | # Recycle Bin used on file shares
53 | $RECYCLE.BIN/
54 |
55 | # Windows Installer files
56 | *.cab
57 | *.msi
58 | *.msm
59 | *.msp
60 |
61 | # Windows shortcuts
62 | *.lnk
63 |
64 |
65 | ### Sass template
66 | .sass-cache
67 | *.css.map
68 |
69 |
70 | ### Vim template
71 | [._]*.s[a-w][a-z]
72 | [._]s[a-w][a-z]
73 | *.un~
74 | Session.vim
75 | .netrwhist
76 | *~
77 |
78 |
79 | ### Emacs template
80 | # -*- mode: gitignore; -*-
81 | *~
82 | \#*\#
83 | /.emacs.desktop
84 | /.emacs.desktop.lock
85 | *.elc
86 | auto-save-list
87 | tramp
88 | .\#*
89 |
90 | # Org-mode
91 | .org-id-locations
92 | *_archive
93 |
94 | # flymake-mode
95 | *_flymake.*
96 |
97 | # eshell files
98 | /eshell/history
99 | /eshell/lastdir
100 |
101 | # elpa packages
102 | /elpa/
103 |
104 | # reftex files
105 | *.rel
106 |
107 | # AUCTeX auto folder
108 | /auto/
109 |
110 | # cask packages
111 | .cask/
112 |
113 |
114 | ### Xcode template
115 | build/
116 | *.pbxuser
117 | !default.pbxuser
118 | *.mode1v3
119 | !default.mode1v3
120 | *.mode2v3
121 | !default.mode2v3
122 | *.perspectivev3
123 | !default.perspectivev3
124 | xcuserdata
125 | *.xccheckout
126 | *.moved-aside
127 | DerivedData
128 | *.xcuserstate
129 |
130 |
131 | ### SublimeText template
132 | # cache files for sublime text
133 | *.tmlanguage.cache
134 | *.tmPreferences.cache
135 | *.stTheme.cache
136 |
137 | # workspace files are user-specific
138 | *.sublime-workspace
139 |
140 | # project files should be checked into the repository, unless a significant
141 | # proportion of contributors will probably not be using SublimeText
142 | # *.sublime-project
143 |
144 | # sftp configuration file
145 | sftp-config.json
146 |
147 |
148 | ### JetBrains template
149 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
150 |
151 | *.iml
152 |
153 | ## Directory-based project format:
154 | .idea/
155 | # if you remove the above rule, at least ignore the following:
156 |
157 | # User-specific stuff:
158 | # .idea/workspace.xml
159 | # .idea/tasks.xml
160 | # .idea/dictionaries
161 |
162 | # Sensitive or high-churn files:
163 | # .idea/dataSources.ids
164 | # .idea/dataSources.xml
165 | # .idea/sqlDataSources.xml
166 | # .idea/dynamic.xml
167 | # .idea/uiDesigner.xml
168 |
169 | # Gradle:
170 | # .idea/gradle.xml
171 | # .idea/libraries
172 |
173 | # Mongo Explorer plugin:
174 | # .idea/mongoSettings.xml
175 |
176 | ## File-based project format:
177 | *.ipr
178 | *.iws
179 |
180 | ## Plugin-specific files:
181 |
182 | # IntelliJ
183 | /out/
184 |
185 | # mpeltonen/sbt-idea plugin
186 | .idea_modules/
187 |
188 | # JIRA plugin
189 | atlassian-ide-plugin.xml
190 |
191 | # Crashlytics plugin (for Android Studio and IntelliJ)
192 | com_crashlytics_export_strings.xml
193 | crashlytics.properties
194 | crashlytics-build.properties
195 |
196 | # node bower npm
197 | bower_components/
198 | node_modules/
--------------------------------------------------------------------------------
/.gulp/build.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 |
5 | var paths = gulp.paths;
6 |
7 | var $ = require('gulp-load-plugins')({
8 | pattern: ['gulp-*', 'main-bower-files', 'uglify-save-license', 'del']
9 | });
10 |
11 | gulp.task('partials', function () {
12 | return gulp.src([
13 | paths.src + '/**/*.html'
14 | ])
15 | .pipe($.minifyHtml({
16 | empty: true,
17 | spare: true,
18 | quotes: true
19 | }))
20 | .pipe($.angularTemplatecache('templateCacheHtml.js', {
21 | module: gulp.moduleName
22 | }))
23 | .pipe(gulp.dest(paths.tmp + '/partials/'));
24 | });
25 |
26 | gulp.task('js',['partials'], function () {
27 | gulp.src([
28 | paths.src + '/js/**/*.js',
29 | paths.tmp + '/partials/**/*.js'
30 | ])
31 | .pipe($.angularFilesort())
32 | .pipe($.concat(gulp.appName+'.js')) //合并所有js到gulp.appName + .js
33 | .pipe($.useref())
34 | .pipe($.revReplace())
35 | .pipe(gulp.dest(paths.dist + '/')) //输出gulp.appName + .js到文件夹
36 | .pipe($.rename({suffix: '.min'})) //rename压缩后的文件名
37 | .pipe($.uglify({preserveComments: $.uglifySaveLicense})) //压缩
38 | .pipe(gulp.dest(paths.dist + '/'))
39 | .pipe($.size({ title: paths.dist + '/', showFiles: true }));
40 | });
41 |
42 | gulp.task('styles:dest', function () {
43 |
44 | return gulp.src([
45 | paths.src + '/css/**/*.less'
46 |
47 | ]).pipe($.plumber({errorHandler: function handleError(err) {
48 | console.error(err.toString());
49 | }}))
50 | .pipe($.less())
51 | .pipe($.autoprefixer())
52 | .pipe($.concat(gulp.appName+'.css')) //合并所有js到gulp.appName + .css
53 | .pipe($.useref())
54 | .pipe($.revReplace())
55 | .pipe(gulp.dest(paths.dist + '/')) //输出gulp.appName + .css到文件夹
56 | .pipe($.rename({suffix: '.min'})) //rename压缩后的文件名
57 | .pipe($.minifyCss()) //压缩
58 | .pipe(gulp.dest(paths.dist + '/'))
59 | .pipe($.size({ title: paths.dist + '/', showFiles: true }));
60 | });
61 |
62 | gulp.task('images', function () {
63 | return gulp.src(paths.src + '/images/**/*')
64 | .pipe(gulp.dest(paths.dist + '/images/'));
65 | });
66 |
67 | gulp.task('fonts', function () {
68 | return gulp.src(paths.src + '/fonts/**/*')
69 | .pipe(gulp.dest(paths.dist + '/fonts/'));
70 | });
71 |
72 | gulp.task('misc', function () {
73 | return gulp.src(paths.src + '/**/*.ico')
74 | .pipe(gulp.dest(paths.dist + '/'));
75 | });
76 |
77 | gulp.task('langs', function () {
78 | return gulp.src([
79 | paths.src + '/langs/*.json'
80 | ])
81 | .pipe(gulp.dest(paths.dist + '/langs/'));
82 | });
83 |
84 | gulp.task('clean', function (done) {
85 | $.del([paths.dist + '/', paths.tmp + '/', paths.reports + '/'], done);
86 | });
87 |
88 | gulp.task('build', ['js', 'styles:dest', 'images', 'fonts', 'misc','langs']);
89 |
--------------------------------------------------------------------------------
/.gulp/demo.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 |
3 | var paths = gulp.paths;
4 |
5 | var $ = require('gulp-load-plugins')({
6 | pattern: ['gulp-*', 'main-bower-files', 'uglify-save-license', 'del']
7 | });
8 |
9 | gulp.task("demo",['clean:demo','html'], function (done) {
10 | $.del([paths.tmp + '/'], done);
11 | });
12 |
13 | gulp.task('html', ['inject', 'partials'], function () {
14 | var partialsInjectFile = gulp.src(paths.tmp + '/partials/templateCacheHtml.js', { read: false });
15 | var partialsInjectOptions = {
16 | starttag: '',
17 | ignorePath: paths.tmp + '/partials',
18 | addRootSlash: false
19 | };
20 |
21 | var htmlFilter = $.filter('*.html');
22 | var jsFilter = $.filter('**/*.js');
23 | var cssFilter = $.filter('**/*.css');
24 | var assets;
25 |
26 | return gulp.src(paths.tmp + '/serve/*.html')
27 | .pipe($.inject(partialsInjectFile, partialsInjectOptions))
28 | .pipe(assets = $.useref.assets())
29 | .pipe($.rev())
30 | .pipe(jsFilter)
31 | //.pipe($.ngAnnotate())
32 | .pipe($.uglify({preserveComments: $.uglifySaveLicense}))
33 | .pipe(jsFilter.restore())
34 | .pipe(cssFilter)
35 | .pipe($.replace('../bootstrap/fonts', '../fonts'))
36 | .pipe($.replace('bower_components/bootstrap/fonts', '../fonts'))
37 | .pipe($.replace('/bower_components/font-awesome/fonts', '../fonts'))
38 | //.pipe($.replace('font-awesome/fonts', '../fonts'))
39 | .pipe($.replace('../../../images', '../images'))
40 | .pipe($.replace('../../images', '../images'))
41 | .pipe($.csso())
42 | .pipe(cssFilter.restore())
43 | .pipe(assets.restore())
44 | .pipe($.useref())
45 | .pipe($.revReplace())
46 | .pipe(htmlFilter)
47 | .pipe($.minifyHtml({
48 | empty: true,
49 | spare: true,
50 | quotes: true
51 | }))
52 | .pipe(htmlFilter.restore())
53 | .pipe(gulp.dest(paths.demo + '/'))
54 | .pipe($.size({ title: paths.demo + '/', showFiles: true }));
55 | });
56 |
57 | gulp.task("clean:demo", function (done) {
58 | $.del([paths.demo + '/'], done);
59 | })
60 |
--------------------------------------------------------------------------------
/.gulp/docs.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 15/9/9.
3 | */
4 |
5 | 'use strict';
6 |
7 | var gulp = require('gulp');
8 |
9 | var paths = gulp.paths;
10 |
11 | var $ = require('gulp-load-plugins')({
12 | pattern: ['gulp-*', 'main-bower-files', 'uglify-save-license', 'del']
13 | });
14 |
15 | gulp.task('docs', ['clean'], function () {
16 | gulp.src([
17 | paths.src + '/js/**/*.js'
18 | ])
19 | .pipe($.jsdoc.parser())
20 | .pipe($.jsdoc.generator('./docs/api'));
21 | //.pipe($.jsdoc('./docs'));
22 | });
23 |
24 | gulp.task('lintHTML', function () {
25 | gulp.src([
26 | paths.src + '/**/*.html'
27 | ])
28 | .pipe($.jshint.extract('auto|always|never'))
29 | .pipe($.jshint())
30 | .pipe($.jshint.reporter('default', { verbose: true }))
31 | });
32 |
33 | gulp.task('lint', function () {
34 | gulp.src([
35 | paths.src + '/js/**/*.js'
36 | ])
37 | .pipe($.jshint.extract('auto|always|never'))
38 | .pipe($.jshint())
39 | .pipe($.jshint.reporter('default', { verbose: true }))
40 | .pipe($.jshint.reporter('fail'))
41 | });
42 |
--------------------------------------------------------------------------------
/.gulp/e2e-tests.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 |
5 | var $ = require('gulp-load-plugins')();
6 |
7 | var browserSync = require('browser-sync');
8 |
9 | var paths = gulp.paths;
10 |
11 | // Downloads the selenium webdriver
12 | gulp.task('webdriver-update', $.protractor.webdriver_update);
13 |
14 | gulp.task('webdriver-standalone', $.protractor.webdriver_standalone);
15 |
16 | function runProtractor (done) {
17 |
18 | gulp.src(paths.e2e + '/**/*.js')
19 | .pipe($.protractor.protractor({
20 | configFile: 'protractor.conf.js'
21 | }))
22 | .on('error', function (err) {
23 | // Make sure failed tests cause gulp to exit non-zero
24 | throw err;
25 | })
26 | .on('end', function () {
27 | // Close browser sync server
28 | browserSync.exit();
29 | done();
30 | });
31 | }
32 |
33 | gulp.task('protractor', ['protractor:src']);
34 | gulp.task('protractor:src', ['serve:e2e'], runProtractor);
35 | gulp.task('protractor:dist', ['serve:e2e-dist'], runProtractor);
36 |
--------------------------------------------------------------------------------
/.gulp/inject.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 |
5 | var paths = gulp.paths;
6 |
7 | var $ = require('gulp-load-plugins')();
8 |
9 | var wiredep = require('wiredep').stream;
10 |
11 | gulp.task('inject', ['styles'], function () {
12 |
13 | var injectStyles = gulp.src([
14 | paths.tmp + '/serve/{app,css}/**/*.css',
15 | paths.test_server + '/**/*.css'
16 | ], {read: false});
17 |
18 | var injectScripts = gulp.src([
19 | paths.src + '/**/*.js',
20 | paths.test_server + '/**/*.js'
21 | ]).pipe($.plumber({errorHandler: function handleError(err) {
22 | console.error(err.toString());
23 | //this.emit('end');
24 | }})).pipe($.angularFilesort());
25 |
26 | var injectOptions = {
27 | ignorePath: [paths.src, paths.tmp + '/serve', paths.test_server],
28 | addRootSlash: false
29 | };
30 |
31 | var wiredepOptions = {
32 | directory: 'bower_components',
33 | exclude: []// /bootstrap\.js/, /bootstrap\.css/, /bootstrap\.css/, /foundation\.css/
34 | };
35 |
36 |
37 | return gulp.src(paths.test_server + '/*.html')
38 | .pipe($.plumber({errorHandler: function handleError(err) {
39 | console.error(err.toString());
40 | //this.emit('end');
41 | }}))
42 | .pipe($.inject(injectStyles, injectOptions))
43 | .pipe($.inject(injectScripts, injectOptions))
44 | .pipe(wiredep(wiredepOptions))
45 | .pipe(gulp.dest(paths.tmp + '/serve'));
46 |
47 | });
48 |
--------------------------------------------------------------------------------
/.gulp/proxy.js:
--------------------------------------------------------------------------------
1 | /*jshint unused:false */
2 |
3 | /***************
4 |
5 | This file allow to configure a proxy system plugged into BrowserSync
6 | in order to redirect backend requests while still serving and watching
7 | files from the web project
8 |
9 | IMPORTANT: The proxy is disabled by default.
10 |
11 | If you want to enable it, watch at the configuration options and finally
12 | change the `module.exports` at the end of the file
13 |
14 | ***************/
15 |
16 | 'use strict';
17 |
18 | var httpProxy = require('http-proxy');
19 | var chalk = require('chalk');
20 |
21 | /*
22 | * Location of your backend server
23 | */
24 | var proxyTarget = 'http://server/context/';
25 |
26 | var proxy = httpProxy.createProxyServer({
27 | target: proxyTarget
28 | });
29 |
30 | proxy.on('error', function(error, req, res) {
31 | res.writeHead(500, {
32 | 'Content-Type': 'text/plain'
33 | });
34 |
35 | console.error(chalk.red('[Proxy]'), error);
36 | });
37 |
38 | /*
39 | * The proxy middleware is an Express middleware added to BrowserSync to
40 | * handle backend request and proxy them to your backend.
41 | */
42 | function proxyMiddleware(req, res, next) {
43 | /*
44 | * This test is the switch of each request to determine if the request is
45 | * for a static file to be handled by BrowserSync or a backend request to proxy.
46 | *
47 | * The existing test is a standard check on the files extensions but it may fail
48 | * for your needs. If you can, you could also check on a context in the url which
49 | * may be more reliable but can't be generic.
50 | */
51 | if (/\.(html|css|js|png|jpg|jpeg|gif|ico|xml|rss|txt|eot|svg|ttf|woff|cur)(\?((r|v|rel|rev)=[\-\.\w]*)?)?$/.test(req.url)) {
52 | next();
53 | } else {
54 | proxy.web(req, res);
55 | }
56 | }
57 |
58 | /*
59 | * This is where you activate or not your proxy.
60 | *
61 | * The first line activate if and the second one ignored it
62 | */
63 |
64 | //module.exports = [proxyMiddleware];
65 | module.exports = [];
66 |
--------------------------------------------------------------------------------
/.gulp/server.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 |
5 | var opn = require('opn');
6 |
7 | var paths = gulp.paths;
8 |
9 | var util = require('util');
10 |
11 | var browserSync = require('browser-sync');
12 |
13 | var middleware = require('./proxy');
14 |
15 | function browserSyncInit(baseDir, files, browser) {
16 | // browser = browser === undefined ? 'default' : browser;
17 |
18 | var routes = null;
19 | if(baseDir === paths.src || (util.isArray(baseDir) && baseDir.indexOf(paths.src) !== -1)) {
20 | routes = {
21 | '/bower_components': 'bower_components',
22 | '/demo_js': paths.test_server+'/demo_js',
23 | '/images': paths.test_server+'/images',
24 | };
25 | }
26 |
27 | browserSync.instance = browserSync.init(files, {
28 | startPath: '/',
29 | server: {
30 | baseDir: baseDir,
31 | middleware: middleware,
32 | routes: routes
33 | },
34 | port: 3002,
35 | open: false,
36 | browser: browser
37 | }, function(){
38 | var homepage = 'http://localhost:3002/demo.html';
39 | if(browser){
40 | //opn(homepage, {app: browser})
41 | }else{
42 | opn(homepage)
43 | }
44 | });
45 | }
46 |
47 | gulp.task('serve', ['watch'], function () {
48 | browserSyncInit([
49 | paths.tmp + '/serve',
50 | paths.src
51 | ], [
52 | paths.tmp + '/serve/{app,lib,components}/**/*.css',
53 | paths.src + '/{app,lib,components}/**/*.js',
54 | paths.src + 'src/assets/images/**/*',
55 | paths.tmp + '/serve/*.html',
56 | paths.tmp + '/serve/{app,lib,components,common}/**/*.html',
57 | paths.src + '/{app,lib,components,common}/**/*.html',
58 | paths.test_server + '/**/*'
59 | ]);
60 | });
61 |
62 | gulp.task('serve:test', ['watch'], function () {
63 | browserSyncInit([paths.tmp + '/serve', paths.src], [
64 | paths.tmp + '/**/*',
65 | paths.tmp + '/*',
66 | paths.src + '/**/*',
67 | paths.src + '/*',
68 | paths.test_server + '/**/*',
69 | paths.test_server + '/*'
70 | ]);
71 | });
72 |
73 | gulp.task('serve:dist', ['build'], function () {
74 | browserSyncInit(paths.dist);
75 | });
76 |
77 | gulp.task('serve:e2e', ['inject'], function () {
78 | browserSyncInit([paths.tmp + '/serve', paths.src], null, []);
79 | });
80 |
81 | gulp.task('serve:e2e-dist', ['build'], function () {
82 | browserSyncInit(paths.dist, null, []);
83 | });
84 |
--------------------------------------------------------------------------------
/.gulp/styles.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 |
5 | var paths = gulp.paths;
6 |
7 | var $ = require('gulp-load-plugins')();
8 |
9 | gulp.task('css', function() {
10 | gulp.src([
11 | paths.src + '/**/*.css'
12 | ]).pipe($.plumber({errorHandler: function handleError(err) {
13 | console.error(err.toString());
14 | //this.emit('end');
15 | }}))
16 | .pipe($.autoprefixer())
17 | .pipe(gulp.dest(paths.tmp + '/serve/app/'));
18 | });
19 |
20 | gulp.task('sass', function() {
21 | gulp.src([
22 | paths.src + '/css/**/*.scss'
23 | ]).pipe($.plumber({errorHandler: function handleError(err) {
24 | console.error(err.toString());
25 | //this.emit('end');
26 | }}))
27 | .pipe($.sass({outputStyle: 'compressed'}).on('error', $.sass.logError))
28 | .pipe($.autoprefixer())
29 | .pipe(gulp.dest(paths.tmp + '/serve/app/'));
30 | });
31 |
32 | gulp.task('stylus', function() {
33 | return gulp.src([
34 | paths.src + '/css/**/*.styl'
35 | ]).pipe($.plumber({errorHandler: function handleError(err) {
36 | console.error(err.toString());
37 | //this.emit('end');
38 | }}))
39 | .pipe($.stylus())
40 | //.pipe($.autoprefixer())
41 | .pipe(gulp.dest(paths.tmp + '/serve/app/'));
42 | });
43 |
44 | gulp.task('less', function() {
45 | return gulp.src([
46 | paths.src + '/css/**/*.less'
47 | ]).pipe($.plumber({errorHandler: function handleError(err) {
48 | console.error(err.toString());
49 | //this.emit('end');
50 | }}))
51 | .pipe($.less())
52 | //.pipe($.autoprefixer())
53 | .pipe(gulp.dest(paths.tmp + '/serve/app/'));
54 | });
55 |
56 | gulp.task('styles', ['css', 'stylus','sass'], function () {
57 |
58 | var lessOptions = {
59 | paths: [
60 | 'bower_components',
61 | paths.src + '/app',
62 | paths.src + '/components'
63 | ]
64 | };
65 |
66 | var injectFiles = gulp.src([
67 | paths.src + '/{app,components}/**/*.css',
68 | '!' + paths.src + '/css/index.less',
69 | '!' + paths.src + '/css/vendor.less'
70 | ], {read: false});
71 |
72 | var injectOptions = {
73 | transform: function (filePath) {
74 | filePath = filePath.replace(paths.src + '/app/', '');
75 | filePath = filePath.replace(paths.src + '/components/', '../components/');
76 | return '@import \'' + filePath + '\';';
77 | },
78 | starttag: '// injector',
79 | endtag: '// endinjector',
80 | addRootSlash: false
81 | };
82 |
83 | var indexFilter = $.filter('index.less');
84 |
85 | return gulp.src([
86 | //paths.src + '/css/**/*.css'
87 | ]).pipe($.plumber({errorHandler: function handleError(err) {
88 | console.error(err.toString());
89 | //this.emit('end');
90 | }}))
91 | //.pipe(indexFilter)
92 | .pipe($.inject(injectFiles, injectOptions))
93 | //.pipe(indexFilter.restore())
94 | //.pipe($.autoprefixer())
95 | .on('error', function handleError(err) {
96 | console.error(err.toString());
97 | //this.emit('end');
98 | })
99 | .pipe(gulp.dest(paths.tmp + '/serve/app/'));
100 | });
101 |
--------------------------------------------------------------------------------
/.gulp/unit-tests.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 |
5 | var $ = require('gulp-load-plugins')();
6 |
7 | var wiredep = require('wiredep');
8 |
9 | var paths = gulp.paths;
10 |
11 | function runTests (singleRun, done) {
12 | var bowerDeps = wiredep({
13 | directory: 'bower_components',
14 | exclude: ['bootstrap-sass-official'],
15 | dependencies: true,
16 | devDependencies: true
17 | });
18 |
19 | var testFiles = bowerDeps.js.concat([
20 | paths.src + '/js/poler.js',
21 | paths.src + '/**/*.js',
22 | paths.unit +'/**/*.js'
23 | ]);
24 |
25 | gulp.src(testFiles)
26 | //.pipe($.angularFilesort())
27 | .on('end', function () {
28 |
29 | })
30 | .pipe($.karma({
31 | configFile: 'karma.conf.js',
32 | action: (singleRun)? 'run': 'watch'
33 | }))
34 | .on('error', function (err) {
35 | // Make sure failed tests cause gulp to exit non-zero
36 | throw err;
37 | });
38 | }
39 |
40 | gulp.task('test', ['clean'], function (done) { runTests(true /* singleRun */, done) });
41 | gulp.task('test:auto', function (done) { runTests(false /* singleRun */, done) });
42 |
--------------------------------------------------------------------------------
/.gulp/watch.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 |
5 | var paths = gulp.paths;
6 |
7 | gulp.task('watch', ['inject'], function () {
8 | gulp.watch([
9 | paths.src + '/*',
10 | paths.src + '/**/*.js',
11 | paths.src + '/**/*.html',
12 | paths.src + '/**/*.css',
13 | paths.src + '/**/*.less',
14 | paths.src + '/**/*.scss',
15 | paths.src + '/**/*.styl',
16 | paths.test_server + '/*',
17 | paths.test_server + '/**/*.html',
18 | paths.test_server + '/**/*.js',
19 | paths.test_server + '/**/*.css',
20 | 'bower.json'
21 | ], ['inject']);
22 | });
23 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "esnext": true,
4 | "bitwise": true,
5 | "camelcase": true,
6 | "curly": true,
7 | "eqeqeq": true,
8 | "immed": true,
9 | "indent": 2,
10 | "latedef": true,
11 | "newcap": true,
12 | "noarg": true,
13 | "quotmark": "single",
14 | "regexp": true,
15 | "undef": true,
16 | "unused": true,
17 | "strict": true,
18 | "trailing": true,
19 | "smarttabs": true,
20 | "white": true,
21 | "validthis": true,
22 | "globals": {
23 | "angular": false,
24 | // Angular Mocks
25 | "inject": false,
26 | // JASMINE
27 | "describe": false,
28 | "it": false,
29 | "before": false,
30 | "beforeEach": false,
31 | "after": false,
32 | "afterEach": false,
33 | "expect": false
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-gulp-angular": {
3 | "props": {
4 | "paths": {
5 | "src": "src",
6 | "dist": "dist",
7 | "e2e": "test/e2e",
8 | "tmp": ".tmp"
9 | },
10 | "angularVersion": "~1.3.4",
11 | "angularModules": [
12 | {
13 | "name": "angular-animate",
14 | "module": "ngAnimate"
15 | },
16 | {
17 | "name": "angular-cookies",
18 | "module": "ngCookies"
19 | },
20 | {
21 | "name": "angular-touch",
22 | "module": "ngTouch"
23 | },
24 | {
25 | "name": "angular-sanitize",
26 | "module": "ngSanitize"
27 | }
28 | ],
29 | "jQuery": {
30 | "name": "jquery",
31 | "version": "~2.1.1"
32 | },
33 | "resource": {
34 | "name": "angular-resource",
35 | "module": "ngResource"
36 | },
37 | "router": {
38 | "name": "angular-ui-router",
39 | "version": "~0.2.13",
40 | "module": "ui.router"
41 | },
42 | "ui": {
43 | "name": "bootstrap-sass-official",
44 | "version": "~3.3.1",
45 | "key": "bootstrap",
46 | "module": null
47 | },
48 | "bootstrapComponents": {
49 | "name": "angular-bootstrap",
50 | "version": "0.12.x",
51 | "key": "ui-bootstrap",
52 | "module": "ui.bootstrap"
53 | },
54 | "cssPreprocessor": {
55 | "key": "less",
56 | "extension": "less",
57 | "module": "gulp-less",
58 | "version": "~1.3.6"
59 | },
60 | "jsPreprocessor": {
61 | "key": "none",
62 | "extension": "js",
63 | "srcExtension": "js",
64 | "module": null,
65 | "version": null
66 | },
67 | "htmlPreprocessor": {
68 | "key": "none",
69 | "extension": "html",
70 | "module": null,
71 | "version": null
72 | },
73 | "foundationComponents": {
74 | "name": null,
75 | "version": null,
76 | "key": null,
77 | "module": null
78 | }
79 | }
80 | }
81 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 three
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-weui
2 |
3 | weui的angular组件版本。同时封装微信jssdk接口为angular服务。依赖:
4 | > angular 1.x
5 | >
6 | > weui: [https://github.com/weui/weui](https://github.com/weui/weui)
7 | >
8 | > jquery
9 | >
10 | > 微信jssdk 1.1.0
11 |
12 | # TODO list
13 |
14 | 1. [x] 核心组件
15 | > * 浏览器检测组件
16 |
17 | 1. [x] actionsheet 组件
18 |
19 | 1. [x] dialog 组件
20 | > * alert
21 | > * confirm
22 |
23 | 1. [x] toast 组件
24 | > * loading
25 | > * complete
26 | > * show message
27 |
28 | 1. [x] wu-click 组件:防止重复点击
29 | 1. [x] 进度条组件
30 | 1. [ ] 图片预览组件
31 |
32 | 1. [ ] 表单组件
33 | > * 图片上传
34 | > * 文本域
35 |
36 | # api说明
37 |
38 | ### WuBrowserChecker
39 |
40 | 客户端检测.支持android/ios/window版本微信客户端,mac/linux/window平台上的各种浏览器检测.
41 | 同时会在window作用域中创建一个weui_client_browser_checker对象存放客户端信息
42 |
43 | WuBrowserChecker.engine // 呈现引擎信息
44 |
45 | WuBrowserChecker.browser // 浏览器信息
46 |
47 | WuBrowserChecker.system // 系统平台信息
48 |
49 |
50 | ### WuActionSheet
51 |
52 | WuActionSheet是一个angular服务,只提供一个方法:`open(options)`
53 |
54 | #### WuActionsSheet open 方法
55 |
56 | ##### options参数
57 |
58 | * btnGroups *(Type: Array)* - 按钮组配置列表。每个按钮组提供 `action` *`(Type:String, Default: cancel)`* 和 `buttons`参数:`action`指定点击过后执行结果通知时的通道,取值只能是`ok`或`cancel`;`buttons`指定一组中包含的按钮对象,每个对象包含的属性有`title`和`value`,`title`按钮显示信息,`value`按钮点击时的返回值
59 | * 返回值:返回一个angular的 WuActionSheet 实例。提供有result,close等方法,对用户点击结果和 WuActionSheet 进行控制
60 |
61 | ##### Example
62 |
63 | ```javascript
64 | WuActionSheet.open({
65 | btnGroups:[
66 | {
67 | action: 'Ok',
68 | buttons:[
69 | {
70 | title:'11',
71 | value:'11'
72 | },
73 | {
74 | title:'22',
75 | value:'22'
76 | },
77 | {
78 | title:'33',
79 | value:'33'
80 | },
81 | {
82 | title:'44',
83 | value:'44'
84 | }
85 | ]
86 | },
87 | {
88 | action: 'Cancel',
89 | buttons:[
90 | { title: 'cancel1', value: 'cancel1'}
91 | ]
92 | },
93 | {
94 | action: 'Close',
95 | buttons:[
96 | { title: 'cancel11', value: 'cancel1'}
97 | ]
98 | }
99 | ]
100 | }).result.then(function (btn) {
101 | console.log(btn)
102 | }, function (cancel) {
103 | console.log(cancel)
104 | });
105 | ```
106 | ### WuDialog
107 |
108 | WuDialog是个angular服务,提供弹框服务。提供的方法有:`open(options)`、`alert(options)`、`confirm(options)`
109 |
110 | #### WuDialog open 方法
111 |
112 | ```javascript
113 | WuDialog.open({
114 | title:'自定义按钮',
115 | content:'自定义按钮测试',
116 | buttons:[
117 | { action:'ok', title:'btn1', class: 'default', value:'btn1' },
118 | { action:'ok', title:'btn2', class: 'primary', value:'btn2' },
119 | { action:'cancel', title:'btn3', class: 'default', value:'btn3' },
120 | { action:'cancel', title:'btn4', class: 'primary', value:'btn4' }
121 | ]
122 | }).result.then(function () {
123 | console.log("OK: ", arguments[0])
124 | },function () {
125 | console.log("Cancel: ", arguments[0])
126 | })
127 | ```
128 |
129 | #### WuDialog alert 方法
130 |
131 | ```javascript
132 | WuDialog.alert({
133 | title: '提示框',
134 | content: '
xxxx Alert内容
'
135 | }).result.then(function () {
136 | console.log('ok');
137 | }, function () {
138 | console.log('close alert')
139 | });
140 | ```
141 |
142 | #### WuDialog confirm 方法
143 |
144 | ```javascript
145 | WuDialog.confirm({
146 | title: '确认框',
147 | content: '
xxxx确认内容
'
148 | }).result.then(function () {
149 | console.log('ok');
150 | }, function () {
151 | console.log('cancel')
152 | });
153 | ```
154 |
155 | ### WuToast
156 |
157 | WuDialog是个angular服务,提供消息提醒服务。提供的方法有:`message(options)`、`complete(options)`、`loading(options)`
158 |
159 | #### WuToast message 方法
160 |
161 | ```javascript
162 | var loadingObj = WuToast.message({
163 | message:'test asdfasdf sdfasdf asdfsadfv sdfsad asfsadf sdfasfda sdfasfasdf message show'
164 | time: 2000
165 | });
166 |
167 | // 或者手多关闭
168 | setTimeout(function () {
169 | loadingObj.close();
170 | }, 1000)
171 | ```
172 |
173 | #### WuToast complete 方法
174 |
175 | ```javascript
176 | WuToast.complete({
177 | time:1000
178 | });
179 | ```
180 |
181 | #### WuToast loading 方法
182 |
183 | ```javascript
184 | var loadingObj = WuToast.loading({
185 | message:'数据加载中'
186 | });
187 | setTimeout(function () {
188 | loadingObj.close();
189 | }, 1000)
190 | ```
191 |
192 | ### wu-progress
193 |
194 | wu-progress 是一个angular指令,提供进度条显示。
195 |
196 | ```html
197 |
wuProgress
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 | ```
206 |
207 | ### wu-click
208 |
209 | wu-click 是一个angular指令,提供事件点击服务,可以防止用户快速点击按钮。
210 |
211 | ```html
212 |
button wu-click test
213 |
按钮
214 |
按钮
215 |
216 | ```
217 |
218 | # angular-weui 开发
219 |
220 | 1. 克隆 angular-weui 工程
221 |
222 | ```
223 | git clone git@github.com:threeq/angular-weui.git
224 |
225 | cd angular-weui
226 | ```
227 |
228 | 2. 安装工程依赖库
229 |
230 | ```
231 | # npm 环境依赖
232 | npm intall
233 |
234 | # 使用 bower 安装angular-weui依赖库
235 | npm run bower
236 | ```
237 |
238 | 3. 启动工程
239 |
240 | ```
241 | npm run dev
242 | ```
243 |
244 | 这时会自动启动浏览器打开 demo 界面,如果没有打开可以自己打开浏览器输入地址: http://localhost:3002/test.html
245 |
246 | 4. 工程打包
247 |
248 | ```
249 | npm run dist
250 | ```
251 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-weui",
3 | "version": "0.0.1",
4 | "authors": [
5 | "three <448987046@qq.com>"
6 | ],
7 | "description": "angular weui plugins",
8 | "main": [
9 | "dist/*.min.js",
10 | "dist/*.min.css"
11 | ],
12 | "keywords": [
13 | "angular",
14 | "weui",
15 | "angular-weui"
16 | ],
17 | "license": "MIT",
18 | "ignore": [
19 | "**/.*",
20 | "node_modules",
21 | "bower_components",
22 | "test",
23 | "tests"
24 | ],
25 | "dependencies": {
26 | "jquery": "~2.1.4",
27 | "angular": "~1.4.5",
28 | "weui": "^1.0.0",
29 | "swiper": "^3.4.0"
30 | },
31 | "devDependencies": {
32 | "angular-mocks": "~1.4.5"
33 | },
34 | "resolutions": {
35 | "jquery": "~2.1.4",
36 | "angular": "~1.4.5"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/deploy_version.sh:
--------------------------------------------------------------------------------
1 | echo build version: $1
2 | echo build message: $2
3 |
4 | gulp clean
5 | gulp build
6 | git add .
7 | git commit -am "$2"
8 | git tag -a $1 -m "$2"
9 |
10 |
--------------------------------------------------------------------------------
/dist/angular-weui.min.js:
--------------------------------------------------------------------------------
1 | "use strict";angular.module("ng.weui.core",[]),angular.module("ng.weui.jssdk",[]),angular.module("ng.weui.swiper",["ng.weui.core"]),angular.module("ng.weui.button",[]),angular.module("ng.weui.progress",[]),angular.module("ng.weui.dialog",["ng.weui.core"]),angular.module("ng.weui.actionsheet",["ng.weui.core"]),angular.module("ng.weui.toast",["ng.weui.core"]),angular.module("ng.weui.form",["ng.weui.core"]),angular.module("ng.weui.gallery",["ng.weui.core","ng.weui.swiper"]),angular.module("ng.weui.loading",["ng.weui.core"]),angular.module("ng.weui",["ng.weui.core","ng.weui.button","ng.weui.actionsheet","ng.weui.dialog","ng.weui.toast","ng.weui.form","ng.weui.gallery","ng.weui.loading","ng.weui.progress"]),angular.module("ng.weui").run(["$templateCache",function(e){e.put("weui/template/wu-window.html",'
'),e.put("weui/template/action-sheet/action-sheet.html",'
'),e.put("weui/template/dialog/android.html",'
'),e.put("weui/template/dialog/default.html",'
'),e.put("weui/template/form/input-image.html",'
'),e.put("weui/template/form/input-textarea.html",'
'),e.put("weui/template/gallery/gallery.html",'
'),e.put("weui/template/loading/loading.html",'
'),e.put("weui/template/toast/complete.html",'
'),e.put("weui/template/toast/loading.html",'
'),e.put("weui/template/toast/message.html",'
')}]),function(e,t){e.factory("WuWxJsSdk",["$q",function(e){function n(e){return t.wx?t.wx:(e({errMsg:"没有js接口对象,请确认是否引入微信js文件"}),!1)}function i(e,t,n){return e.success=function(e){t(e)},e.fail=function(e){n(e)},e.complete=function(){},e.cancel=function(){n({errMsg:"用户取消"})},e.trigger=function(){},e}for(var a={config:function(){return e(function(e,i){var a=n(i);a&&(a.config.apply(t,arguments),a.ready(function(){e({errMsg:"config:ok"})}),a.error(function(e){i(e)}))})}},o=["checkJsApi","onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ","onMenuShareWeibo","onMenuShareWeibo","chooseImage","previewImage","uploadImage","downloadImage","startRecord","stopRecord","onVoiceRecordEnd","playVoice","pauseVoice","stopVoice","onVoicePlayEnd","uploadVoice","downloadVoice","translateVoice","getNetworkType","openLocation","getLocation","hideOptionMenu","showOptionMenu","closeWindow","hideMenuItems","showMenuItems","hideAllNonBaseMenuItem","showAllNonBaseMenuItem","scanQRCode","startSearchBeacons","stopSearchBeacons","onSearchBeacons","openProductSpecificView","chooseCard","addCard","openCard","consumeAndShareCard","chooseWXPay"],r=0;r
',link:function(e){e.filterProgress=function(e){return e>100?"100%":0>e?"0%":parseFloat(e)+"%"},e.filterHeight=function(e){return(e&&e>1?e:3)+"px"}}}}])}(angular.module("ng.weui.progress")),function(e,t){t.directive("wuSwiperContainer",["IdWorkerFactory",function(e){var t=e("wuSwiperContainer");return{restrict:"E",transclude:!0,scope:{onReady:"&",slidesPerView:"=",slidesPerColumn:"=",spaceBetween:"=",parallax:"=",parallaxTransition:"@",paginationIsActive:"=",paginationClickable:"=",showNavButtons:"=",showScrollBar:"=",loop:"=",autoplay:"=",initialSlide:"=",containerCls:"@",wrapperCls:"@",paginationCls:"@",slideCls:"@",direction:"@",swiper:"=",overrideParameters:"="},controller:function(e,n,i){var a=t();e.swiper_uuid=a;var o={slidesPerView:e.slidesPerView||1,slidesPerColumn:e.slidesPerColumn||1,spaceBetween:e.spaceBetween||0,direction:e.direction||"horizontal",loop:e.loop||!1,initialSlide:e.initialSlide||0,showNavButtons:!1};angular.isUndefined(e.autoplay)||"number"!=typeof e.autoplay||(o=angular.extend({},o,{autoplay:e.autoplay})),e.paginationIsActive===!0&&(o=angular.extend({},o,{paginationClickable:e.paginationClickable||!0,pagination:"#paginator-"+e.swiper_uuid})),e.showNavButtons===!0&&(o.nextButton="#nextButton-"+e.swiper_uuid,o.prevButton="#prevButton-"+e.swiper_uuid),e.showScrollBar===!0&&(o.scrollbar="#scrollBar-"+e.swiper_uuid),e.overrideParameters&&(o=angular.extend({},o,e.overrideParameters)),i(function(){var t=null;angular.isObject(e.swiper)?(e.swiper=new Swiper(n[0].firstChild,o),t=e.swiper):t=new Swiper(n[0].firstChild,o),angular.isUndefined(e.onReady)||e.onReady({swiper:t})})},link:function(e,t){var n=e.swiper_uuid,i="paginator-"+n,a="prevButton-"+n,o="nextButton-"+n,r="scrollBar-"+n,s=t[0];angular.element(s.querySelector(".swiper-pagination")).attr("id",i),angular.element(s.querySelector(".swiper-button-next")).attr("id",o),angular.element(s.querySelector(".swiper-button-prev")).attr("id",a),angular.element(t[0].querySelector(".swiper-scrollbar")).attr("id",r)},template:'
'}}]).directive("wuSwiperSlide",[function(){return{restrict:"E",require:"^ksSwiperContainer",transclude:!0,scope:{sliderCls:"@"},template:'
',replace:!0}}])}(window,angular.module("ng.weui.swiper"),void 0),function(e){e.directive("loadingEnable",[function(){return{restrict:"A",replace:!0,templateUrl:"weui/template/loading/loading.html",transclude:!0,link:function(){}}}])}(angular.module("ng.weui.loading"),window),function(e){e.factory("PreviewImages",["WuWxJsSdk",function(e){return{show:function(t,n){e.previewImage({current:t,urls:n})}}}]),e.directive("previewImages",["PreviewImages",function(e){return{restrict:"AE",link:function(t,n,i){var a=n,o=i.preview?i.preview:"img",r=i.attrName?i.attrName:"src";n.on("click",o,function(t){var n=$(this),i=[];return a.find(o).each(function(e,t){i.push(t.attr(r))}),e.show(n.attr(r),i),t.preventDefault(),t.stopPropagation(),!1})}}}]),e.directive("gallery",["$timeout","IdWorkerFactory",function(e,t){var n=t.new("weui-gallery_swiper");return{restrict:"EA",templateUrl:"weui/template/gallery/gallery.html",scope:{images:"="},link:function(t,i){function a(){e(function(){console.log("#"+o+" .swiper-images");var e=new Swiper("#"+o+" .swiper-images",{nextButton:".swiper-button-next",prevButton:".swiper-button-prev",spaceBetween:10,effect:"coverflow",grabCursor:!0,centeredSlides:!0,slidesPerView:"auto",coverflow:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0}});if(t.showThumb){var n=new Swiper("#"+o+" .gallery-thumbs",{spaceBetween:10,centeredSlides:!0,slidesPerView:"auto",touchRatio:.2,slideToClickedSlide:!0});e.params.control=n,n.params.control=e}},10)}var o=n();i.attr("id",o),i.addClass("weui-gallery"),i.show(),t.showThumb=!1,angular.isArray(t.images)&&t.images.length>0&&(t.images[0].hasOwnProperty("thumb")&&(t.showThumb=!0),a()),t.imageStyle=function(e){return{"background-image":"url("+e.url+")"}}}}}])}(angular.module("ng.weui.gallery")),function(e){e.directive("inputTextarea",[function(){return{restrict:"EA",replace:!0,templateUrl:"weui/template/form/input-textarea.html",require:"ngModel",link:function(e,t,n,i){i.$render=function(){console.log()}}}}]),e.directive("inputImage",[function(){return{restrict:"EA",replace:!0,templateUrl:"weui/template/form/input-image.html",require:"ngModel",link:function(e,t,n,i){i.$render=function(){console.log()}}}}])}(angular.module("ng.weui.form")),function(e){e.provider("WuDialog",[function(){var e=this;e.$get=["$wuModal",function(e){return{open:function(t){t.buttons=t.buttons||[{action:"ok",title:"确定","class":"default",value:"ok"}];var n="wu-dialog-default-template";return t.hasOwnProperty("template")&&t.template&&(n=t.template),e.open({backdrop:!1,windowTemplateUrl:"weui/template/wu-window.html",template:"
",controller:["$scope",function(e){e.title=t.title,e.content=t.content,e.buttons=t.buttons,e.clickBtn=function(t){"ok"===t.action.toLowerCase()?e.$close(t.value):e.$dismiss(t.value)}}]})},alert:function(e){return this.open({title:e.title,content:e.content})},confirm:function(e){return this.open({title:e.title,content:e.content,buttons:[{action:"cancel",title:"取消","class":"default",value:"cancel"},{action:"ok",title:"确定","class":"primary",value:"ok"}]})}}}]}]);var t=function(e,t){var n=t.find(".weui-mask");n.on("click",function(){e.$apply(function(){e.$dismiss("mask:click")})});var i="weui-dialog__alert";e.buttons.length>1&&(i="weui-dialog__confirm"),t.addClass(i)};e.directive("wuDialogDefaultTemplate",[function(){return{restrict:"A",templateUrl:"weui/template/dialog/default.html",link:t}}]).directive("wuDialogAndroidTemplate",[function(){return{restrict:"A",templateUrl:"weui/template/dialog/android.html",link:t}}]),e.directive("unsafeShowHtml",["$compile",function(e){return{restrict:"A",scope:{content:"=unsafeShowHtml"},link:function(t,n){var i=function(){var i="
"+t.content+"
";n.html("").append(e(i)(t))};i()}}}])}(angular.module("ng.weui.dialog")),function(e,t){e.factory("$$stackedMap",function(){return{createNew:function(){var e=[];return{add:function(t,n){e.push({key:t,value:n})},get:function(t){for(var n=0;n
0&&(t=b.top().value,t.modalDomEl.toggleClass(t.windowTopClass||"",e))}function d(){if(m&&-1===l()){var e=v;p(m,v,function(){e=null}),m=void 0,v=void 0}}function p(e,n,i,a){function r(){r.done||(r.done=!0,t(e,{event:"leave"}).start().then(function(){e.remove(),a&&a.resolve()}),n.$destroy(),i&&i())}var s,l=null,u=function(){return s||(s=o.defer(),l=s.promise),function(){s.resolve()}};return n.$broadcast(_.NOW_CLOSING_EVENT,u),o.when(l).then(r)}function w(e){if(e.isDefaultPrevented())return e;var t=b.top();if(t)switch(e.which){case 27:t.value.keyboard&&(e.preventDefault(),a.$apply(function(){_.dismiss(t.key,"escape key press")}));break;case 9:_.loadFocusElementList(t);var n=!1;e.shiftKey?_.isFocusInFirstItem(e)&&(n=_.focusLastFocusableElement()):_.isFocusInLastItem(e)&&(n=_.focusFirstFocusableElement()),n&&(e.preventDefault(),e.stopPropagation())}}function g(e,t,n){return!e.value.modalScope.$broadcast("modal.closing",t,n).defaultPrevented}var m,v,f,h="modal-open",b=s.createNew(),k=r.createNew(),_={NOW_CLOSING_EVENT:"modal.stack.now-closing"},$=0,y="a[href], area[href], input:not([disabled]), button:not([disabled]),select:not([disabled]), textarea:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable=true]";return a.$watch(l,function(e){v&&(v.index=e)}),n.on("keydown",w),a.$on("$destroy",function(){n.off("keydown",w)}),_.open=function(t,o){var r=n[0].activeElement,s=o.openedClass||h;c(!1),b.add(t,{deferred:o.deferred,renderDeferred:o.renderDeferred,closedDeferred:o.closedDeferred,modalScope:o.scope,backdrop:o.backdrop,keyboard:o.keyboard,openedClass:o.openedClass,windowTopClass:o.windowTopClass,animation:o.animation,appendTo:o.appendTo}),k.put(s,t);var u=o.appendTo,d=l();if(!u.length)throw new Error("appendTo element not found. Make sure that the element passed is in DOM.");d>=0&&!m&&(v=a.$new(!0),v.modalOptions=o,v.index=d,m=angular.element(''),m.attr("backdrop-class",o.backdropClass),o.animation&&m.attr("modal-animation","true"),i(m)(v),e.enter(m,u));var p=angular.element('');p.attr({"template-url":o.windowTemplateUrl,"window-class":o.windowClass,"window-top-class":o.windowTopClass,size:o.size,index:b.length()-1,animate:"animate"}).html(o.content),o.animation&&p.attr("modal-animation","true"),e.enter(p,u).then(function(){i(p)(o.scope),e.addClass(u,s)}),b.top().value.modalDomEl=p,b.top().value.modalOpener=r,_.clearFocusListCache()},_.close=function(e,t){var n=b.get(e);return n&&g(n,t,!0)?(n.value.modalScope.$$wuDestructionScheduled=!0,n.value.deferred.resolve(t),u(e,n.value.modalOpener),!0):!n},_.dismiss=function(e,t){var n=b.get(e);return n&&g(n,t,!1)?(n.value.modalScope.$$wuDestructionScheduled=!0,n.value.deferred.reject(t),u(e,n.value.modalOpener),!0):!n},_.dismissAll=function(e){for(var t=this.getTop();t&&this.dismiss(t.key,e);)t=this.getTop()},_.getTop=function(){return b.top()},_.modalRendered=function(e){var t=b.get(e);t&&t.value.renderDeferred.resolve()},_.focusFirstFocusableElement=function(){return f.length>0?(f[0].focus(),!0):!1},_.focusLastFocusableElement=function(){return f.length>0?(f[f.length-1].focus(),!0):!1},_.isFocusInFirstItem=function(e){return f.length>0?(e.target||e.srcElement)===f[0]:!1},_.isFocusInLastItem=function(e){return f.length>0?(e.target||e.srcElement)===f[f.length-1]:!1},_.clearFocusListCache=function(){f=[],$=0},_.loadFocusElementList=function(e){if((void 0===f||!f.length)&&e){var t=e.value.modalDomEl;t&&t.length&&(f=t[0].querySelectorAll(y))}},_}]).provider("$wuModal",function(){var e={options:{animation:!0,backdrop:!0,keyboard:!0},$get:["$rootScope","$q","$document","$templateRequest","$controller","$wuResolve","$wuModalStack",function(t,n,i,a,o,r,s){function l(e){return e.template?n.when(e.template):a(angular.isFunction(e.templateUrl)?e.templateUrl():e.templateUrl)}var u={},c=null;return u.getPromiseChain=function(){return c},u.open=function(a){function u(){return f}var d=n.defer(),p=n.defer(),w=n.defer(),g=n.defer(),m={result:d.promise,opened:p.promise,closed:w.promise,rendered:g.promise,close:function(e){return s.close(m,e)},dismiss:function(e){return s.dismiss(m,e)}};if(a=angular.extend({},e.options,a),a.resolve=a.resolve||{},a.appendTo=a.appendTo||i.find("body").eq(0),!a.template&&!a.templateUrl)throw new Error("One of template or templateUrl options is required.");var v,f=n.all([l(a),r.resolve(a.resolve,{},null,null)]);return v=c=n.all([c]).then(u,u).then(function(e){var n=a.scope||t,i=n.$new();i.$close=m.close,i.$dismiss=m.dismiss,i.$on("$destroy",function(){i.$$wuDestructionScheduled||i.$dismiss("$wuUnscheduledDestruction")});var r,l={};a.controller&&(l.$scope=i,l.$wuModalInstance=m,angular.forEach(e[1],function(e,t){l[t]=e}),r=o(a.controller,l),a.controllerAs&&(a.bindToController&&(r.$close=i.$close,r.$dismiss=i.$dismiss,angular.extend(r,n)),i[a.controllerAs]=r)),s.open(m,{scope:i,deferred:d,renderDeferred:g,closedDeferred:w,content:e[0],animation:a.animation,backdrop:a.backdrop,keyboard:a.keyboard,backdropClass:a.backdropClass,windowTopClass:a.windowTopClass,windowClass:a.windowClass,windowTemplateUrl:a.windowTemplateUrl,size:a.size,openedClass:a.openedClass,appendTo:a.appendTo}),p.resolve(!0)},function(e){p.reject(e),d.reject(e)})["finally"](function(){c===v&&(c=null)}),m},u}]};return e}),t.weui_client_browser_checker=function(){var e={ie:0,gecko:0,webkit:0,khtml:0,opera:0,ver:null},n={ie:0,firefox:0,safari:0,konq:0,opera:0,chrome:0,wx:0,wxpc:0,ver:null},i={win:!1,mac:!1,x11:!1,iphone:!1,ipod:!1,ipad:!1,ios:!1,android:!1,nokiaN:!1,winMobile:!1,wii:!1,ps:!1},a=navigator.userAgent;if(t.opera)e.ver=n.ver=t.opera.version(),e.opera=n.opera=parseFloat(e.ver);else if(/AppleWebKit\/(\S+)/.test(a))if(e.ver=RegExp.$1,e.webkit=parseFloat(e.ver),/Chrome\/(\S+)/.test(a))n.ver=RegExp.$1,n.chrome=parseFloat(n.ver);else if(/Version\/(\S+)/.test(a))n.ver=RegExp.$1,n.safari=parseFloat(n.ver);else{var o=1;o=e.webkit<100?1:e.webkit<312?1.2:e.webkit<412?1.3:2,n.safari=n.ver=o}else/KHTML\/(\S+)/.test(a)||/Konqueror\/([^;]+])/.test(a)?(e.ver=n.ver=RegExp.$1,e.khtml=n.konq=parseFloat(e.ver)):/rv:([^\)]+)\) Gecko\/\d{8}/.test(a)?(e.ver=RegExp.$1,n.gecko=parseFloat(e.ver),/Firefox\/(\S+)/.test(a)&&(n.ver=RegExp.$1,n.firefox=parseFloat(n.ver))):/MSIE ([^;]+)/.test(a)&&(e.ver=n.ver=RegExp.$1,e.ie=n.ie=parseFloat(e.ver));/MicroMessenger\/([\d\.]+)/i.test(a)&&(n.ver=RegExp.$1,n.wx="micromessenger",n.wxpc=/WindowsWechat/i.test(a)),n.ie=e.ie,n.opera=e.opera;var r=navigator.platform;if(i.win=r.indexOf("Win")>=0,i.mac=r.indexOf("Mac")>=0,i.x11="X11"==r||0==r.indexOf("Linux"),i.win&&/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(a))if("NT"==RegExp.$1)switch(RegExp.$2){case"5.0":i.win="2000";break;case"5.1":i.win="XP";break;case"6.0":i.win="vista";break;case"6.1":i.win="7";break;default:i.win="NT"}else i.win="9x"==RegExp.$1?"ME":RegExp.$1;return i.iphone=a.indexOf("iPhone")>-1,i.ipod=a.indexOf("iPod")>-1,i.ipad=a.indexOf("iPad")>-1,i.nokiaN=a.indexOf("NokinaN")>-1,"CE"==i.win?i.winMobile=i.win:"Ph"==i.win&&/Window Phone OS (\d+.\d+)/.test(a)&&(i.win="Phone",i.winMobile=parseFloat(RegExp.$1)),i.iphone&&a.indexOf("Mobile")>-1&&(i.ios=/CPU (?:iPhone)?[ ]?OS (\d+_\d+)/.test(a)?parseFloat(RegExp.$1.replace("_",".")):2),/Android (\d+\.\d+)/.test(a)&&(i.android=parseFloat(RegExp.$1)),i.wii=a.indexOf("Wii")>-1,i.ps=/playstation/i.test(a),{engine:e,browser:n,system:i}}(),e.provider("WuBrowserChecker",[function(){var e=this;e.$get=[function(){return t.weui_client_browser_checker}]}]),e.provider("IdWorkerFactory",[function(){var e={};this.new=function(t){return e.hasOwnProperty(t)||(e[t]=function(e){var t=0;return function(){return e+"_"+t++}}(t)),e[t]},this.$get=[function(){return this}]}])}(angular.module("ng.weui.core"),window),function(e){e.directive("wuClick",["$parse","$timeout","$rootScope",function(e,t){return{restrict:"EA",compile:function(n,i){var a=e(i.wuClick),o=e(i.wuInterval||"300");return function(e,n){var i=parseInt(o(e)),r=!1;n.on("click",function(o){r||(e.$apply(function(){a(e,{$event:o})}),n.attr("disabled","disabled").addClass("weui_btn_disabled"),r=!0,t(function(){n.removeAttr("disabled").removeClass("weui_btn_disabled"),r=!1},i))})}}}}])}(angular.module("ng.weui.button")),function(e){e.provider("WuActionSheet",[function(){var e=this;e.$get=["$wuModal",function(e){return{open:function(t){return e.open({backdrop:!1,windowTemplateUrl:"weui/template/wu-window.html",template:"",controller:["$scope",function(e){e.btnGroups=t.btnGroups||[{action:"Cancel",buttons:[{title:"取消",value:"cancel"}]}],e.triggerBtn=function(t,n){var i=t.action.toLowerCase();"ok"===i?e.$close(n.value):e.$dismiss(n.value)}}]})}}}]}]).directive("wuActionSheetTemplate",["$q",function(e){return{restrict:"A",templateUrl:"weui/template/action-sheet/action-sheet.html",link:function(t,n){function i(t,n){return e(function(e){t.removeClass("weui-actionsheet_toggle"),n.removeClass("actionsheet__mask_show"),t.on("transitionend",function(){n.hide(),e()}).on("webkitTransitionEnd",function(){n.hide(),e()})})}var a=n.find(".weui-mask_transparent.actionsheet__mask"),o=n.find(".weui-actionsheet");!function(){a.show().addClass("actionsheet__mask_show").on("click",function(){i(o,a).then(function(){t.$dismiss("mask:click")})}),o.addClass("weui-actionsheet_toggle")}(),t.clickBtn=function(e,n){i(o,a).then(function(){t.triggerBtn(e,n)})}}}}])}(angular.module("ng.weui.actionsheet"));
--------------------------------------------------------------------------------
/docs/demo-gallery.html:
--------------------------------------------------------------------------------
1 | angular-WeUI
--------------------------------------------------------------------------------
/docs/demo.html:
--------------------------------------------------------------------------------
1 | angular-WeUIAction Sheet confirm confirm no title alert 自定义按钮 自定义按钮 android Toast 完成 Toast Loading Toast Message showbutton wu-click test
按钮 按钮wuProgress
swiper 测试
--------------------------------------------------------------------------------
/docs/scripts/app-75093ba9.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 15/9/7.
3 | */
4 | !function(e){e.controller("TestCtrl",["WuActionSheet","WuDialog","WuToast",function(e,t,n){this.actionSheet=function(){e.open({btnGroups:[{action:"Ok",buttons:[{title:"11",value:"11"},{title:"22",value:"22"},{title:"33",value:"33"},{title:"44",value:"44"}]},{action:"Cancel",buttons:[{title:"cancel1",value:"cancel1"}]},{action:"Close",buttons:[{title:"cancel11",value:"cancel1"}]}]}).result.then(function(e){console.log(e)},function(e){console.log(e)})},this.confirm=function(){t.confirm({title:"确认框",content:"xxxx确认内容sfsfsdfsadfsadfdsafdsafsdaf"}).result.then(function(){console.log("ok")},function(){console.log("cancel")})},this.confirmNoTitle=function(){t.confirm({content:"sfsafsfsasadfsfsfsfasfas"}).result.then(function(){console.log("ok")},function(){console.log("cancel")})},this.alert=function(){t.alert({title:"提示框",content:'xxxx Alert内容
'}).result.then(function(){console.log("ok")},function(){console.log("close alert")})},this.dialog=function(){t.open({title:"自定义按钮",content:"自定义按钮测试",buttons:[{action:"ok",title:"btn1","class":"default",value:"btn1"},{action:"ok",title:"btn2","class":"primary",value:"btn2"},{action:"cancel",title:"btn3","class":"default",value:"btn3"},{action:"cancel",title:"btn4","class":"primary",value:"btn4"}]}).result.then(function(){console.log("OK: ",arguments[0])},function(){console.log("Cancel: ",arguments[0])})},this.dialogAndroid=function(){t.open({title:"自定义按钮",content:"自定义按钮测试",template:"wu-dialog-android-template",buttons:[{action:"ok",title:"btn1","class":"default",value:"btn1"},{action:"ok",title:"btn2","class":"primary",value:"btn2"},{action:"cancel",title:"btn3","class":"default",value:"btn3"},{action:"cancel",title:"btn4","class":"primary",value:"btn4"}]}).result.then(function(){console.log("OK: ",arguments[0])},function(){console.log("Cancel: ",arguments[0])})},this.toastComplete=function(){n.complete({time:1e3})},this.toastLoading=function(){var e=n.loading({message:"数据加载中"});setTimeout(function(){e.close()},1e3)},this.toastMessage=function(){n.message({message:"test asdfasdf sdfasdf asdfsadfv sdfsad asfsadf sdfasfda sdfasfasdf message show"})},this.wuButtonTest=function(){console.log("xxxxxxxxxxxxxxx")},this.testVar="nihao",this.wuButtonTest1=function(e){console.log("000000000000000",e)},this.cancelProgress=function(){this.wuProgress=50}}])}(angular.module("test",["ng.weui"])),function(e){e.controller("TestGalleryCtrl",["WuActionSheet","WuDialog","WuToast",function(){this.previewImages=[{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"},{thumb:"images/pic_article.png",url:"images/pic_article.png"}]}])}(angular.module("test.gallery",["ng.weui"])),angular.module("ng.weui.core",[]),angular.module("ng.weui.jssdk",[]),angular.module("ng.weui.swiper",["ng.weui.core"]),angular.module("ng.weui.button",[]),angular.module("ng.weui.progress",[]),angular.module("ng.weui.dialog",["ng.weui.core"]),angular.module("ng.weui.actionsheet",["ng.weui.core"]),angular.module("ng.weui.toast",["ng.weui.core"]),angular.module("ng.weui.form",["ng.weui.core"]),angular.module("ng.weui.gallery",["ng.weui.core","ng.weui.swiper"]),angular.module("ng.weui.loading",["ng.weui.core"]),angular.module("ng.weui",["ng.weui.core","ng.weui.button","ng.weui.actionsheet","ng.weui.dialog","ng.weui.toast","ng.weui.form","ng.weui.gallery","ng.weui.loading","ng.weui.progress"]),function(e,t){e.factory("WuWxJsSdk",["$q",function(e){function n(e){return t.wx?t.wx:(e({errMsg:"没有js接口对象,请确认是否引入微信js文件"}),!1)}function i(e,t,n){return e.success=function(e){t(e)},e.fail=function(e){n(e)},e.complete=function(){},e.cancel=function(){n({errMsg:"用户取消"})},e.trigger=function(){},e}for(var a={config:function(){return e(function(e,i){var a=n(i);a&&(a.config.apply(t,arguments),a.ready(function(){e({errMsg:"config:ok"})}),a.error(function(e){i(e)}))})}},o=["checkJsApi","onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ","onMenuShareWeibo","onMenuShareWeibo","chooseImage","previewImage","uploadImage","downloadImage","startRecord","stopRecord","onVoiceRecordEnd","playVoice","pauseVoice","stopVoice","onVoicePlayEnd","uploadVoice","downloadVoice","translateVoice","getNetworkType","openLocation","getLocation","hideOptionMenu","showOptionMenu","closeWindow","hideMenuItems","showMenuItems","hideAllNonBaseMenuItem","showAllNonBaseMenuItem","scanQRCode","startSearchBeacons","stopSearchBeacons","onSearchBeacons","openProductSpecificView","chooseCard","addCard","openCard","consumeAndShareCard","chooseWXPay"],r=0;r
',link:function(e){e.filterProgress=function(e){return e>100?"100%":0>e?"0%":parseFloat(e)+"%"},e.filterHeight=function(e){return(e&&e>1?e:3)+"px"}}}}])}(angular.module("ng.weui.progress")),function(e,t){"use strict";t.directive("wuSwiperContainer",["IdWorkerFactory",function(e){var t=e("wuSwiperContainer");return{restrict:"E",transclude:!0,scope:{onReady:"&",slidesPerView:"=",slidesPerColumn:"=",spaceBetween:"=",parallax:"=",parallaxTransition:"@",paginationIsActive:"=",paginationClickable:"=",showNavButtons:"=",showScrollBar:"=",loop:"=",autoplay:"=",initialSlide:"=",containerCls:"@",wrapperCls:"@",paginationCls:"@",slideCls:"@",direction:"@",swiper:"=",overrideParameters:"="},controller:function(e,n,i){var a=t();e.swiper_uuid=a;var o={slidesPerView:e.slidesPerView||1,slidesPerColumn:e.slidesPerColumn||1,spaceBetween:e.spaceBetween||0,direction:e.direction||"horizontal",loop:e.loop||!1,initialSlide:e.initialSlide||0,showNavButtons:!1};angular.isUndefined(e.autoplay)||"number"!=typeof e.autoplay||(o=angular.extend({},o,{autoplay:e.autoplay})),e.paginationIsActive===!0&&(o=angular.extend({},o,{paginationClickable:e.paginationClickable||!0,pagination:"#paginator-"+e.swiper_uuid})),e.showNavButtons===!0&&(o.nextButton="#nextButton-"+e.swiper_uuid,o.prevButton="#prevButton-"+e.swiper_uuid),e.showScrollBar===!0&&(o.scrollbar="#scrollBar-"+e.swiper_uuid),e.overrideParameters&&(o=angular.extend({},o,e.overrideParameters)),i(function(){var t=null;angular.isObject(e.swiper)?(e.swiper=new Swiper(n[0].firstChild,o),t=e.swiper):t=new Swiper(n[0].firstChild,o),angular.isUndefined(e.onReady)||e.onReady({swiper:t})})},link:function(e,t){var n=e.swiper_uuid,i="paginator-"+n,a="prevButton-"+n,o="nextButton-"+n,r="scrollBar-"+n,l=t[0];angular.element(l.querySelector(".swiper-pagination")).attr("id",i),angular.element(l.querySelector(".swiper-button-next")).attr("id",o),angular.element(l.querySelector(".swiper-button-prev")).attr("id",a),angular.element(t[0].querySelector(".swiper-scrollbar")).attr("id",r)},template:'
'}}]).directive("wuSwiperSlide",[function(){return{restrict:"E",require:"^ksSwiperContainer",transclude:!0,scope:{sliderCls:"@"},template:'
',replace:!0}}])}(window,angular.module("ng.weui.swiper"),void 0),function(e){e.directive("loadingEnable",[function(){return{restrict:"A",replace:!0,templateUrl:"weui/template/loading/loading.html",transclude:!0,link:function(){}}}])}(angular.module("ng.weui.loading"),window),function(e){e.factory("PreviewImages",["WuWxJsSdk",function(e){return{show:function(t,n){e.previewImage({current:t,urls:n})}}}]),e.directive("previewImages",["PreviewImages",function(e){return{restrict:"AE",link:function(t,n,i){var a=n,o=i.preview?i.preview:"img",r=i.attrName?i.attrName:"src";n.on("click",o,function(t){var n=$(this),i=[];return a.find(o).each(function(e,t){i.push(t.attr(r))}),e.show(n.attr(r),i),t.preventDefault(),t.stopPropagation(),!1})}}}]),e.directive("gallery",["$timeout","IdWorkerFactory",function(e,t){var n=t.new("weui-gallery_swiper");return{restrict:"EA",templateUrl:"weui/template/gallery/gallery.html",scope:{images:"="},link:function(t,i){function a(){e(function(){console.log("#"+o+" .swiper-images");var e=new Swiper("#"+o+" .swiper-images",{nextButton:".swiper-button-next",prevButton:".swiper-button-prev",spaceBetween:10,effect:"coverflow",grabCursor:!0,centeredSlides:!0,slidesPerView:"auto",coverflow:{rotate:50,stretch:0,depth:100,modifier:1,slideShadows:!0}});if(t.showThumb){var n=new Swiper("#"+o+" .gallery-thumbs",{spaceBetween:10,centeredSlides:!0,slidesPerView:"auto",touchRatio:.2,slideToClickedSlide:!0});e.params.control=n,n.params.control=e}},10)}var o=n();i.attr("id",o),i.addClass("weui-gallery"),i.show(),t.showThumb=!1,angular.isArray(t.images)&&t.images.length>0&&(t.images[0].hasOwnProperty("thumb")&&(t.showThumb=!0),a()),t.imageStyle=function(e){return{"background-image":"url("+e.url+")"}}}}}])}(angular.module("ng.weui.gallery")),function(e){e.directive("inputTextarea",[function(){return{restrict:"EA",replace:!0,templateUrl:"weui/template/form/input-textarea.html",require:"ngModel",link:function(e,t,n,i){i.$render=function(){console.log()}}}}]),e.directive("inputImage",[function(){return{restrict:"EA",replace:!0,templateUrl:"weui/template/form/input-image.html",require:"ngModel",link:function(e,t,n,i){i.$render=function(){console.log()}}}}])}(angular.module("ng.weui.form")),function(e){e.provider("WuDialog",[function(){var e=this;e.$get=["$wuModal",function(e){return{open:function(t){t.buttons=t.buttons||[{action:"ok",title:"确定","class":"default",value:"ok"}];var n="wu-dialog-default-template";return t.hasOwnProperty("template")&&t.template&&(n=t.template),e.open({backdrop:!1,windowTemplateUrl:"weui/template/wu-window.html",template:"
",controller:["$scope",function(e){e.title=t.title,e.content=t.content,e.buttons=t.buttons,e.clickBtn=function(t){"ok"===t.action.toLowerCase()?e.$close(t.value):e.$dismiss(t.value)}}]})},alert:function(e){return this.open({title:e.title,content:e.content})},confirm:function(e){return this.open({title:e.title,content:e.content,buttons:[{action:"cancel",title:"取消","class":"default",value:"cancel"},{action:"ok",title:"确定","class":"primary",value:"ok"}]})}}}]}]);var t=function(e,t){var n=t.find(".weui-mask");n.on("click",function(){e.$apply(function(){e.$dismiss("mask:click")})});var i="weui-dialog__alert";e.buttons.length>1&&(i="weui-dialog__confirm"),t.addClass(i)};e.directive("wuDialogDefaultTemplate",[function(){return{restrict:"A",templateUrl:"weui/template/dialog/default.html",link:t}}]).directive("wuDialogAndroidTemplate",[function(){return{restrict:"A",templateUrl:"weui/template/dialog/android.html",link:t}}]),e.directive("unsafeShowHtml",["$compile",function(e){return{restrict:"A",scope:{content:"=unsafeShowHtml"},link:function(t,n){var i=function(){var i="
"+t.content+"
";n.html("").append(e(i)(t))};i()}}}])}(angular.module("ng.weui.dialog")),function(e,t){e.factory("$$stackedMap",function(){return{createNew:function(){var e=[];return{add:function(t,n){e.push({key:t,value:n})},get:function(t){for(var n=0;n
0&&(t=b.top().value,t.modalDomEl.toggleClass(t.windowTopClass||"",e))}function d(){if(m&&-1===s()){var e=f;p(m,f,function(){e=null}),m=void 0,f=void 0}}function p(e,n,i,a){function r(){r.done||(r.done=!0,t(e,{event:"leave"}).start().then(function(){e.remove(),a&&a.resolve()}),n.$destroy(),i&&i())}var l,s=null,u=function(){return l||(l=o.defer(),s=l.promise),function(){l.resolve()}};return n.$broadcast(k.NOW_CLOSING_EVENT,u),o.when(s).then(r)}function g(e){if(e.isDefaultPrevented())return e;var t=b.top();if(t)switch(e.which){case 27:t.value.keyboard&&(e.preventDefault(),a.$apply(function(){k.dismiss(t.key,"escape key press")}));break;case 9:k.loadFocusElementList(t);var n=!1;e.shiftKey?k.isFocusInFirstItem(e)&&(n=k.focusLastFocusableElement()):k.isFocusInLastItem(e)&&(n=k.focusFirstFocusableElement()),n&&(e.preventDefault(),e.stopPropagation())}}function w(e,t,n){return!e.value.modalScope.$broadcast("modal.closing",t,n).defaultPrevented}var m,f,v,h="modal-open",b=l.createNew(),_=r.createNew(),k={NOW_CLOSING_EVENT:"modal.stack.now-closing"},y=0,$="a[href], area[href], input:not([disabled]), button:not([disabled]),select:not([disabled]), textarea:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable=true]";return a.$watch(s,function(e){f&&(f.index=e)}),n.on("keydown",g),a.$on("$destroy",function(){n.off("keydown",g)}),k.open=function(t,o){var r=n[0].activeElement,l=o.openedClass||h;c(!1),b.add(t,{deferred:o.deferred,renderDeferred:o.renderDeferred,closedDeferred:o.closedDeferred,modalScope:o.scope,backdrop:o.backdrop,keyboard:o.keyboard,openedClass:o.openedClass,windowTopClass:o.windowTopClass,animation:o.animation,appendTo:o.appendTo}),_.put(l,t);var u=o.appendTo,d=s();if(!u.length)throw new Error("appendTo element not found. Make sure that the element passed is in DOM.");d>=0&&!m&&(f=a.$new(!0),f.modalOptions=o,f.index=d,m=angular.element(''),m.attr("backdrop-class",o.backdropClass),o.animation&&m.attr("modal-animation","true"),i(m)(f),e.enter(m,u));var p=angular.element('');p.attr({"template-url":o.windowTemplateUrl,"window-class":o.windowClass,"window-top-class":o.windowTopClass,size:o.size,index:b.length()-1,animate:"animate"}).html(o.content),o.animation&&p.attr("modal-animation","true"),e.enter(p,u).then(function(){i(p)(o.scope),e.addClass(u,l)}),b.top().value.modalDomEl=p,b.top().value.modalOpener=r,k.clearFocusListCache()},k.close=function(e,t){var n=b.get(e);return n&&w(n,t,!0)?(n.value.modalScope.$$wuDestructionScheduled=!0,n.value.deferred.resolve(t),u(e,n.value.modalOpener),!0):!n},k.dismiss=function(e,t){var n=b.get(e);return n&&w(n,t,!1)?(n.value.modalScope.$$wuDestructionScheduled=!0,n.value.deferred.reject(t),u(e,n.value.modalOpener),!0):!n},k.dismissAll=function(e){for(var t=this.getTop();t&&this.dismiss(t.key,e);)t=this.getTop()},k.getTop=function(){return b.top()},k.modalRendered=function(e){var t=b.get(e);t&&t.value.renderDeferred.resolve()},k.focusFirstFocusableElement=function(){return v.length>0?(v[0].focus(),!0):!1},k.focusLastFocusableElement=function(){return v.length>0?(v[v.length-1].focus(),!0):!1},k.isFocusInFirstItem=function(e){return v.length>0?(e.target||e.srcElement)===v[0]:!1},k.isFocusInLastItem=function(e){return v.length>0?(e.target||e.srcElement)===v[v.length-1]:!1},k.clearFocusListCache=function(){v=[],y=0},k.loadFocusElementList=function(e){if((void 0===v||!v.length)&&e){var t=e.value.modalDomEl;t&&t.length&&(v=t[0].querySelectorAll($))}},k}]).provider("$wuModal",function(){var e={options:{animation:!0,backdrop:!0,keyboard:!0},$get:["$rootScope","$q","$document","$templateRequest","$controller","$wuResolve","$wuModalStack",function(t,n,i,a,o,r,l){function s(e){return e.template?n.when(e.template):a(angular.isFunction(e.templateUrl)?e.templateUrl():e.templateUrl)}var u={},c=null;return u.getPromiseChain=function(){return c},u.open=function(a){function u(){return v}var d=n.defer(),p=n.defer(),g=n.defer(),w=n.defer(),m={result:d.promise,opened:p.promise,closed:g.promise,rendered:w.promise,close:function(e){return l.close(m,e)},dismiss:function(e){return l.dismiss(m,e)}};if(a=angular.extend({},e.options,a),a.resolve=a.resolve||{},a.appendTo=a.appendTo||i.find("body").eq(0),!a.template&&!a.templateUrl)throw new Error("One of template or templateUrl options is required.");var f,v=n.all([s(a),r.resolve(a.resolve,{},null,null)]);return f=c=n.all([c]).then(u,u).then(function(e){var n=a.scope||t,i=n.$new();i.$close=m.close,i.$dismiss=m.dismiss,i.$on("$destroy",function(){i.$$wuDestructionScheduled||i.$dismiss("$wuUnscheduledDestruction")});var r,s={};a.controller&&(s.$scope=i,s.$wuModalInstance=m,angular.forEach(e[1],function(e,t){s[t]=e}),r=o(a.controller,s),a.controllerAs&&(a.bindToController&&(r.$close=i.$close,r.$dismiss=i.$dismiss,angular.extend(r,n)),i[a.controllerAs]=r)),l.open(m,{scope:i,deferred:d,renderDeferred:w,closedDeferred:g,content:e[0],animation:a.animation,backdrop:a.backdrop,keyboard:a.keyboard,backdropClass:a.backdropClass,windowTopClass:a.windowTopClass,windowClass:a.windowClass,windowTemplateUrl:a.windowTemplateUrl,size:a.size,openedClass:a.openedClass,appendTo:a.appendTo}),p.resolve(!0)},function(e){p.reject(e),d.reject(e)})["finally"](function(){c===f&&(c=null)}),m},u}]};return e}),t.weui_client_browser_checker=function(){var e={ie:0,gecko:0,webkit:0,khtml:0,opera:0,ver:null},n={ie:0,firefox:0,safari:0,konq:0,opera:0,chrome:0,wx:0,wxpc:0,ver:null},i={win:!1,mac:!1,x11:!1,iphone:!1,ipod:!1,ipad:!1,ios:!1,android:!1,nokiaN:!1,winMobile:!1,wii:!1,ps:!1},a=navigator.userAgent;if(t.opera)e.ver=n.ver=t.opera.version(),e.opera=n.opera=parseFloat(e.ver);else if(/AppleWebKit\/(\S+)/.test(a))if(e.ver=RegExp.$1,e.webkit=parseFloat(e.ver),/Chrome\/(\S+)/.test(a))n.ver=RegExp.$1,n.chrome=parseFloat(n.ver);else if(/Version\/(\S+)/.test(a))n.ver=RegExp.$1,n.safari=parseFloat(n.ver);else{var o=1;o=e.webkit<100?1:e.webkit<312?1.2:e.webkit<412?1.3:2,n.safari=n.ver=o}else/KHTML\/(\S+)/.test(a)||/Konqueror\/([^;]+])/.test(a)?(e.ver=n.ver=RegExp.$1,e.khtml=n.konq=parseFloat(e.ver)):/rv:([^\)]+)\) Gecko\/\d{8}/.test(a)?(e.ver=RegExp.$1,n.gecko=parseFloat(e.ver),/Firefox\/(\S+)/.test(a)&&(n.ver=RegExp.$1,n.firefox=parseFloat(n.ver))):/MSIE ([^;]+)/.test(a)&&(e.ver=n.ver=RegExp.$1,e.ie=n.ie=parseFloat(e.ver));/MicroMessenger\/([\d\.]+)/i.test(a)&&(n.ver=RegExp.$1,n.wx="micromessenger",n.wxpc=/WindowsWechat/i.test(a)),n.ie=e.ie,n.opera=e.opera;var r=navigator.platform;if(i.win=r.indexOf("Win")>=0,i.mac=r.indexOf("Mac")>=0,i.x11="X11"==r||0==r.indexOf("Linux"),i.win&&/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(a))if("NT"==RegExp.$1)switch(RegExp.$2){case"5.0":i.win="2000";break;case"5.1":i.win="XP";break;case"6.0":i.win="vista";break;case"6.1":i.win="7";break;default:i.win="NT"}else i.win="9x"==RegExp.$1?"ME":RegExp.$1;return i.iphone=a.indexOf("iPhone")>-1,i.ipod=a.indexOf("iPod")>-1,i.ipad=a.indexOf("iPad")>-1,i.nokiaN=a.indexOf("NokinaN")>-1,"CE"==i.win?i.winMobile=i.win:"Ph"==i.win&&/Window Phone OS (\d+.\d+)/.test(a)&&(i.win="Phone",i.winMobile=parseFloat(RegExp.$1)),i.iphone&&a.indexOf("Mobile")>-1&&(i.ios=/CPU (?:iPhone)?[ ]?OS (\d+_\d+)/.test(a)?parseFloat(RegExp.$1.replace("_",".")):2),/Android (\d+\.\d+)/.test(a)&&(i.android=parseFloat(RegExp.$1)),i.wii=a.indexOf("Wii")>-1,i.ps=/playstation/i.test(a),{engine:e,browser:n,system:i}}(),e.provider("WuBrowserChecker",[function(){var e=this;e.$get=[function(){return t.weui_client_browser_checker}]}]),e.provider("IdWorkerFactory",[function(){var e={};this.new=function(t){return e.hasOwnProperty(t)||(e[t]=function(e){var t=0;return function(){return e+"_"+t++}}(t)),e[t]},this.$get=[function(){return this}]}])}(angular.module("ng.weui.core"),window),function(e){e.directive("wuClick",["$parse","$timeout","$rootScope",function(e,t){return{restrict:"EA",compile:function(n,i){var a=e(i.wuClick),o=e(i.wuInterval||"300");return function(e,n){var i=parseInt(o(e)),r=!1;n.on("click",function(o){r||(e.$apply(function(){a(e,{$event:o})}),n.attr("disabled","disabled").addClass("weui_btn_disabled"),r=!0,t(function(){n.removeAttr("disabled").removeClass("weui_btn_disabled"),r=!1},i))})}}}}])}(angular.module("ng.weui.button")),function(e){e.provider("WuActionSheet",[function(){var e=this;e.$get=["$wuModal",function(e){return{open:function(t){return e.open({backdrop:!1,windowTemplateUrl:"weui/template/wu-window.html",template:"",controller:["$scope",function(e){e.btnGroups=t.btnGroups||[{action:"Cancel",buttons:[{title:"取消",value:"cancel"}]}],e.triggerBtn=function(t,n){var i=t.action.toLowerCase();"ok"===i?e.$close(n.value):e.$dismiss(n.value)}}]})}}}]}]).directive("wuActionSheetTemplate",["$q",function(e){return{restrict:"A",templateUrl:"weui/template/action-sheet/action-sheet.html",link:function(t,n){function i(t,n){return e(function(e){t.removeClass("weui-actionsheet_toggle"),n.removeClass("actionsheet__mask_show"),t.on("transitionend",function(){n.hide(),e()}).on("webkitTransitionEnd",function(){n.hide(),e()})})}var a=n.find(".weui-mask_transparent.actionsheet__mask"),o=n.find(".weui-actionsheet");!function(){a.show().addClass("actionsheet__mask_show").on("click",function(){i(o,a).then(function(){t.$dismiss("mask:click")})}),o.addClass("weui-actionsheet_toggle")}(),t.clickBtn=function(e,n){i(o,a).then(function(){t.triggerBtn(e,n)})}}}}])}(angular.module("ng.weui.actionsheet")),angular.module("ng.weui").run(["$templateCache",function(e){e.put("weui/template/wu-window.html",''),e.put("weui/template/action-sheet/action-sheet.html",''),e.put("weui/template/dialog/android.html",''),e.put("weui/template/dialog/default.html",''),e.put("weui/template/form/input-image.html",''),e.put("weui/template/form/input-textarea.html",''),e.put("weui/template/gallery/gallery.html",''),e.put("weui/template/loading/loading.html",''),e.put("weui/template/toast/complete.html",''),e.put("weui/template/toast/loading.html",''),e.put("weui/template/toast/message.html",'')}]);
--------------------------------------------------------------------------------
/docs/styles/app-e8d70c78.css:
--------------------------------------------------------------------------------
1 | .actionsheet__mask_show{background:rgba(0,0,0,.6)}.weui-gallery .weui-page{width:100%;height:100%}.weui-gallery .weui-gallery_swiper{position:relative;height:100%;width:100%;overflow:hidden}.weui-gallery .swiper-container{width:100%;height:90%;margin-left:auto;margin-right:auto}.weui-gallery .swiper-container.gallery-top{height:80%;width:100%}.weui-gallery .swiper-slide{top:0;right:0;bottom:60px;left:0;background:center center no-repeat;background-size:contain}.weui-gallery .gallery-thumbs.swiper-container{height:20%;box-sizing:border-box;padding:10px 0}.weui-gallery .gallery-thumbs .swiper-slide{width:25%;height:100%;opacity:.4}.weui-gallery .gallery-thumbs .swiper-slide-active{opacity:1}.weui-toast.wu_toast_message{bottom:32px;top:auto;min-height:inherit;width:15.6em;margin-left:-7.8em}
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var gulp = require('gulp');
4 | gulp.appName = 'angular-weui';
5 | gulp.moduleName = 'ng.weui';
6 | gulp.paths = {
7 | src: 'src',
8 | dist: 'dist',
9 | tmp: '.tmp',
10 | e2e: 'test/e2e',
11 | unit: 'test/unit',
12 | test_server:'test/serve',
13 | docs: 'docs/api',
14 | demo: 'docs',
15 | reports: 'reports'
16 | };
17 |
18 | require('require-dir')('./.gulp');
19 |
20 | gulp.task('default', ['clean'], function () {
21 | gulp.start('build');
22 | });
23 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(config) {
4 |
5 | config.set({
6 | autoWatch : true,
7 |
8 | frameworks: ['jasmine'],
9 |
10 | browsers : ['PhantomJS'],
11 |
12 | plugins : [
13 | 'karma-phantomjs-launcher',
14 | 'karma-jasmine',
15 | 'karma-coverage'
16 | ],
17 | preprocessors: {
18 | 'src/**/*.js': ['coverage']
19 | },
20 | reporters: ['progress', 'coverage'],
21 | coverageReporter: {
22 | type: 'lcov',
23 | dir: 'reports',
24 | subdir: 'coverage'
25 | },
26 |
27 | colors: true
28 | });
29 | };
30 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-weui",
3 | "version": "0.0.1",
4 | "scripts": {
5 | "install:bower": "bower install --save",
6 | "dev": "gulp serve",
7 | "build:dist": "gulp",
8 | "build:docs": "gulp docs",
9 | "build:demo": "gulp demo",
10 | "gulp": "gulp"
11 | },
12 | "dependencies": {},
13 | "devDependencies": {
14 | "bower": "^1.7.9",
15 | "browser-sync": "~1.7.1",
16 | "chalk": "~0.5.1",
17 | "del": "~0.1.3",
18 | "gulp": "^3.9.0",
19 | "gulp-angular-filesort": "~1.0.4",
20 | "gulp-angular-templatecache": "~1.4.2",
21 | "gulp-autoprefixer": "~2.0.0",
22 | "gulp-concat": "~2.6.0",
23 | "gulp-consolidate": "~0.1.2",
24 | "gulp-csso": "~0.2.9",
25 | "gulp-filter": "~1.0.2",
26 | "gulp-flatten": "~0.0.4",
27 | "gulp-inject": "~1.0.2",
28 | "gulp-jsdoc": "~0.1.4",
29 | "gulp-jshint": "~1.9.0",
30 | "gulp-karma": "~0.0.4",
31 | "gulp-less": "~1.3.6",
32 | "gulp-load-plugins": "~0.7.1",
33 | "gulp-minify-css": "~1.2.1",
34 | "gulp-minify-html": "~0.1.7",
35 | "gulp-ng-annotate": "~0.3.6",
36 | "gulp-plumber": "~1.0.1",
37 | "gulp-protractor": "~0.0.11",
38 | "gulp-rename": "~1.2.0",
39 | "gulp-replace": "~0.5.0",
40 | "gulp-rev": "~2.0.1",
41 | "gulp-rev-replace": "~0.3.1",
42 | "gulp-sass": "^2.3.2",
43 | "gulp-size": "~1.1.0",
44 | "gulp-stylus": "^2.2.0",
45 | "gulp-uglify": "~1.0.1",
46 | "gulp-useref": "~1.0.2",
47 | "http-proxy": "~1.7.0",
48 | "jshint-stylish": "~1.0.0",
49 | "karma-coverage": "~0.5.2",
50 | "karma-jasmine": "~0.3.1",
51 | "karma-phantomjs-launcher": "~0.1.4",
52 | "main-bower-files": "~2.4.0",
53 | "opn": "^3.0.2",
54 | "protractor": "~1.4.0",
55 | "require-dir": "~0.1.0",
56 | "uglify-save-license": "~0.4.1",
57 | "wiredep": "~2.2.0"
58 | },
59 | "engines": {
60 | "node": ">=0.10.0"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var paths = require('./.yo-rc.json')['generator-gulp-angular'].props.paths;
4 |
5 | /*
6 | npm install chai
7 | npm install chai-as-promised
8 | */
9 |
10 | // An example configuration file.
11 | exports.config = {
12 | // The address of a running selenium server.
13 | seleniumAddress: 'http://localhost:4444/wd/hub',
14 | //seleniumServerJar: deprecated, this should be set on node_modules/protractor/config.json
15 | // framework: 'jasmine', // jasmine2 mocha cucumber
16 |
17 | chromeDriver: '/Users/three/tools/selenium/chromedriver',
18 | seleniumServerJar: '/Users/three/tools/selenium/selenium-server-standalone-2.44.0.jar',
19 |
20 | //firefoxPath:'/Applications/Firefox.app/Contents/MacOS/firefox-bin',
21 |
22 |
23 | // Capabilities to be passed to the webdriver instance.
24 | //capabilities: {
25 | // 'browserName': 'chrome'
26 | //},
27 | multiCapabilities: [{
28 | name: 'chrome_mac',
29 | browserName: 'chrome',
30 | platformName: 'MAC',
31 | deviceName: 'ChromeDriver'
32 | }, {
33 | name: 'chrome_android',
34 | browserName: 'chrome',
35 | platformName: 'ANDROID',
36 | deviceName: 'ChromeDriver',
37 | 'chromeOptions': {
38 | 'androidPackage': 'com.android.chrome'
39 | }
40 | }, {
41 | name: 'chrome_firefox',
42 | browserName: 'firefox',
43 | platformName: 'MAC',
44 | deviceName: 'FirefoxDriver'
45 | }/*,{
46 | 'browserName': 'phantomjs',
47 |
48 | /!*
49 | * Can be used to specify the phantomjs binary path.
50 | * This can generally be ommitted if you installed phantomjs globally.
51 | *!/
52 | 'phantomjs.binary.path': require('phantomjs').path,
53 |
54 | /!*
55 | * Command line args to pass to ghostdriver, phantomjs's browser driver.
56 | * See https://github.com/detro/ghostdriver#faq
57 | *!/
58 | 'phantomjs.ghostdriver.cli.args': ['--loglevel=DEBUG']
59 | }*/],
60 |
61 | //directConnect:true,
62 | // Spec patterns are relative to the current working directly when
63 | // protractor is called.
64 | specs: [paths.e2e + '/**/*.js'],
65 |
66 | mochaOpts: {
67 | ui: 'bdd',
68 | reporter: 'list'
69 | },
70 | // Options to be passed to Jasmine-node.
71 | jasmineNodeOpts: {
72 | showColors: true,
73 | defaultTimeoutInterval: 30000
74 | }
75 | };
76 |
--------------------------------------------------------------------------------
/src/css/actionsheet.styl:
--------------------------------------------------------------------------------
1 | .actionsheet__mask_show {
2 | background: rgba(0,0,0,.6);
3 | }
4 |
--------------------------------------------------------------------------------
/src/css/gallery.styl:
--------------------------------------------------------------------------------
1 | .weui-gallery{
2 | .weui-page {
3 | width 100%
4 | height 100%
5 | }
6 | .weui-gallery_swiper {
7 | position: relative;
8 | height:100%
9 | width 100%
10 | overflow hidden
11 | }
12 | .swiper-container {
13 | width: 100%;
14 | height: 90%;
15 | margin-left: auto;
16 | margin-right: auto;
17 | &.gallery-top {
18 | height: 80%;
19 | width: 100%;
20 | }
21 | //position: absolute;
22 | }
23 | .swiper-slide {
24 | //background-size: cover;
25 | //background-position: center;
26 | //position: absolute;
27 | top: 0;
28 | right: 0;
29 | bottom: 60px;
30 | left: 0;
31 | background: center center no-repeat;
32 | background-size: contain;
33 | }
34 |
35 | .gallery-thumbs {
36 | &.swiper-container {
37 | height: 20%;
38 | box-sizing: border-box;
39 | padding: 10px 0;
40 | }
41 | .swiper-slide {
42 | width: 25%;
43 | height: 100%;
44 | opacity: 0.4;
45 | }
46 | .swiper-slide-active {
47 | opacity: 1;
48 | }
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/src/css/toast.styl:
--------------------------------------------------------------------------------
1 | .weui-toast.wu_toast_message {
2 | bottom: 32px;
3 | top: auto;
4 | min-height: inherit;
5 | width: 15.6em;
6 | margin-left: -7.8em
7 | }
8 |
--------------------------------------------------------------------------------
/src/js/Dialog.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 16/1/13.
3 | *
4 | * 目前 `WuDialog` 并不是安全的,需要调用者控制输出的 html 代码防止 xss
5 | * 可以参考:https://github.com/leizongmin/js-xss
6 | */
7 |
8 | (function (app) {
9 | app.provider('WuDialog', [function () {
10 | var _self = this;
11 |
12 | _self.$get = ['$wuModal',function ($wuModal) {
13 | return {
14 | open: function (config) {
15 | config.buttons = config.buttons || [
16 | {
17 | action:'ok',
18 | title:'确定',
19 | class: 'default',
20 | value:'ok'
21 | }
22 | ];
23 |
24 | var template = 'wu-dialog-default-template';
25 | if(config.hasOwnProperty('template') && !!config.template) {
26 | template = config.template;
27 | }
28 | return $wuModal.open({
29 | backdrop: false,
30 | windowTemplateUrl: 'weui/template/wu-window.html',
31 | template: '',
32 | controller: ['$scope', function ($scope) {
33 | $scope.title = config.title;
34 | $scope.content = config.content;
35 | $scope.buttons = config.buttons;
36 |
37 | $scope.clickBtn = function (btn) {
38 | if(btn.action.toLowerCase()==='ok') {
39 | $scope.$close(btn.value);
40 | } else {
41 | $scope.$dismiss(btn.value);
42 | }
43 | }
44 | }]
45 | })
46 | },
47 | alert: function(config){
48 | return this.open({
49 | title: config.title,
50 | content: config.content
51 | });
52 | },
53 | confirm: function(config) {
54 | return this.open({
55 | title: config.title,
56 | content: config.content,
57 | buttons: [
58 | {
59 | action:'cancel',
60 | title:'取消',
61 | class: 'default',
62 | value:'cancel'
63 | },
64 | {
65 | action:'ok',
66 | title:'确定',
67 | class: 'primary',
68 | value:'ok'
69 | }
70 | ]
71 | });
72 | }
73 | }
74 | }];
75 | }]);
76 |
77 | var linkFunction = function (scope, element, attrs) {
78 | var mask = element.find('.weui-mask');
79 | mask.on('click', function () {
80 | scope.$apply(function () {
81 | scope.$dismiss('mask:click');
82 | });
83 | });
84 |
85 | var openedClass = 'weui-dialog__alert';
86 | if(scope.buttons.length>1) {
87 | openedClass= 'weui-dialog__confirm'
88 | }
89 | element.addClass(openedClass);
90 | }
91 | app.directive('wuDialogDefaultTemplate', [function () {
92 | return {
93 | restrict: 'A',
94 | templateUrl: 'weui/template/dialog/default.html',
95 | link: linkFunction
96 | };
97 | }])
98 | .directive('wuDialogAndroidTemplate', [function () {
99 | return {
100 | restrict: 'A',
101 | templateUrl: 'weui/template/dialog/android.html',
102 | link: linkFunction
103 | };
104 | }])
105 | ;
106 | /**
107 | * 表格数据 html 输出
108 | * 这个会有 xss 风险
109 | */
110 | app.directive('unsafeShowHtml', ['$compile', function ($compile) {
111 |
112 | /**
113 | * html 编码,html源码输出
114 | * @param {[type]} html [description]
115 | */
116 | function HTMLEncode(html) {
117 | var temp = document.createElement("div");
118 | (temp.textContent != null) ? (temp.textContent = html) : (temp.innerText = html);
119 | var output = temp.innerHTML;
120 | temp = null;
121 | return output;
122 | }
123 |
124 | return {
125 | restrict: 'A',
126 | scope: {
127 | content: '=unsafeShowHtml'
128 | },
129 | link: function (scope, element, attrs) {
130 |
131 | var change = function () {
132 | var showHtml = ''+scope.content+'
';
133 | element.html('').append($compile(showHtml)(scope));
134 | };
135 | //scope.$watch('content', function () {
136 | change();
137 | //});
138 | }
139 | }
140 | }]);
141 | })(angular.module('ng.weui.dialog'));
142 |
--------------------------------------------------------------------------------
/src/js/Toast.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 16/1/13.
3 | */
4 |
5 | (function (app) {
6 | app.provider('WuToast',[function () {
7 | var _self = this;
8 |
9 | _self.$get = ['$wuModal','$timeout',function ($wuModal,$timeout) {
10 | return {
11 | complete: function (config) {
12 | config = config || {};
13 | var toastInstance = $wuModal.open({
14 | backdrop: false,
15 | windowTemplateUrl:'weui/template/wu-window.html',
16 | templateUrl:'weui/template/toast/complete.html',
17 | controller:['$scope', function ($scope) {
18 | $scope.message = config.message || '已完成';
19 | }]
20 | });
21 | if(config.hasOwnProperty('time')) {
22 | $timeout(function () {
23 | toastInstance.close();
24 | }, parseInt(config.time))
25 | }
26 | return {
27 | close: function () {
28 | toastInstance.close();
29 | }
30 | }
31 | },
32 | loading: function (config) {
33 | config = config || {};
34 | var toastInstance = $wuModal.open({
35 | backdrop: false,
36 | windowTemplateUrl:'weui/template/wu-window.html',
37 | templateUrl:'weui/template/toast/loading.html',
38 | controller:['$scope', function ($scope) {
39 | $scope.message = config.message || '数据加载中';
40 | }]
41 | });
42 | if(config.hasOwnProperty('time')) {
43 | $timeout(function () {
44 | toastInstance.close();
45 | }, parseInt(config.time))
46 | }
47 | return {
48 | close: function () {
49 | toastInstance.close();
50 | }
51 | }
52 | },
53 | message: function (config) {
54 | config = config || {};
55 | var toastInstance = $wuModal.open({
56 | backdrop: false,
57 | windowTemplateUrl:'weui/template/wu-window.html',
58 | templateUrl:'weui/template/toast/message.html',
59 | controller:['$scope', function ($scope) {
60 | $scope.message = config.message || '消息提示';
61 | }]
62 | });
63 | if(config.hasOwnProperty('time')) {
64 | $timeout(function () {
65 | toastInstance.close();
66 | }, parseInt(config.time))
67 | }
68 | return {
69 | close: function () {
70 | toastInstance.close();
71 | }
72 | }
73 | }
74 | }
75 | }];
76 | }])
77 | })(angular.module('ng.weui.toast'));
78 |
--------------------------------------------------------------------------------
/src/js/action-sheet.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 16/1/13.
3 | */
4 |
5 | /**
6 | * ActionSheet 封装
7 | */
8 | (function (app) {
9 | app.provider('WuActionSheet',[function () {
10 | var _self = this;
11 |
12 | _self.$get = ['$wuModal',function ($wuModal) {
13 | return {
14 | open: function(config){
15 | return $wuModal.open({
16 | backdrop: false,
17 | windowTemplateUrl:'weui/template/wu-window.html',
18 | template:'',
19 | controller:['$scope', function ($scope) {
20 | $scope.btnGroups = config.btnGroups || [
21 | {
22 | action: 'Cancel',
23 | buttons:[
24 | { title: '取消', value: 'cancel'}
25 | ]
26 | }
27 | ];
28 |
29 | $scope.triggerBtn = function(group, btn) {
30 | var action = group.action.toLowerCase();
31 | if(action==='ok'){
32 | $scope.$close(btn.value);
33 | } else {
34 | $scope.$dismiss(btn.value);
35 | }
36 | }
37 | }]
38 | });
39 | }
40 | }
41 | }];
42 | }])
43 | .directive('wuActionSheetTemplate',['$q', function ($q) {
44 | return {
45 | restrict:'A',
46 | templateUrl:'weui/template/action-sheet/action-sheet.html',
47 | link: function (scope, element, attrs) {
48 | var mask = element.find('.weui-mask_transparent.actionsheet__mask');
49 | var actionSheet = element.find('.weui-actionsheet');
50 |
51 | /**
52 | * 打开初始化
53 | */
54 | (function () {
55 | mask.show().addClass('actionsheet__mask_show').on('click',function () {
56 | closeActionSheetAnimate(actionSheet, mask).then(function () {
57 | scope.$dismiss('mask:click');
58 | })
59 | });
60 | actionSheet.addClass('weui-actionsheet_toggle');
61 | })();
62 |
63 | /**
64 | * 点击按钮
65 | * @param group
66 | * @param btn
67 | */
68 | scope.clickBtn = function(group, btn) {
69 | closeActionSheetAnimate(actionSheet, mask).then(function () {
70 | scope.triggerBtn(group, btn);
71 | });
72 | };
73 |
74 | /**
75 | * 关闭ActionSheet动画
76 | * @param actionSheet
77 | * @param mask
78 | * @returns {*}
79 | */
80 | function closeActionSheetAnimate(actionSheet, mask) {
81 | return $q(function (resovle, reject) {
82 | actionSheet.removeClass('weui-actionsheet_toggle');
83 | mask.removeClass('actionsheet__mask_show');
84 | actionSheet.on('transitionend', function () {
85 | mask.hide();
86 | resovle();
87 | }).on('webkitTransitionEnd', function () {
88 | mask.hide();
89 | resovle();
90 | })
91 | });
92 | }
93 | }
94 | }
95 | }])
96 | ;
97 | })(angular.module('ng.weui.actionsheet'));
98 |
--------------------------------------------------------------------------------
/src/js/button.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 16/1/13.
3 | */
4 |
5 | (function (app) {
6 | app.directive('wuClick',['$parse','$timeout','$rootScope',function ($parse,$timeout,$rootScope) {
7 | return {
8 | restrict:'EA',
9 | compile: function (element, attrs) {
10 |
11 | var wuClickFn = $parse(attrs['wuClick']);
12 | var wuIntervalFn = $parse(attrs['wuInterval'] || '300');
13 |
14 | return function (scope, element, attrs) {
15 | var wuInterval = parseInt(wuIntervalFn(scope));
16 | var isBusy = false;
17 |
18 | element.on('click', function(event) {
19 | if(!isBusy) {
20 | scope.$apply(function() {
21 | wuClickFn(scope, {$event:event});
22 | });
23 |
24 | element.attr('disabled','disabled').addClass('weui_btn_disabled');
25 | isBusy = true;
26 | $timeout(function () {
27 | element.removeAttr('disabled').removeClass('weui_btn_disabled');
28 | isBusy = false;
29 | },wuInterval);
30 | }
31 |
32 | })
33 | };
34 | }
35 | }
36 | }])
37 | })(angular.module('ng.weui.button'));
38 |
--------------------------------------------------------------------------------
/src/js/core.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 16/1/13.
3 | */
4 | (function (app,window) { app
5 | /**
6 | * A helper, internal data structure that acts as a map but also allows getting / removing
7 | * elements in the LIFO order
8 | */
9 | .factory('$$stackedMap', function() {
10 | return {
11 | createNew: function() {
12 | var stack = [];
13 |
14 | return {
15 | add: function(key, value) {
16 | stack.push({
17 | key: key,
18 | value: value
19 | });
20 | },
21 | get: function(key) {
22 | for (var i = 0; i < stack.length; i++) {
23 | if (key === stack[i].key) {
24 | return stack[i];
25 | }
26 | }
27 | },
28 | keys: function() {
29 | var keys = [];
30 | for (var i = 0; i < stack.length; i++) {
31 | keys.push(stack[i].key);
32 | }
33 | return keys;
34 | },
35 | top: function() {
36 | return stack[stack.length - 1];
37 | },
38 | remove: function(key) {
39 | var idx = -1;
40 | for (var i = 0; i < stack.length; i++) {
41 | if (key === stack[i].key) {
42 | idx = i;
43 | break;
44 | }
45 | }
46 | return stack.splice(idx, 1)[0];
47 | },
48 | removeTop: function() {
49 | return stack.splice(stack.length - 1, 1)[0];
50 | },
51 | length: function() {
52 | return stack.length;
53 | }
54 | };
55 | }
56 | };
57 | })
58 | /**
59 | * A helper, internal data structure that stores all references attached to key
60 | */
61 | .factory('$$multiMap', function() {
62 | return {
63 | createNew: function() {
64 | var map = {};
65 |
66 | return {
67 | entries: function() {
68 | return Object.keys(map).map(function(key) {
69 | return {
70 | key: key,
71 | value: map[key]
72 | };
73 | });
74 | },
75 | get: function(key) {
76 | return map[key];
77 | },
78 | hasKey: function(key) {
79 | return !!map[key];
80 | },
81 | keys: function() {
82 | return Object.keys(map);
83 | },
84 | put: function(key, value) {
85 | if (!map[key]) {
86 | map[key] = [];
87 | }
88 |
89 | map[key].push(value);
90 | },
91 | remove: function(key, value) {
92 | var values = map[key];
93 |
94 | if (!values) {
95 | return;
96 | }
97 |
98 | var idx = values.indexOf(value);
99 |
100 | if (idx !== -1) {
101 | values.splice(idx, 1);
102 | }
103 |
104 | if (!values.length) {
105 | delete map[key];
106 | }
107 | }
108 | };
109 | }
110 | };
111 | })
112 |
113 | /**
114 | * Pluggable resolve mechanism for the modal resolve resolution
115 | * Supports UI Router's $resolve service
116 | */
117 | .provider('$wuResolve', function() {
118 | var resolve = this;
119 | this.resolver = null;
120 |
121 | this.setResolver = function(resolver) {
122 | this.resolver = resolver;
123 | };
124 |
125 | this.$get = ['$injector', '$q', function($injector, $q) {
126 | var resolver = resolve.resolver ? $injector.get(resolve.resolver) : null;
127 | return {
128 | resolve: function(invocables, locals, parent, self) {
129 | if (resolver) {
130 | return resolver.resolve(invocables, locals, parent, self);
131 | }
132 |
133 | var promises = [];
134 |
135 | angular.forEach(invocables, function(value) {
136 | if (angular.isFunction(value) || angular.isArray(value)) {
137 | promises.push($q.resolve($injector.invoke(value)));
138 | } else if (angular.isString(value)) {
139 | promises.push($q.resolve($injector.get(value)));
140 | } else {
141 | promises.push($q.resolve(value));
142 | }
143 | });
144 |
145 | return $q.all(promises).then(function(resolves) {
146 | var resolveObj = {};
147 | var resolveIter = 0;
148 | angular.forEach(invocables, function(value, key) {
149 | resolveObj[key] = resolves[resolveIter++];
150 | });
151 |
152 | return resolveObj;
153 | });
154 | }
155 | };
156 | }];
157 | })
158 |
159 | /**
160 | * A helper directive for the $modal service. It creates a backdrop element.
161 | *//*
162 | .directive('wuModalBackdrop', ['$animateCss', '$injector', '$wuModalStack',
163 | function($animateCss, $injector, $modalStack) {
164 | return {
165 | replace: true,
166 | templateUrl: 'wu/template/modal/backdrop.html',
167 | compile: function(tElement, tAttrs) {
168 | tElement.addClass(tAttrs.backdropClass);
169 | return linkFn;
170 | }
171 | };
172 |
173 | function linkFn(scope, element, attrs) {
174 | if (attrs.modalInClass) {
175 | $animateCss(element, {
176 | addClass: attrs.modalInClass
177 | }).start();
178 |
179 | scope.$on($modalStack.NOW_CLOSING_EVENT, function(e, setIsAsync) {
180 | var done = setIsAsync();
181 | if (scope.modalOptions.animation) {
182 | $animateCss(element, {
183 | removeClass: attrs.modalInClass
184 | }).start().then(done);
185 | } else {
186 | done();
187 | }
188 | });
189 | }
190 | }
191 | }])
192 |
193 | .directive('wuModalWindow', ['$wuModalStack', '$q', '$animate', '$animateCss', '$document',
194 | function($modalStack, $q, $animate, $animateCss, $document) {
195 | return {
196 | scope: {
197 | index: '@'
198 | },
199 | replace: true,
200 | transclude: true,
201 | templateUrl: function(tElement, tAttrs) {
202 | return tAttrs.templateUrl || 'wu/template/modal/window.html';
203 | },
204 | link: function(scope, element, attrs) {
205 | element.addClass(attrs.windowClass || '');
206 | element.addClass(attrs.windowTopClass || '');
207 | scope.size = attrs.size;
208 |
209 | scope.close = function(evt) {
210 | var modal = $modalStack.getTop();
211 | if (modal && modal.value.backdrop &&
212 | modal.value.backdrop !== 'static' &&
213 | evt.target === evt.currentTarget) {
214 | evt.preventDefault();
215 | evt.stopPropagation();
216 | $modalStack.dismiss(modal.key, 'backdrop click');
217 | }
218 | };
219 |
220 | // moved from template to fix issue #2280
221 | element.on('click', scope.close);
222 |
223 | // This property is only added to the scope for the purpose of detecting when this directive is rendered.
224 | // We can detect that by using this property in the template associated with this directive and then use
225 | // {@link Attribute#$observe} on it. For more details please see {@link TableColumnResize}.
226 | scope.$isRendered = true;
227 |
228 | // Deferred object that will be resolved when this modal is render.
229 | var modalRenderDeferObj = $q.defer();
230 | // Observe function will be called on next digest cycle after compilation, ensuring that the DOM is ready.
231 | // In order to use this way of finding whether DOM is ready, we need to observe a scope property used in modal's template.
232 | attrs.$observe('modalRender', function(value) {
233 | if (value === 'true') {
234 | modalRenderDeferObj.resolve();
235 | }
236 | });
237 |
238 | modalRenderDeferObj.promise.then(function() {
239 | var animationPromise = null;
240 |
241 | if (attrs.modalInClass) {
242 | animationPromise = $animateCss(element, {
243 | addClass: attrs.modalInClass
244 | }).start();
245 |
246 | scope.$on($modalStack.NOW_CLOSING_EVENT, function(e, setIsAsync) {
247 | var done = setIsAsync();
248 | if ($animateCss) {
249 | $animateCss(element, {
250 | removeClass: attrs.modalInClass
251 | }).start().then(done);
252 | } else {
253 | $animate.removeClass(element, attrs.modalInClass).then(done);
254 | }
255 | });
256 | }
257 |
258 |
259 | $q.when(animationPromise).then(function() {
260 | /!**
261 | * If something within the freshly-opened modal already has focus (perhaps via a
262 | * directive that causes focus). then no need to try and focus anything.
263 | *!/
264 | if (!($document[0].activeElement && element[0].contains($document[0].activeElement))) {
265 | var inputWithAutofocus = element[0].querySelector('[autofocus]');
266 | /!**
267 | * Auto-focusing of a freshly-opened modal element causes any child elements
268 | * with the autofocus attribute to lose focus. This is an issue on touch
269 | * based devices which will show and then hide the onscreen keyboard.
270 | * Attempts to refocus the autofocus element via JavaScript will not reopen
271 | * the onscreen keyboard. Fixed by updated the focusing logic to only autofocus
272 | * the modal element if the modal does not contain an autofocus element.
273 | *!/
274 | if (inputWithAutofocus) {
275 | inputWithAutofocus.focus();
276 | } else {
277 | element[0].focus();
278 | }
279 | }
280 | });
281 |
282 | // Notify {@link $modalStack} that modal is rendered.
283 | var modal = $modalStack.getTop();
284 | if (modal) {
285 | $modalStack.modalRendered(modal.key);
286 | }
287 | });
288 | }
289 | };
290 | }])
291 |
292 | .directive('wuModalAnimationClass', function() {
293 | return {
294 | compile: function(tElement, tAttrs) {
295 | if (tAttrs.modalAnimation) {
296 | tElement.addClass(tAttrs.wuModalAnimationClass);
297 | }
298 | }
299 | };
300 | })
301 | */
302 | .directive('wuModalTransclude', function() {
303 | return {
304 | link: function(scope, element, attrs, controller, transclude) {
305 | transclude(scope.$parent, function(clone) {
306 | element.empty();
307 | element.append(clone);
308 | });
309 | }
310 | };
311 | })
312 |
313 | .factory('$wuModalStack', ['$animate', '$animateCss', '$document',
314 | '$compile', '$rootScope', '$q', '$$multiMap', '$$stackedMap',
315 | function($animate, $animateCss, $document, $compile, $rootScope, $q, $$multiMap, $$stackedMap) {
316 | var OPENED_MODAL_CLASS = 'modal-open';
317 |
318 | var backdropDomEl, backdropScope;
319 | var openedWindows = $$stackedMap.createNew();
320 | var openedClasses = $$multiMap.createNew();
321 | var $modalStack = {
322 | NOW_CLOSING_EVENT: 'modal.stack.now-closing'
323 | };
324 |
325 | //Modal focus behavior
326 | var focusableElementList;
327 | var focusIndex = 0;
328 | var tababbleSelector = 'a[href], area[href], input:not([disabled]), ' +
329 | 'button:not([disabled]),select:not([disabled]), textarea:not([disabled]), ' +
330 | 'iframe, object, embed, *[tabindex], *[contenteditable=true]';
331 |
332 | function backdropIndex() {
333 | var topBackdropIndex = -1;
334 | var opened = openedWindows.keys();
335 | for (var i = 0; i < opened.length; i++) {
336 | if (openedWindows.get(opened[i]).value.backdrop) {
337 | topBackdropIndex = i;
338 | }
339 | }
340 | return topBackdropIndex;
341 | }
342 |
343 | $rootScope.$watch(backdropIndex, function(newBackdropIndex) {
344 | if (backdropScope) {
345 | backdropScope.index = newBackdropIndex;
346 | }
347 | });
348 |
349 | function removeModalWindow(modalInstance, elementToReceiveFocus) {
350 | var modalWindow = openedWindows.get(modalInstance).value;
351 | var appendToElement = modalWindow.appendTo;
352 |
353 | //clean up the stack
354 | openedWindows.remove(modalInstance);
355 |
356 | removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, function() {
357 | var modalBodyClass = modalWindow.openedClass || OPENED_MODAL_CLASS;
358 | openedClasses.remove(modalBodyClass, modalInstance);
359 | appendToElement.toggleClass(modalBodyClass, openedClasses.hasKey(modalBodyClass));
360 | toggleTopWindowClass(true);
361 | });
362 | checkRemoveBackdrop();
363 |
364 | //move focus to specified element if available, or else to body
365 | if (elementToReceiveFocus && elementToReceiveFocus.focus) {
366 | elementToReceiveFocus.focus();
367 | } else if (appendToElement.focus) {
368 | appendToElement.focus();
369 | }
370 | }
371 |
372 | // Add or remove "windowTopClass" from the top window in the stack
373 | function toggleTopWindowClass(toggleSwitch) {
374 | var modalWindow;
375 |
376 | if (openedWindows.length() > 0) {
377 | modalWindow = openedWindows.top().value;
378 | modalWindow.modalDomEl.toggleClass(modalWindow.windowTopClass || '', toggleSwitch);
379 | }
380 | }
381 |
382 | function checkRemoveBackdrop() {
383 | //remove backdrop if no longer needed
384 | if (backdropDomEl && backdropIndex() === -1) {
385 | var backdropScopeRef = backdropScope;
386 | removeAfterAnimate(backdropDomEl, backdropScope, function() {
387 | backdropScopeRef = null;
388 | });
389 | backdropDomEl = undefined;
390 | backdropScope = undefined;
391 | }
392 | }
393 |
394 | function removeAfterAnimate(domEl, scope, done, closedDeferred) {
395 | var asyncDeferred;
396 | var asyncPromise = null;
397 | var setIsAsync = function() {
398 | if (!asyncDeferred) {
399 | asyncDeferred = $q.defer();
400 | asyncPromise = asyncDeferred.promise;
401 | }
402 |
403 | return function asyncDone() {
404 | asyncDeferred.resolve();
405 | };
406 | };
407 | scope.$broadcast($modalStack.NOW_CLOSING_EVENT, setIsAsync);
408 |
409 | // Note that it's intentional that asyncPromise might be null.
410 | // That's when setIsAsync has not been called during the
411 | // NOW_CLOSING_EVENT broadcast.
412 | return $q.when(asyncPromise).then(afterAnimating);
413 |
414 | function afterAnimating() {
415 | if (afterAnimating.done) {
416 | return;
417 | }
418 | afterAnimating.done = true;
419 |
420 | $animateCss(domEl, {
421 | event: 'leave'
422 | }).start().then(function() {
423 | domEl.remove();
424 | if (closedDeferred) {
425 | closedDeferred.resolve();
426 | }
427 | });
428 |
429 | scope.$destroy();
430 | if (done) {
431 | done();
432 | }
433 | }
434 | }
435 |
436 | $document.on('keydown', keydownListener);
437 |
438 | $rootScope.$on('$destroy', function() {
439 | $document.off('keydown', keydownListener);
440 | });
441 |
442 | function keydownListener(evt) {
443 | if (evt.isDefaultPrevented()) {
444 | return evt;
445 | }
446 |
447 | var modal = openedWindows.top();
448 | if (modal) {
449 | switch (evt.which) {
450 | case 27: {
451 | if (modal.value.keyboard) {
452 | evt.preventDefault();
453 | $rootScope.$apply(function() {
454 | $modalStack.dismiss(modal.key, 'escape key press');
455 | });
456 | }
457 | break;
458 | }
459 | case 9: {
460 | $modalStack.loadFocusElementList(modal);
461 | var focusChanged = false;
462 | if (evt.shiftKey) {
463 | if ($modalStack.isFocusInFirstItem(evt)) {
464 | focusChanged = $modalStack.focusLastFocusableElement();
465 | }
466 | } else {
467 | if ($modalStack.isFocusInLastItem(evt)) {
468 | focusChanged = $modalStack.focusFirstFocusableElement();
469 | }
470 | }
471 |
472 | if (focusChanged) {
473 | evt.preventDefault();
474 | evt.stopPropagation();
475 | }
476 | break;
477 | }
478 | }
479 | }
480 | }
481 |
482 | $modalStack.open = function(modalInstance, modal) {
483 | var modalOpener = $document[0].activeElement,
484 | modalBodyClass = modal.openedClass || OPENED_MODAL_CLASS;
485 |
486 | toggleTopWindowClass(false);
487 |
488 | openedWindows.add(modalInstance, {
489 | deferred: modal.deferred,
490 | renderDeferred: modal.renderDeferred,
491 | closedDeferred: modal.closedDeferred,
492 | modalScope: modal.scope,
493 | backdrop: modal.backdrop,
494 | keyboard: modal.keyboard,
495 | openedClass: modal.openedClass,
496 | windowTopClass: modal.windowTopClass,
497 | animation: modal.animation,
498 | appendTo: modal.appendTo
499 | });
500 |
501 | openedClasses.put(modalBodyClass, modalInstance);
502 |
503 | var appendToElement = modal.appendTo,
504 | currBackdropIndex = backdropIndex();
505 |
506 | if (!appendToElement.length) {
507 | throw new Error('appendTo element not found. Make sure that the element passed is in DOM.');
508 | }
509 |
510 | if (currBackdropIndex >= 0 && !backdropDomEl) {
511 | backdropScope = $rootScope.$new(true);
512 | backdropScope.modalOptions = modal;
513 | backdropScope.index = currBackdropIndex;
514 | backdropDomEl = angular.element('');
515 | backdropDomEl.attr('backdrop-class', modal.backdropClass);
516 | if (modal.animation) {
517 | backdropDomEl.attr('modal-animation', 'true');
518 | }
519 | $compile(backdropDomEl)(backdropScope);
520 | $animate.enter(backdropDomEl, appendToElement);
521 | }
522 |
523 | var angularDomEl = angular.element('');
524 | angularDomEl.attr({
525 | 'template-url': modal.windowTemplateUrl,
526 | 'window-class': modal.windowClass,
527 | 'window-top-class': modal.windowTopClass,
528 | 'size': modal.size,
529 | 'index': openedWindows.length() - 1,
530 | 'animate': 'animate'
531 | }).html(modal.content);
532 | if (modal.animation) {
533 | angularDomEl.attr('modal-animation', 'true');
534 | }
535 |
536 | $animate.enter(angularDomEl, appendToElement)
537 | .then(function() {
538 | $compile(angularDomEl)(modal.scope);
539 | $animate.addClass(appendToElement, modalBodyClass);
540 | });
541 |
542 | openedWindows.top().value.modalDomEl = angularDomEl;
543 | openedWindows.top().value.modalOpener = modalOpener;
544 |
545 | $modalStack.clearFocusListCache();
546 | };
547 |
548 | function broadcastClosing(modalWindow, resultOrReason, closing) {
549 | return !modalWindow.value.modalScope.$broadcast('modal.closing', resultOrReason, closing).defaultPrevented;
550 | }
551 |
552 | $modalStack.close = function(modalInstance, result) {
553 | var modalWindow = openedWindows.get(modalInstance);
554 | if (modalWindow && broadcastClosing(modalWindow, result, true)) {
555 | modalWindow.value.modalScope.$$wuDestructionScheduled = true;
556 | modalWindow.value.deferred.resolve(result);
557 | removeModalWindow(modalInstance, modalWindow.value.modalOpener);
558 | return true;
559 | }
560 | return !modalWindow;
561 | };
562 |
563 | $modalStack.dismiss = function(modalInstance, reason) {
564 | var modalWindow = openedWindows.get(modalInstance);
565 | if (modalWindow && broadcastClosing(modalWindow, reason, false)) {
566 | modalWindow.value.modalScope.$$wuDestructionScheduled = true;
567 | modalWindow.value.deferred.reject(reason);
568 | removeModalWindow(modalInstance, modalWindow.value.modalOpener);
569 | return true;
570 | }
571 | return !modalWindow;
572 | };
573 |
574 | $modalStack.dismissAll = function(reason) {
575 | var topModal = this.getTop();
576 | while (topModal && this.dismiss(topModal.key, reason)) {
577 | topModal = this.getTop();
578 | }
579 | };
580 |
581 | $modalStack.getTop = function() {
582 | return openedWindows.top();
583 | };
584 |
585 | $modalStack.modalRendered = function(modalInstance) {
586 | var modalWindow = openedWindows.get(modalInstance);
587 | if (modalWindow) {
588 | modalWindow.value.renderDeferred.resolve();
589 | }
590 | };
591 |
592 | $modalStack.focusFirstFocusableElement = function() {
593 | if (focusableElementList.length > 0) {
594 | focusableElementList[0].focus();
595 | return true;
596 | }
597 | return false;
598 | };
599 | $modalStack.focusLastFocusableElement = function() {
600 | if (focusableElementList.length > 0) {
601 | focusableElementList[focusableElementList.length - 1].focus();
602 | return true;
603 | }
604 | return false;
605 | };
606 |
607 | $modalStack.isFocusInFirstItem = function(evt) {
608 | if (focusableElementList.length > 0) {
609 | return (evt.target || evt.srcElement) === focusableElementList[0];
610 | }
611 | return false;
612 | };
613 |
614 | $modalStack.isFocusInLastItem = function(evt) {
615 | if (focusableElementList.length > 0) {
616 | return (evt.target || evt.srcElement) === focusableElementList[focusableElementList.length - 1];
617 | }
618 | return false;
619 | };
620 |
621 | $modalStack.clearFocusListCache = function() {
622 | focusableElementList = [];
623 | focusIndex = 0;
624 | };
625 |
626 | $modalStack.loadFocusElementList = function(modalWindow) {
627 | if (focusableElementList === undefined || !focusableElementList.length) {
628 | if (modalWindow) {
629 | var modalDomE1 = modalWindow.value.modalDomEl;
630 | if (modalDomE1 && modalDomE1.length) {
631 | focusableElementList = modalDomE1[0].querySelectorAll(tababbleSelector);
632 | }
633 | }
634 | }
635 | };
636 |
637 | return $modalStack;
638 | }])
639 |
640 | .provider('$wuModal', function() {
641 | var $modalProvider = {
642 | options: {
643 | animation: true,
644 | backdrop: true, //can also be false or 'static'
645 | keyboard: true
646 | },
647 | $get: ['$rootScope', '$q', '$document', '$templateRequest', '$controller', '$wuResolve', '$wuModalStack',
648 | function ($rootScope, $q, $document, $templateRequest, $controller, $wuResolve, $modalStack) {
649 | var $modal = {};
650 |
651 | function getTemplatePromise(options) {
652 | return options.template ? $q.when(options.template) :
653 | $templateRequest(angular.isFunction(options.templateUrl) ?
654 | options.templateUrl() : options.templateUrl);
655 | }
656 |
657 | var promiseChain = null;
658 | $modal.getPromiseChain = function() {
659 | return promiseChain;
660 | };
661 |
662 | $modal.open = function(modalOptions) {
663 | var modalResultDeferred = $q.defer();
664 | var modalOpenedDeferred = $q.defer();
665 | var modalClosedDeferred = $q.defer();
666 | var modalRenderDeferred = $q.defer();
667 |
668 | //prepare an instance of a modal to be injected into controllers and
669 | // returned to a caller
670 | var modalInstance = {
671 | result: modalResultDeferred.promise,
672 | opened: modalOpenedDeferred.promise,
673 | closed: modalClosedDeferred.promise,
674 | rendered: modalRenderDeferred.promise,
675 | close: function (result) {
676 | return $modalStack.close(modalInstance, result);
677 | },
678 | dismiss: function (reason) {
679 | return $modalStack.dismiss(modalInstance, reason);
680 | }
681 | };
682 |
683 | //merge and clean up options
684 | modalOptions = angular.extend({}, $modalProvider.options, modalOptions);
685 | modalOptions.resolve = modalOptions.resolve || {};
686 | modalOptions.appendTo = modalOptions.appendTo || $document.find('body').eq(0);
687 |
688 | //verify options
689 | if (!modalOptions.template && !modalOptions.templateUrl) {
690 | throw new Error('One of template or templateUrl options is required.');
691 | }
692 |
693 | var templateAndResolvePromise =
694 | $q.all([getTemplatePromise(modalOptions), $wuResolve.resolve(modalOptions.resolve, {}, null, null)]);
695 |
696 | function resolveWithTemplate() {
697 | return templateAndResolvePromise;
698 | }
699 |
700 | // Wait for the resolution of the existing promise chain.
701 | // Then switch to our own combined promise dependency (regardless of how
702 | // the previous modal fared). Then add to $modalStack and resolve opened.
703 | // Finally clean up the chain variable if no subsequent modal has
704 | // overwritten it.
705 | var samePromise;
706 | samePromise = promiseChain = $q.all([promiseChain])
707 | .then(resolveWithTemplate, resolveWithTemplate)
708 | .then(function resolveSuccess(tplAndVars) {
709 | var providedScope = modalOptions.scope || $rootScope;
710 |
711 | var modalScope = providedScope.$new();
712 | modalScope.$close = modalInstance.close;
713 | modalScope.$dismiss = modalInstance.dismiss;
714 |
715 | modalScope.$on('$destroy', function() {
716 | if (!modalScope.$$wuDestructionScheduled) {
717 | modalScope.$dismiss('$wuUnscheduledDestruction');
718 | }
719 | });
720 |
721 | var ctrlInstance, ctrlLocals = {};
722 |
723 | //controllers
724 | if (modalOptions.controller) {
725 | ctrlLocals.$scope = modalScope;
726 | ctrlLocals.$wuModalInstance = modalInstance;
727 | angular.forEach(tplAndVars[1], function(value, key) {
728 | ctrlLocals[key] = value;
729 | });
730 |
731 | ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
732 | if (modalOptions.controllerAs) {
733 | if (modalOptions.bindToController) {
734 | ctrlInstance.$close = modalScope.$close;
735 | ctrlInstance.$dismiss = modalScope.$dismiss;
736 | angular.extend(ctrlInstance, providedScope);
737 | }
738 |
739 | modalScope[modalOptions.controllerAs] = ctrlInstance;
740 | }
741 | }
742 |
743 | $modalStack.open(modalInstance, {
744 | scope: modalScope,
745 | deferred: modalResultDeferred,
746 | renderDeferred: modalRenderDeferred,
747 | closedDeferred: modalClosedDeferred,
748 | content: tplAndVars[0],
749 | animation: modalOptions.animation,
750 | backdrop: modalOptions.backdrop,
751 | keyboard: modalOptions.keyboard,
752 | backdropClass: modalOptions.backdropClass,
753 | windowTopClass: modalOptions.windowTopClass,
754 | windowClass: modalOptions.windowClass,
755 | windowTemplateUrl: modalOptions.windowTemplateUrl,
756 | size: modalOptions.size,
757 | openedClass: modalOptions.openedClass,
758 | appendTo: modalOptions.appendTo
759 | });
760 | modalOpenedDeferred.resolve(true);
761 |
762 | }, function resolveError(reason) {
763 | modalOpenedDeferred.reject(reason);
764 | modalResultDeferred.reject(reason);
765 | })['finally'](function() {
766 | if (promiseChain === samePromise) {
767 | promiseChain = null;
768 | }
769 | });
770 |
771 | return modalInstance;
772 | };
773 |
774 | return $modal;
775 | }
776 | ]
777 | };
778 |
779 | return $modalProvider;
780 | });
781 |
782 | /**
783 | * 客户端检测代码
784 | */
785 | window.weui_client_browser_checker = (function () {
786 | // 呈现引擎
787 | var engine = {
788 | ie: 0,
789 | gecko: 0,
790 | webkit: 0,
791 | khtml: 0,
792 | opera: 0,
793 | // 完整的版本号
794 | ver: null
795 | };
796 |
797 | // 浏览器
798 | var browser = {
799 | // 主要浏览器
800 | ie: 0,
801 | firefox: 0,
802 | safari: 0,
803 | konq: 0,
804 | opera: 0,
805 | chrome: 0,
806 | wx: 0,
807 | wxpc: 0,
808 | // 具体的版本号
809 | ver: null
810 | };
811 |
812 | // 平台、设备和操作系统
813 | var system = {
814 | win: false,
815 | mac: false,
816 | x11: false,
817 |
818 | // 移动设备
819 | iphone: false,
820 | ipod: false,
821 | ipad: false,
822 | ios: false,
823 | android: false,
824 | nokiaN: false,
825 | winMobile: false,
826 |
827 | //游戏系统
828 | wii: false,
829 | ps: false
830 | };
831 |
832 | // 检测呈现引擎和浏览器
833 | var ua = navigator.userAgent;
834 | if (window.opera) {
835 | engine.ver = browser.ver = window.opera.version();
836 | engine.opera = browser.opera = parseFloat(engine.ver);
837 | } else if (/AppleWebKit\/(\S+)/.test(ua)) {
838 | engine.ver = RegExp["$1"];
839 | engine.webkit = parseFloat(engine.ver);
840 |
841 | // 确定是 chrome 还是 safari
842 | if (/Chrome\/(\S+)/.test(ua)) {
843 | browser.ver = RegExp["$1"];
844 | browser.chrome = parseFloat(browser.ver);
845 | } else if (/Version\/(\S+)/.test(ua)) {
846 | browser.ver = RegExp["$1"];
847 | browser.safari = parseFloat(browser.ver);
848 | } else {
849 | // 近似地确定版本号
850 | var safariVersion = 1;
851 | if (engine.webkit < 100) {
852 | safariVersion = 1;
853 | } else if (engine.webkit < 312) {
854 | safariVersion = 1.2;
855 | } else if (engine.webkit < 412) {
856 | safariVersion = 1.3;
857 | } else {
858 | safariVersion = 2;
859 | }
860 | browser.safari = browser.ver = safariVersion;
861 | }
862 | } else if (/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+])/.test(ua)) {
863 | engine.ver = browser.ver = RegExp["$1"];
864 | engine.khtml = browser.konq = parseFloat(engine.ver);
865 | } else if (/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)) {
866 | engine.ver = RegExp["$1"];
867 | browser.gecko = parseFloat(engine.ver);
868 |
869 | // 确定是否是firefox
870 | if (/Firefox\/(\S+)/.test(ua)) {
871 | browser.ver = RegExp["$1"];
872 | browser.firefox = parseFloat(browser.ver);
873 | }
874 | } else if (/MSIE ([^;]+)/.test(ua)) {
875 | engine.ver = browser.ver = RegExp["$1"];
876 | engine.ie = browser.ie = parseFloat(engine.ver);
877 | }
878 |
879 | // 微信检查
880 | if (/MicroMessenger\/([\d\.]+)/i.test(ua)) {
881 | browser.ver = RegExp["$1"];
882 | browser.wx = 'micromessenger';
883 |
884 | browser.wxpc = /WindowsWechat/i.test(ua);
885 | }
886 |
887 | // 坚持浏览器
888 | browser.ie = engine.ie;
889 | browser.opera = engine.opera;
890 |
891 | // 检测平台
892 | var p = navigator.platform;
893 | system.win = p.indexOf("Win") >= 0;
894 | system.mac = p.indexOf("Mac") >= 0;
895 | system.x11 = (p == "X11") || (p.indexOf("Linux") == 0);
896 |
897 | // 检测 windows 操作版本
898 | if (system.win) {
899 | if (/Win(?:dows )?([^do]{2})\s?(\d+\.\d+)?/.test(ua)) {
900 | if (RegExp["$1"] == "NT") {
901 | switch (RegExp["$2"]) {
902 | case "5.0":
903 | system.win = "2000";
904 | break;
905 | case "5.1":
906 | system.win = "XP";
907 | break;
908 | case "6.0":
909 | system.win = "vista";
910 | break;
911 | case "6.1":
912 | system.win = "7";
913 | break;
914 | default :
915 | system.win = "NT";
916 | break;
917 | }
918 | } else if (RegExp["$1"] == "9x") {
919 | system.win = "ME";
920 | } else {
921 | system.win = RegExp["$1"];
922 | }
923 | }
924 | }
925 |
926 | // 检测移动设备
927 | system.iphone = ua.indexOf("iPhone") > -1;
928 | system.ipod = ua.indexOf("iPod") > -1;
929 | system.ipad = ua.indexOf("iPad") > -1;
930 | system.nokiaN = ua.indexOf("NokinaN") > -1;
931 |
932 | // windows mobile
933 | if (system.win == "CE") {
934 | system.winMobile = system.win;
935 | } else if (system.win == "Ph") {
936 | if (/Window Phone OS (\d+.\d+)/.test(ua)) {
937 | system.win = "Phone";
938 | system.winMobile = parseFloat(RegExp["$1"]);
939 | }
940 | }
941 |
942 | // 检测 iOS 版本
943 | if (system.iphone && ua.indexOf("Mobile") > -1) {
944 | if (/CPU (?:iPhone)?[ ]?OS (\d+_\d+)/.test(ua)) {
945 | system.ios = parseFloat(RegExp.$1.replace("_", "."));
946 | } else {
947 | system.ios = 2; // 不能真正检测出来,所以只能猜测
948 | }
949 | }
950 |
951 | // 检测 android 版本
952 | if (/Android (\d+\.\d+)/.test(ua)) {
953 | system.android = parseFloat(RegExp.$1);
954 | }
955 |
956 | // 游戏系统
957 | system.wii = ua.indexOf("Wii") > -1;
958 | system.ps = /playstation/i.test(ua);
959 |
960 | // 返回对象
961 | return {
962 | engine: engine,
963 | browser: browser,
964 | system: system
965 | }
966 | })();
967 | app.provider('WuBrowserChecker', [function () {
968 | var self = this;
969 | self.$get = [function () {
970 | return window.weui_client_browser_checker;
971 | }]
972 | }]);
973 |
974 | app.provider('IdWorkerFactory',[function () {
975 | var factories = {};
976 | this.new = function IdWorkerFactory(prefix) {
977 | if(!factories.hasOwnProperty(prefix)) {
978 | factories[prefix] = (function (p) {
979 | var count = 0;
980 | return function () {
981 | return p+'_'+(count++);
982 | }
983 | })(prefix);
984 | }
985 | return factories[prefix];
986 | };
987 |
988 | this.$get = [function() {
989 | return this;
990 | }]
991 | }])
992 |
993 | })(angular.module('ng.weui.core'), window);
994 |
--------------------------------------------------------------------------------
/src/js/form.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 常用form组件封装,包含表单验证
3 | */
4 | (function (app) {
5 | // input-text
6 | // input-textarea
7 | // input-file
8 | // input-image
9 | // input-date
10 | // input-map
11 | // input-address
12 | // input-phone
13 | // input-email
14 | // input-number
15 | // input-search
16 | // input-select
17 | // input-checkbox
18 | // input-radio
19 | // input-switch
20 | /**
21 | * TODO 还不知道是否必要 form 组件
22 | */
23 | app.directive('inputTextarea',[function () {
24 |
25 | return {
26 | restrict:'EA',
27 | replace: true,
28 | templateUrl:'weui/template/form/input-textarea.html',
29 | require:'ngModel',
30 | link: function(scope, element, attrs, ngModelCtrl) {
31 | ngModelCtrl.$render = function() {
32 | console.log()
33 | }
34 | }
35 | }
36 | }]);
37 |
38 | /**
39 | * 微信上传图片
40 | * TODO 需要识别微信手机端和微信pc端,需要微信jssdk支持
41 | */
42 | app.directive('inputImage', [function () {
43 | return {
44 | restrict:'EA',
45 | replace: true,
46 | templateUrl:'weui/template/form/input-image.html',
47 | require:'ngModel',
48 | link: function(scope, element, attrs, ngModelCtrl) {
49 | ngModelCtrl.$render = function() {
50 | console.log()
51 | }
52 | }
53 | }
54 | }])
55 | })(angular.module('ng.weui.form'));
56 |
--------------------------------------------------------------------------------
/src/js/gallery.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @Date 16/10/6
4 | * @User three
5 | */
6 |
7 | (function (app) {
8 | /**
9 | * 调用微信js api 演示图片预览
10 | */
11 | app.factory('PreviewImages', ['WuWxJsSdk', function (WuWxJsSdk) {
12 | return {
13 | show: function (current, imgList) {
14 | WuWxJsSdk.previewImage({
15 | current: current,
16 | urls: imgList
17 | });
18 | }
19 | }
20 | }]);
21 | /**
22 | * 调用微信js api 演示图片预览指令
23 | */
24 | app.directive('previewImages', ['PreviewImages', function (PreviewImages) {
25 | return {
26 | restrict: 'AE',
27 | link: function (scope, element, attrs) {
28 | var box = element;
29 | var selector = attrs.preview? attrs.preview : 'img';
30 | var attrName = attrs.attrName? attrs.attrName : 'src';
31 |
32 | element.on('click', selector, function (e) {
33 | var src = $(this),
34 | imgList = [];
35 | box.find(selector).each(function (index,item) {
36 | imgList.push(item.attr(attrName));
37 | });
38 |
39 | PreviewImages.show(src.attr(attrName), imgList);
40 |
41 | e.preventDefault();
42 | e.stopPropagation();
43 | return false;
44 | });
45 | }
46 | }
47 | }]);
48 |
49 | /**
50 | * h5 实现预览功能
51 | */
52 | app.directive('gallery', ['$timeout','IdWorkerFactory', function ($timeout,IdWorkerFactory) {
53 |
54 | var galleryIdWorker = IdWorkerFactory.new('weui-gallery_swiper');
55 |
56 | return {
57 | restrict: 'EA',
58 | //replace: true,
59 | templateUrl: 'weui/template/gallery/gallery.html',
60 | scope: {
61 | images: "="
62 | },
63 | link: function (scope, element, attrs) {
64 |
65 | var galleryId = galleryIdWorker();
66 | element.attr("id", galleryId);
67 | element.addClass("weui-gallery");
68 |
69 | element.show();
70 | //scope.clickElement = function () {
71 | // element.hide();
72 | //};
73 |
74 | ///**
75 | // * 用户操作回调
76 | // */
77 | //scope.clickBtn = function (e) {
78 | // scope.action && scope.action({
79 | // image: scope.image
80 | // });
81 | // e.preventDefault();
82 | //};
83 |
84 | /**
85 | * 显示缩略图
86 | * @type {boolean}
87 | */
88 | scope.showThumb = false;
89 | if(angular.isArray(scope.images) && scope.images.length>0) {
90 |
91 | if(scope.images[0].hasOwnProperty('thumb')) {
92 | scope.showThumb = true;
93 | }
94 |
95 | initSwiper();
96 | }
97 |
98 | scope.imageStyle = function (image) {
99 | return {
100 | 'background-image': 'url('+image.url+')'
101 | }
102 | };
103 |
104 | function initSwiper() {
105 |
106 | $timeout(function () {
107 | console.log('#'+galleryId+' .swiper-images');
108 |
109 | var galleryTop = new Swiper('#'+galleryId+' .swiper-images', {
110 | nextButton: '.swiper-button-next',
111 | prevButton: '.swiper-button-prev',
112 | spaceBetween: 10,
113 | effect: 'coverflow',
114 | grabCursor: true,
115 | centeredSlides: true,
116 | slidesPerView: 'auto',
117 | coverflow: {
118 | rotate: 50,
119 | stretch: 0,
120 | depth: 100,
121 | modifier: 1,
122 | slideShadows : true
123 | }
124 | });
125 |
126 | if(scope.showThumb) {
127 | var galleryThumbs = new Swiper('#'+galleryId+' .gallery-thumbs', {
128 | spaceBetween: 10,
129 | centeredSlides: true,
130 | slidesPerView: 'auto',
131 | touchRatio: 0.2,
132 | slideToClickedSlide: true
133 | });
134 | galleryTop.params.control = galleryThumbs;
135 | galleryThumbs.params.control = galleryTop;
136 | }
137 |
138 | },10)
139 | }
140 |
141 | }
142 | }
143 | }])
144 | })(angular.module('ng.weui.gallery'));
145 |
146 |
--------------------------------------------------------------------------------
/src/js/loading.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @Date 16/10/6
4 | * @User three
5 | */
6 |
7 | (function(app){
8 | app.directive('loadingEnable', [function () {
9 | return {
10 | restrict: 'A',
11 | replace:true,
12 | templateUrl: 'weui/template/loading/loading.html',
13 | transclude:true,
14 | link: function ($scope, $element, $attrs) {
15 |
16 | }
17 | }
18 | }])
19 | })(angular.module('ng.weui.loading'), window);
--------------------------------------------------------------------------------
/src/js/module.js:
--------------------------------------------------------------------------------
1 |
2 | 'use strict';
3 | angular.module('ng.weui.core',[]);
4 |
5 | /**
6 | * 企业号/服务号jssdk封装
7 | */
8 | angular.module('ng.weui.jssdk',[]);
9 | /**
10 | * swiper 封装
11 | */
12 | angular.module('ng.weui.swiper', ['ng.weui.core']);
13 |
14 | angular.module('ng.weui.button',[]);
15 | angular.module('ng.weui.progress',[]);
16 | angular.module('ng.weui.dialog',['ng.weui.core']);
17 | angular.module('ng.weui.actionsheet',['ng.weui.core']);
18 | angular.module('ng.weui.toast',['ng.weui.core']);
19 | angular.module('ng.weui.form',['ng.weui.core']);
20 | angular.module('ng.weui.gallery',['ng.weui.core', 'ng.weui.swiper']);
21 | angular.module('ng.weui.loading',['ng.weui.core']);
22 | angular.module('ng.weui',[
23 | 'ng.weui.core',
24 | 'ng.weui.button',
25 | 'ng.weui.actionsheet',
26 | 'ng.weui.dialog',
27 | 'ng.weui.toast',
28 | 'ng.weui.form',
29 | 'ng.weui.gallery',
30 | 'ng.weui.loading',
31 | 'ng.weui.progress'
32 | ]);
33 |
--------------------------------------------------------------------------------
/src/js/ng-swiper.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @Date 2016/11/3
4 | * @User three
5 | */
6 |
7 | (function(window, app, undefined) {
8 |
9 | 'use strict';
10 |
11 | app
12 | .directive('wuSwiperContainer', ['IdWorkerFactory', function (IdWorkerFactory) {
13 | var IdWorker = IdWorkerFactory('wuSwiperContainer');
14 | return {
15 | restrict: 'E',
16 | transclude: true,
17 | scope: {
18 | onReady: '&',
19 | slidesPerView: '=',
20 | slidesPerColumn: '=',
21 | spaceBetween: '=',
22 | parallax: '=',
23 | parallaxTransition: '@',
24 | paginationIsActive: '=',
25 | paginationClickable: '=',
26 | showNavButtons: '=',
27 | showScrollBar: '=',
28 | loop: '=',
29 | autoplay: '=',
30 | initialSlide: '=',
31 | containerCls: '@',
32 | wrapperCls: '@',
33 | paginationCls: '@',
34 | slideCls: '@',
35 | direction: '@',
36 | swiper: '=',
37 | overrideParameters: '='
38 | },
39 | controller: function($scope, $element, $timeout) {
40 | var uuid = IdWorker();
41 |
42 | $scope.swiper_uuid = uuid;
43 |
44 | // directive defaults
45 | var params = {
46 | slidesPerView: $scope.slidesPerView || 1,
47 | slidesPerColumn: $scope.slidesPerColumn || 1,
48 | spaceBetween: $scope.spaceBetween || 0,
49 | direction: $scope.direction || 'horizontal',
50 | loop: $scope.loop || false,
51 | initialSlide: $scope.initialSlide || 0,
52 | showNavButtons: false
53 | };
54 |
55 | if (!angular.isUndefined($scope.autoplay) && typeof $scope.autoplay === 'number') {
56 | params = angular.extend({}, params, {
57 | autoplay: $scope.autoplay
58 | });
59 | }
60 |
61 | if ($scope.paginationIsActive === true) {
62 | params = angular.extend({}, params, {
63 | paginationClickable: $scope.paginationClickable || true,
64 | pagination: '#paginator-' + $scope.swiper_uuid
65 | });
66 | }
67 |
68 | if ($scope.showNavButtons === true) {
69 | params.nextButton = '#nextButton-' + $scope.swiper_uuid;
70 | params.prevButton = '#prevButton-' + $scope.swiper_uuid;
71 | }
72 |
73 | if ($scope.showScrollBar === true) {
74 | params.scrollbar = '#scrollBar-' + $scope.swiper_uuid;
75 | }
76 |
77 | if ($scope.overrideParameters) {
78 | params = angular.extend({}, params, $scope.overrideParameters);
79 | }
80 |
81 | $timeout(function() {
82 | var swiper = null;
83 |
84 | if (angular.isObject($scope.swiper)) {
85 | $scope.swiper = new Swiper($element[0].firstChild, params);
86 | swiper = $scope.swiper;
87 | } else {
88 | swiper = new Swiper($element[0].firstChild, params);
89 | }
90 |
91 | //If specified, calls this function when the swiper object is available
92 | if (!angular.isUndefined($scope.onReady)) {
93 | $scope.onReady({
94 | swiper: swiper
95 | });
96 | }
97 | });
98 | },
99 |
100 | link: function(scope, element) {
101 |
102 | var uuid = scope.swiper_uuid;
103 |
104 | var paginatorId = "paginator-" + uuid;
105 | var prevButtonId = "prevButton-" + uuid;
106 | var nextButtonId = "nextButton-" + uuid;
107 | var scrollBarId = 'scrollBar-' + uuid;
108 |
109 | var containerElement = element[0];
110 |
111 | angular.element(containerElement.querySelector('.swiper-pagination'))
112 | .attr('id', paginatorId);
113 |
114 | angular.element(containerElement.querySelector('.swiper-button-next'))
115 | .attr('id', nextButtonId);
116 |
117 | angular.element(containerElement.querySelector('.swiper-button-prev'))
118 | .attr('id', prevButtonId);
119 |
120 | angular.element(element[0].querySelector('.swiper-scrollbar'))
121 | .attr('id', scrollBarId);
122 | },
123 |
124 | template: '' +
125 | '
' +
126 | '
' +
127 | '' +
128 | '
' +
129 | '
' +
130 | '
' +
131 | '
'
132 | };
133 | }])
134 | .directive('wuSwiperSlide', [function SwiperSlide() {
135 | return {
136 | restrict: 'E',
137 | require: '^ksSwiperContainer',
138 | transclude: true,
139 | scope: {
140 | sliderCls: '@',
141 | },
142 | template: '',
143 | replace: true
144 | };
145 | }]);
146 |
147 | })(window, angular.module('ng.weui.swiper'), undefined);
--------------------------------------------------------------------------------
/src/js/progress.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 16/1/14.
3 | */
4 |
5 | (function (app) {
6 | app.directive('wuProgress',[function () {
7 | return {
8 | restrict:'EA',
9 | replace: true,
10 | scope: {
11 | wuProgress:"=",
12 | wuColor:'=',
13 | wuHeight:'='
14 | },
15 | transclude:true,
16 | template:'\
17 | ',
27 | link: function (scope, element, attrs) {
28 | scope.filterProgress = function (number) {
29 | if(number>100) {
30 | return '100%';
31 | }
32 | if(number<0) {
33 | return '0%';
34 | }
35 | return parseFloat(number)+'%';
36 | };
37 | scope.filterHeight = function (height) {
38 | return ((height && height>1)?height:3)+'px';
39 | }
40 | }
41 | }
42 | }]);
43 | })(angular.module('ng.weui.progress'));
44 |
--------------------------------------------------------------------------------
/src/js/wx-jssdk.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 微信基本js接口
3 | */
4 | (function (app, window) {
5 | app.factory('WuWxJsSdk',['$q', function ($q) {
6 | /**
7 | * 获取微信js接口对象
8 | * @param reject 如果没有js接口对象,调用通知方法
9 | * @returns {*} false 或 js接口对象
10 | */
11 | function checkWxObj(reject) {
12 | if(!window.wx) {
13 | reject({
14 | errMsg: '没有js接口对象,请确认是否引入微信js文件'
15 | });
16 | return false;
17 | }
18 | return window.wx;
19 | }
20 |
21 | /**
22 | * 构建接口参数回调
23 | * @param params
4 |
11 |
--------------------------------------------------------------------------------
/src/weui/template/dialog/android.html:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/src/weui/template/dialog/default.html:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/src/weui/template/form/input-image.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
9 |
10 |
11 |
12 |
13 | -
14 |
15 |
16 |
17 |
18 | 50%
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/weui/template/form/input-textarea.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/weui/template/gallery/gallery.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/weui/template/loading/loading.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 正在加载
5 |
6 |
7 | 暂无数据
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/weui/template/toast/complete.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/weui/template/toast/loading.html:
--------------------------------------------------------------------------------
1 |
2 |
6 |
--------------------------------------------------------------------------------
/src/weui/template/toast/message.html:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/src/weui/template/wu-window.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/test/e2e/main.po.js:
--------------------------------------------------------------------------------
1 | /**
2 | * This file uses the Page Object pattern to define the main page for tests
3 | * https://docs.google.com/presentation/d/1B6manhG0zEXkC-H-tPo2vwU06JhL8w9-XCF9oehXzAQ
4 | */
5 |
6 | 'use strict';
7 |
8 | var MainPage = function() {
9 | this.div = element(by.css('body div'));
10 | };
11 |
12 | module.exports = new MainPage();
13 |
--------------------------------------------------------------------------------
/test/e2e/main.spec.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('The main view', function () {
4 | var page;
5 |
6 | beforeEach(function () {
7 | browser.get('http://192.168.35.188:3000/test.html');
8 | page = require('./main.po');
9 | });
10 |
11 | it('should include binding test.aaa data', function() {
12 | // 取绑定数据 方式1
13 | element(by.binding('test.aaa')).getText().then(function (aaa) {
14 | expect(aaa).toBe('bbbbbbbbbbbbbcccc');
15 | });
16 | // 取绑定数据 方式2
17 | expect(element(by.binding('test.aaa')).getText()).toBe('bbbbbbbbbbbbbcccc');
18 |
19 | // 获取div
20 | element(by.css('div')).getText().then(function (aaa) {
21 | console.log(aaa);
22 | })
23 | });
24 |
25 | });
26 |
--------------------------------------------------------------------------------
/test/serve/demo-gallery.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | angular-WeUI
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/test/serve/demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | angular-WeUI
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Action Sheet
26 | confirm
27 | confirm no title
28 | alert
29 | 自定义按钮
30 | 自定义按钮 android
31 | Toast 完成
32 | Toast Loading
33 | Toast Message show
34 | button wu-click test
35 | 按钮
36 | 按钮
37 | wuProgress
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
59 |
60 | swiper 测试
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/test/serve/demo_js/test-gallery.js:
--------------------------------------------------------------------------------
1 | /**
2 | *
3 | * @Date 2016/11/3
4 | * @User three
5 | */
6 |
7 | (function (app) {
8 | app.controller('TestGalleryCtrl',['WuActionSheet','WuDialog','WuToast', function (WuActionSheet,WuDialog,WuToast) {
9 |
10 | this.previewImages = [
11 | {
12 | thumb:'images/pic_article.png',
13 | url:'images/pic_article.png'
14 | },{
15 | thumb:'images/pic_article.png',
16 | url:'images/pic_article.png'
17 | },{
18 | thumb:'images/pic_article.png',
19 | url:'images/pic_article.png'
20 | },{
21 | thumb:'images/pic_article.png',
22 | url:'images/pic_article.png'
23 | },{
24 | thumb:'images/pic_article.png',
25 | url:'images/pic_article.png'
26 | },{
27 | thumb:'images/pic_article.png',
28 | url:'images/pic_article.png'
29 | },{
30 | thumb:'images/pic_article.png',
31 | url:'images/pic_article.png'
32 | },{
33 | thumb:'images/pic_article.png',
34 | url:'images/pic_article.png'
35 | },{
36 | thumb:'images/pic_article.png',
37 | url:'images/pic_article.png'
38 | },{
39 | thumb:'images/pic_article.png',
40 | url:'images/pic_article.png'
41 | },
42 | ];
43 | }])
44 | })(angular.module('test.gallery',['ng.weui']));
45 |
--------------------------------------------------------------------------------
/test/serve/demo_js/test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 15/9/7.
3 | */
4 |
5 | (function (app) {
6 | app.controller('TestCtrl',['WuActionSheet','WuDialog','WuToast', function (WuActionSheet,WuDialog,WuToast) {
7 |
8 | this.actionSheet = function () {
9 | WuActionSheet.open({
10 | btnGroups:[
11 | {
12 | action: 'Ok',
13 | buttons:[
14 | {
15 | title:'11',
16 | value:'11'
17 | },
18 | {
19 | title:'22',
20 | value:'22'
21 | },
22 | {
23 | title:'33',
24 | value:'33'
25 | },
26 | {
27 | title:'44',
28 | value:'44'
29 | }
30 | ]
31 | },
32 | {
33 | action: 'Cancel',
34 | buttons:[
35 | { title: 'cancel1', value: 'cancel1'}
36 | ]
37 | },
38 | {
39 | action: 'Close',
40 | buttons:[
41 | { title: 'cancel11', value: 'cancel1'}
42 | ]
43 | }
44 | ]
45 | }).result.then(function (btn) {
46 | console.log(btn)
47 | }, function (cancel) {
48 | console.log(cancel)
49 | });
50 | };
51 |
52 | this.confirm = function () {
53 | WuDialog.confirm({
54 | title: '确认框',
55 | content: 'xxxx确认内容sfsfsdfsadfsadfdsafdsafsdaf'
56 | }).result.then(function () {
57 | console.log('ok');
58 | }, function () {
59 | console.log('cancel')
60 | });
61 | };
62 | this.confirmNoTitle = function () {
63 | WuDialog.confirm({
64 | content: 'sfsafsfsasadfsfsfsfasfas'
65 | }).result.then(function () {
66 | console.log('ok');
67 | }, function () {
68 | console.log('cancel')
69 | });
70 | };
71 |
72 | this.alert = function () {
73 | WuDialog.alert({
74 | title: '提示框',
75 | content: 'xxxx Alert内容
'
76 | }).result.then(function () {
77 | console.log('ok');
78 | }, function () {
79 | console.log('close alert')
80 | });
81 | };
82 |
83 | this.dialog = function () {
84 | WuDialog.open({
85 | title:'自定义按钮',
86 | content:'自定义按钮测试',
87 | buttons:[
88 | { action:'ok', title:'btn1', class: 'default', value:'btn1' },
89 | { action:'ok', title:'btn2', class: 'primary', value:'btn2' },
90 | { action:'cancel', title:'btn3', class: 'default', value:'btn3' },
91 | { action:'cancel', title:'btn4', class: 'primary', value:'btn4' }
92 | ]
93 | }).result.then(function () {
94 | console.log("OK: ", arguments[0])
95 | },function () {
96 | console.log("Cancel: ", arguments[0])
97 | })
98 | };
99 |
100 | this.dialogAndroid = function () {
101 | WuDialog.open({
102 | title:'自定义按钮',
103 | content:'自定义按钮测试',
104 | template: 'wu-dialog-android-template',
105 | buttons:[
106 | { action:'ok', title:'btn1', class: 'default', value:'btn1' },
107 | { action:'ok', title:'btn2', class: 'primary', value:'btn2' },
108 | { action:'cancel', title:'btn3', class: 'default', value:'btn3' },
109 | { action:'cancel', title:'btn4', class: 'primary', value:'btn4' }
110 | ]
111 | }).result.then(function () {
112 | console.log("OK: ", arguments[0])
113 | },function () {
114 | console.log("Cancel: ", arguments[0])
115 | })
116 | }
117 | this.toastComplete = function () {
118 | WuToast.complete({
119 | time:1000
120 | });
121 | };
122 |
123 | this.toastLoading = function () {
124 | var loadingObj = WuToast.loading({
125 | message:'数据加载中'
126 | });
127 | setTimeout(function () {
128 | loadingObj.close();
129 | }, 1000)
130 | };
131 | this.toastMessage = function () {
132 | var loadingObj = WuToast.message({
133 | message:'test asdfasdf sdfasdf asdfsadfv sdfsad asfsadf sdfasfda sdfasfasdf message show'
134 | });
135 | };
136 |
137 | this.wuButtonTest = function () {
138 | console.log('xxxxxxxxxxxxxxx');
139 | };
140 |
141 | this.testVar = 'nihao'
142 |
143 | this.wuButtonTest1 = function (data) {
144 | console.log('000000000000000', data);
145 | };
146 |
147 | this.cancelProgress = function () {
148 | this.wuProgress = 50;
149 | }
150 | }])
151 | })(angular.module('test',['ng.weui']));
152 |
--------------------------------------------------------------------------------
/test/serve/images/pic_article.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/threeq/angular-weui/1002a448faaa734df74dc7ab03acb3afe31a1454/test/serve/images/pic_article.png
--------------------------------------------------------------------------------
/test/unit/localize-test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by three on 15/7/7.
3 | */
4 |
5 | describe('components:localize test', function() {
6 | var $compile;
7 | var $rootScope;
8 | var $filter;
9 | var httpBackend;
10 | var __localize;
11 | // Load the myApp module, which contains the directive
12 | beforeEach(angular.mock.module('ng.poler'));
13 | // Store references to $rootScope and $compile
14 | // so they are available to all tests in this describe block
15 | beforeEach(inject(function(_$compile_, _$rootScope_,_$filter_,$httpBackend, localize){
16 | // The injector unwraps the underscores (_) from around the parameter names when matching
17 | $compile = _$compile_;
18 | $rootScope = _$rootScope_;
19 | $filter = _$filter_;
20 | httpBackend = $httpBackend;
21 | __localize = localize;
22 |
23 | __localize.configLang('zh_CN',{
24 | hello:"你好",
25 | change:"我改变了"
26 | }).configLang("en_US",{
27 | hello:"hello US",
28 | change:"changed US"
29 | }).configLang('server', "/lang/server_lang.json");
30 |
31 | }));
32 |
33 | afterEach(function () {
34 | httpBackend.verifyNoOutstandingExpectation();
35 | httpBackend.verifyNoOutstandingRequest();
36 | });
37 |
38 | it('localize 配置测试', function () {
39 |
40 | __localize.configLang();
41 |
42 | httpBackend.when('GET','/lang/error_lang.json').respond(404,"没有语言文件");
43 | __localize.configLang('error_lang', '/lang/error_lang.json');
44 | var p = __localize.setLang('error_lang');
45 | httpBackend.flush();
46 | p.then(function (data) {
47 | //expect().to
48 | console.log('测试失败:获取语言失败', data)
49 | }, function (error) {
50 | console.log('测试成功:获取语言失败', error)
51 | });
52 |
53 | httpBackend.when('GET','/lang/500.json').respond(500,"没有语言文件");
54 | __localize.configLang('500', '/lang/500.json');
55 | var p = __localize.setLang('500');
56 | httpBackend.flush();
57 | p.then(function (data) {
58 | //expect().to
59 | console.log('测试失败:获取语言失败', data)
60 | }, function (error) {
61 | console.log('测试成功:获取语言失败', error)
62 | });
63 |
64 | __localize.configLang('error_lang1', true);
65 | __localize.setLang('error_lang1').then(function (data) {
66 | //expect().to
67 | console.log('测试失败:获取语言失败', data)
68 | }, function (error) {
69 | console.log('测试成功:获取语言失败', error)
70 | });
71 |
72 | __localize.configLang('error_lang2', [1,2,4]);
73 | __localize.setLang('error_lang2').then(function (data) {
74 | //expect().to
75 | console.log('测试失败', data)
76 | }, function (error) {
77 | console.log('测试成功', error)
78 | });
79 |
80 | __localize.configLang('error_lang3', new Date());
81 | __localize.setLang('error_lang3').then(function (data) {
82 | //expect().to
83 | console.log('测试失败', data)
84 | }, function (error) {
85 | console.log('测试成功', error)
86 | });
87 |
88 | __localize.configLang('error_lang4', function () {
89 |
90 | });
91 | __localize.setLang('error_lang4').then(function (data) {
92 | //expect().to
93 | console.log('测试失败', data)
94 | }, function (error) {
95 | console.log('测试成功', error)
96 | });
97 |
98 | __localize.configLang('success_lang5', function () {
99 | return {a:'a',b:'b'};
100 | });
101 | __localize.setLang('success_lang5').then(function (data) {
102 | //expect().to
103 | console.log('测试成功', data)
104 | }, function (error) {
105 | console.log('测试失败', error)
106 | });
107 |
108 |
109 | __localize.configLang('success_lang6', function () {
110 | return '/lang/success_lang6.json';
111 | });
112 | httpBackend.when('GET','/lang/success_lang6.json').respond(200, {
113 | success:'test'
114 | });
115 | __localize.setLang('success_lang6').then(function (data) {
116 | //expect().to
117 | console.log('测试成功', data)
118 | }, function (error) {
119 | console.log('测试失败', error)
120 | });
121 | httpBackend.flush();
122 | });
123 |
124 | it('localize service 语言翻译测试', function() {
125 | var hello_CN;
126 | var world_CN;
127 | __localize.setLang("zh_CN");
128 | hello_CN = __localize.localizeText("hello");
129 | world_CN = __localize.localizeText("world");
130 | expect(hello_CN).toEqual("你好");
131 | expect(world_CN).toEqual("world");
132 |
133 | __localize.setLang('en_US');
134 | hello_CN = __localize.localizeText("hello");
135 | world_CN = __localize.localizeText("world");
136 | expect(hello_CN).toEqual("hello US");
137 | expect(world_CN).toEqual("world");
138 |
139 | __localize.setLang('bbb');
140 |
141 | httpBackend.when('GET','/lang/server_lang.json').respond(200, {
142 | hello:"hello Server",
143 | change:"changed Server"
144 | });
145 | __localize.setLang('server');
146 | httpBackend.flush();
147 |
148 | hello_CN = __localize.localizeText("hello");
149 | world_CN = __localize.localizeText("world");
150 | expect(hello_CN).toEqual("hello Server");
151 | expect(world_CN).toEqual("world");
152 |
153 | });
154 |
155 | it('localize 指令 语言翻译测试', function () {
156 |
157 |
158 | $rootScope.test='hello';
159 | var helloElement = $compile('');
160 | var worldElement = $compile('');
161 |
162 | var hello1Element = $compile('');
163 | var world1Element = $compile('');
164 |
165 | var hello2Element = $compile('{{test}}');
166 | var world2Element = $compile('world');
167 |
168 | var hello3Element = $compile('{{test}}');
169 | var world3Element = $compile('world');
170 |
171 | var input1Element = $compile('');
172 | var input2Element = $compile('');
173 | var input3Element = $compile('');
174 | var input4Element = $compile('');
175 | var input5Element = $compile('');
176 | var input6Element = $compile('');
177 |
178 | expect(helloElement($rootScope).html()).toEqual('hello');
179 | expect(worldElement($rootScope).html()).toEqual('world');
180 |
181 | expect(hello1Element($rootScope).html()).toEqual('hello');
182 | expect(world1Element($rootScope).html()).toEqual('world');
183 |
184 | expect(hello2Element($rootScope).html()).toEqual('hello');
185 | expect(world2Element($rootScope).html()).toEqual('world');
186 |
187 | expect(hello3Element($rootScope).html()).toEqual('hello');
188 | expect(world3Element($rootScope).html()).toEqual('world');
189 |
190 | expect(input1Element($rootScope).attr('placeholder')).toEqual('hello');
191 | expect(input2Element($rootScope).attr('placeholder')).toEqual('world');
192 | expect(input3Element($rootScope).attr('placeholder')).toEqual('hello');
193 | expect(input4Element($rootScope).attr('placeholder')).toEqual('world');
194 | expect(input5Element($rootScope).attr('placeholder')).toBeUndefined();
195 | expect(input6Element($rootScope).attr('placeholder')).toEqual('');
196 |
197 |
198 | __localize.setLang('zh_CN');
199 | expect(helloElement($rootScope).html()).toEqual('你好');
200 | expect(worldElement($rootScope).html()).toEqual('world');
201 | expect(hello1Element($rootScope).html()).toEqual('你好');
202 | expect(world1Element($rootScope).html()).toEqual('world');
203 | expect(hello2Element($rootScope).html()).toEqual('你好');
204 | expect(world2Element($rootScope).html()).toEqual('world');
205 | expect(hello3Element($rootScope).html()).toEqual('你好');
206 | expect(world3Element($rootScope).html()).toEqual('world');
207 |
208 | expect(input1Element($rootScope).attr('placeholder')).toEqual('你好');
209 | expect(input2Element($rootScope).attr('placeholder')).toEqual('world');
210 | expect(input3Element($rootScope).attr('placeholder')).toEqual('你好');
211 | expect(input4Element($rootScope).attr('placeholder')).toEqual('world');
212 | expect(input5Element($rootScope).attr('placeholder')).toBeUndefined();
213 | expect(input6Element($rootScope).attr('placeholder')).toEqual('');
214 |
215 | __localize.setLang('en_US');
216 | expect(helloElement($rootScope).html()).toEqual('hello US');
217 | expect(worldElement($rootScope).html()).toEqual('world');
218 | expect(hello1Element($rootScope).html()).toEqual('hello US');
219 | expect(world1Element($rootScope).html()).toEqual('world');
220 | expect(hello2Element($rootScope).html()).toEqual('hello US');
221 | expect(world2Element($rootScope).html()).toEqual('world');
222 | expect(hello3Element($rootScope).html()).toEqual('hello US');
223 | expect(world3Element($rootScope).html()).toEqual('world');
224 |
225 | expect(input1Element($rootScope).attr('placeholder')).toEqual('hello US');
226 | expect(input2Element($rootScope).attr('placeholder')).toEqual('world');
227 | expect(input3Element($rootScope).attr('placeholder')).toEqual('hello US');
228 | expect(input4Element($rootScope).attr('placeholder')).toEqual('world');
229 | expect(input5Element($rootScope).attr('placeholder')).toBeUndefined();
230 | expect(input6Element($rootScope).attr('placeholder')).toEqual('');
231 |
232 |
233 | $rootScope.test = "change";
234 | expect(helloElement($rootScope).html()).toEqual('changed US');
235 | expect(worldElement($rootScope).html()).toEqual('world');
236 | expect(hello1Element($rootScope).html()).toEqual('changed US');
237 | expect(world1Element($rootScope).html()).toEqual('world');
238 | expect(hello2Element($rootScope).html()).toEqual('changed US');
239 | expect(world2Element($rootScope).html()).toEqual('world');
240 | expect(hello3Element($rootScope).html()).toEqual('changed US');
241 | expect(world3Element($rootScope).html()).toEqual('world');
242 |
243 | expect(input1Element($rootScope).attr('placeholder')).toEqual('changed US');
244 | expect(input2Element($rootScope).attr('placeholder')).toEqual('world');
245 | expect(input3Element($rootScope).attr('placeholder')).toEqual('changed US');
246 | expect(input4Element($rootScope).attr('placeholder')).toEqual('world');
247 | expect(input5Element($rootScope).attr('placeholder')).toBeUndefined();
248 | expect(input6Element($rootScope).attr('placeholder')).toEqual('');
249 |
250 |
251 | __localize.setLang('zh_CN');
252 | expect(helloElement($rootScope).html()).toEqual('我改变了');
253 | expect(worldElement($rootScope).html()).toEqual('world');
254 | expect(hello1Element($rootScope).html()).toEqual('我改变了');
255 | expect(world1Element($rootScope).html()).toEqual('world');
256 | expect(hello2Element($rootScope).html()).toEqual('我改变了');
257 | expect(world2Element($rootScope).html()).toEqual('world');
258 | expect(hello3Element($rootScope).html()).toEqual('我改变了');
259 | expect(world3Element($rootScope).html()).toEqual('world');
260 |
261 | expect(input1Element($rootScope).attr('placeholder')).toEqual('我改变了');
262 | expect(input2Element($rootScope).attr('placeholder')).toEqual('world');
263 | expect(input3Element($rootScope).attr('placeholder')).toEqual('我改变了');
264 | expect(input4Element($rootScope).attr('placeholder')).toEqual('world');
265 | expect(input5Element($rootScope).attr('placeholder')).toBeUndefined();
266 | expect(input6Element($rootScope).attr('placeholder')).toEqual('');
267 |
268 | });
269 |
270 | it('localize 过滤器 语言翻译测试', inject(function ($interpolate) {
271 | $rootScope.test='hello';
272 | var text;
273 | var localizeFilter = $filter('localize');
274 | var localizeInterpolate = $interpolate('{{test|localize}}');
275 | text = localizeFilter('hello');
276 | expect(text).toEqual('hello');
277 | expect(localizeInterpolate($rootScope)).toEqual('hello');
278 |
279 | __localize.setLang('zh_CN');
280 | text = localizeFilter('hello');
281 | expect(text).toEqual('你好');
282 | expect(localizeInterpolate($rootScope)).toEqual('你好');
283 |
284 |
285 | __localize.setLang('en_US');
286 | text = localizeFilter('hello');
287 | expect(text).toEqual('hello US');
288 | expect(localizeInterpolate($rootScope)).toEqual('hello US');
289 |
290 | $rootScope.test='change';
291 |
292 | expect(localizeInterpolate($rootScope)).toEqual('changed US');
293 | }))
294 | });
295 |
--------------------------------------------------------------------------------